Plotting graphs

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Hey Sven,

      I thank you for your reply, and also for the PID file. That is great!

      So, the codes work correctly as they are meant to : touch screen button works and so the graph. This will give a good starting point to rework on my project.

      Have a great day and with kind regards,

    • Dear Sven,

      I have got one question while working on my project :
      #1. When I work with the array, how can I convert the type uint32_t to the type GUI_POINT ?
      I have been trying to resolve this issue, but fail so far.....

      I thank you in advance for your technical assistance and with my kind regards,

    • Hi,

      there are two types of graph data. One is using points (the XY version) and the other one uses values (YT).

      Call GRAPH_DATA_XY_GetPoint() to get a point of the given index. If you added 3 points use an index of 1 to get the second point. The point values are getting stored where pPoint points to.

      If you want to get the data stored in a YT graph call GRAPH_DATA_YT_GetValue(). Although, this data object doesn't work with GUI_POINTs you can create your own:

      Source Code

      1. GUI_POINT Point;
      2. Point.x = 10;
      3. GRAPH_DATA_YT_GetValue(hData, &Point.y, Point.x);

      You can use the return value of GRAPH_DATA_YT_GetValue() to check if there is a value at the given index.


    • Good morning Sven,

      I thank you very much for your quick and great reply : that helps me to move forward in my project.

      Further, I am going to implement this in my codes, and also to learn better the GUI chapter from your manual.
      Then, I will give you a feedback on how things work.....

      Have a nice day and with my kind regards,

    • Good morning Sven,

      I managed to get your example code of WIDGET_GraphXY.c and learn from it about the GUI_POINT.
      This part interests me a lot :
      _aPoint[0].x = (int) (100 - r * cos(Rad));
      _aPoint[0][i].y = (int) (100 + r * sin(Rad) * Deg / 360);

      So, inspiring from the above codes, I have done something similar :
      _aI[i].x = (int) Axis_U_Array[i];
      _aI[i].y = (int) Axis_I_Array[i];

      However, I have experienced the following issue with those codes :
      #1. Putting the break point just after those codes, the Axis_U_Array[i] and Axis_I_Array[i] have got the correct values. However, the _aI[i].x and _aI[i].y registers have got null values.
      Do you know what is wrong with that operation ?
      #2. I have been trying to use the function GRAPH_DATA_XY_GetPoint() to put the measurement values (from an array) to GUI_POINT, but fail so far.
      May I ask you an example or a tip on how to do this ?

      I thank you in advance for your useful help and with my kind regards,

    • Hey Sven,

      I have double-checked the break point and also the variables to get the values of the array registered into the _aI[] and _aP[] GUI_POINT array.
      That seems to be working, indeed. So, the point #1 is okay.

      Have a nice day and with kind regards,

    • Hey Sven,

      Learning from the WIDGET_GraphXY.c, I have managed to read and to display the measurement points. So, this is okay now.
      And I thank you for your technical support and help so far.

      Nowadays I have 2 questions regarding the graph display :
      #1. Plotting 2 graphs on the same display window, is it possible to have 2 different vertical Y axis sharing the same horizontal X axis ?
      The first Y axis for current measurements, and the second Y axis for power measurements.
      If this is possible, how could I do this ?
      #2. Is it possible to display a logo on the graph display window ? Do you have an example on how to do this ?

      I thank you in advance for your reply and have a nice day.

      With kind regards,

    • Hi Sven,

      I thank you very much for your reply.

      #1. Yes, I have done this. I had thought that the 2nd scale could be more complicated to do....

      #2. I have been working on this function GRAPH_SetUserDraw() to implement the company logo.
      Indeed, the WIDGET_GraphXY.c example has got this function, so it helps to understand how it should be done.

      Have a nice day and with kind regards,

    • Hey Sven,

      I hope that you have been going okay.... :)

      My project has been progressing finely, and I thank you very much for your technical support in resolving the problems. The STemWin is a great tool and I am pleased on how it works for the graphics application.
      So far, I have managed to display 2 graphs (Current and Power) as shown on the previous page, with some values and scales. Also, the WIDGET_GraphXY.c example has helped me a lot.

      However, I have been experiencing the following issue with the graph :
      #1. Using the "_OwnerDraw()" function and the "case WIDGET_ITEM_DRAW:" to display the circle (GUI_FillCircle), the circle is shown in around 2ms or less then disappears. This happens on the second graph.
      #2. On the first graph, I am able to display these points normally. But the points are not displayed / shown when their heights are near to 0.
      #3. Could I ask you how to resolve these problems ?

      Please feel free to say if you need further information about this (c file, for example).

      I thank you in advance and with kind regards,

      • WindowDLG.txt

        (19.78 kB, downloaded 180 times, last: )
    • Hi Sue,

      The GRAPH widget has no owner draw function. Instead it has a user draw which works slightly different. It uses different commands (although it might work cause they use similar values).

      Just refer to the API description of GRAPH_SetUserDraw(). It makes use of the following commands:


      A user draw func might look like this (pretty similar to a owner draw function):

      C Source Code

      1. /*********************************************************************
      2. *
      3. * _UserDraw
      4. */
      5. static void _UserDraw(WM_HWIN hWin, int Stage) {
      6. GUI_POINT Point;
      7. switch (Stage) {
      8. case GRAPH_DRAW_FIRST:
      9. GUI_DrawBitmap(&bmGradient_240x200, 40, 0);
      10. break;
      11. case GRAPH_DRAW_LAST:
      12. GUI_SetLineStyle(GUI_LS_DASH);
      13. if (GRAPH_DATA_XY_GetPoint(_hDataI, &Point, 1) == 0) {
      14. GUI_SetColor(GUI_BLUE);
      15. Point.x += BORDER_L;
      16. Point.y = 200 - (Point.y + BORDER_B);
      17. GUI_DrawLine(BORDER_L, Point.y, Point.x, Point.y);
      18. GUI_DrawLine(Point.x, Point.y, Point.x, 200 - BORDER_B);
      19. }
      20. GUI_SetColor(GUI_WHITE);
      21. GUI_FillCircle(Point.x, Point.y, 5);
      22. GUI_SetColor(GUI_BLUE);
      23. GUI_DrawCircle(Point.x, Point.y, 5);
      24. if (GRAPH_DATA_XY_GetPoint(_hDataP, &Point, 1) == 0) {
      25. GUI_SetColor(GUI_RED);
      26. Point.x += BORDER_L;
      27. Point.y = 200 - (Point.y + BORDER_B);
      28. GUI_DrawLine(BORDER_L, Point.y, Point.x, Point.y);
      29. GUI_DrawLine(Point.x, Point.y, Point.x, 200 - BORDER_B);
      30. }
      31. GUI_SetColor(GUI_WHITE);
      32. GUI_FillCircle(Point.x, Point.y, 5);
      33. GUI_SetColor(GUI_RED);
      34. GUI_DrawCircle(Point.x, Point.y, 5);
      35. break;
      36. }
      37. }
      Display All
      Also refer to the sample I have posted some time ago in this thread.

    • Hi Sven,

      I thank you very much for your reply, and also for having put me in the right direction.
      Your technical support is really helpful and valuable to work with STemWin. :) :thumbsup:

      So, I am going to work on this for my project and will keep you informed on the results.

      Thanks a lot again and I wish you a nice day. :)

      With kind regards,

    • Hi Sven,

      How have you been going ?

      It has been some time ago that I had asked you some technical assistance for my project. And here are the late news :
      The project of measuring a solar cell and plotting the I-U and Power graphs has been going very well. It works fine and I am quite happy about it. Also, I thank you very much for having helped me to use the STemWin.
      However, while doing a more consistent test on the project, I have experienced a technical issue. Also, I have been working to fix this issue, but fail so far.....

      As a brief explication, the project was built in the following way :
      #1. I used the WIDGET_GraphXY.c from your example (UM03001, Chapter 19, page 628) and then modified the code to fit my purpose.
      #2. The measurement sequence works as the following (in a loop) :
      #2.1. Push a button (as an interrupt) to start the sequence of measurement + plotting graphs.
      #2.1. Call CreateWindow() function to refresh the graphs.
      #2.2. Read the datas from DAC and ADC converters.
      #2.3. Call CreateWindow() function again to display the last measurement.

      The technical issue :
      #3. The code works properly. However, when doing the measurement in repetitive way, the code get stuck or freeze. I have done many tests and trials on this, and the results are : the scale is not displayed, unable to display the graphs and the program got stuck.
      Importantly, this issue happens very often after 10 or 15 measurements.

      Could I ask you the possible reason of this problem ? And, which parts of the file should I check ?

      Please feel free to comment as your help is very much appreciated. And I thank you in advance.

      With kind regards, :)

    • Hi,

      Do you only call CreateWindow() but never a WM_Delete() or something?

      Might it be possible that you run out of memory at some point?

      Are there some other resources which need to get freed (like Memory Device or user allocated buffers)?

    • Hi Sven,

      I thank you for your reply.

      Yes, I have used the function CreateWindow() without implementing the case WM_Delete, until now.

      My understanding is that the program runs out of memory at some points, and I really need to refresh / free the memory. Ideally, the program frees the memory after calling the function CreateWindow(). This way, there will not be an overflow of the memory being used.

      Here is a brief sequence of the code :

      static void _cbDialog(WM_MESSAGE * pMSG) {
      WM_HWIN hDlg;
      hDlg = pMsg->hWin;

      switch (pMsg->MsgId) {
      case WM_INIT_DIALOG :
      case WM_TIMER :
      // The case WM_DELETE is to be implemented.
      case WM_DELETE :
      default :

      I have been working on how to free the memory until now, without success unfortunately.

      On file STemwin_wrapper.c, I can see that the memory device is activated. Therefore, is there a way that I can free or delete the memory device ?
      Also, I have been searching the similar issue on the Segger forum, without getting an obvious understanding on how to do this.

      I thank you in advance for your help and with kind regards,

    • Hey Sven,

      So, I have made further investigations and tests regarding my technical issues. And, here are what I have done :
      #1. I put the maximum value for the emWin memory : GUI_NUMBYTES (1024) * 110
      #2. I implemented the code GUI_ALLOC_GetNumFreeBytes() to check the memory used every time I call CreateWindow().
      Using STMStudio to monitor, I could see that the free memory available has decreased each time the function CreateWindow() is called. And, every time the memory reached around 50'000, the program got stuck or does not work anymore.
      #3. So, ideally the memory must be freed or refreshed every time the function CreateWindow() is called.
      #4. I have been using several codes to free the memory : GUI_ALLOC_Free() / GUI_MEMDEV_Delete() / WM_InvalidateWindow() / WM_DeleteWindow(). Unfortunately without success so far....

      And, my questions are the following :
      #5. Is there a tutorial or an example on how to free the memory when working with emWin ?
      #6. Could I ask you the function or the way to do this properly ?

      I thank you in advance for your help and with kind regards, :)