//libraries
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
//#include "TimerOne.h"
#include <TimerOne.h>
#include <SPI.h>
#include <DHT.h>
#include "DHT.h"
#include <EEPROM.h>
// Display
// set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include "RTClib.h"
RTC_DS1307 rtc;
//int hour, minute, second =0;
int hour, minute, second;
int addr = 0;
void WellcomeScreen() {
lcd.setCursor(2, 1);
lcd.print("I am M A Majeed");
lcd.setCursor(5,2);
lcd.print("This is my");
lcd.setCursor(1, 3);
String message = "Arduino Calculator";
for (byte i = 0; i < message.length(); i++) {
lcd.print(message[i]);
delay(50);
}
delay(1000);
}
void MyTime() {
DateTime now=rtc.now();
hour=now.hour();
minute = now.minute();
second=now.second();
String MyClk=String(hour)+":"+ String(minute)+":"+String(second);
lcd.setCursor(12,0);
if(hour<10)lcd.print("0");
lcd.print(hour);
lcd.print(":");
if(minute<10)lcd.print("0");
lcd.print(minute);
lcd.print(":");
if(second<10)lcd.print("0");
lcd.print(second);
}
#define DHTPIN 5
#define DHTTYPE DHT22 // DHT 22 (AM2302),
DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor.
void myTemperature() {
// Reading temperature or humidity takes 250 milliseconds!
// Sensor readings may also be up to 2 seconds
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
lcd.setCursor(0,0); lcd.print(t); lcd.print("c");
}
const uint8_t no_key = 0U;
// Keypad setup
const uint8_t ROWS = 5;
const uint8_t COLS = 5;
char keys_val[ROWS][COLS] = {
{'F', 'C', 'S', '%', '/'},
{'A', '7', '8', '9', '*'},
{'B', '4', '5', '6', '-'},
{'X', '1', '2', '3', '+'},
{'Y', '0', '.', 'P', '='}
};
volatile uint8_t key_main_access;
volatile uint8_t key_state;
volatile uint8_t old_col;
volatile uint8_t new_col;
volatile uint8_t new_row;
volatile uint8_t main_read;
volatile uint8_t main_interrupted;
volatile uint8_t key1;
volatile uint8_t key2;
const int row_1 = 25;
const int row_2 = 27;
const int row_3 = 29;
const int row_4 = 31;
const int row_5 = 33;
const int col_1 = 37;
const int col_2 = 39;
const int col_3 = 41;
const int col_4 = 43;
const int col_5 = 45;
double myMemory = 0;
volatile uint32_t old_time, new_time, diff = 0U;
static const byte BUTTON_PIN = 3;
void setup()
{
Serial.begin(115200);
lcd.begin(20, 4);
dht.begin();
rtc.begin();
WellcomeScreen();
/* init all vars for keypad in default state */
init_all_vars__key_c();
/* 20ms timer interrupt */
Timer1.initialize(20000);
Timer1.attachInterrupt(isr_key_callback);
/* all colums inout high */
pinMode(col_1, INPUT_PULLUP);
pinMode(col_2, INPUT_PULLUP);
pinMode(col_3, INPUT_PULLUP);
pinMode(col_4, INPUT_PULLUP);
pinMode(col_5, INPUT_PULLUP);
/* all rows output HIGH */
pinMode(row_1, OUTPUT);
pinMode(row_2, OUTPUT);
pinMode(row_3, OUTPUT);
pinMode(row_4, OUTPUT);
pinMode(row_5, OUTPUT);
digitalWrite(row_1, HIGH);
digitalWrite(row_2, HIGH);
digitalWrite(row_3, HIGH);
digitalWrite(row_4, HIGH);
digitalWrite(row_5, HIGH);
}
//void isr_key_callback()
void isr_key_callback()
{
uint8_t check;
if (0U == key_main_access) /* if main is not accessing keypad variable,
will happen if main wants to reset keypad varaibles */
{
if (0U == key_state) /* ground all rows & check for any col low */
{
digitalWrite(row_1, LOW); digitalWrite(row_2, LOW); digitalWrite(row_3, LOW); digitalWrite(row_4, LOW); digitalWrite(row_5, LOW);
if (!digitalRead(col_1)) /* if found store the col & move to next state */
{
old_col = 1U;
key_state = 1U;
}
else if (!digitalRead(col_2))
{
old_col = 2U;
key_state = 1U;
}
else if (!digitalRead(col_3))
{
old_col = 3U;
key_state = 1U;
}
else if (!digitalRead(col_4))
{
old_col = 4U;
key_state = 1U;
}
else if (!digitalRead(col_5))
{
old_col = 5U;
key_state = 1U;
}
else
{
}
}
else if (1U == key_state) /* ground one row at a time & check for col low */
{
check = 0U; /* assume row 1 is found to be low */
digitalWrite(row_1, LOW); digitalWrite(row_2, HIGH); digitalWrite(row_3, HIGH); digitalWrite(row_4, HIGH); digitalWrite(row_5, HIGH);
if (!digitalRead(col_1)) /* if found store the col & row */
{
new_col = 1U;
new_row = 1U;
}
else if (!digitalRead(col_2))
{
new_col = 2U;
new_row = 1U;
}
else if (!digitalRead(col_3))
{
new_col = 3U;
new_row = 1U;
}
else if (!digitalRead(col_4))
{
new_col = 4U;
new_row = 1U;
}
else if (!digitalRead(col_5))
{
new_col = 5U;
new_row = 1U;
}
else
{
check = 1U; /* initial assumption that this row found to be false, so now check next row */
}
if (1U == check) /* repeat same as row 1 */
{
check = 0U;
digitalWrite(row_1, HIGH); digitalWrite(row_2, LOW); digitalWrite(row_3, HIGH); digitalWrite(row_4, HIGH); digitalWrite(row_5, HIGH);
if (!digitalRead(col_1))
{
new_col = 1U;
new_row = 2U;
}
else if (!digitalRead(col_2))
{
new_col = 2U;
new_row = 2U;
}
else if (!digitalRead(col_3))
{
new_col = 3U;
new_row = 2U;
}
else if (!digitalRead(col_4))
{
new_col = 4U;
new_row = 2U;
}
else if (!digitalRead(col_5))
{
new_col = 5U;
new_row = 2U;
}
else
{
check = 1U;
}
}
if (1U == check) /* repeat same as row 1 */
{
check = 0U;
digitalWrite(row_1, HIGH); digitalWrite(row_2, HIGH); digitalWrite(row_3, LOW); digitalWrite(row_4, HIGH); digitalWrite(row_5, HIGH);
if (!digitalRead(col_1))
{
new_col = 1U;
new_row = 3U;
}
else if (!digitalRead(col_2))
{
new_col = 2U;
new_row = 3U;
}
else if (!digitalRead(col_3))
{
new_col = 3U;
new_row = 3U;
}
else if (!digitalRead(col_4))
{
new_col = 4U;
new_row = 3U;
}
else if (!digitalRead(col_5))
{
new_col = 5U;
new_row = 3U;
}
else
{
check = 1U;
}
}
if (1U == check) /* repeat same as row 1 */
{
check = 0U;
digitalWrite(row_1, HIGH); digitalWrite(row_2, HIGH); digitalWrite(row_3, HIGH); digitalWrite(row_4, LOW); digitalWrite(row_5, HIGH);
if (!digitalRead(col_1))
{
new_col = 1U;
new_row = 4U;
}
else if (!digitalRead(col_2))
{
new_col = 2U;
new_row = 4U;
}
else if (!digitalRead(col_3))
{
new_col = 3U;
new_row = 4U;
}
else if (!digitalRead(col_4))
{
new_col = 4U;
new_row = 4U;
}
else if (!digitalRead(col_5))
{
new_col = 5U;
new_row = 4U;
}
else
{
check = 1U;
}
}
if (1U == check) /* repeat same as row 1 */
{
check = 0U;
digitalWrite(row_1, HIGH); digitalWrite(row_2, HIGH); digitalWrite(row_3, HIGH); digitalWrite(row_4, HIGH); digitalWrite(row_5, LOW);
if (!digitalRead(col_1))
{
new_col = 1U;
new_row = 5U;
}
else if (!digitalRead(col_2))
{
new_col = 2U;
new_row = 5U;
}
else if (!digitalRead(col_3))
{
new_col = 3U;
new_row = 5U;
}
else if (!digitalRead(col_4))
{
new_col = 4U;
new_row = 5U;
}
else if (!digitalRead(col_5))
{
new_col = 5U;
new_row = 5U;
}
else
{
check = 1U;
}
}
if (1U == check) /* repeat same as row 1 */
{
check = 0U;
digitalWrite(row_1, HIGH); digitalWrite(row_2, HIGH); digitalWrite(row_3, HIGH); digitalWrite(row_4, HIGH); digitalWrite(row_5, HIGH);
if (!digitalRead(col_1))
{
new_col = 1U;
new_row = 6U;
}
else if (!digitalRead(col_2))
{
new_col = 2U;
new_row = 6U;
}
else if (!digitalRead(col_3))
{
new_col = 3U;
new_row = 6U;
}
else if (!digitalRead(col_4))
{
new_col = 4U;
new_row = 6U;
}
else if (!digitalRead(col_5))
{
new_col = 5U;
new_row = 6U;
}
else
{
check = 1U;
}
}
if (0U == check) /* a row low has been found */
{
if (new_col == old_col) /* if new column & old colum has been equal */
{
if ((new_col >= 1) && (new_col <= 5) && (new_row >= 1) && (new_row <= 5)) /* if new col & new row are within array boundaries */
{
if (0U == main_read) /* if main is not reading the key state */
{
key1 = keys_val[new_row - 1U][new_col - 1U]; /* store the key value */
}
else
{
key2 = keys_val[new_row - 1U][new_col - 1U]; /* mainline got interrupted */
main_interrupted = 1U;
}
key_state = 2U; /* key found successfully, now move to next state */
}
else
{
key_state = 0U; /* if new col & new row are not within array boundaries, something wrong, move to default state */
}
}
else /* if new col & old col are not same, something wrong, move to default state */
{
key_state = 0U;
}
}
else /* if no row low has been found, something wrong,move to default state */
{
key_state = 0U;
}
}
else if (2U == key_state) /* wait for all keys to open again, by grounding all rows, & wait for col to be high */
{
digitalWrite(row_1, LOW); digitalWrite(row_2, LOW); digitalWrite(row_3, LOW); digitalWrite(row_4, LOW); digitalWrite(row_5, LOW);
if (digitalRead(col_1) && digitalRead(col_2) && digitalRead(col_3) && digitalRead(col_4)&& digitalRead(col_5))
{
key_state = 0U; /* all col found high, move to default state */
}
}
else
{
}
}
}
void loop()
{
uint8_t temp;
// String num1;
int i=0;
while (1)
{
myTemperature();
MyTime();
temp = key_read();
if (no_key != temp)
{
Serial.print("KEY: ");
Serial.println((char)temp);
myCalculator(temp);
}
}
}
uint8_t key_read(void)
{
uint8_t temp;
main_read = 1U; /* set var for main line read & read the key value */
temp = key1;
key1 = no_key;
main_read = 0U;
if (1U == main_interrupted) /* if main line gets interupted, again read the key var */
{
temp = key2;
key2 = no_key;
main_interrupted = 0U;
}
return temp;
}
void clear_key_vars(void)
{
key_main_access = 1U; /* clear all previous key varaibles & start aagin */
key_state = 0U;
old_col = 1U;
new_col = 1U;
new_row = 1U;
main_read = 0U;
main_interrupted = 0U;
key1 = no_key;
key2 = no_key;
key_main_access = 0U;
}
void init_all_vars__key_c(void)
{
key_main_access = 0U; /* init ll vars to default state */
key_state = 0U;
old_col = 1U;
new_col = 1U;
new_row = 1U;
main_read = 0U;
main_interrupted = 0U;
key1 = no_key;
key2 = no_key;
}
uint8_t temp;
boolean presentValue = false;
boolean next = false;
boolean next1 = false;
boolean final = false;
String num1, num2,num3;
double answer;
char Operator1=' ';
char Operator2=' ';
int numLength1 =0;
int numLength2 =0;
int DpState = LOW;
void myCalculator(char temp){
if (((char)temp== '.' ||(char)temp== '1' ||(char)temp== '2' ||(char)temp== '3' ||(char)temp== '4' ||(char)temp== '5' ||(char)temp== '6' ||(char)temp== '7' ||(char)temp== '8' ||(char)temp== '9' ||(char)temp== '0' ))
{
Serial.print("op2: ");
Serial.println(Operator2);
Serial.print("op1: ");
Serial.println(Operator1);
if (presentValue !=true)
{
num1 += (char)temp;
lcd.setCursor(0,2);
lcd.print(num1);
Serial.print("num1: ");
Serial.println(num1);
numLength1 =num1.length();
}
else if (next ==true)
{
num2 += (char)temp;
lcd.setCursor(numLength1+1,2);
lcd.print(num2);
Serial.print("num2: ");
Serial.println(num2);
numLength2 =num2.length();
next1 = true;
}
else
{
num3 += (char)temp;
lcd.setCursor(numLength1+numLength2+2,2);
lcd.print(num3);
Serial.print("num3: ");
Serial.println(num3);
}
}
//plus minus
else if ((char)temp== 'P' ) {
num1= -1*(num1.toDouble());
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,2);
//lcd.print("Sq:");
lcd.print(num1);
Serial.print("num1: ");
Serial.println(num1);
numLength1 =num1.length();
//numLength1 =num1.length();
presentValue !=true;
//myNumsEmpty();
}
//square root
else if ((char)temp== 'S' ) {
num1= sqrt(num1.toDouble());
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Sqr:");
lcd.print(num1);
Serial.print("num1: ");
Serial.println(num1);
//numLength1 =num1.length();
presentValue !=true;
myNumsEmpty();
}
// Percentage
else if ((char)temp== '%' ) {
num1= (num1.toDouble())*(num2.toDouble())/100;
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("P:");
lcd.print(num1);
Serial.print("num1: ");
Serial.println(num1);
//numLength1 =num1.length();
presentValue !=true;
myNumsEmpty();
}
// Memory M+
else if ((char)temp== 'Y' ) {
myMemory+= (num1.toDouble());
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("M:");
lcd.print(myMemory);
Serial.print("myMemory: ");
Serial.println(myMemory);
//numLength1 =num1.length();
presentValue !=true;
myNumsEmpty();
}
// Memory M-
else if ((char)temp== 'X' ) {
myMemory-= (num1.toDouble());
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("M:");
lcd.print(myMemory);
Serial.print("myMemory: ");
Serial.println(myMemory);
//numLength1 =num1.length();
presentValue !=true;
myNumsEmpty();
}
// Memory Recall
else if ((char)temp== 'B' ) {
// myMemory-= (num1.toDouble());
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("M:");
lcd.print(myMemory);
Serial.print("myMemory: ");
Serial.println(myMemory);
//numLength1 =num1.length();
presentValue !=true;
myNumsEmpty();
}
// Memory Clear
else if ((char)temp== 'A' ) {
myMemory=0;
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("M:");
lcd.print(myMemory);
Serial.print("myMemory: ");
Serial.println(myMemory);
//numLength1 =num1.length();
presentValue !=true;
myNumsEmpty();
}
else if (((char)temp== '/' ||(char)temp== '*' ||(char)temp== '-' ||(char)temp== '+' ))
{
if (presentValue == false )
{
//if ((char)temp== '-' ||(char)temp== '+' ))
presentValue = true;
Operator1=(char)temp;
lcd.setCursor(numLength1,2);
lcd.print(Operator1);
next= true;
Serial.println(next);
}
else if (next1 == true && (char)temp!= '=')
{
next = false;
Operator2=(char)temp;
Serial.print("op2: ");
Serial.println(Operator2);
Serial.print("op1: ");
Serial.println(Operator1);
lcd.setCursor(numLength1+numLength2+1,2);
lcd.print(Operator2);
next1= false;
}
}
else if ((char)temp == '=')
{
Serial.print("calop2: ");
Serial.println(Operator2);
Serial.print("calop1: ");
Serial.println(Operator1);
//calculation part for num1, num2
if (Operator2 ==' ')
{
switch (Operator1) {
case '*':
answer= num1.toDouble()* num2.toDouble();
break;
case '/':
answer= num1.toDouble()/ num2.toDouble();
break;
case '+':
answer= num1.toDouble()+ num2.toDouble();
break;
case '-':
answer= num1.toDouble()- num2.toDouble();
break;
}
}
else
//calculation part for num1,num2,num3
switch (Operator1) {
Serial.print("Operator2: ");
Serial.println(Operator2);
case '*':
{
switch (Operator2) {
case '*':
answer= num1.toDouble()* num2.toDouble()* num3.toDouble();
break;
case '/':
answer= num1.toDouble()* num2.toDouble()/ num3.toDouble();
break;
case '+':
answer= num1.toDouble()* num2.toDouble()+ num3.toDouble();
break;
case '-':
answer= num1.toDouble()* num2.toDouble()- num3.toDouble();
break;
}
}
break;
case '/':
{
switch (Operator2) {
case '*':
answer= num1.toDouble()/ num2.toDouble()* num3.toDouble();
break;
case '/':
answer= num1.toDouble()/ num2.toDouble()/ num3.toDouble();
break;
case '+':
answer= num1.toDouble()/ num2.toDouble()+ num3.toDouble();
break;
case '-':
answer= num1.toDouble()/ num2.toDouble()- num3.toDouble();
break;
}
}
break;
case '+':
switch (Operator2) {
case '*':
answer= num1.toDouble()+ num2.toDouble()* num3.toDouble();
break;
case '/':
answer= num1.toDouble()+ num2.toDouble()/ num3.toDouble();
break;
case '+':
answer= num1.toDouble()+ num2.toDouble()+ num3.toDouble();
break;
case '-':
answer= num1.toDouble()+ num2.toDouble()- num3.toDouble();
break;
}
break;
case '-':
switch (Operator2) {
case '*':
answer= num1.toDouble()- num2.toDouble()* num3.toDouble();
break;
case '/':
answer= num1.toDouble()- num2.toDouble()/ num3.toDouble();
break;
case '+':
answer= num1.toDouble()- num2.toDouble()+ num3.toDouble();
break;
case '-':
answer= num1.toDouble()- num2.toDouble()- num3.toDouble();
break;
}
break;
}
Serial.print("answer: ");
Serial.println(answer);
lcd.setCursor(0,3);
lcd.print("=");
lcd.print(answer);
//lcd.noAutoscroll();
}
else if ((char)temp == 'C'){
myScreenCleaner();
}
else if ((char)temp == 'F'){
myOnOff();
}
/*
else if ((char)temp =='P') {
// Serial.print("answer:PPPP ");
if ((char)temp== '+'){
(char)temp== '-';
}
else if ((char)temp== '-'){
(char)temp== '+';
}
// num1= -1*(num1.toDouble());
answer=-1*(answer);
lcd.setCursor(0,3);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print("=");
lcd.print(answer);
presentValue !=true;
}
*/
} //my calculator ending
void myNumsEmpty(){
presentValue = false;
final = false;
next = false;
next1 = false;
num1 = "";
num2 = "";
num3 = "";
answer=0;
Operator1 = ' ';
Operator2 = ' ';
}
void myScreenCleaner(){
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print(" ");
presentValue = false;
final = false;
next = false;
next1 = false;
num1 = "";
num2 = "";
num3 = "";
answer=0;
Operator1 = ' ';
Operator2 = ' ';
}
void myOnOff(){
// toggle state of dp
DpState = !DpState;
if(DpState==HIGH)
{
lcd.noDisplay(); // turn off the display
//lcd.print("hello, world!");
lcd.noCursor(); // turn off the cursor
//lcd.clear();
}
else if(DpState==LOW)
{
lcd.display(); // turn on the display
// lcd.cursor();
lcd.clear();
// lcd.home(); // move the cursor to the upper-left corner of the LCD
presentValue = false;
final = false;
next = false;
next1 = false;
num1 = "";
num2 = "";
num3 = "";
answer=0;
Operator1 = ' ';
Operator2 = ' ';
}
}