TransWikia.com

Global variable changes its value when loop starts again

Arduino Asked by Gary77 on September 25, 2021

I have a problem with the global variable calibrationValue. It is initially set with the correct value and is also displayed correctly in the output. As soon as the loop function is restarted, the value of the variable is wrong, although it is not rewritten. Can someone help me please?
The following values ​​are printed in the image:

  1. new AI value
  2. wrong calibrationValue (!)
  3. sumOfValues (needed for calculation of calibrationValue) correct
  4. numValues (needed for calculation of calibrationValue) correct
  5. Text and calibrationValue (correct!)
    int op_mode_Pin = 7;                      // Digital input Pin which transmittes the op_mode_Ardui
    int op_mode_Ardui;                        // Operator Mode of Arduino
    int returnValue1 = 12;                    // First digital return value for transmitting box weight
    int returnValue2 = 13;                    // Second digital return value for transmitting box weight  
    
    int sensorPin = A0;                       // Select the input pin for the potentiometer
    long weightValue = 0;                     // Variable to store the value from the sensor
    long calibrationValue = 0;                // Value which is filled in calibration progress
    int numValues = 50;                       // Number of taken values for calculating an average
    int thresBoxWeight = 300;                 // Weight for separating heavy and light boxes
    
    unsigned long sumOfValues;                // Sum of the taken values
    unsigned long aveOfValues;                // Average of the values
    
    char stringBuffer[30];                    // Buffer for combining string and variables
    
    void setup() {
      // Initiate serial communication to screen
      Serial.begin(9600);
    
      // Initiate some variables 
      //weightValue = 0;
      //calibrationValue = 0;
      //numValues = 50;
      //thresBoxWeight = 300;
      
      // Set the Input Pins for op_mode_Ardui
      pinMode(op_mode_Pin, INPUT);            // sets the digital pin 7 as input  
      
      // Set the Output Pins for Box declaration
      pinMode(returnValue1, OUTPUT);          // sets the digital pin 12 as output  
      pinMode(returnValue2, OUTPUT);          // sets the digital pin 13 as output
     
    }
    
    void loop() {
      Serial.println(analogRead(sensorPin));
      Serial.println(calibrationValue);
      // Reset of Sum and Average variables for next cycle
      sumOfValues = 0;
      aveOfValues = 0;
      op_mode_Ardui = digitalRead(op_mode_Pin);
      
      if (op_mode_Ardui == HIGH){
        for (int i=0; i<numValues; i++){
          weightValue = analogRead(sensorPin);                                                  // read the value from the sensor
          sumOfValues = sumOfValues + weightValue;                                              // Build the sum of all values
        }
        Serial.println(sumOfValues);
        Serial.println(numValues);
        
        calibrationValue = sumOfValues / numValues;
        sprintf(stringBuffer, "Calibration accomplished with value: %d", calibrationValue);     // Combine text and variable to output
        Serial.println(stringBuffer);                                                           // print text and variable to screen
        delay(3000);
      }
    }

enter image description here

One Answer

This:

sprintf(stringBuffer, "Calibration accomplished with value: %d", calibrationValue);

is a buffer overflow: the function sprintf() is writing a 40-byte string into a 30-byte buffer. Whatever happens to lie in memory right after the buffer will be overwritten by sprintf(). Apparently this happened to be calibrationValue. You should use snprintf() rather that sprintf(), as the former is designed to prevent this kind of overflows.

Or better yet, stick with Serial.print[ln]():

Serial.print("Calibration accomplished with value: ");
Serial.println(calibrationValue);

Edit: You may notice that 13108 is the same as 0x3334, which on a little endian architecture is stored in memory as 0x34 0x33. These are the ASCII codes for "43", which is part of what sprintf() wrote past the end of the buffer.

Correct answer by Edgar Bonet on September 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP