Plotting sensor data on an LCD

Post content partially lost due to vandalism by author

It also plots an arbitrary sine wave.

It is my thinking that I can somehow associate the 'x' variable at the bottom of the code with the analogValue that is being read from the sensor. That should plot the waveform. I've been experimenting for the last few days with no luck.

So in short; the areas I would like some help in are:

  1. Plotting the sensor data to the LCD.
  2. Transitioning from the initial image to the plot screen.

SomewhatCompetent:
It also plots an arbitrary sine wave.

It is my thinking that I can somehow associate the 'x' variable at the bottom of the code with the analogValue that is being read from the sensor. That should plot the waveform. I've been experimenting for the last few days with no luck.

So in short; the areas I would like some help in are:

  1. Plotting the sensor data to the LCD.
  2. Transitioning from the initial image to the plot screen.

By definition, there is nothing arbitary about a sine wave. If you understand how it is drawn, you know just about all you need to know. The x-axis normally depicts a regular input, typically time, and the y-axis the resultant value, or a multiple thereof. Essentially, it is just a matter of transferring this to the x,y coordinates of a pixel, each time around the loop. This could be as simple as advancing the x-coord by one, using the value of the derived variable for the y-coordinate, and going round the loop again.

attached is a set of functions that all wo9rk but they are incorporated into my bigger project at the moment and i dont really have the time to dig out the pieces ... but it gives you these funtions.

void Graph(MCUFRIEND_kbv &d, double x, double y, double gx, double gy, double w, double h, double xlo, double xhi, double xinc, double ylo, double yhi, double yinc, String title, String xlabel, String ylabel, unsigned int gcolor, unsigned int acolor, unsigned int pcolor, unsigned int tcolor, unsigned int bcolor, boolean &redraw) 

void DrawBarChartV(MCUFRIEND_kbv & d, double x , double y , double w, double h , double loval , double hival , double inc , double curval ,  int dig , int dec, unsigned int barcolor, unsigned int voidcolor, unsigned int bordercolor, unsigned int textcolor, unsigned int backcolor, String label, boolean & redraw)


void DrawDial(MCUFRIEND_kbv & d, int cx, int cy, int r, double loval , double hival , double inc, double sa, double curval,  int dig , int dec, unsigned int needlecolor, unsigned int dialcolor, unsigned int  textcolor, String label, boolean & redraw) 


void DrawBarChartH(MCUFRIEND_kbv & d, double x , double y , double w, double h , double loval , double hival , double inc , double curval ,  int dig , int dec, unsigned int barcolor, unsigned int voidcolor, unsigned int bordercolor, unsigned int textcolor, unsigned int backcolor, String label, boolean & redraw)

void drawScale(){  


void drawBar (int nPer){

maybe in an hour or sow i will run the demo and post the vid or take some pictures. i adapted the codee from somewhere else to work with the mcu friend libraries, however they will work with any library just replace MCUFRIEND_KBV with what ever your graphics lib is..

-tbillion

graphs.ino (13.7 KB)

SomewhatCompetent:
Sorry, I meant arbitrary as in 'not related to any physical inputs'. It's being generated by code and not basing it off any inputs as I want to.

It can hardly do anything else, as it is just a demo, but if you look at the code it should nonetheless be clear, and clearly identified. There will probably be a for/next count routine, which you replace with a count, and then a formula calculating a sine, which you replace by a variable. The only problem is that a calculated sine looks nasty because it involves radians.

So, using the Henning Karlsen library, the example would be

  for (int i=80; i<478; i++)
  {
    myGLCD.drawPixel((i-20),119+(sin(((i*0.9)*3.14)/180)*95));
  }

and a real job would be more like

   i++;                                 //x-axis 0>640
    myGLCD.drawPixel(i,variable);   //y-axis sensor input 0>480

I don't know anything about analogue but you seem to be on the right track. It might pay to Serial.print y to make sure it is what yo would expect.

There are many different LCD devices. Many currently available and several obsolete. Which one do you have?

Paul

It isn't relevant.

There is clearly no problem with the LCD or the library. What is relevant is that you are drawing a bar when it should be a point. A bar is lots of points with one common coordinate.

I don't think your code is complete. The x-axis indicates time but you don't seem to have any control of it, and the loop is just going round as fast as it can. It may thus be that the LCD is working perfectly and is going through the X-count so fast that there is no time for y to change, hence the horizontal line, i.e. the code is working properly as written, but not as intended. A
delay(100);
might fix this, or at least prove the point.

You are cross-posting, which is not nice and will incur the wrath of the moderator.

I don't see the need for a swag of delays, just one big one at the end of the loop should suffice. This delay is essentially the x-interval.

I use, and I thought you were using, the Henning Karlsen RinkyDink library. I can't comment on the others, but I understand one library is much the same as another and I would have thought the features were common.

I'd also prefer a smooth line rather than thousands of little data points.

I can't see any value in using the straight line facility when you want to draw a curve. The curve is "smoothed" by scale adjustment and x-interval, but this may be at the expense of accuracy. Another option is to calculate and overlay a new graph showing trend - something perhaps better left to Excel to fix.

I don't know about scrolling but it can't be hard. I imagine you might have to store the y-values for a complete screen so that you can plot a dot of the background colour in order to erase the previous as you plot the new. This is rather like the two-speed graph shown below, where the x-axis changed after six minutes and old data re-drawn. A similar option is where you constantly re-draw an entire line to erase, and plot again with a shifting x-axis.

SomewhatCompetent:
I think I would prefer the old data to be redrawn rather than scrolling. That might look a little better. I've been trying to use 'myGLCD.clrScr();' but that just wipes the entire screen including what was in void setup(); rather than just the data, which was obtained in void loop();.

I clear the screen. It's jarring, but I only have to do it once. The y-data is stored because it is displayed at a different x-scale. In the case of wrap-round you would always be printing at two y-coordinates for each x-coordinate.

Yes. When x=1, you either

  1. re-draw the entire graph in the background colour.
    or
  2. re-draw just the y-value for x=1 in the background colour, along with the new y-value in a new colour, thereby clearing the screen progressively.

I'm afraid I have said about as much as I can, and it's mostly theoretical anyway. In the example I gave, I had to

  1. Draw the first pass, and store the y-data - six minutes worth
  2. Clear the screen
  3. Re-draw with the stored data to a different scale
  4. Continue for the next 25 minutes

The vital bit is storing the data, and I assume you need to do this too. I'm theorising that you may

  1. Draw the first pass and store the y-data
  2. Start the second pass but
    i. simultaneously draw the previous y-val in the background colour, thereby erasing it.
    ii Store the new y-val in the place of the old y-val, for use in the third pass
  3. Carry on.........

The result is that

  1. After the first pass, you always have a full time window on display
  2. You only have to draw two dots on each update.
  3. You avoid ugly and time-consuming screen clears.

I had to clear the screen because I was changing the x-scale.

Having the stored data also enables you to re-draw the whole graph in a different colour at the end of the pass, thereby enabling you to differentiate between old and new if you need to.