Resetting LED Delay Time After Presssing Keypad Button

Hello! I’m still unfamiliar with Arduino looping concept. I just got an assignment to connect Arduino with a keypad and LCD screen.

Here we can input a number to set the LED blink delay time. The task is: after inputting the first value, the LED will blink continuously, and by pressing “A” in the keypad, it should stop and accept another delay time value. However, in my case, I can’t insert another value after inputting the first one. Here are the codes:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

int pin = 13;

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'  },
  {'4','5','6','B'  },
  {'7','8','9','C'  },
  {'*','0','#','D'  }
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad, row1,2,3,4
byte colPins[COLS] = {8, 9, 10, 11}; //connect to the column pinouts of the keypad col1,2,3,4

// initialize Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// check address, you can you IIC scan code to check
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

// input delay time
int delay_time = 0;

void setup() {
  // set the pin mode for LED
  pinMode(pin, OUTPUT);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // set the cursor in the first row and first column
  lcd.setCursor(0, 0);
  // Print a message to the LCD.
  lcd.print("Delay time (ms):");
  // set the cursor in the second row
  lcd.setCursor(0, 1);
  // input delay time in millisecond
  delay_time = input();
}

void loop() {
  // Turn off the LED:
  digitalWrite(pin, LOW);
  delay(delay_time);
   // Turn on the LED:
  digitalWrite(pin, HIGH);
  delay(delay_time);
}

//Input Chars
//return: input number
int input()
{
  unsigned int n=0; //holding no. of chars inputted
  unsigned char tmp=0;
  char input_temp[10];
  int input_len=0, i;


  tmp = keypad.getKey();

  lcd.cursor(); //show cursor
  lcd.blink();  //blink cursor
  while(tmp != '#')
  {
    if(tmp == '*')
    {
      //Clear Data
      lcd.rightToLeft();
      
      for(i=0; i<n; i++)
        lcd.print(" ");

      lcd.leftToRight();
      lcd.print(" ");
      
      lcd.rightToLeft();
      lcd.print(" ");
      lcd.leftToRight();
      n = 0;
    }
    else if(tmp != NO_KEY && tmp != '*')
    {
      input_temp[n++] = tmp;
      lcd.print(input_temp[n-1]);
    }

    tmp = keypad.getKey();
  }

  lcd.noCursor(); //no cursor

  return convert_chars_to_int(input_temp, n);
}//end input_chars

//Convert Chars to integer
//Parameters: *buf: chars in string
//            len: no. of chars
//return: a integer
int convert_chars_to_int(char *buf, int len)
{
  int i, value=0, j=len;

  for(i=0; i<j; i++)
    value += (pow_int(10, --len) * (buf[i] - '0'));

  return value;
}//end convert_chars_to_int

int pow_int(int base, int expo)
{
  int value =1, i;

  for(i=0; i<expo; i++)
    value *= 10;

  return value;
}//end pow_int

I’ve tried using another code model. It can reset the value after I pressed “A”, however, the LED will only blink once. Can you guys give any suggestions about this? Thank you very much! :slight_smile:

After entering loop() input() is never called again.

Here’s one that does what you ask using the serial monitor. Maybe you can adapt this to your keyboard thing?

#include <blinker.h>
#include <lilParser.h>

#define LED_PIN 13 // Pin for built in LED.

 
enum commands {   noCommand,  // ALWAYS start with noCommand. Or something simlar.
                  LEDOn,      // The rest is up to you. help would be a good one. Have it list
                  LEDOff,     // What the other commands are, how they work and what they do.
                  A           // Set blinker delay.
                  };          // Our list of commands.

lilParser   ourParser;              // The parser object.
blinker     ourBlinker(LED_PIN);    // The blinker object.

void setup() {
   
   Serial.begin(9600);
   ourParser.addCmd(A,"A");         // Type off to turn it off again.
   ourParser.addCmd(LEDOn,"on");    // Type on to turn on the LED.
   ourParser.addCmd(LEDOff,"off");  // Type off to turn it off again.
   ourBlinker.setOnOff(false);      // Start it with it off.
}


// Your loop where it parses out all your typings.
void loop(void) {

   char  inChar;
   int   command;

   idle();                                                     // Runs things like the blinker.
   if (Serial.available()) {                                   // If serial has some data..
      inChar = Serial.read();                                  // Read out a charactor.
      Serial.print(inChar);                                    // If using development machine, echo the charactor.
      command = ourParser.addChar(inChar);                     // Try parsing what we have.
      switch (command) {                                       // Check the results.
         case noCommand : break;                               // Nothing to report, move along.
         case A         : doBlinkDelay();             break;   // Deal with changing blibnk delay
         case LEDOn     : ourBlinker.setOnOff(true);  break;   // Turn the LED on (HIGH is the voltage level)
         case LEDOff    : ourBlinker.setOnOff(false); break;   // Turn the LED off by making the voltage LOW
         default        : Serial.println("What?");    break;   // No idea. Try again?
      }
   }
}


// Deal with changing the delay of the blinker.
void doBlinkDelay(void) {

   char* charBuff;                                 // A pointer for the number string.
   int   delayMS;                                  // The incoming number.
   
   if (ourParser.numParams()) {                    // If they typed in somethng past the command.
      charBuff = ourParser.getParamBuff();         // We get the first parameter, assume its the number.
      delayMS = atoi(charBuff);                    // Grab the value.
      free(charBuff);                              // Dump the parameter buffer ASAP.
      ourBlinker.setPeriod(delayMS);               // Set the dealy.
      ourBlinker.setOnOff(true);                   // Make sure it's on.
   }
}

To try this you’ll need to install LC_baseTools & LC_lilParser using the IDE’s library manager.

Good luck!

-jim lee