#include "tinyexpr.h"
// #include "arduino.h"
#include "DHT.h"
#include "ezButton.h"
#include <EEPROM.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
// define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {{'1', '2', '3', '-'},
{'4', '5', '6', '+'},
{'7', '8', '9', '*'},
{'C', '0', '.', '='}};
byte rowPins[ROWS] = {31, 33, 35, 37};
byte colPins[COLS] = {39, 41, 43, 45};
Keypad kpd = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
const String password = "EEE20003";
ezButton button_percent(6);
ezButton button_divide(7);
ezButton button_m_plus(8);
ezButton button_m_minus(9);
ezButton button_mr(10);
ezButton button_mc(11);
ezButton button_ce(12);
LiquidCrystal_I2C lcd(0x27, 20, 4);
// set the LCD address to 0x27 for a 16 chars and 2 line display
enum {
SET_PASSWORD,
SHOW_TEMP,
CALCULATOR,
};
#define password_address 0
#define store_cal_address 10
void input_password();
void setup_lcd();
void turn_on_lcd();
void turn_off_lcd();
String get_password();
String readStringSerial();
// int choice_mode();
void choice_mode();
void save_password_to_eeprom(String pass);
String get_password_from_eeprom();
void save_m_to_eeprom(float cal);
float get_m_from_eeprom();
void setup_button();
void button_loop();
void new_password();
void writeString(char add, String data);
String read_String(char add);
int mode = -1;
bool calculated = false;
void setup() {
Serial.begin(9600);
Wire.begin();
setup_lcd();
turn_on_lcd();
setup_button();
save_m_to_eeprom(0);
input_password();
choice_mode();
dht.begin();
// while (mode == SET_PASSWORD) {
// new_password();
// // choice_mode();
// }
}
// 357202098711287
int error;
unsigned long old_time_lcd = 0;
unsigned long time_to_update_lcd = 1000;
bool force_update_lcd = false;
String line_1_specical_button = "";
String line_2_input_cal = "";
String line_3_result = "0";
String line_4_error = "";
unsigned long old_time_update_lcd = 0;
unsigned long time_update_sensor_lcd = 1000;
void loop() {
if (mode == SET_PASSWORD) {
new_password();
choice_mode();
// get_password();
} else if (mode == SHOW_TEMP) {
if (millis() - old_time_update_lcd > time_update_sensor_lcd) {
old_time_update_lcd = millis();
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("sensor value: ");
lcd.setCursor(0, 1);
lcd.print("humi: ");
lcd.print(h);
lcd.setCursor(0, 2);
lcd.print("temp: ");
lcd.print(t);
}
} else if (mode == CALCULATOR) {
if (force_update_lcd) {
force_update_lcd = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line_1_specical_button);
lcd.setCursor(0, 1);
lcd.print(line_2_input_cal);
if (line_3_result.length()) {
lcd.setCursor(0, 2);
lcd.print("result: ");
}
lcd.setCursor(20 - line_3_result.length(), 2);
lcd.print(line_3_result);
lcd.setCursor(0, 3);
lcd.print(line_4_error);
}
button_loop();
if (button_percent.isReleased()) {
Serial.println("percent");
double res = te_interp(line_2_input_cal.c_str(), &error);
if (error) {
line_4_error = "error";
} else {
line_1_specical_button = "%";
line_3_result = String(res / 100);
line_4_error = "";
}
force_update_lcd = true;
}
if (button_divide.isReleased()) {
Serial.println("divide");
line_2_input_cal += "/";
force_update_lcd = true;
}
if (button_m_plus.isReleased()) {
Serial.println("m_plus");
line_1_specical_button = "M+";
force_update_lcd = true;
calculated = true;
float m = get_m_from_eeprom();
Serial.println(m);
double res = te_interp(line_2_input_cal.c_str(), &error);
if (error) {
line_4_error = "error";
} else {
line_3_result = String(res + m);
save_m_to_eeprom(res + m);
line_4_error = "";
}
}
if (button_m_minus.isReleased()) {
calculated = true;
Serial.println("m_minus");
line_1_specical_button = "M-";
force_update_lcd = true;
float m = get_m_from_eeprom();
Serial.println(m);
double res = te_interp(line_2_input_cal.c_str(), &error);
if (error) {
line_4_error = "error";
} else {
line_3_result = String(m - res);
save_m_to_eeprom(m - res);
line_4_error = "";
}
}
if (button_mr.isReleased()) {
calculated = true;
Serial.println("mr");
line_1_specical_button = "MR";
force_update_lcd = true;
line_2_input_cal = String(get_m_from_eeprom());
line_3_result = get_m_from_eeprom();
line_4_error = "";
}
if (button_mc.isReleased()) {
Serial.println("mc");
calculated = true;
line_1_specical_button = "MC";
force_update_lcd = true;
save_m_to_eeprom(0);
line_3_result = "0";
}
if (button_ce.isReleased()) {
Serial.println("ce");
line_2_input_cal.remove(line_2_input_cal.length() - 1);
force_update_lcd = true;
}
char key = kpd.getKey();
if (key) {
if (key != '=' && key != 'C') {
if (calculated) {
line_1_specical_button = "";
line_2_input_cal = "";
line_3_result = "0";
line_4_error = "";
calculated = false;
}
line_2_input_cal += key;
force_update_lcd = true;
}
if (key == '=') {
double res = te_interp(line_2_input_cal.c_str(), &error);
if (error == 0) {
line_3_result = String(res);
line_4_error = "";
} else {
line_4_error = "error";
}
force_update_lcd = true;
}
if (key == 'C') {
line_1_specical_button = "";
line_2_input_cal = "";
line_3_result = "0";
line_4_error = "";
force_update_lcd = true;
calculated = true;
}
}
}
}
void setup_button() {
button_percent.setDebounceTime(100);
button_divide.setDebounceTime(100);
button_m_plus.setDebounceTime(100);
button_m_minus.setDebounceTime(100);
button_mr.setDebounceTime(100);
button_mc.setDebounceTime(100);
button_ce.setDebounceTime(100);
}
void button_loop() {
button_percent.loop();
button_divide.loop();
button_m_plus.loop();
button_m_minus.loop();
button_mr.loop();
button_mc.loop();
button_ce.loop();
}
void setup_lcd() {
lcd.init(); // initialize the lcd
}
void writeString(char add, String data) {
int _size = data.length();
int i;
for (i = 0; i < _size; i++) {
EEPROM.write(add + i, data[i]);
}
EEPROM.write(add + _size,
'\0'); // Add termination null character for String Data
}
String read_String(char add) {
int i;
char data[100]; // Max 100 Bytes
int len = 0;
unsigned char k;
k = EEPROM.read(add);
while (k != '\0' && len < 500) // Read until null character
{
k = EEPROM.read(add + len);
data[len] = k;
len++;
}
data[len] = '\0';
return String(data);
}
void save_password_to_eeprom(String pass) {
// EEPROM.put(password_address, pass);
writeString(password_address, pass);
}
void new_password() {
Serial.println("input new password: ");
String pass = readStringSerial();
save_password_to_eeprom(pass);
Serial.println(pass);
}
String get_password_from_eeprom() { return read_String(password_address); }
void save_m_to_eeprom(float cal) { EEPROM.put(store_cal_address, cal); }
float get_m_from_eeprom() {
float cal;
EEPROM.get(store_cal_address, cal);
return cal;
}
void turn_on_lcd() {
lcd.backlight();
lcd.setCursor(0, 0);
lcd.clear();
}
void turn_off_lcd() {
lcd.clear();
lcd.noBacklight();
lcd.setCursor(0, 0);
}
void choice_mode() {
Serial.println();
Serial.println("choice mode");
Serial.println("1. New password");
Serial.println("2. Sensor data");
Serial.println("3. Calculator");
Serial.println("Enter your choice: ");
mode = readStringSerial().toInt();
Serial.println("choice mode: " + String(mode));
mode = mode - 1;
if (mode > 2 || mode < 0) {
Serial.println("Invalid choice");
choice_mode();
}
}
void input_password() {
Serial.print("input password: ");
String pass = readStringSerial();
Serial.println(pass);
if (pass == password) {
Serial.println("correct");
} else {
Serial.println("wrong");
input_password();
}
}
String readStringSerial() {
while (1) {
if (Serial.available() > 0) {
return Serial.readStringUntil('\r');
}
}
}
String get_password() {
String pass = "";
while (true) {
char key = kpd.getKey();
if (key) {
lcd.clear();
if (key != '-' && key != '+' && key != '*' && key != '=' && key != 'C' &&
key != '.') {
pass += String(key);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter password:");
lcd.setCursor(0, 1);
lcd.print(pass);
}
if (key == 'C') {
return pass;
}
Serial.println();
}
}
}