Arduino Mega 2560

Hi everyone, i have a question. Why does Arduino Mega 2560 restart when i press several keys on my keypad?

Why does Arduino Mega 2560 restart when i press several keys on my keypad?

Because there is something wrong with your hardware or software.

PLEASE, how the hell do we know without more details?


Rob

Thank you for the reply sir, i believe its not in the hardware maybe its in the software. What do you think is the cause?
Here is my code, its not finished yet…

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Password.h>
#include <ctype.h>

Password password = Password ("1234");
char PasswordArray[5];
char eLimitArray[5];
int i = 0;
int l = 0;
const byte ledPin13 = 13;

long Delay1 = 0;

double eLimit = 99999;

boolean alpha = false;   // Start with the numeric keypad.

LiquidCrystal lcd(12, 11, 37, 35, 33, 31, 29, 27, 25, 23);

int backlight = 30;
boolean ledPin_state;
char key;
char key2;

int voltagePin = 0;
int adcVolts[255];
int magV = 0;
int magCountV = 0;
double voltage;
double Vstep = 0.0048875855;
double Vscope = 0.4283461622;
double VTR = 18.00766284;

int currentPin = 1;
int adcCurrent[255];
int magI = 0;
int magCountI = 0;
double current;

double power = 0;
double powerFactor;
double phase;
int countDelta;

unsigned long last_kWhTime, kWhTime;
float kilowattHour = 0.0;

const byte ROWS = 4;
const byte COLS = 4; 

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

char datakeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'Z','0','Y','D'}
};

char* keypadMap = (alpha == true) ? makeKeymap(datakeys) : makeKeymap(keys);

byte colPins[COLS] = { 44, 42, 40, 38 };

byte rowPins[ROWS] = { 52, 50, 48, 46 }; 

Keypad keypad = Keypad(keypadMap, rowPins, colPins, sizeof(rowPins), sizeof(colPins));


void setup()
{
    Serial.begin(9600);
    lcd.begin(20,4);
    pinMode(backlight, OUTPUT);
    digitalWrite(backlight, HIGH);
    lcd.clear();
    ledPin_state = digitalRead(backlight);   
    keypad.addEventListener(keypadEvent);
    keypad.setDebounceTime(200);
    pinMode (ledPin13, OUTPUT);
}


char lastKey = '\0';

void loop()
{
  solving();
  
 char key = keypad.getKey();
 
   if ( (key == 'A') || (key =='B') || (key == 'C' ) || (key == '*') || (key == '#') ) lastKey = key;
  switch(lastKey)
  {
    case 'A' : Display1(); break;
    case 'B' : Display2(); break;
    case 'C' :
      if (key == 'C'){
        digitalWrite(backlight,!digitalRead(backlight));
        ledPin_state = digitalRead(backlight);
      }
      break;
    case '*': break;
    case '#': break;
 //   default:  break; // default display
  }
  
  if ((key == '*') || (key == '#') || (key == '1') || (key == '2') || (key == '3') || (key == '4') || (key == '5') || (key == '6') || (key == '7') || (key == '8') || (key == '9') || (key == '0') || (key == 'Z') || (key == 'Y') ){
    switch (key){
      case '*':
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Enter Pass Code:");
      lcd.setCursor(0,2);
      resetPasswordArray();
      break;
      
      case '#':
      checkPassword();
      break;
      
      case 'Z':
      if (key == 'Z'){
        lcd.setCursor(0,2);
        lcd.print("        ");
        lcd.setCursor(0,2);
        eLimitArray[l] = '\0';
      }
      break;
      
      case 'Y':
      if(key == 'Y'){
        eLimit = eLimitArray[l];
        lcd.setCursor(0,3);
        lcd.print("Data Stored!");
        keypad.begin(*keys);
      }
      break;
      
      default: 
      if ((key != '#') && (key != '*') && (key != 'Z') && (key != 'Y')){
        lcd.print(key);
      }
      if (key != '#'){
       PasswordArray[i] = key; i++;
      }
      
      if ((key != '#') && (key != '*') && (key != 'A') && (key != 'B') && (key != 'C') && (key != 'D') && (key != 'Z') && (key != 'Y') ){
        eLimitArray[l] = key; l++;
      }
    }
      
  }
}

void keypadEvent(KeypadEvent key){
}

void solving()
{
   for (int i=0; i < 255; i++){
  adcVolts[i] = analogRead(voltagePin);
  adcCurrent[i] = analogRead(currentPin);
  }

magV = 0;
magI = 0;
magCountV = 0;
magCountI = 0;

for (int i=0; i < 255; i++){
  if (adcVolts[i] > magV){
    magV = adcVolts[i];
    magCountV = i;
  }
  if (adcCurrent[i] > magI){
    magI = adcCurrent[i];
    magCountI = i;
  }
}

  voltage = (7.2686218 * pow((magV * Vstep * Vscope), 0.98175303)) * VTR;
  current = (3.8208634 * pow((magI * Vstep * Vscope), 1.1647062));
  
  countDelta = abs(magCountI - magCountV);
  
  while (countDelta > 73){
    countDelta = countDelta - 73;
  }
  
  phase = countDelta * 360 / 73;
  powerFactor = abs(cos( phase / 180*3.1459));
  power = voltage * current * powerFactor;
  
  last_kWhTime = kWhTime;
  kWhTime = millis();
  
  kilowattHour += (power/1000)*((kWhTime - last_kWhTime)/3600000.0);
  
}

void Display1()
{
  if (millis() >= Delay1){
  lcd.begin(20,4);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ECons(kWh):");
  lcd.setCursor(13,0);
  lcd.print(kilowattHour, 2);
  lcd.setCursor(0,1);
  lcd.print("ECons(PHP):");
//  lcd.setCursor(13,1);
//  lcd.print(current, 5);
  lcd.setCursor(0,2);
  lcd.print("Limit(kWh):");
  lcd.setCursor(13,2);
  lcd.print(eLimit,5);
  lcd.setCursor(0,3);
  lcd.print("Date:");
  lcd.setCursor(6,3);
  
  Delay1 += 1000;
  }
}

void Display2()
{
  if (millis() >= Delay1){
    lcd.begin(20,4);
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Voltage (V):");
   lcd.setCursor(13,0);
   lcd.print(voltage, 0);
   lcd.setCursor(0,1);
   lcd.print("Current (I):");
   lcd.setCursor(13,1);
   lcd.print(current, 2);
   lcd.setCursor(0,2);
   lcd.print("Power(Watt):");
   lcd.setCursor(13,2);
   lcd.print(power,2);
   lcd.setCursor(0,3);
   lcd.print("PF:");
   lcd.setCursor(4,3);
   lcd.print(powerFactor,2);
   lcd.setCursor(10,3);
   lcd.print("Rate:");
   lcd.setCursor(17,3);
//   lcd.print(rate);
    Delay1 += 1000;
  }
}
  
void resetPasswordArray() { //Clear entry array
  
       for (i=0;i<5;i++){
    PasswordArray[i] = '\0'; //set all characters in the entry array to null
    }
     
    i=0; //reset counter
}

void checkPassword() { 
  if (i>3 && i<5){
    if (password.is(PasswordArray)){
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Access Granted");
      delay (2000);
      lcd.clear();
      input();
    } 
    else {
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Access Denied");
      delay(2000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Enter Pass Code:");
      lcd.setCursor(0,2);
      
    }
  }
  else{
     lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Must Be 4 Charac!");
      delay(2000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Enter Pass Code:");
      lcd.setCursor(0,2);
  }
  i=0;
  resetPasswordArray();
  password.reset();
}

void input(){
  if (password.is(PasswordArray)){
    lcd.setCursor(0,1);
    lcd.print("Energy Limit:");
    lcd.setCursor(0,2);
    lcd.print(eLimit);
    lcd.setCursor(9,2);
    lcd.print("kWh");
    keypad.begin(*datakeys);
  }
}


void blink (const byte LED, int DELAY){
  
  digitalWrite(LED, !digitalRead(LED));
  delay (DELAY);
  digitalWrite(LED, !digitalRead(LED));
  
}

What do you mean by "when i press several keys on my keypad"? If you are pressing several keys at once, you could be causing a short circuit, which can result in a reset.

Not at once sir, when i run the code and press some key for the command and inputs there comes a time that it will restart.

when i run the code and press some key for the command and inputs there comes a time that it will restart.

Perhaps a clue as to what keys you are pressing, in what order, and what serial output you get, would be in order, then.

You really need to add more Serial.print() statements to determine what is happening.

Not your problem I think but you are using a global called “i” for all your loops, that’s bazaar. EG

void resetPasswordArray() { //Clear entry array
  
       for (i=0;i<5;i++){
    PasswordArray[i] = '\0'; //set all characters in the entry array to null
    }
     
    i=0; //reset counter
}

That’s asking for trouble, make it local to the loops.


Rob

Thank you for the advice i'll try to fix this and update you if what happens. :)

      if (key != '#'){
       PasswordArray[i] = key; i++;
      }

Buffer overrun bug here. You cannot just write to an array without checking that
the index is in bounds - if you don’t the program behaviour is “undefined” - you have
corrupted RAM. Would easily explain resets.

      case 'Y':
      if(key == 'Y'){
        eLimit = eLimitArray[l];
        lcd.setCursor(0,3);
        lcd.print("Data Stored!");
        keypad.begin(*keys);
      }
      break;

The switch statement is already comparing key to ‘Y’, so the if clause is
completely unnecessary. There are many places where you are doing such
unnecessary tests.

There are many places where you are doing such unnecessary tests.

Except that the switch is based on lastKey, not key, which is what is being tested in the cases.

Thanks Paul and Mark. I have a problem, on taking the value of eLimit at:

case 'Y':
        eLimit = eLimitArray[l];
        lcd.setCursor(0,3);
        lcd.print("Data Stored!");
        keypad.begin(*keys);
      break;

the number i input is not the same as what i want to display at “Limit(kWh):” what do you think should i do?

        eLimit = eLimitArray[l];

You only write one value to eLimitArray, to the 2nd element of the array. Why?

Paul, do you mean [l]? its letter L not 1. Did i answer you correctly?

Here is the code:

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Password.h>
#include <ctype.h>

Password password = Password ("1234");
char PasswordArray[5];
char eLimitArray[5];
int i = 0;
int c = 0;
const byte ledPin13 = 13;

long Delay1 = 0;

unsigned long eLimit = 99999;

boolean alpha = false;   // Start with the numeric keypad.

LiquidCrystal lcd(12, 11, 37, 35, 33, 31, 29, 27, 25, 23);

int backlight = 30;
boolean ledPin_state;
char key;
char key2;

int voltagePin = 0;
int adcVolts[255];
int magV = 0;
int magCountV = 0;
double voltage;
double Vstep = 0.0048875855;
double Vscope = 0.4283461622;
double VTR = 18.00766284;

int currentPin = 1;
int adcCurrent[255];
int magI = 0;
int magCountI = 0;
double current;

double power = 0;
double powerFactor;
double phase;
int countDelta;

unsigned long last_kWhTime, kWhTime;
float kilowattHour = 0.0;

const byte ROWS = 4;
const byte COLS = 4; 

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

char datakeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'Z','0','Y','D'}
};

char* keypadMap = (alpha == true) ? makeKeymap(datakeys) : makeKeymap(keys);

byte colPins[COLS] = { 44, 42, 40, 38 };

byte rowPins[ROWS] = { 52, 50, 48, 46 }; 

Keypad keypad = Keypad(keypadMap, rowPins, colPins, sizeof(rowPins), sizeof(colPins));


void setup()
{
    Serial.begin(9600);
    lcd.begin(20,4);
    pinMode(backlight, OUTPUT);
    digitalWrite(backlight, HIGH);
    lcd.clear();
    ledPin_state = digitalRead(backlight);   
    keypad.addEventListener(keypadEvent);
    keypad.setDebounceTime(200);
    pinMode (ledPin13, OUTPUT);
}


char lastKey = '\0';

void loop()
{
  solving();
  
 char key = keypad.getKey();
 
   if ( (key == 'A') || (key =='B') || (key == 'C' ) || (key == '*') || (key == '#') ) lastKey = key;
  switch(lastKey)
  {
    case 'A' : Display1(); break;
    case 'B' : Display2(); break;
    case 'C' :
      if (key == 'C'){
        digitalWrite(backlight,!digitalRead(backlight));
        ledPin_state = digitalRead(backlight);
      }
      break;
    case '*': break;
    case '#': break;
 //   default:  break; // default display
  }
  
  if ((key == '*') || (key == '#') || (key == '1') || (key == '2') || (key == '3') || (key == '4') || (key == '5') || (key == '6') || (key == '7') || (key == '8') || (key == '9') || (key == '0') || (key == 'Z') || (key == 'Y') ){
    switch (key){
      case '*':
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Enter Pass Code:");
      lcd.setCursor(0,2);
      resetPasswordArray();
      break;
      
      case '#':
      checkPassword();
      break;
      
      case 'Z':
        lcd.setCursor(0,2);
        lcd.print("        ");
        lcd.setCursor(0,2);
        eLimitArray[c] = '\0';
        break;
      
      case 'Y':
        eLimit = eLimitArray[c];
        lcd.setCursor(0,3);
        lcd.print("Data Stored!");
        keypad.begin(*keys);
      break;
      
      default: 
      if ((key != '#') && (key != '*') && (key != 'Z') && (key != 'Y')){
        lcd.print(key);
      }
      if ((key != '#') && (key != '*') && (key != 'Z') && (key != 'Y')) {
          PasswordArray[i] = key; i++;
      }
      
      if ((key != '#') && (key != '*') && (key != 'A') && (key != 'B') && (key != 'C') && (key != 'D') && (key != 'Z') && (key != 'Y') ){
        eLimitArray[c] = key; c++;
      }
    }
      
  }
}

void keypadEvent(KeypadEvent key){
}

void solving()
{
   for (int i=0; i < 255; i++){
  adcVolts[i] = analogRead(voltagePin);
  adcCurrent[i] = analogRead(currentPin);
  }

magV = 0;
magI = 0;
magCountV = 0;
magCountI = 0;

for (int i=0; i < 255; i++){
  if (adcVolts[i] > magV){
    magV = adcVolts[i];
    magCountV = i;
  }
  if (adcCurrent[i] > magI){
    magI = adcCurrent[i];
    magCountI = i;
  }
}

  voltage = (7.2686218 * pow((magV * Vstep * Vscope), 0.98175303)) * VTR;
  current = (3.8208634 * pow((magI * Vstep * Vscope), 1.1647062));
  
  countDelta = abs(magCountI - magCountV);
  
  while (countDelta > 73){
    countDelta = countDelta - 73;
  }
  
  phase = countDelta * 360 / 73;
  powerFactor = abs(cos( phase / 180*3.1459));
  power = voltage * current * powerFactor;
  
  last_kWhTime = kWhTime;
  kWhTime = millis();
  
  kilowattHour += (power/1000)*((kWhTime - last_kWhTime)/3600000.0);
  
}

void Display1()
{
  if (millis() >= Delay1){
  lcd.begin(20,4);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ECons(kWh):");
  lcd.setCursor(13,0);
  lcd.print(kilowattHour, 2);
  lcd.setCursor(0,1);
  lcd.print("ECons(PHP):");
//  lcd.setCursor(13,1);
//  lcd.print(current, 5);
  lcd.setCursor(0,2);
  lcd.print("Limit(kWh):");
  lcd.setCursor(13,2);
  lcd.print(eLimit);
  lcd.setCursor(0,3);
  lcd.print("Date:");
  lcd.setCursor(6,3);
  
  Delay1 += 1000;
  }
}

void Display2()
{
  if (millis() >= Delay1){
    lcd.begin(20,4);
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Voltage (V):");
   lcd.setCursor(13,0);
   lcd.print(voltage, 0);
   lcd.setCursor(0,1);
   lcd.print("Current (I):");
   lcd.setCursor(13,1);
   lcd.print(current, 2);
   lcd.setCursor(0,2);
   lcd.print("Power(Watt):");
   lcd.setCursor(13,2);
   lcd.print(power,2);
   lcd.setCursor(0,3);
   lcd.print("PF:");
   lcd.setCursor(4,3);
   lcd.print(powerFactor,2);
   lcd.setCursor(10,3);
   lcd.print("Rate:");
   lcd.setCursor(17,3);
//   lcd.print(rate);
    Delay1 += 1000;
  }
}
  
void resetPasswordArray() { //Clear entry array
  
       for (i=0;i<5;i++){
    PasswordArray[i] = '\0'; //set all characters in the entry array to null
    }
     
    i=0; //reset counter
}

void checkPassword() { 
  if (i>3 && i<5){
    if (password.is(PasswordArray)){
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Access Granted");
      delay (2000);
      resetPasswordArray();
      lcd.clear();
      input();
    } 
    else {
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Access Denied");
      delay(2000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Enter Pass Code:");
      lcd.setCursor(0,2);
      
    }
  }
  else{
     lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Must Be 4 Charac!");
      delay(2000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Enter Pass Code:");
      lcd.setCursor(0,2);
  }
  i=0;
  resetPasswordArray();
  password.reset();
}

void input(){
  if (password.is(PasswordArray)){
    lcd.setCursor(0,1);
    lcd.print("Energy Limit:");
    lcd.setCursor(0,2);
    lcd.print(eLimit);
    lcd.setCursor(9,2);
    lcd.print("kWh");
    keypad.begin(*datakeys);
  }
}


void blink (const byte LED, int DELAY){
  
  digitalWrite(LED, !digitalRead(LED));
  delay (DELAY);
  digitalWrite(LED, !digitalRead(LED));
  
}

i don’t know how can i get the right value of the eLimit when i input it, maybe there is something wrong from eLimitArray. can you help me? thanks!

kengwapo: Paul, do you mean [l]? its letter L not 1. Did i answer you correctly?

That is an incredibly bad variable name, especially for something that is likely to hold a value of 1. You will eventually want to come back to this code to upgrade or change it, and it's best to name your variables with meaningful names, and names that cannot be mistaken for numbers.

I can't see anywhere that "c" is reset and it's used to index into that array then incremented.

eLimitArray[c] = key; c++;

+1 about variable names.


Rob

I already changed it to c.

void reseteLimitArray(){
  for (c=0; c<5; c++){
    eLimitArray[c] = '\0';
  }
  c=0;
}
 case 'Z':
        lcd.setCursor(0,2);
        lcd.print("        ");
        lcd.setCursor(0,2);
        delay(2000);
        reseteLimitArray();
        break;

is this right sir? the way i reset the eLimit? when i press ‘Z’ it will reset and start a new array? my problem is i can input the values for eLimitArray but when i go back to the display to check if the display is the same as what i input, it is not. What do you think is the problem? the declaration of the codes? thank you.

the way i reset the eLimit?

It's OK, but unnecessary. A string is a NULL terminated array of chars. Think of the NULL as a stop sign for functions that expect strings. It isn't necessary to put 5 stop signs in the array. One will do.

my problem is i can input the values for eLimitArray but when i go back to the display to check if the display is the same as what i input, it is not.

One letter global variable names, like c are a bad idea. It's too easy to use one in place/way that you didn't mean to. For instance, the index variable in the for loop in the reseteLimitArray() function should NOT be using a global variable as the index.

Put each { on a new line. Use Tools + Auto Format BEFORE posting your code again. Post all of it. Snippets are best posted to http://snippets-r-us.com.