Hi all,
I have read tons of forum threads, blogs and how to-pages but I'm new to C++ and Arduino so I need some help.
I want to use one keypad, one lcd screen and one temp/RH sensor. As default I want to show temperatur and RH from sensor on the LCD. When a key is pressed on the keypad I want to run a function which saves the number from keypad to eeprom. After saving, it will go back to default and show current temp/RH again. Sounds quite easy to do, right?
This works: I can display temp/RH on lcd. I can read values from temp/RH sensor. I can use keypad to enter and save new temp to eeprom.
My problem is that I can't figure out how to go to function directly when a key is pressed. In all my attempts I need to press the keys many, many times before the function starts. Once started, the function works.
My code has changed several times during my tests but the latest try is here:
#include <Keypad.h>
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
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] = { 11, 10, 9, 8 };
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 7, 6, 5, 4 };
// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
#define ledpin 13
#define DHTPIN 2 // DHT sensor pin
//Define sensor type
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);
int value = 0;
int T = 0;
int RH = 1;
byte Tvalue;
byte RHvalue;
bool change = false;
void setup()
{
pinMode(ledpin,OUTPUT);
digitalWrite(ledpin, HIGH);
lcd.begin(16,2); // initialize the lcd for 16 chars 2 lines, turn on backlight
Serial.begin(9600);
dht.begin();
//Read/set initial temperatur and RH
Tvalue = EEPROM.read(T);
RHvalue = EEPROM.read(RH);
if (Tvalue == NULL) {
EEPROM.write(T, 20);
Tvalue = EEPROM.read(T);
}
if (RHvalue == NULL) {
EEPROM.write(RH, 80);
RHvalue = EEPROM.read(RH);
}
// Add an event listener for this keypad
keypad.addEventListener(keypadEvent);
}
void loop()
{
//scan the pins of the keypad
char key = keypad.getKey();
if (change == true) getnum();
else lcdprint();
}
// Starting getnum() when * is pressed
void keypadEvent(KeypadEvent key){
switch (keypad.getState()){
case PRESSED:
if (key == '*') {
//when '*' is pressed allow the user to input a key.
change = true;
}
break;
}
}
void lcdprint() {
// Reading temperature and humidity
float Hsensor = dht.readHumidity();
// Read temperature as Celsius (the default)
float Tsensor = dht.readTemperature();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("T: ");
lcd.setCursor(4,0);
lcd.print(Tsensor, 1);
lcd.setCursor(8,0);
lcd.print((char)223);
lcd.print("C ");
lcd.print(Tvalue);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0,1);
lcd.print("RH: ");
lcd.setCursor(4,1);
lcd.print(Hsensor, 1);
lcd.setCursor(8,1);
lcd.print("% ");
lcd.print(RHvalue);
lcd.print("%");
delay(2000);
}
void getnum() {
char key = keypad.waitForKey();
switch (key) {
case NO_KEY:
// Wait and then tell user they can start the Serial Monitor and type in characters to
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
// Digits from 0 to 9
// Don't forget we deal with ASCII characters and not numbers
value = value * 10 + key - '0';
if (value >= 100 ){
lcd.clear();
lcd.setCursor(0,0); //Start at character 0 on line 0
lcd.print("For hogt varde!" );
lcd.setCursor(0,1); //Start at character 0 on line 0
lcd.print("A: Temp B: RH");
value = 0;
}
lcd.clear();
lcd.setCursor(0,0); //Start at character 0 on line 0
lcd.print("Nytt varde: ");
lcd.print(value);
lcd.setCursor(0,1); //Start at character 0 on line 0
lcd.print("A: Temp B: RH");
break;
case 'A':
EEPROM.update(T, value);
value = 0;
Serial.print ("Temperatur: ");
Tvalue = EEPROM.read(T);
Serial.println (Tvalue);
Serial.print ("Luftfuktighet: ");
RHvalue = EEPROM.read(RH);
Serial.println (RHvalue);
change = false;
case 'B':
EEPROM.update(RH, value);
value = 0;
Serial.print ("Temperatur: ");
Tvalue = EEPROM.read(T);
Serial.println (Tvalue);
Serial.print ("Luftfuktighet: ");
RHvalue = EEPROM.read(RH);
Serial.println (RHvalue);
change = false;
}
}
Any suggestions on how to make function getnum() start as soon as * (or any other) key is pressed? There must be some kind of delay in the code printing sensor values to lcd.