can't blink using switch case

Hello everybody,

I have a problem with my arduino project. Basically, what I’m trying to do is to blink 4 LEDs depending on the key pressed in the keypad. The rate of the blinking depends on what number is pressed.

I used millis() instead of delay() to blink the LEDs. My problem is:

with the delay() on every case, the LEDs and the servo motor turns off for 5 seconds and turns on again and does the ‘default’ part of the source code.

without the delay(), it doesn’t do anything, i mean it just goes on and does the ‘default’ part again even if I press a number on the keypad.

this is my code

#include <Keypad.h>
#include <Servo.h>
#define led1 4
#define led2 5
#define led3 6
#define led4 7

unsigned long previousMillis[4]; //[x] = number of leds

//SERVO MOTOR
int servo = 3;

//KEYPAD
const byte Rows = 3;
const byte Cols = 3;
char keymap [Rows][Cols] = 
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'}
};
byte rPins[Rows] = {A0, A1, A2}; //Rows 0 to 3
byte cPins[Cols] = {A3, A4, A5}; //Columns 0 to 2
Keypad kpd = Keypad (makeKeymap(keymap), rPins, cPins, Rows, Cols);

void setup()
{
  Serial.begin(9600);
  pinMode(servo, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
}

void loop(){
    unsigned long currentMillis  = millis();
    char keypressed = kpd.getKey();
    if(keypressed != NO_KEY)
    {
      Serial.println(keypressed);
    }

    switch (keypressed)
    {
      case '1':
        blinkled(led1, 100, 0);
        blinkled(led2, 100, 1);
        blinkled(led3, 100, 2);
        blinkled(led4, 100, 3);
        servomotor();
//        delay(5000);
        break;
     
      case '2':
        blinkled(led1, 50, 0);
        blinkled(led2, 50, 1);
        blinkled(led3, 50, 2);
        blinkled(led4, 50, 3);
        servomotor();
//        delay(5000);
        break;

      case '3':
        blinkled(led1, 500, 0);
        blinkled(led2, 800, 1);
        blinkled(led3, 500, 2);
        blinkled(led4, 800, 3);
        servomotor();
//        delay(5000);
        break;

      case '4':
        blinkled(led1, 250, 0);
        blinkled(led2, 0, 1);
        blinkled(led3, 250, 2);
        blinkled(led4, 0, 3); 
        servomotor();
//        delay(5000);
        break;

      case '5':
        blinkled(led1, 00, 0);
        blinkled(led2, 250, 1);
        blinkled(led3, 0, 2);
        blinkled(led4, 250, 3);
        servomotor();
//        delay(5000);
        break;
    
      case '6':
        blinkled(led1, 1000, 0);
        blinkled(led2, 2000, 1);
        blinkled(led3, 3000, 2);
        blinkled(led4, 4000, 3);
        servomotor();
//        delay(5000);
        break;
    
      case '7':
        blinkled(led1, 105, 0);
        blinkled(led2, 2034, 1);
        blinkled(led3, 3030, 2);
        blinkled(led4, 450, 3); 
        servomotor();
//        delay(5000);
        break;
    
      case '8':
        blinkled(led1, 160, 0);
        blinkled(led2, 250, 1);
        blinkled(led3, 430, 2);
        blinkled(led4, 440, 3);
        servomotor();
//        delay(5000);
        break;
    
      case '9':
        blinkled(led1, 150, 0);
        blinkled(led2, 2060, 1);
        blinkled(led3, 700, 2);
        blinkled(led4, 480, 3);
        servomotor();
//        delay(5000);
        break;

      default:
        blinkled(led1, 100, 0);
        blinkled(led2, 100, 1);
        blinkled(led3, 100, 2);
        blinkled(led4, 100, 3);
        servomotor();
        break;
    }
  }

void blinkled(int led, int interval, int array)
{
  if ((long)millis() - previousMillis[array] >= interval) //or change millis() to currentMillis
  {
    previousMillis[array] = millis();
    digitalWrite(led, !digitalRead(led)); //changes led state
  }
}

void servomotor()
{
  digitalWrite(servo, HIGH);
  delayMicroseconds(1500);
  digitalWrite(servo, LOW);
  delay(20);
}

please help. thank you.

What is supposed to happen when a button gets pushed? Are the other buttons capable of interrupting the button that's being serviced of doe the pushed button rin to completion before the other buttons can cause further action?

Driving a servo, with delays, whilst trying to blink a LED without delays is madness.

Try the Servo library instead.

I think the problem is that once you start the blinking process you replace keypressed with the next value and you switch doesn't have the same value to execute the same case.

Change:

    char keypressed = kpd.getKey();
    if(keypressed != NO_KEY)
    {
      Serial.println(keypressed);
    }

To:

    char key = kpd.getKey();
    if(key != NO_KEY)
    {
      keypressed = key;
      Serial.println(keypressed);
    }

You also need to declare 'keypressed' as a static or global variable so it keeps its value across function calls.

    static char keypressed = NO_KEY;
    char newkey = kpd.getKey();
    if(newkey != NO_KEY)
    {
      keypressed = newkey;
      Serial.println(keypressed);
    }

johnwasser:
I think the problem is that once you start the blinking process you replace keypressed with the next value and you switch doesn't have the same value to execute the same case.

Change:

    char keypressed = kpd.getKey();

if(keypressed != NO_KEY)
    {
      Serial.println(keypressed);
    }




To:


char key = kpd.getKey();
    if(key != NO_KEY)
    {
      keypressed = key;
      Serial.println(keypressed);
    }




You also need to declare 'keypressed' as a static or global variable so it keeps its value across function calls.


static char keypressed = NO_KEY;
    char newkey = kpd.getKey();
    if(newkey != NO_KEY)
    {
      keypressed = newkey;
      Serial.println(keypressed);
    }

I tried doing that and it works fine now! thank you!

DKWatson:
What is supposed to happen when a button gets pushed? Are the other buttons capable of interrupting the button that's being serviced of doe the pushed button rin to completion before the other buttons can cause further action?

The other buttons are supposed to be able to interrupt the button that is pressed.

But you have it working now?

AWOL:
Driving a servo, with delays, whilst trying to blink a LED without delays is madness.

Try the Servo library instead.

I did servo.write(degrees) first but the rpm is just too fast that's why I resorted to using delays.

DKWatson:
But you have it working now?

Yes. =)