Conceptual question regarding variables...

My first post here so let’s hope I get it right…

I’m not an experienced programmer so I was a bit surprised when the following code produced five different results.

#include "U8glib.h"
U8GLIB_LC7981_160X80 u8g(26, 27, 28, 29, 22, 23, 24, 25,  34, 30, 31, 33, 32); // 8Bit Com: D0..D7: 26,27,28,29,22,23,24,25, en=34, cs=30 ,di=31,rw=33, reset = 32

int analogIn0;
String displayValueStr;

void setup(void) {
  u8g.setFont(u8g_font_6x10);
  u8g.setRot180();
  u8g.setColorIndex(1);
}

void loop(void) {  // picture loop
  u8g.firstPage();  
  do {

    analogIn0=analogRead(A0); 

    displayValueStr =  String(analogIn0, DEC);

    u8g.setPrintPos(30,7);  
    u8g.print( "Variable displayValueStr = " + displayValueStr);

    u8g.setPrintPos(30,17);  
    u8g.print( "Variable displayValueStr = " + displayValueStr);

    u8g.setPrintPos(30,27);  
    u8g.print( "Variable displayValueStr = " + displayValueStr);

    u8g.setPrintPos(30,37);  
    u8g.print( "Variable displayValueStr = " + displayValueStr);

    u8g.setPrintPos(30,47);  
    u8g.print( "Variable displayValueStr = " + displayValueStr);

  }
  while( u8g.nextPage() );
  delay(500);
}

The variable analogIn0 is assigned the value of analogRead(A0) only once, but thereafter each time it is used it has a different value.

It looks like each time the variable is used it is re-evaluated - in this case it looks like another analogRead of A0 is done resulting in a new value for each reference to the variable. Is this correct?

If so, what is the best way of preventing this dynamic re-evaluation of the variable?

I want to produce 240 readings of A0 with synchronous readings of A(1) and then manipulate them after the readings have been taken.

Thanks for any help,
Andy.

findrew: The variable analogIn0 is assigned the value of analogRead(A0) only once, but thereafter each time it is used it has a different value.

No it isn't, you are in a "while" loop:

void loop(void) {  // picture loop
...

  do {

    analogIn0=analogRead(A0); 

    displayValueStr =  String(analogIn0, DEC);

 ...

  }
  while( u8g.nextPage() );
  delay(500);
}

Also the "loop" function gets called repeatedly.

Each time loop 'loops' it goes into the 'do' loop. Each time the 'do' loop cycles the analogue reading is taken

the reading is not re-sampled each time you read from the analogIn0 variable. It is only re-sampled when you explicitly assign it the value from an analogue read.

Move the read either outside of the 'do' loop or do it in the setup() function

Thanks pYro_65 and Nick, You are quite right that I don't see the same behaviour if I move the assignment outside the loop. Unfortunately, I was hoping I could do the readings inside the display loop. The 240 readings correspond to the x (pixel width) of the display. The ratio of the A(0) and A(1) readings would have been key to forming the y value. I thought that would have been easy. If I can't rely on synchronous analog readings inside the loop loop it looks like I'm going to have to mess around with big arrays to draw a screen bitmap instead. Re-think time. Andy.

Here is the solution to my problem.

I’m using a Chinese Mega1280 Arduino clone to work like an oscilloscope with my LC7981 based 240x128 display. I have modified the u8glib entry for the U8GLIB_LC7981_160X80 by changing the width and height in u8g_dev_lc7981_160x80.c as follows:

#define WIDTH 240 //this was 160
#define HEIGHT 128 //and this was 80

With those two changes my Hitachi SP14N003 works perfectly.

The following code reads analog(0) 240 times and displays it as an oscilloscope would show it (or if you dig in there you’ll find an alternative bar-chart display). The top three text lines can display info on the last set of 240 readings. Try it - you’ll see what I mean.

#include "U8glib.h"

U8GLIB_LC7981_160X80 u8g(26, 27, 28, 29, 22, 23, 24, 25,  34, 30, 31, 33, 32); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=34, cs=30 ,di=31,rw=33, reset = 32
/* 
 
 N.B. The u8glib I'm using has been modified to change the screen 
 width and height of the LC7981_160X80 panel to 240x128. My panel 
 is the Hitachi SP14N003. The pinouts in the above constructor just
 reflect the way I connected it up to my Chinese Mega1280 Arduino 
 clone. If you wire it up differently, you will need to change the
 above to match your wiring.
 
 */

int analogIn0[241]; //An array to hold the analog readings. 
int amplitudeScaled[241]; //Another array to hold the scaled version of the above array.
int sampleNum; //The index for the above arrays
long cumulator; //Used in calculating the average value of analog readings
int averageVal; //integer version of the average reading value
String averageValStr; //receives the string version of the calculated average analog readings
int maxSampNumber; //The index of the first occurrence of the highest reading in the arrays
int minSampNumber; //The index of the last occurrence of the lowest reading in the arrays
int maxim; //The highest reading found in the analog reading array
int minim; //The lowest reading found in the analog reading array
String highestValStr; //The string version of maxim
String lowestValStr;  //The string version of minim
String maxSampNumStr; //The string version of the maxSampNumber index
String minSampNumStr; //The string version of the minSampNumber index
int height; //the on-screen height of the displayed reading in pixels
int voltage; //holds the calculated average voltage in mV
String voltStr; //The string version of voltage

void setup(void) {
  u8g.setFont(u8g_font_6x10);  //This size works well - it allows three lines of legible text above the graph.
  u8g.setRot180(); //Because my screen works better upside-down
  u8g.setColorIndex(1); // Mono. Set to 0 before a write if you want to clear a pixel
}


void draw(void) {
  for (sampleNum=0; sampleNum <= 239; sampleNum++)
  {
    amplitudeScaled[sampleNum] = analogIn0[sampleNum]/10; //This just divides the 0 to 1023 readings by 10 so it will fit in the bottom 103 pixels of the display
    //amplitudeScaled[sampleNum] = analogIn0[sampleNum]- averageVal + 60; //Rough and ready way to zoom in - needs work
    height = amplitudeScaled[sampleNum]; //not sure if I need this
    //u8g.drawVLine(sampleNum, 127-height, height); //BarChart - slower but prettier?
    u8g.drawPixel(sampleNum, 127-amplitudeScaled[sampleNum]);  //Oscilloscope trace - quicker but basic
  }
  //The following lines just print some info on the array data
  u8g.setPrintPos(0,7);  
  u8g.print( "Av'ge reading = " + averageValStr + " (= " + voltStr  +"mV)");
  u8g.setPrintPos(0,15);  
  u8g.print( "Max reading = " + highestValStr);
  u8g.setPrintPos(121,15);
  u8g.print( "first @ sample # " + maxSampNumStr);
  u8g.setPrintPos(0,23);
  u8g.print( "Min reading = " + lowestValStr);
  u8g.setPrintPos(127,23);
  u8g.print( "last @ sample # " + minSampNumStr);
}


void buildArray(void) {
  cumulator=0;
  maxim=0;
  minim=1023;
  for (sampleNum=0; sampleNum <= 239; sampleNum++)
  {
    analogIn0[sampleNum]=analogRead(A0);
    cumulator = cumulator + analogIn0[sampleNum];
    if (analogIn0[sampleNum] > maxim) { //looking for the first highest instance in the array
      maxim=analogIn0[sampleNum]; //sets 'maxim' to the highest value found in the array 
      maxSampNumber=sampleNum; //saves the index for the first occurrence of it
    }
    if (analogIn0[sampleNum] <= minim) { //looking for the last lowest instance in the array
      minim=analogIn0[sampleNum]; //sets minim to the lowest value found in the array
      minSampNumber=sampleNum; //saves the index for the last occurrence of it.
    }
  }
  averageVal = cumulator/240;
  averageValStr = String(averageVal);
  voltage = cumulator*1000/49104; //mV actually, not V. Avoids problems converting floats to strings.
  voltStr = String(voltage);  // again, it is mV.
  highestValStr = String(maxim); // The next few lines just convert integers to strings ready for display
  maxSampNumStr = String(maxSampNumber);
  lowestValStr = String(minim);
  minSampNumStr = String(minSampNumber);
}  


void loop(void) {
  // picture loop
  u8g.firstPage();  // See the u8glib documentation
  buildArray();  // Fill the array with analog readings and calculate some statistics etc.
  do {
    draw(); // Draw the screen
  } 
  while( u8g.nextPage() ); // See the u8glib documentation

  // rebuild the picture after some delay - useful in debugging
  //delay(3000);
}

This works! I’m getting nearly 2 fps which is enough for my ultimate purpose (watch this space).
Enjoy!
Andy.