1

I'm working on an escape room for my university with an Arduino Mega. The last part consists of a 7segment display representing a time countdown, and the participants have to introduce the correct number in a matrix keyboard before it reaches zero.

My problem comes when for representing the seconds in the countdown, I have to use a delay, and this stops the matrix keyboard from getting the numbers.

The code I have so far:

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

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

int pinA = 26; //2
int pinB = 34; //3
int pinC = 31; //4
int pinD = 27; //5
int pinE = 25; //6
int pinF = 28; //7
int pinG = 33; //8
int D1 = 24; //9
int D2 = 30; //10
int D3 = 32; //11
int D4 = 35; //12

Keypad mykeypad = Keypad( makeKeymap(keys), colPins, rowPins, 4, 4);

void setup()
{
Serial.begin(9600);


pinMode(pinA, OUTPUT);     
pinMode(pinB, OUTPUT);     
pinMode(pinC, OUTPUT);     
pinMode(pinD, OUTPUT);     
pinMode(pinE, OUTPUT);     
pinMode(pinF, OUTPUT);     
pinMode(pinG, OUTPUT);   
pinMode(D1, OUTPUT);  //Turns the first digit on.
pinMode(D2, OUTPUT);  //Turns the second digit on.
pinMode(D3, OUTPUT);  //Turns the third digit on.
pinMode(D4, OUTPUT);  //Turns the forth digit on.
}

//
void showTime(){

  digitalWrite(D1, LOW);
  digitalWrite(D2, LOW);
  digitalWrite(D3, LOW);
  digitalWrite(D4, LOW); 

 //3
  digitalWrite(pinA, HIGH);   
  digitalWrite(pinB, HIGH);   
  digitalWrite(pinC, HIGH);   
  digitalWrite(pinD, HIGH);   
  digitalWrite(pinE, LOW);   
  digitalWrite(pinF, LOW);   
  digitalWrite(pinG, HIGH);     
  delay(1000);   

//2
  digitalWrite(pinA, HIGH);   
  digitalWrite(pinB, HIGH);   
  digitalWrite(pinC, LOW);   
  digitalWrite(pinD, HIGH);   
  digitalWrite(pinE, HIGH);   
  digitalWrite(pinF, LOW);   
  digitalWrite(pinG, HIGH);     
  delay(1000); 

  //1
  digitalWrite(pinA, LOW);   
  digitalWrite(pinB, HIGH);   
  digitalWrite(pinC, HIGH);   
  digitalWrite(pinD, LOW);   
  digitalWrite(pinE, LOW);   
  digitalWrite(pinF, LOW);   
  digitalWrite(pinG, LOW);   
  delay(1000); 

  //0
  digitalWrite(pinA, HIGH);   
  digitalWrite(pinB, HIGH);   
  digitalWrite(pinC, HIGH);   
  digitalWrite(pinD, HIGH);   
  digitalWrite(pinE, HIGH);   
  digitalWrite(pinF, HIGH);   
  digitalWrite(pinG, LOW);   
  delay(1000);               

}

//Receives the chars from the matrix keyboard.
void getCode(){
   char key = mykeypad.getKey();
  if(key){
     Serial.print(key);
  }
}

void loop() 
{

  showTime();

}

Any idea on how can I archieve this combination? Have been trying to find something similiar to a Thread, but Arduino doesn't support it.

Thanks in advance.

1

Try using millis(), it returns the number of milliseconds passed since the Arduino board began running the current program.

When you start the countdown you set a variable for a beginning time

int millisBegin = millis(); //put this at the end of your setup() {}.

You will also need a "border" to know when one second is over, so

int millisBorder = 1000; //one second border

Every time your the loop() {} starts over you can check if one second has passed so far

int millisNow = millis();
if(millisNow - millisBegin >= millisBorder){} //if one second over, do {}

Now I would work on the segment showing thingy. In the {} I would put a new variable, let's call it counter = 4; //4 because I found 3 numbers in your sketch. Every time the if() {} is being executed, you go through more if () {} statements, checking what number to display next.

if (counter == 3)
{
  //show number 3
}

if (counter == 2)
{
  //show number 2
}

if (counter == 1)
{
  //show number 1
}

if (counter == 0)
{
  //show number 0
}
counter = counter - 1;

At the end we take one off the counter, so the next time we enter the if(one second over) the number displayed will get lower

And well now there are multiple ways of doing the keyboard thingy. You can keep checking if there is a key available, and if so you can safe it as a String (most people hate strings, but I never had a problem with them to be honest).

After you've saved the key as a String you can use the strcmp(); method to compare the string with the solution/answer strcmp(key,answer);. If the key and the answer are the same, it will return 1.

if(strcmp(key,answer) == 1)
{
  Serial.println("you made it");
}
0

Use the "blink without delay" examples in the IDE, whereby you perform an action and then basically watch the clock until and let the rest of the code run until the time elapes. For example, this blinks the onboard LED on and off, you can add to it for your keypad reading and time outputs.

unsigned long currentTime;
unsigned long previousTime;
unsigned long elapsedTime;
const byte ledPin = 13;
byte ledState = 0;

void setup(){
pinMode (ledPin, OUTPUT);
previousTime = millis();
}
void loop(){
currentTime = millis();  // capture the 'time' now
elapsedTme = currentTime - previousTime; // how much 'time' has passed
if (elapsedTime >= 1000){  // at least one second?
ledState = 1 - ledState; // results in 1,0,1,0,1,0 ...
digitalWrite (ledPin, ledState); // toddle the L led
previousTime = currentTime;   // set up for the next pass thru loop
// update the to display, and output it
}
// now add keypad reading stuff
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.