News:

Let's find out together what makes a PIC Tick!

Main Menu

Crating a chart on the 1 inch SSD1306 display

Started by Yves, Aug 09, 2023, 10:39 AM

Previous topic - Next topic

Yves

Hello Picsters,

I'm like to draw a X/Y chart on the small SSD1306 1 inch display. X is increasing regularly every second and y get resized value from an a/d signal. Now I'm using DrawPixel, but it is not looking that good. I'm not sure on how to join the dots with a line on each point. Below the excellent Dompie code snippet.   

[Graphic_]DrawPixel(x0, y0, color)
        -    draw a Pixel
[Graphic_]DrawLine(x0, y0, x1, y1, Color)
        -    draw a Line
[Graphic_]DrawLinTo(x1, y1, Color)
        -    draw a Line from last DrawLine endpoint To x1, y1

Regards,

Yves
Yves

TimB


When I had to create a graph on an LCD I scaled the input to match the screen. Also depending the amount of data I wanted to squeeze on the screen I would plot only every x data point

I hope to answer your point I just used a line function from last x,y to next x,y

If it might be of help I can post the code

Tim


Yves

Thanks Tim,
Your explanation was clear and succinct. So the last x,y to the new x,y then then the previous new x,y becomes the last x,y and so on. thanks again.

Yves
Yves

Yves

Hello all,
I'm still battling with doing a chart with the X/Y line chart on the small SSD1306 1 inch display. I'm using Demo_SSD1306_v1.bas from Dompe. My code goes like this:
 fillRectangle (0,0,128,30,0) 'draw a filled rectangle delete the top display

SelectFont(Calibri_10)
Print At 1,9,"mV:  ",SDec0 (New Value * mV_factor), "  mA: ", Dec2 mA.

If loop_seconds = 120 Then
     New_X = (New_Seconds/2)
  Else
     New_X = New_Seconds
EndIf

New_Y = Abs(New_Derivative/120)+30   

[Graphic_]DrawLine(x0, y0, x1, y1, Color)
 -    draw a Line   

 DrawLine(Old_X, Old_Y, New_X, New_Y, 1) 
 
RefreshDisplay()     

Old_X = New_X
Old_Y = New_Y


The seconds are moving horizontally and the Y values within 30 to 64.
I'm not getting the normal line chart. While x is increasing 1 step at the time.
I have the ssd1306 demo 

Yves

trastikata

Quote from: Yves on Aug 16, 2023, 03:37 PMI'm not getting the normal line chart. While x is increasing 1 step at the time.

If you are increasing x by 1, then you don't have any pixels in between the old and the new value to make the line. Instead of 128 points graph, make a 20 or so points graph and space the them equally over the abscissa, then you can connect the individual data points with a line ... but on a 128x64 display it still will look rough.

I usually make a circular chart buffer and re-draw the chart with each new point - gives the impression of live chart. 

Yves

Thanks trastikata,
It is not really true. For example if Y deviate quite significantly from the previous Y, there will be two points quite apart and it will look nicer to have a line in between those 2 points. It is a life chart I tried to do. I will be grateful if someone could clarify a little further on the subject. Many thanks in advance.

Regards,

Yves   
Yves

trastikata

Quote from: Yves on Aug 16, 2023, 07:44 PMIt is not really true. For example if Y deviate quite significantly from the previous Y, there will be two points quite apart and it will look nicer to have a line in between those 2 points.

Yves,

I think here's some misunderstanding. A 128x64 (or any other display) display has grid of pixels forming 128 columns (representing the abscissa, thus x) and 64 rows (representing the ordinate, thus y). A line is drawn illuminating all pixels calculated from the line equation (derived from the two points coordinates) by changing one of the variables (either x or y) - remember pixels are represented only by integer values - column xx, row yy.

If you take two points with sequential values over the abscissa, regardless their ordinate values, you still have no pixels to draw between them over the abscissa.

For example point A(10,15) and point B(11,30) and you want to draw a line between them. How many points i.e. pixels, will have your line representing the x-direction, remember you don't have a pixel at position 10.1 , 10.2 etc.?

 

david

#7
Hi,
It may be worth taking a look at the various scrolling commands the device has available.  You can even set up a scrolling window to the size you want, which might be most of the screen, print a data value on the far right then do a left scroll and print a new data value at the same x location followed by another left scroll etc etc....
I should warn that this is not from experience but looking at the datasheet it seems it should be possible to create a live plot this way.

Cheers,
David

Yves

Thank you very much but so far I didn't get a straight answer on how to draw a line chart on the ssd1306 oled. I know how to squeeze the data and drawing pixels put battling to join those pixels with a line, that is all i need to know. it is a life chart. I have that function below but not sure how to use it.

[Graphic_]DrawPixel(x0, y0, color)
        -    draw a Pixel
    [Graphic_]DrawLine(x0, y0, x1, y1, Color)
        -    draw a Line 
Is x0 and y0 are the previous data and x1 and y1 the new one? I have tried along these but it doesn't work.

Regards,

Yves
Yves

david

Hello Yves,
Your understanding of the line function is correct but I have never used it for either OLED displays or for LCD graphic displays so I'm sorry I'm unable to help you.  I would also question how useful it would be on a such a small display.
As trastikata eloquently explained, you can not have a line drawn between two sequential x values regardless of the y values.
Have a look at the attached picture representing illuminated pixels on a display.  Yes it looks like gaps near the upper right where the y value has changed rapidly within 1 sample period but at least they are valid sample values and not some interpolated ones.  The plot may look prettier if you printed two pixels on the same x value in areas where there was transient behaviour but the data is not real.
If I needed to produce a live plot I would still be tempted to look at printing in the far right column and trying the shift left command of the display chip.

Cheers,
David

Gabi

Hello Yves

With a step of just 1 pixel for the Time axis there are not many options to plot your data.
So either the lonely dot plot as above, might be meaningless in heavy swing, or
draw a vertical line to the left of your new pixel.

It may be or not what you are after, something like:

dim oldX as byte = 0
dim oldY as byte = 0


proc draw_graph(newX as byte, newY as byte, color as byte)

    DrawPixel(newX, newX, color);    // plot new dot
   
    if oldX <> 0 and oldY <> 0 then; // whatever test for valid
        if newX - oldX = 1 then
            Draw_Vertical_Line(oldX, oldY, newX-1, newY, color); // draw line to the left of your new
        else
            DrawLine(oldX, oldY, newX, newY, color);
        EndIf
    Endif
    oldX = newX; //
    oldY = newY;
end proc

PS: If I am not mistaken, guess we were exchanging some emails back in 2008 ?, I was about to join a project in Harare but for whatever reasons I was diverted to Lusaka. Anyways, spent some good times there with Brian 9J2BO, and got myself 9J2YO at that time.

Best,
Gabi.
GL & 73
YO4WM