Arduino Scrambles Array Data

Hey,

Recently, I wanted to measure a sound sensor. I wanted to have a way, so that a user could simply give a duration and interval, so you could have a series of datapoints.

So i started to store them in an array. Each datapoint has its own set place.

When i wanted to read out the full array with the help of a for-loop, all my numbers corrupted. I dit not have the same numbers that were stored in it.

I am using the ESP8266 (the new one).

Here is my code and output: (to test, i call the fuction from the setup(): enableMeassureData();

void loop() {

//measure stuff
if(measureActive){
int numDataPoints = floor(durationS/intervalS);
int dataPoints[numDataPoints];
int value;
if(measureLastEnabled == false){
Serial.println(“measuring started”);
measureLastEnabled = true;
lastTimeDur = millis();
lastTimeInterval = millis();
}
if(millis() - lastTimeDur < durationS*1000){

if(millis() - lastTimeInterval > intervalS1000){
value = analogRead(A0);
Serial.println(value);
dataPoints[counter] = value;
Serial.println(dataPoints[counter]);
counter++;
lastTimeInterval = millis();
}
}else{
Serial.println(“measuring stopped”);
for(int i = 0; i < numDataPoints; i++){
Serial.print(i+1);
Serial.print(": ");
Serial.println(dataPoints
);*

  • }*
  • measureActive = false;*
  • measureLastEnabled = false;*
  • }*
    }
    }
    void enableMeassureData(){
    if(/server1.args() == 0/false){
  • Serial.println(“No params given!”);*
  • server1.send(200, “text/plain”, “No params given!”);*
    }else{
    _ intervalS = /server1.arg(0).toFloat()/1.0;_
    _ durationS = /server1.arg(1).toFloat()/30.0;_
  • measureActive = true;*
  • counter = 0;*
    }
    }

    measuring started
    42
    41
    41
    42
    42
    41
    41
    42
    42
    41
    41
    41
    41
    42
    42
    42
    42
    42
    42
    42
    42
    41
    41
    41
    41
    42
    41
    42
    41
    measuring stopped
    1: 0
    2: 1073732304
    3: 1073671948
    4: 48
    5: 0
    6: 1073741728
    7: 1073671132
    8: 1075854978
    9: 0
    10: 55
    11: 1073671732
    12: 1075864428
    13: 0
    14: 1073671128
    15: 1073671128
    16: 1075869620
    17: 1076033286
    18: 0
    19: 1073671128
    20: 1075858813
    21: 1075870136
    22: 0
    23: 5000
    24: 1075864936
    25: 0
    26: 0
    27: 16
    28: 1073741712
    29: 1073671364
    30: 0
 //measure shit 
 if(measureActive){
   int numDataPoints = floor(durationS/intervalS);
   int dataPoints[numDataPoints];
   int value;
   if(measureLastEnabled == false){
     Serial.println("measuring started");
     measureLastEnabled = true;
     lastTimeDur = millis();
     lastTimeInterval = millis();
   }

--> int numDataPoints = floor(durationS/intervalS); read about variable scope. (and how to post with code tags)

All needed variables are declared in the begining.
This is my full code:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

int togglePin = 16;

//meetvars
boolean measureActive = false;
boolean measureLastEnabled = false;
float durationS;
float intervalS;
float lastTimeDur;
float lastTimeInterval;
int counter;

const char *ssid = "Amparo";
const char *password = "amparowalter";

ESP8266WebServer server1( 80 );

void setup() {

  Serial.begin(115200);
  //server setup
  WiFi.begin(ssid, password);
  Serial.println("Wifi booted. Waiting for connection.\n");
  establishUplink();

  server1.onNotFound ( [](){
    server1.send(200, "text/plain", "Servercommand not found!");
    Serial.println("Servercommand not found!");
    });
  server1.on( "/", [](){
    server1.send(200, "text/html", "Root page");
    Serial.println("Root page loaded");
    });

  server1.on( "/startMeeting", enableMeassureData );
  Serial.println("HTTP-server started\nProcessor initialistaion completed.");
  
  
  
  //pin def
  pinMode(togglePin, OUTPUT);

  //standard pinset
  digitalWrite(togglePin, LOW);


  enableMeassureData();
}

void establishUplink(){
  while(WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(250);
  }
  printConnectionInfo();

  
}

void loop() {

  if (WiFi.status() == WL_CONNECTED){
    server1.handleClient();
  }else{
    Serial.println("Connection lost. Reconnecting...");
    establishUplink();
  }


  //measure shit
  if(measureActive){
    int numDataPoints = floor(durationS/intervalS);
    int dataPoints[numDataPoints];
    int value;
    if(measureLastEnabled == false){
      Serial.println("measuring started");
      measureLastEnabled = true;
      lastTimeDur = millis();
      lastTimeInterval = millis();
    }
    if(millis() - lastTimeDur < durationS*1000){
      
      if(millis() - lastTimeInterval > intervalS*1000){
        value = analogRead(A0);
        Serial.println(value);
        dataPoints[counter] = value;
        Serial.println(dataPoints[counter]);
        counter++;
        lastTimeInterval = millis();
      }
    }else{
      Serial.println("measuring stopped");
      for(int i = 0; i < numDataPoints; i++){
        Serial.print(i+1);
        Serial.print(": ");
        Serial.println(dataPoints[i]);
      }
      measureActive = false;
      measureLastEnabled = false;
    }
  }

}

void printConnectionInfo(){
  Serial.print("\nConnected to: ");
  Serial.println(ssid);
  Serial.print("IP-adress: ");
  Serial.println(WiFi.localIP());
}

void enableMeassureData(){
  if(/*server1.args() == 0*/false){
    Serial.println("No params given!");
    server1.send(200, "text/plain", "No params given!");
  }else{
    intervalS = /*server1.arg(0).toFloat()*/1.0;
    durationS = /*server1.arg(1).toFloat()*/30.0;
    measureActive = true;
    counter = 0;
  }
}

Check the scope of your variables.

Mind your language.

    int dataPoints[numDataPoints];

Every time this line of code is executed a new array named dataPoints will be created and because it is a local variable its contents could be any value. Is this what you want to happen ?

No, I just can't seem to get past that. If I declare the array, it has to have a certain lenth (that is in Eclipse). you can not just add any value to any certain point in your array?

So, getting past that scope is hard. Unless you do not have to specify the length of the array before adding data to it.

If I declare the array, it has to have a certain lenth

It does. But, there is also a practical limit. You can't define an integer array with 1000000000000 elements.

So, define a global array with a realistic number of elements. Then, reject any attempt by the user to cause more elements to be needed.

PaulS: So, define a global array with a realistic number of elements.

the example ive shown here, has only a lenth of 30. So i don't think it is exceeding the limit

AmpyTech: the example ive shown here, has only a lenth of 30. So i don't think it is exceeding the limit

No, it won't be, but if it is a local array, then any expectations of how it will behave are up-in-the-air.

Take the easy way out. Declare it globally at the top of the program with a reasonable number of elements then later in the code just use it but check that you never write (or read) outside of the array bounds

numDataPoints = floor(durationS / intervalS);

I was thinking that too...

But i won't give up! I was thinking to write my own push function.

goes as folow:

copy the length of the array + 1 copy all data assign in the last slot the value you want to add return the new array

But then my problem is that i cant reasign an old array. Therefor i cont make a push funtion.

is there any way?

But then my problem is that i cant reasign an old array.

What do you mean by "re-assign"? You can certainly copy data from one array to another (old) array.

Perhaps you need to look into malloc() and realloc() (but don't come here complaining you can't dynamically allocate a two terabyte array).

have you read about variable scope?