Go Down

Topic: Setting a 5 digit count using 4x4 matrix keypad & the Arduino Uno (Read 2337 times) previous topic - next topic

GautamD

Code: [Select]

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

#include <Keypad.h>

const byte ROWS = 4; // Four rows
const byte COLS = 4; // Three columns


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


// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 6, 7, 8, 9 };
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 5, 4, 12, 11};


// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );



void setup()
{
   lcd.begin(LCD_COLS, LCD_ROWS);
}

void loop()
{
  const byte entryMaxSize = 5;
  static char count[entryMaxSize];

  // index
  static byte x = 0;

  char key = kpd.getKey();

  if (key != NO_KEY) // Check for a valid key.
  {
    switch (key)
    {

      case 'A':
      lcd.setCursor(0,0);
        lcd.print("Set Count:");
        // reset the counter
        x = 0;
        break;

      case 'D':
        lcd.setCursor(0,1);
        lcd.print("Count Set:");
        for (byte i = 0; i < x; i++)
        {
          lcd.print(count[i]);
        }
        break;

      default:
        // if not 5 characters yet
        if (x < entryMaxSize)
        {
          // add key to userinput array and increment counter
          count[x++] = key;
        }
        break;
    }
  }
}



Issues:

1. Even if the key A is not pressed I am able to enter a count and set it by pressing the key D.
2. How to make sure that unless and until key A is pressed, user must not be allowed to set a count?

aarg

Add a boolean variable key_A_was_pressed, set it, check it, clear it.
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

GautamD

I have now tried the following:

Code: [Select]


#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

#include <Keypad.h>

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] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 12, 11}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
bool a = true;

void setup()
{
  lcd.begin(LCD_COLS, LCD_ROWS);
  lcd.setCursor(3, 0);
  lcd.print("  PRIYA");
  lcd.setCursor(3, 1);
  lcd.print("ELECTRONICS");
  delay(100);
  for (int positionCounter = 0; positionCounter < 40; positionCounter++)
  {
    lcd.scrollDisplayLeft();
    delay(150);
  }
  delay(800);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Set Count:");
}


void loop()
{
  const byte entryMaxSize = 5;
  static char count[entryMaxSize];

  // index
  static byte x = 0;
  char key = keypad.getKey();

  if (key != NO_KEY) // Check for a valid key.
  {
      switch (key)
    {
      case 'A':
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("Set Count:");
        // reset the counter
        x = 0;
        a = true;   
        break;

      case 'D':
      if (a){
        lcd.clear();
        lcd.print("Count Set: ");
        for(byte i=0;i<x;i++) {
        lcd.print(count[i]);
        }
      }
       break;

      default:
        // if not 5 characters yet
        if (x < entryMaxSize)
        {
          // add key to userinput array and increment counter
          count[x++] = key;
        }
        break;
    }
  }
  }


6v6gt

In case 'D' add a statement to set "a" to false ( to clear it as aarg said).
In default, add a condition "if ( a == true ) . . . " so that numbers are accepted only after "a" has been set to true ( to check it as aarg said).

GautamD

Thanks for the explanation, I shall make the corrections.

GautamD

With corrections:

Code: [Select]

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

#include <Keypad.h>

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] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 12, 11}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
bool a = true;

void setup()
{
  lcd.begin(LCD_COLS, LCD_ROWS);
  lcd.setCursor(3, 0);
  lcd.print("  PRIYA");
  lcd.setCursor(3, 1);
  lcd.print("ELECTRONICS");
  delay(100);
  for (int positionCounter = 0; positionCounter < 40; positionCounter++)
  {
    lcd.scrollDisplayLeft();
    delay(150);
  }
  delay(800);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Set Count:");
}


void loop()
{
  const byte entryMaxSize = 5;
  static char count[entryMaxSize];

  // index
  static byte x = 0;
  char key = keypad.getKey();

  if (key != NO_KEY) // Check for a valid key.
  {
      switch (key)
    {
      case 'A':
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("Set Count:");
        // reset the counter
        x = 0;
        a = true;   
        break;

      case 'D':
      if (a){
        lcd.clear();
        lcd.print("Count Set:");
        for(byte i=0;i<x;i++) {
        lcd.print(count[i]);
        a = false;
        }
      }
       break;

      default:
      if (a)
      {
        // if not 5 characters yet
        if (x < entryMaxSize)
        {
          // add key to userinput array and increment counter
          count[x++] = key;
        }
        break;
    }
  }
  }
}



But I am not able to print the digits onto the lcd as I enter them. Only after I press the 'D' key which is the enter key in my case, I am able to see the entire count. Can you suggest something? Thanks.

6v6gt

remove the  "if ( a )" condition from the "case 'D' " section of code so it looks like this:

Code: [Select]

      case 'D':
        lcd.clear();
        lcd.print("Count Set:");
        for(byte i=0;i<x;i++) {
        lcd.print(count[i]);
        a = false;
      }
       break;



and the global variable "a" should be initialised to false, not true as you currently have it.

GautamD

How do I print the digits as I enter them for setting a count, I've not been able to figure that out?

6v6gt

How do I print the digits as I enter them for setting a count, I've not been able to figure that out?
That appears to me to be so obvious that I fear I must have misunderstood something. Anyway, does this solve your problem ?:

Code: [Select]


      default:
        if (a)
        {
          // if not 5 characters yet
          if (x < entryMaxSize)
          {
            // add key to userinput array and increment counter
            count[x++] = key;
            Serial.println( key ) ;  // new print statement <<<<<<<<<<<<<<<<
          }
          break;
        }


GautamD

Thanks alot it does work!! I need to implement a few more things could you help me out with that?

6v6gt

Just keep the questions coming and you will surely get help. Of course, it would be good if you also regard this project as a learning experience and demonstrate some attempts to solve the individual problems yourself.

GautamD

Of course, it would be good if you also regard this project as a learning experience and demonstrate some attempts to solve the individual problems yourself.
Surely !! :-)

Things I want to implement:

1. If the user presses the key 'D' which is the enter key in our case, lcd must blink invalid count and direct him to the set count option where he gets to enter a valid count.

2. If user tries to enter the 6th digit while entering the 5 digit count lcd must display "5 digits only!!", while also displaying the count he has entered with only 5 digits. The count would be on the first line and the warning message on the second line.

GautamD

In the first point I mean to say if enter key is pressed without entering any count.

GautamD

Surely !! :-)


2. If user tries to enter the 6th digit while entering the 5 digit count lcd must display "5 digits only!!", while also displaying the count he has entered with only 5 digits. The count would be on the first line and the warning message on the second line.
I have implemented the following, a little modified though.

Code: [Select]

default:
        if (a)
        {
          // if not 5 characters yet
          if (x < entryMaxSize)
          {
            // add key to userinput array and increment counter
            count[x++] = key;
            lcd.print( key ) ;  // new print statement <<<<<<<<<<<<<<<<
          }
          else {
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("Only 5 Digits!!");
            lcd.setCursor(0, 1);
            lcd.print("Press A");
          }
        }
          break;
        }
    }
  }


6v6gt

That looks OK for the second part on quick inspection. You may also have to set "a" back to false.

For the first part (zero characters entered), the code should be in case 'D'

Go Up