How do I increment a global variable in a function?

I am using an Arduino uno and mega connected by UART. I have been given the task to have the mega receive input from the computer keyboard through serial communication and the Arduino kit keypad and then display the characters on a LCD display attached to the Arduino uno. For the program to end the character '*' or 'E' must be pressed three times consecutively with no other characters in between. However, the "count" variable I have does not increment but gets stuck at value of 1.

#include <Keypad.h>

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

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


byte rowPins[ROWS] = {9, 8, 7, 6}; 
byte colPins[COLS] = {5, 4, 3, 2}; 


Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

char userInput;

boolean newChar = false;

int count = 0;

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600); // communication between 
                       // mega and uno 
}

void loop() {
  getOneChar();
  displayChar();

  /*if(Serial.available())
  {
    userInput = Serial.read(); // reads user Input  
    Serial1.write(userInput); // send useraInput to arduino
    Serial.print(userInput); // Prints userInput on console 
  }
  
  char customKey = customKeypad.getKey();
  if (customKey)
  {
     userInput = customKey;
     Serial1.write(customKey);
     Serial.println(customKey);
  }*/

  checkCharVal();

  if( count == 3)
  {
    exit(0);
  }
  
}


void getOneChar()
{
  char customKey = customKeypad.getKey();
  //userInput = Serial.read(); // reads user Input  
  
  if(Serial.available())
  { 
    userInput = Serial.read(); // reads user Input 
    newChar = true;
  }
  
  if (customKey)
  {
     userInput = customKey;
     newChar = true;
  }
}

void displayChar()
{
  if(newChar == true)
  {
    Serial1.write(userInput);
    Serial.println(userInput);
    newChar = false;
  }
}


void checkCharVal()
{
  if(userInput == '*')
  {
    addToCount();
  }
  else if (userInput != '*')
  {
    count = 0;
  } 

  if(userInput == 'E')
  {
    addToCount();
  }
  else if (userInput != 'E')
  {
    count = 0;
  } 
}


void addToCount()
{
  count++;
  Serial.println(count);
}

What have you got the Line Ending set to in the Serial Monitor ? If it is anything except No line ending then your code will not work because the line ending characters will cause count to be reset to zero

In addition, consider what happens if you enter '*' because the second if/else will reset count to zero in any case

Consider multiple conditions and the OR operator

Think about your code

If not x Reset
If not y reset

When used together means
If x do, then because x is not y reset

You want: if not x or y reset ie if x or y do

What happens if you send EEE

On top of what @UKHeliBob said your code is going to be a bit more complex than the above.

If you are looking for 3 consecutive presses of either "*" or "E", you also need to check that once count is greater then zero, you continue pressing the same key.

You could keep separate counts.

if (key == ‘E’)
  Ecount++;
else
  Ecount = 0;

if (Key == ‘*’)
  Acount++;
else
  Acount = 0;
if (Ecount == 3 || Acount == 3)
  // three in a row

If

It seems like setting a count is not going to work. Maybe it has to do with the way the characters are being read. Count never progresses past the value 1. I tried to store the characters in a character array size of 3 and check if the values in the character array are the same, if not empty it, and once another terminating character has been entered start the process over again. It seems like I am having trouble incrementing. If I print out the value if my count it will either print "1" several times or enter an infinite loop where the value of count prints out as "1".

Code I have so far...

#include <Keypad.h>

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

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


byte rowPins[ROWS] = {9, 8, 7, 6}; 
byte colPins[COLS] = {5, 4, 3, 2}; 


Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

char userInput; // input from computer
char userInput2; // input from keypad 
char currChar; //character to be stored in character array

boolean newChar = false; 
boolean newChar2 = false;
boolean terminate = false; // if true then it ends the program
const byte numChars = 3; // size of character array 
char receivedChars[numChars]; // stores characters if '*' or 'E' is pressed

int count = 0;

static byte i = 0; //keeps index of receivedChars array

int Ecount = 0; //keeps track of number of E entered 

int Acount = 0; //keeps track of number of * entered

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600); // communication between 
                       // mega and uno 
}

void loop() {
  getOneChar();
  displayChar();
  //checkCharVal();

  if( Ecount == 3 || Acount == 3)
  {
    exit(0);
  }

  /*if(terminate = true)
  {
    exit(0);
  }*/
  
}


void getOneChar() // gets characters from computer or keypad
{
  char customKey = customKeypad.getKey();
  char endMarker = '*';
  char endMarker2 = 'E';
  
  if(Serial.available()) // deals with computer input 
  { 
    userInput = Serial.read(); // reads user Input 
    if(userInput == 'E')
    {
      //currChar = userInput;
      //checkCharVal();
      Ecount++;
    }
    else 
    {
      Ecount = 0;
    }

    if(userInput == '*')
    {
      //currChar = userInput;
      //checkCharVal();
      Acount++;
    }
    else 
    {
      Acount = 0;
    }
    
    newChar = true;
  }
  
  if (customKey) //deals with the keypad input. 
  {
    userInput2 = customKey;
    if(userInput2 == 'E')
    {
      //currChar = userInput;
      //checkCharVal();
      Ecount++;
    }
    else 
    {
      Ecount = 0;
    }

    if(userInput2 == '*')
    {
      //currChar = userInput;
      //checkCharVal();
      Acount++;
    }
    else 
    {
      Acount = 0;
    }
    newChar2 = true;
  }
}

void displayChar() // displays the inputs from both computer and keypad
{
  if(newChar == true)
  {
    Serial1.write(userInput); // sends char to Arduino uno to be displayed on LCD
    Serial.print(userInput); // prints char on console 
    newChar = false;
  }

  if(newChar2 == true)
  {
    Serial1.print(userInput2); // sends char to Arduino to be displayed on LCD
    Serial.println(userInput2); //displays char on the console 
    newChar2 = false;
  }
  
}


void checkCharVal() // stores terminating character and 2 characters behind it in character array and checks the values  
{

  /*if( i < 3)
  {
    receivedChars[i] = currChar; // stores char at index i of array depending on what value i is
    i+=1; // i increments everytime function is called while i < 3
  }
  else if( i == 3)
  {
    if( receivedChars[0] == 'E' && receivedChars[1] == 'E' && receivedChars[2] == 'E' )
    {
      Serial.print("Array: ");
      Serial.print(receivedChars);
      terminate = true;
    }
    if( receivedChars[0] == '*' && receivedChars[1] == '*' && receivedChars[2] == '*' )
    {
      terminate = true;
    }
    else if( receivedChars[0] != receivedChars[1] && receivedChars[1] != receivedChars[2] ) //x is just a dummy character
    {
      receivedChars[0] = x;
      receivedChars[1] = x;
      receivedChars[2] = x;
      i = 0;
    }
  }*/  

}

Why are you coding for eee and *** if you haven’t got one or the other working fully first

My approach was I assumed that each character would be evaluated by the if statements separately. So if another character is entered that does not satisfy the condition then count just gets set back to zero. If the condition is met 3 times in a row, the code in the else block never gets called and count eventually adds up to 3.

print that so you know what it is.

Also, make sure customKey is not making your counts reset.

Add printing to wherever the count gets reset saying why you do that.

You are flying blind! No shame in putting some things in there so you know where you at, why and what's doing what.

a7

Actually I tried the "||" operator my first attempt. so something like

  if( currChar == 'E' || currChar == '*' )
  {
    //Then do the counting based on some more conditions 
  }
  else if( currChar != 'E' || currChar != '*' )
  {
    //set counter to value 0 
  }

That won’t work either I feel. Serial print char and serial print for each if statement where you are
M you don’t need second statement

Sorry, my code is a bit messy with commented bits. I am already able to see every character entered from the computer and the key pad to the Arduino. The values are displayed both on the console and the LCD screen attached to the Arduino uno that the mega is communicating with. That part all works well.

Here's the output, when I press 'A', the press 'E' twice, the press 'A' again. While entering A does output an Ecount value of 0, It seems that Ecount does increment when 'E' is pressed, but then reverts back to zero regardless.

0
0
A0
0

1
0
E0
0

1
0
E0
0

0
0
A0
0

That output may be meaningful to you, but unless I crawl all over your code it does me no good. Even then, not sure enough the effort would be worth undertaking.

Do or don't, but I'd spare a few characters and put verbose ubiquitous print statements on in there to see why this can possibly be happening, with enough variable values to see if the logic is doing what you think.

Which it obvsly isn't, yet.

a7

Back in post #2 I asked what you had the Line ending set to in the Serial monitor

Did you ever answer that ?

EDIT : My apologies. I had not appreciated that the input was coming from a keypad rather than Serial. Please ignore my question

Here is what I have now

#include <Keypad.h>

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

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


byte rowPins[ROWS] = {9, 8, 7, 6}; 
byte colPins[COLS] = {5, 4, 3, 2}; 


Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

char userInput; // input from computer
char userInput2; // input from keypad 
char currChar; //character to be stored in character array

boolean newChar = false; 
boolean newChar2 = false;
boolean terminate = false; // if true then it ends the program
const byte numChars = 3; // size of character array 
char receivedChars[numChars]; // stores characters if '*' or 'E' is pressed

int count = 0;

static byte i = 0; //keeps index of receivedChars array

int Ecount = 0; //keeps track of number of E entered 

int Acount = 0; //keeps track of number of * entered



void setup() {
  Serial.begin(9600);
  Serial1.begin(9600); // communication between 
                       // mega and uno 
}

void loop() {
  getOneChar();
  displayChar();
  //checkCharVal();


  if( terminate == true )
  {
    exit(0); //is supposed to terminate program when consition met 
  }
  
}


void getOneChar()
{
  //char customKey = customKeypad.getKey();
  //userInput = Serial.read(); // reads user Input  
  char endMarker = '*';
  char endMarker2 = 'E';
  
  if(Serial.available()) //receives data from computer 
  { 
    currChar = Serial.read(); // reads user Input from computer 
    userInput = currChar; //stores the character in userInput var
    
    if(userInput == 'E')
    {
      //checkCharVal();
      ++Ecount;
      Serial.println("Ecount: "); 
      Serial.println(Ecount); // gives value of Ecount  
      if( Ecount == 3) //checks if val of Ecount = 3
      {
        Serial.println("PROGRAM TERMINATED");
        //terminate = true;
      }
    }
    else 
    {
      Ecount = 0;
      Serial.println("Ecount set back to value of: ");
      Serial.println(Ecount);
    }

    /*if(userInput == '*') 
    {
      //currChar = userInput;
      //checkCharVal();
      Serial.println("Acount: ");
      Serial.println(Acount);
      Acount++;
    }
    else 
    {
      Acount = 0;
      Serial.println("Acount set back to value of: ");
      Serial.println(Acount);
    }*/
    
    newChar = true;
  }

  char customKey = customKeypad.getKey();
  
  if (customKey)
  {
    userInput2 = customKey; 

    if(customKey == '*') // checks value of customKey
    {
      //currChar = userInput;
      //checkCharVal();
      ++Acount;
      Serial.println("Acount: ");
      Serial.println(Acount); //prints val of Acount
      if( Acount == 3) //checks of Acount is equal to 3
      {
        Serial.println("PROGRAM TERMINATED");
        //terminate = true;
      }
    }
    else 
    {
      Acount = 0; // resets Acount to 0 if condition not met 
      Serial.println("Acount set back to value of: ");
      Serial.println(Acount); // gives current val of Acount 
    }
    newChar2 = true;
  }
}

void displayChar()
{
  if(newChar == true) // deals with char from computer
  {
    Serial1.write(userInput); // displays char from computer on LCD
    Serial.println("Character Received from computer: ");
    Serial.println(userInput); // displays char from computer on console 
    newChar = false;
  }

  if(newChar2 == true) // deals with char from keypad 
  {
    Serial1.print(userInput2); // displays char from keypad on LCD
    Serial.println("Character Received from keypad: ");
    Serial.println(userInput2); // displays char from keyoad on console 
    newChar2 = false;
  }
  
}

Test for input coming from Keypad:

Acount: 
1
Character Received from keypad: 
*
Acount set back to value of: 
0
Character Received from keypad: 
C
Acount: 
1
Character Received from keypad: 
*
Acount: 
2
Character Received from keypad: 
*
Acount set back to value of: 
0
Character Received from keypad: 
9
Acount: 
1
Character Received from keypad: 
*
Acount: 
2
Character Received from keypad: 
*
Acount: 
3
PROGRAM TERMINATED
Character Received from keypad: 
*

Things are going in the right direction, the program terminates before the third consecutive '' is printed. For testing purposes if exit(0) is called I never see the program output the last ''. However, this is fine as long as it acknowledge 3 '*' were input consecutively. So it seems fine..

Input coming from computer:

Ecount: 
1
Character Received from computer: 
E
Ecount set back to value of: 
0
Character Received from computer: 


Ecount: 
1
Character Received from computer: 
E
Ecount set back to value of: 
0
Character Received from computer: 


Ecount: 
1
Character Received from computer: 
E
Ecount set back to value of: 
0
Character Received from computer: 


Ecount set back to value of: 
0
Character Received from computer: 
Q
Ecount set back to value of: 
0
Character Received from computer: 


Ecount: 
1
Character Received from computer: 
E
Ecount set back to value of: 
0
Character Received from computer: 

This seems to be a different story. Ecount is stuck at value of "1" regardless of how many consecutive 'E's that I enter. However, it does reset when I enter a character that is not 'E'. Unfortunately it seems like it runs the line "Character Received from computer: " again without user input and outputs a blank line.

It seems the lines of code are not executing in the order I want. the comparison of whether Acount is == 3 trumps my print statements and ends the program. For Ecount the if statement moves forward without even receiving a user input and fails to properly increment ECount.

It may be receiving a null character which is not E

I was actually looking at Serial Input Basics - updated yesterday. I was a little confused on how to go about setting it to no line ending. Input from my keypad seems to be working just fine. it's the input from the computer that is giving me problems.

Maybe I wasn't so wrong after all

Are you using the Serial monitor to enter the data from the PC ?

Things are working correctly for the input coming from the keypad. Adding a small delay seems to have given the program enough time to output the last '*' before shutting down the program

  char customKey = customKeypad.getKey();
  
  if (customKey)
  {
    userInput2 = customKey; 

    if(customKey == '*') // checks value of customKey
    {
      //currChar = userInput;
      //checkCharVal();
      ++Acount;
      Serial.println("Acount: ");
      Serial.println(Acount); //prints val of Acount
      if( Acount == 3) //checks of Acount is equal to 3
      {
        Serial.println("Character Received from keypad: ");
        Serial.println(userInput2);
        Serial.println("PROGRAM TERMINATED");
        delay(1200);
        terminate = true;
      }
    }
    else 
    {
      Acount = 0; // resets Acount to 0 if condition not met 
      Serial.println("Acount set back to value of: ");
      Serial.println(Acount); // gives current val of Acount 
      
    }
    newChar2 = true;
  }
}

Acount:
1
Character Received from keypad:
*
Acount set back to value of:
0
Character Received from keypad:
9
Acount:
1
Character Received from keypad:
*
Acount:
2
Character Received from keypad:
*
Acount:
3
Character Received from keypad:
*
PROGRAM TERMINATED
Ch