Weird behaviour of an int array vs integer values

Sorry for the confusing title, but I don't know how to describe the problem in a short manner.

I am working on a volt/amp meter for the ST7735 display. I do not like to clear the screen on a regular base to prevent flicker. So I thought to store the previous value in an array and overwrite that with the background color when the value ( reading) changes before displaying the new value.

I made a small test but I am not getting the results I expected. Even when the value stored in the array and the value did not change, it tells me that it is changed.

I am using following code:

bool a;

char bufFloat[5];
char bufText[8];
char test[8];
char *p;

float value;
float newValue;

int intValue;
int intArray[8];

unsigned long currMs;
unsigned long prevMs;

int pollInterval = 3000;


void setup() {
  Serial.begin(115200);
}

void loop() {
  currMs = millis();

  if( currMs - prevMs >= pollInterval){

    prevMs += pollInterval;

    if( a == 1){
      a = !a;
      value += 2.23;
      if( value >= 16) value = 0;
    } else {
      a = 1;
    }

    testLoop();
  }
}


void testLoop(){
  int intValue = value * 10;
  float newValue = (( intValue + 0.5) / 10.0);
  dtostrf( newValue, -6, 1, bufFloat);
//  p = strchr (bufFloat, ' '); // search for space
//  if (p) *p = 0;
//  sprintf( bufText, "%s V", bufFloat);

  Serial.print("intArray\t"); Serial.println( intArray[1]);
  Serial.print("intValue\t"); Serial.println( intValue);

  if( intArray[1] == intValue){
    Serial.println("\tno change");
  } else {
    Serial.println("---- CHANGED ----");
  }

  intArray[1] = intValue;
  Serial.println();
}

What am I doing wrong?

Did I miss something about intArray [1]??

You never put anything into the array so it will always contain zero.

Could you post the entire code in code tags?

Why you may ask?

Your issues seems to be with how the screen is being updated in an attempt to prevent or reduce flicker from an entire screen clear and update. You do NOT have or present any code that does the ST7735 display.

Your test code seems to work ok.

12:24:08.319 -> intArray	0
12:24:08.319 -> intValue	0
12:24:08.319 -> 	no change
12:24:08.319 -> 
12:24:11.287 -> intArray	0
12:24:11.287 -> intValue	22
12:24:11.287 -> ---- CHANGED ----
12:24:11.325 -> 
12:24:14.305 -> intArray	22
12:24:14.305 -> intValue	22
12:24:14.305 -> 	no change
12:24:14.305 -> 
12:24:17.291 -> intArray	22
12:24:17.291 -> intValue	44
12:24:17.291 -> ---- CHANGED ----
12:24:17.291 -> 
12:24:20.289 -> intArray	44
12:24:20.289 -> intValue	44
12:24:20.289 -> 	no change
12:24:20.289 -> 
12:24:23.299 -> intArray	44
12:24:23.299 -> intValue	66
12:24:23.299 -> ---- CHANGED ----
12:24:23.299 -> 
12:24:26.299 -> intArray	66
12:24:26.299 -> intValue	66
12:24:26.299 -> 	no change
12:24:26.299 -> 
12:24:29.300 -> intArray	66
12:24:29.300 -> intValue	88
12:24:29.300 -> ---- CHANGED ----
12:24:29.300 -> 
12:24:32.304 -> intArray	88
12:24:32.304 -> intValue	88
12:24:32.304 -> 	no change
12:24:32.304 -> 
12:24:35.298 -> intArray	88
12:24:35.298 -> intValue	111
12:24:35.298 -> ---- CHANGED ----
12:24:35.298 -> 
12:24:38.299 -> intArray	111
12:24:38.299 -> intValue	110
12:24:38.299 -> ---- CHANGED ----
12:24:38.299 -> 
12:24:41.285 -> intArray	110
12:24:41.285 -> intValue	132
12:24:41.285 -> ---- CHANGED ----
12:24:41.322 -> 
12:24:44.300 -> intArray	132
12:24:44.300 -> intValue	132
12:24:44.300 -> 	no change
12:24:44.300 -> 

What output are you getting?

Doing the ST7789 screen updates without clearing the entire display

 #include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
Adafruit_ST7789 tft   = Adafruit_ST7789( GPIO_NUM_15, GPIO_NUM_0, GPIO_NUM_13, GPIO_NUM_14, GPIO_NUM_22 );

void fDoTheDisplayThing( void * parameter )
{
  tft.init( 240, 320 ); // Init ST7789 320x240
  tft.setRotation( 3 );
  tft.setTextSize( 3 );
  tft.fillScreen( ST77XX_BLACK );
  tft.setTextWrap( false );
  struct stu_eData px_eData;
  const int brightness = 250;
  ledcWrite( 4, brightness ); //backlight set
  const int MaxString      = 20;
  String oldTempString     = "";
  String oldHumidityString = "";
  String oldAQIString      = "";
  String oldRainfall       = "";
  String oldWindDirection  = "";
  String oldAirPressure    = "";
  String oldRMO            = "";
  String oldPM2            = "";
  String oldPower          = "";
  oldHumidityString.reserve( MaxString );
  oldWindDirection.reserve( MaxString );
  oldAirPressure.reserve( MaxString );
  oldTempString.reserve( MaxString );
  oldAQIString.reserve( MaxString );
  oldRainfall.reserve( MaxString );
  oldPower.reserve( MaxString ); 
  oldRMO.reserve( MaxString );
  oldPM2.reserve( MaxString );
  bool Tick = true;
  const int numOfColors = 40;
  /* https://chrishewett.com/blog/true-rgb565-colour-picker/#:~:text=A%20true%20RGB565%20colour%20picker%2021st%20Oct%202017,in%205%20bits%20and%20green%20in%206%20bits. */
  int colors[numOfColors] = { ST77XX_BLACK, ST77XX_RED, ST77XX_WHITE, ST77XX_BLUE, ST77XX_GREEN, ST77XX_CYAN, ST77XX_MAGENTA, ST77XX_YELLOW, 0xd55b, 0xee09, 
                              0x2e15, 0xcb43, 0x6bad, 0x126f, 0x1264, 0xe264, 0xe7e4, 0x87e4, 0x87fe, 0x876a,
                              0xe304, 0x1cc4, 0xf4c4, 0xf4da, 0xcf66, 0xa879, 0x7f28, 0x4f37, 0xfa97, 0x6195,
                              0X8162, 0xc962, 0x517b, 0x325b, 0xea5b, 0x179b, 0xff80, 0xf960, 0x416d, 0x7bd1};
  int colorCounter = 1;
  for (;;)
  {
    if ( xQueueReceive(xQ_eData, &px_eData, portMAX_DELAY) == pdTRUE )
    {
      //log_i( "%d", colors[colorCounter] );
      tft.setCursor( 0, 0 );
      tft.setTextColor( colors[0] );
      tft.print( oldTempString );
      tft.setCursor( 0, 0 );
      tft.setTextColor( colors[colorCounter] );
      oldTempString = "";
      oldTempString.concat( "Temp " + String(px_eData.Temperature) + "F" );
      tft.println( oldTempString );
      tft.setCursor( 0, 30 );
      tft.setTextColor( colors[0] );
      tft.print( oldHumidityString );
      tft.setCursor( 0, 30 );
      tft.setTextColor( colors[colorCounter] );
      oldHumidityString = "";
      oldHumidityString.concat( "Hum  " + String(px_eData.Humidity) + "%" );
      tft.println( oldHumidityString );
      tft.setCursor( 0, 60 );
      tft.setTextColor( colors[0] );
      tft.print( oldAirPressure );
      tft.setCursor( 0, 60 );
      tft.setTextColor( colors[colorCounter] );
      oldAirPressure = "";
      oldAirPressure.concat( "Pres " + String(px_eData.Pressure) + "mmHg" );
      tft.println( oldAirPressure );
      tft.setCursor( 0, 90 );
      tft.setTextColor( colors[0] );
      tft.print( oldAQIString );
      tft.setCursor( 0, 90 );
      tft.setTextColor( colors[colorCounter] );
      oldAQIString = "";
      oldAQIString.concat( "AQI  " + String(px_eData.IAQ) + "%" );
      tft.println( oldAQIString );
      tft.setCursor( 0, 120 );
      tft.setTextColor( colors[0] );
      tft.print( oldRMO );
      tft.setCursor( 0, 120 );
      tft.setTextColor( colors[colorCounter] );
      oldRMO = "";
      if ( Tick )
      {
        oldRMO.concat( "RM0  " + String(px_eData.RM0) + "%" );
        Tick = !Tick;
      } else {
        oldRMO.concat( "CO2  " + String(CO2) + "ppm" );
        Tick = !Tick;
      }
      tft.println( oldRMO );
      tft.setCursor( 0, 150 );
      tft.setTextColor( colors[0] );
      tft.print( oldPM2 );
      tft.setCursor( 0, 150 );
      tft.setTextColor( colors[colorCounter] );
      oldPM2 = "";
      oldPM2.concat( "PM2  " + String(px_eData.PM2) + "ug/m3" );
      tft.println( oldPM2 );
      tft.setCursor( 0, 180 );
      tft.setTextColor( colors[0] );
      tft.print( oldPower );
      tft.setCursor( 0, 180 );
      tft.setTextColor( colors[colorCounter] );
      oldPower = "";
      oldPower.concat(  String(px_eData.WSV) + "V " );
      //oldPower.concat(  String(px_eData.WSV) + "V " + String(int(px_eData.WSC * 1000.0f)) + "mA " + String((int(px_eData.WSP * 1000.0f))) + "mW" );
      tft.println( oldPower );
      colorCounter++;
      if ( colorCounter > (numOfColors-1) )
      {
        colorCounter = 1;
      }
      //log_i( " high watermark % d",  uxTaskGetStackHighWaterMark( NULL ) );
    } //if ( xQueueReceive(xQ_eData, &px_eData, portMAX_DELAY) == pdTRUE )
  } //for (;;)
  vTaskDelete( NULL );
} //void fDoTheDisplayTHing( void * parameter )
////

Some code I use to update the display without doing a screen clear.

First thing needed is a storage location for the old information.

tft.setCursor( 0, 0 ); SET cursor to the desired position to be updated.
tft.setTextColor( colors[0] ); Change the text color to the background color
tft.print( oldTempString ); write the old data to the screen

tft.setCursor( 0, 0 ); set the cursor to the line to be updated.
tft.setTextColor( colors[colorCounter] ); set the text color
oldTempString = ""; << clear the old screen value
oldTempString.concat( "Temp " + String(px_eData.Temperature) + "F" ); <<< create the new screen value
tft.println( oldTempString ); update the screen

The new screen value gets saved into the old screen value variable and is ready for the next time to do a scrren update.

 intArray[1] = intValue;

At an update interval of 3 seconds, it is my opinion that you should just averags 'n' readings and only change the display when the value changes higher or lower than the decimal shown; that is, if 1 decimal place then your ceiling and floor is > 0.1 on high and < 0.1 on the low.

For most of the V & I work I have done on real engines, I only change on +0.9 or -0.9 changes and my update time is based on full-speed loop with no delays or millis() intervals required - only varying the configurable averaging depth.

I did not present the whole code because I want to figure out how to update the display without flicker. This means when the value is changed, I overwrite the old value with in the background color before writing the new value to the screen. I was playing around how to determine if the current value differs from the previous value and then act as neccessary.

if string oldvalue != stringNewValue then update the display.

Thank you for your information. but I used the 3 seconds in order to change the value and to see if the IF statement in the test loop would perform as I thougt it would perform. In real life the measurements are taken every 500 ms and power and energy calculations are performed and displayed.

No it is not outputting correct. One of the previous values is 111 and the stored value is 111 and the IF statement thinks there is a change? It should have said no changi in my opinion

Thank you for sharing, I will have a closer look.

Can you post your output that shows that... I see the following:

Not quite correct. I did not change the value and I get a different value 110 in stead of 111 look at 12:24:38.

You are not using this, might as well get rid of it

Well actually you did... unintentionally.

This statement is corrupting your variables...

  dtostrf( newValue, -6, 1, bufFloat);

because this character array is too small to hold the result...

char bufFloat[5];

as a result I suspect memory is being overwritten.

If you make the char array bigger (say 10) the problem goes away.

If you turn up compiler warnings you will see:

sketch_nov16a.ino: In function 'void loop()':
sketch_nov16a.ino:29:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if ( currMs - prevMs >= pollInterval)
        ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~

To get rid of that warning you should try:
unsigned pollInterval = 3000;

If had noticed that as well but had not figured out that it was because of the array not being big enough. I had choosen bufFloat[5] assuming it was big enough for values like 14,6 or less..
When that line was commented out I had no trouble in the output.

Thanks for the tip. I was unaware that it is better not to use an INT for timing purposes. I will turn up compiler warnings.