Arduino Mega erratic/unpredictable behaviour

Hi guys,

I am having erratic/unpredictable behavior on a Arduino Mega and as it's been around 3 days of debugging without finding out the issue I though to share this hoping that I may receive some ideas/advice on what would be the cause.

The sketch uses a interrupt to count the number of button presses and prints it on the serial port every 200ms.
Sometimes the uC freezes (as in it doesn't execute the loop anymore), sometimes it restarts (re-executes setup), sometimes it prints the same number over the serial port at high speed (as if the 200ms delay much smaller such as 1ms). From one day to another the issue can show up more often or less often. When I made the video, the issue was visible very often.
Fuses are (low, high, ext): 0xFF, 0xD0, 0xFC I also tried 0xF7 for the low fuse (full swing oscillator).
I remember that at some point it was misbehaving even if having "buttonPressed" declared as volatile (even though in this video it wasn't declared). At the moment I am having difficulties getting the error to shop up so I can't redo the video with the "volatile" keyword.

#define measureBtnSense 21

 int buttonPressed;

void setup() {
  //button
  pinMode(measureBtnSense,INPUT_PULLUP ); //Measure button
  attachInterrupt(digitalPinToInterrupt(measureBtnSense), btnPressedFct, RISING);
  buttonPressed=0;
  
  //debug over serial port
  Serial.begin(9600);
  delay(10);
  Serial.println(" -------------------------------> Arduino Mega restarted");
  
}

void loop() {
  Serial.println(buttonPressed);
  delay(200);
}

//button
void btnPressedFct(){
  buttonPressed++;
}

There are two problems with the code, although neither of them should cause the Arduino to reset. You may have intermittent wiring somewhere.

  1. buttonPressed must be declared volatile

  2. When you access buttonPressed in the main loop, you need to protect it from corruption by the interrupt. Make a copy with the interrupts off and use the copy later, as follows:

noInterrupts(); //interrupts off
buttonPressedCopy=buttonPressed;
interrupts(); //interrupts back on
  Serial.println(buttonPressedCopy);

How is the button wired? Do you have a pullup or pulldown resistor connected so the input pin is not floating when the button is not pressed?

OP is using INPUT_PULLUP.

OIC :stuck_out_tongue:

Yes, the pull up is keeping the pin high; the button is pulling it to ground. Additionally there is a 0.1uF cap in parallel with the button which makes the rise time be in the order of milliseconds to dozens of milliseconds (hardware debounce - works well as when the uC doesn't go chaotic the counting is always correct).
Thanks jremington for the programming tips!