bug: unsigned long works as int

In this code I use millis() to determine the time a capacative sensor isn't touched. If this exceeds 1000ms something is executed.

The code works fine, untill millis() hits 32000ms. If that happens, oldTime becomes zero. When millis() hits 60000+ oldTime becomes 'normal' again.

When declaring oldTime not as first unsigned long, but als last unsigned long fixes this problem.

I am running Arduino 0018.

#include <CapSense.h>

CapSense   cs_2_19 = CapSense(2,19);        // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired
CapSense   cs_2_18 = CapSense(2,18);        
CapSense   cs_2_17 = CapSense(2,17);        
CapSense   cs_2_16 = CapSense(2,16);        
CapSense   cs_2_15 = CapSense(2,15);        
CapSense   cs_2_14 = CapSense(2,14);        
CapSense   cs_2_7 = CapSense(2,7);        
CapSense   cs_2_12 = CapSense(2,12);        
CapSense   cs_2_11 = CapSense(2,11);        
CapSense   cs_2_10 = CapSense(2,10);        
CapSense   cs_2_9 = CapSense(2,9);        
CapSense   cs_2_8 = CapSense(2,8);  

int onlyOnce=0;
int resetSwitch;
int resetPin=13;
int ledArray[14]={
  1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int gevoeligHeid=1;
int totalArray[12];
int mySensVals[12];
int highestNumber=12;
int latchPin = 3;     //Pin connected to ST_CP of 74HC595
int clockPin = 4;   //Pin connected to SH_CP of 74HC595
int dataPin = 5;   //Pin connected to DS of 74HC595
unsigned long oldTime=0;
unsigned long overAllTime=0;
unsigned long oldOverAllTime=0;
int startInt=0;

void setup()                    
{
  pinMode(resetPin, INPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  ledjes();
  Serial.begin(115200);

}

void loop()                    
{ 
  if (startInt==0){
    oldOverAllTime=millis();
    startInt=1;  
}
  overAllTime=millis();
  unsigned long changeOverAllTime = overAllTime - oldOverAllTime;
  if (changeOverAllTime > 3000){
    reset();
  }
  
  ledjes();
  resetSwitch=digitalRead(resetPin);
  if (resetSwitch == HIGH){
        reset();
  }
  // hieronder worden de sensoren uitgelezen en weggeschreven in een array.

  totalArray[0] = cs_2_19.capSense(30);      
  totalArray[1] = cs_2_18.capSense(30);      
  totalArray[2] = cs_2_17.capSense(30);      
  totalArray[3] = cs_2_16.capSense(30);      
  totalArray[4] = cs_2_15.capSense(30);
  totalArray[5] = cs_2_14.capSense(30);      
  totalArray[6] = cs_2_7.capSense(30);      
  totalArray[7] = cs_2_12.capSense(30);      
  totalArray[8] = cs_2_11.capSense(30);      
  totalArray[9] = cs_2_10.capSense(30);      
  totalArray[10] = cs_2_9.capSense(30);      
  totalArray[11] = cs_2_8.capSense(30);      


  // hieronder wordt de totalArray gekopieerd naar mySensVals
  for (int k=0; k<12;k++){
    mySensVals[k]=totalArray[k];
  }

  //hieronder wordt de hoogste waarde in de array mySensVals in mySensVals[12] geplaats.
  for (int i =0; i < 12; i++){
    if (mySensVals[i] > mySensVals[i+1]){     // numbers are out of order - swap
      mySensVals[i+1] =  mySensVals[i] ;
    }
  }

  //hieronder wordt gekeken bij welke sensor mySensVals[12] hoort. 
  for (int j=0; j<12;j++){
    if (mySensVals[11]==totalArray[j]){
      highestNumber=j;
    }
  }   
  // de gevoeligheid moet worden ingesteld.
  if (totalArray[0] > gevoeligHeid ||totalArray[2] > gevoeligHeid ||totalArray[3] > gevoeligHeid ||totalArray[4] > gevoeligHeid ||totalArray[5] > gevoeligHeid ||totalArray[6] > gevoeligHeid ||totalArray[7] > gevoeligHeid ||totalArray[8] > gevoeligHeid ||totalArray[9] > gevoeligHeid ||totalArray[10] > gevoeligHeid ||totalArray[11] > gevoeligHeid ||totalArray[1] > gevoeligHeid){
    oldTime=millis();
    
    // actie wordt ondernomen bij de hoogste input
    if (highestNumber==0){
      ledArray[9]=0;
    }
    if (highestNumber==1){
      ledArray[10]=0;
    }
    if (highestNumber==2){
      ledArray[1]=0;
    }
    if (highestNumber==3){
      ledArray[11]=0;
    }
    if (highestNumber==4){
      ledArray[5]=0;
    }
    if (highestNumber==5){
      ledArray[7]=0;
    }
    if (highestNumber==6){
      ledArray[2]=0;
    }
    if (highestNumber==7){
      ledArray[0]=0;
    }
    if (highestNumber==8){
      ledArray[3]=0;
    }
    if (highestNumber==9){
      ledArray[6]=0;
    }
    if (highestNumber==10){
      ledArray[8]=0;
    }
    if (highestNumber==11){
      ledArray[4]=0;
    }
    ledjes();
  }  
  unsigned long newTime= millis();
unsigned long changeTime=newTime-oldTime;
    if (changeTime > 1000){
    reset();
  }
  
  highestNumber=12;
}

//stuur letter door en reset alle sensoren en zet alle ledjes uit.
void reset(){
  sendLetter();
  for (int g=0;g<12;g++){
    ledArray[g]=1;
  }
  onlyOnce=0;
  startInt=0;
}

void ledjes() {
  for (int i=15;i>-1;i--){
    int waarde=ledArray[i];
    digitalWrite(dataPin, waarde);
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
  }
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
}

void sendLetter(){

}

When declaring oldTime not as first unsigned long, but als last unsigned long fixes this problem.

Moving the declaration of oldTime made the problem go away?

Yes. Renaming it to oldTime1 did not help, but declaring all other unsigned longs first before oldTime made the problem go away. Really strange

While it is possible there is a bug in the compiler that's causing this problem, it is more likely...

  • Your Sketch runs out of memory. Typically, the stack grows over the top of the data area which leads to a corrupt stack, corrupt data, or both.

  • Buffer overrun corrupting a neighboring bit of data.

Search this forum for "free memory"; you're searching for a function that returns the amount of free SRAM. Add it to your Sketch and call it at the deepest stack depth. If it returns a small or negative number, your Sketch is probably in trouble.

May, or may not be related, but you declare:

int ledArray[14]=
{
  1,1,1,1,1,1,1,1,1,1,1,1,1,1};

but you iterate from an illegal position here:

void ledjes() {
   for (int i=15;i>-1;i--) {
      int waarde=ledArray[i];
   }
...

Thanks for the replies!
I did the memory test:
Memory test results: 158 bytes free
So 158 bytes is kinda low isn't it?

Changing the for loop did not change anything at the free memory.

So 158 bytes is kinda low isn't it?

No. Five bytes is kind of low. Unless you're manipulating strings, 158 is plenty of space.

This bit of code is very likely the culprit. It writes a value past the end of mySensVals...

  //hieronder wordt de hoogste waarde in de array mySensVals in mySensVals[12] geplaats.
  for (int i =0; i < 12; i++){
    if (mySensVals[i] > mySensVals[i+1]){     // numbers are out of order - swap
      [glow]mySensVals[i+1][/glow] =  mySensVals[i] ;
    }
  }

Either change "12" to "11' or make mySensVals bigger.

Thanx a lot Coding Badly!! That did the trick!
I still don't understand how this could influence the order in which the longs are declarated, but that's ok.

Thanks again.

It didn't "influence", it "overwrote"!

Changing the for loop did not change anything at the free memory.

Of course it didn't change nothing to the free memory it is a read in memory. But you are still reading outside the array you have declared.

Remember in C indexes in arrays are starting from 0. So ledArray[14] goes from ledArray[0] to ledArray[13]. 14 is the number of element.