Arduino Calculator (Multiple Button Pressing) - arduino

We're currently making a 4x3 calculator using Arduino and LCD. We're lacking buttons so instead of one button per operation, there's only one button for all operations. So far, it only does addition. How do you do the thing wherein if I pressed the OPERATION button once, it does addition, if twice, subtraction, etc.
#include <Keypad.h>
#include <LiquidCrystal.h> //import lcd library
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //lcd pins
//LiquidCrystal lcd(5,4,3,2,1,0);
const byte ROWS = 4; // four rows
const byte COLS = 3;
//define the keymap
char keys [ROWS] [COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'+', '0', '='}
};
byte rowPins[ROWS] = {
9 ,8 ,7 ,6}; //connect keypad ROW1, ROW2, ROW3, ROW4 to these arduino pins
byte colPins[COLS] = {
13, 10, 1};
//create the keypad
Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
//variables declaration
boolean valOnePresent = false;
boolean next = false;
boolean final = false;
String num1, num2;
int ans;
char op;
void setup(){
lcd.begin(16,2);
lcd.setCursor(2,0);
lcd.print("Calculator");
delay(2500);
lcd.clear(); //clears the LCD screen and positions the cursor in the upper-left corner.
}
void loop(){
char key = myKeypad.getKey();
if (key != NO_KEY && (key=='1'||key=='2'||key=='3'||key=='4'||key=='5'||key=='6'||key=='7'||key=='8'||key=='9'||key=='0')){
if (valOnePresent != true){
num1 = num1 + key;
int numLength = num1.length();
lcd.setCursor(15 - numLength, 0); //to adjust one whitespace for operator
lcd.print(num1);
}
else {
num2 = num2 + key;
int numLength = num2.length();
lcd.setCursor(15 - numLength, 1);
lcd.print(num2);
final = true;
}
}
else if (valOnePresent == false && key != NO_KEY && (key == '/' || key == '*' || key == '-' || key == '+')){
if (valOnePresent == false){
valOnePresent = true;
op = key;
lcd.setCursor(15,0);
lcd.print(op);
}
}
else if (final == true && key != NO_KEY && key == '='){
if (op == '+')
{
ans = num1.toInt() + num2.toInt();
}
else if (op == '='){
ans = num1.toInt() + num2.toInt();
}
/* else if (op == '+')
{
answ = num1.toInt() - num2.toInt();
}
*/
lcd.clear();
lcd.setCursor(15,0);
lcd.autoscroll();
lcd.print(ans);
lcd.noAutoscroll();
}
}

You could use an array in order to accomplish this. By implementing a while loop with a small delay you can keep iterating through the positions in the array every time the button is pushed until the array times out. Here's an example of some could you could use to implement it.
char ops [4] = {'+','-','/','*'};
int del = 2500;
int strt = millis();
int location = 0;
while (millis() - strt < del) {
key = myKeypad.getkey();
if (key == '+') {
if (loc == 3) {
location = 0;
}
else {
location += 1;
}
strt = millis();
}
}
op = ops(location);

Related

I need the value to go up on 7 segment. help me pls

why is it like this How should I fix it?
It's my first time using PMS5003 with 7segment
I am able to display the value in the Serial Monitor but cannot get the pm2_5 value to be displayed in the 7 segment.
#include "SevSeg.h"
#include <SoftwareSerial.h>
SoftwareSerial mySerial(A0, A1);
SevSeg sevseg;
unsigned int pm1 = 0;
unsigned int pm2_5 = 0;
unsigned int pm10 = 0;
void setup() {
Serial.begin(9600);
while (!Serial) ;
mySerial.begin(9600);
byte numDigits = 4;
byte digitPins[] = {10, 11, 12, 13};
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; //6, 7, 8, 9, 10, 11, 12, 13
bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
byte hardwareConfig = COMMON_CATHODE; // See README.md for options
bool updateWithDelays = false; // Default 'false' is Recommended
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
sevseg.setBrightness(30);
}
void loop() {
int index = 0;
char value;
char previousValue ;
static unsigned long timer = millis ();
static int deciSeconds = 0;
if (millis() - timer >= 100)
{
timer += 100;
sevseg.setNumber(pm2_5, 2);
}
sevseg.refreshDisplay();
while (mySerial.available()) {
value = mySerial.read();
if ((index == 0 && value != 0x42) || (index == 1 && value != 0x4d)) { //0x42,0x4d ค่าคงที่
Serial.println("Cannot find the data header.");
break;
}
if (index == 4 || index == 6 || index == 8 || index == 10 || index == 12 || index == 14) {
previousValue = value;
}
else if (index == 5) {
pm1 = 256 * previousValue + value;
Serial.print("{ ");
Serial.print("\"pm1\": ");
Serial.print(pm1);
Serial.print(" ug/m3");
Serial.print(", ");
}
else if (index == 7) {
pm2_5 = 256 * previousValue + value;
Serial.print("\"pm2_5\": ");
Serial.print(pm2_5);
Serial.print(" ug/m3");
Serial.print(", ");
}
else if (index == 9) {
pm10 = 256 * previousValue + value;
Serial.print("\"pm10\": ");
Serial.print(pm10);
Serial.print(" ug/m3");
} else if (index > 15) {
break;
}
index++;
}
while (mySerial.available()) mySerial.read();
Serial.println(" }");
delay(1000);
}
I want the 7segment to be able to display the value of the sensor PMS5003.

Arduino hex to string decoder not working

I'm creating a HEX -> STR decoder using an LCD screen (display the HEX as well as the decoded values), a keypad (to input the HEX code), and a button (to press for it to decode the HEX values). The decoder works sometimes but sometimes it glitches out and presents unexpected values.
#include <Keypad.h>
#include<LiquidCrystal.h>
String hex; // store the hex values
String text; // store the decoded text
int calcButton = 0;
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'F'},
{'4', '5', '6', 'E'},
{'7', '8', '9', 'D'},
{'A', '0', 'B', 'C'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {13, 12, 11, 10};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
LiquidCrystal lcd(5, 4, 3, 2, A0, A1);
char nibble2c(char c) {
if ((c>='0') && (c<='9'))
return c-'0' ;
if ((c>='A') && (c<='F'))
return c+10-'A' ;
if ((c>='a') && (c<='a'))
return c+10-'a' ;
return -1 ;
}
char hex2c(char c1, char c2) {
if(nibble2c(c2) >= 0)
return nibble2c(c1)*16+nibble2c(c2) ;
return nibble2c(c1) ;
}
// resets string values and clears screen
void erase() {
hex = "";
Serial.println(hex);
text = "";
lcd.clear();
lcd.setCursor(0,0);
}
// decode the hex values
String calculate(String hex) {
if (hex.length()%2 != 0) {
lcd.setCursor(0,0);
lcd.print("No of characters");
lcd.setCursor(0,1);
lcd.print("needs to be even");
delay(2000);
erase();
}
else {
for (int i = 0; i < hex.length() - 1; i+=2){
for (int j = 1; j < hex.length(); j+=2){
text += hex2c(hex[i], hex[j]);
}
}
}
}
void setup() {
pinMode(A2, INPUT);
lcd.begin(16, 2);
lcd.setCursor(0,0);
Serial.begin(9600);
}
void loop() {
calcButton = digitalRead(A2); // decode button
char customKey = customKeypad.getKey();
// if keypad is pressed, add hex values to str
if (customKey){
lcd.print(customKey);
hex += customKey;
Serial.println(hex);
}
// if button is pressed, decode
if (calcButton == 1) {
lcd.clear();
calculate(hex);
hex = "";
lcd.print(text);
text = "";
delay(1500);
lcd.clear();
}
}
I input 49 and get I (which is correct) but when I input 4949 I expect the output to be II but it outputs IIII and when I input 6F expecting o the entire screen blurs and glitches.
The problem is here:
for (int i = 0; i < hex.length() - 1; i+=2){
for (int j = 1; j < hex.length(); j+=2){
text += hex2c(hex[i], hex[j]);
}
}
Notice that you iterate over the hex string length()*length()/4 times, combining every even hex character from the string with every odd character in the string, not just the one immediately following it. For two-digit hexadecimal strings this works because there only is one odd- and one even-indexed character; for longer strings you get wrong results.
4949 will combine 4 (#0) and 9 (#1), then 4 (#0) and 9 (#3) (wrong!), then 4 (#2) and 9 (#1) (wrong!), then 4 (#2) and 9 (#3), which gives you the result that 49494949 should give instead of 4949.
What you want is just:
for (int i = 0; i < hex.length() - 1; i+=2){
text += hex2c(hex[i], hex[i+1]);
}

Rfid with Adafruit fingerprint together not working in Arduino Uno

I am trying to create an ATM module using Arduino. Im using a RFID reader to scan the card and Adafruit Fingerprint Module for fingerprint verification. The issue is both work but not together. Here is my code:
#include <Key.h>
#include <Keypad.h>
#include <Adafruit_Fingerprint.h>
#include <SD.h>
#include <SPI.h>
#include<SoftwareSerial.h>
SoftwareSerial mySerial(0, 1);
SoftwareSerial mySerials(2, 3);
int read_count = 0, tag_count = 0;
int j = 0, k = 0; // Variabvles to iterate in for loops
char data_temp, RFID_data[12], data_store[12];
boolean disp_control;
char filename[4], fileText[30], names[10];
int atm[5];
uint8_t n, num, p;
char key;
int p1, p2, p3, p4, z;
char fid;
File myFile;
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerials);
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad
Keypad keypads = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
finger.begin(57600);
mySerial.begin(9600);
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
Serial.println("Please Place Your Card");
}
void RecieveData()
{
if (mySerial.available() > 0)
{
data_temp = mySerial.read();
RFID_data[read_count] = data_temp;
read_count++;
}
}
void ReadData()
{
if (read_count == 12) {
disp_control = true;
for (j = 0; j < 12; j++) {
data_store[j] = RFID_data[j];
}
int x = 0;
for (int i = 9; i < 12; i++) {
filename[x] = data_store[i];
x++;
}
filename[3] = '.';
filename[4] = 't';
filename[5] = 'x';
filename[6] = 't';
filename[7] = '\0';
myFile = SD.open(filename, FILE_READ);
if (myFile) {
// read from the file until there's nothing else in it:
while (myFile.available()) {
for (int i = 0; i < 20; i++) {
fileText[i] = myFile.read();
}
int a, n = 0;
for (int i = 0; i < 4; i++) {
atm[a] = fileText[i];
a++;
}
for (int i = 5; fileText[i] != '\0'; i++) {
names[n] = fileText[i];
n++;
}
fid = fileText[4];
validate();
myFile.close();
}
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
read_count = 0;
tag_count++;
}
}
void validate() {
Serial.print("Hello ");
Serial.print(names);
Serial.println();
Serial.println();
Serial.println();
pin();
}
void pin() {
Serial.println("Please Enter Your ATM PIN");
p1 = keypads.getKey();
while (p1 == NO_KEY) {
p1 = keypads.getKey(); //UPDATE VALUE
}
Serial.print(p1 - 48);
p2 = keypads.getKey();
while (p2 == NO_KEY) {
p2 = keypads.getKey(); //UPDATE VALUE
}
Serial.print(p2 - 48);
p3 = keypads.getKey(); //UPDATE VALUE
while (p3 == NO_KEY) {
p3 = keypads.getKey(); //UPDATE VALUE
}
Serial.print(p3 - 48);
p4 = keypads.getKey(); //UPDATE VALUE
while (p4 == NO_KEY) {
p4 = keypads.getKey(); //UPDATE VALUE
}
Serial.print(p4 - 48);
Serial.println();
if ((p1 == fileText[0]) && (p2 == fileText[1]) && (p3 == fileText[2]) && (p4 == fileText[3])) {
Serial.println("Please verify Fingerprint");
}
else {
Serial.println("Invalid. Buzzer!!!!");
}
}
uint8_t getFingerprintID() {
uint8_t p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.println("No finger detected");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK success!
p = finger.image2Tz();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK converted!
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK) {
Serial.println("Found a print match!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find a match");
return p;
} else {
Serial.println("Unknown error");
return p;
}
// found a match!
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
return finger.fingerID;
}
int getFingerprintIDez() {
uint8_t p = finger.getImage();
if (p != FINGERPRINT_OK) return -1;
p = finger.image2Tz();
if (p != FINGERPRINT_OK) return -1;
p = finger.fingerFastSearch();
if (p != FINGERPRINT_OK) return -1;
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
return finger.fingerID;
// found a match!
/*z = finger.fingerID;
if ((fid - 48) == z) {
Serial.println("Success");
}
else {
Serial.println("Fail");
}*/
}
void loop() {
RecieveData();
ReadData();
getFingerprintIDez();
delay(50);
}
If I initialize in this format, then fingerprint works:
mySerial.begin(9600);
finger.begin(57600);
Serial.begin(9600);
And if i do it this way, then RFID works:
finger.begin(57600);
mySerial.begin(9600);
Serial.begin(9600);
I want both of them to work i.e; I first Scan the Card, then verify pin and then it checks the validity of the fingerprint. But the issue is only one of them works at a time. If RFID works, then fingerprint doesn't even blink and if Fingerprint works, RFID doesn't read.
I'm new to this and I don't know where I am going wrong.

Redeclared as different kind of symbol in Arduino

I'm currently working on a school project. I want the servo to move according to the number of coins selected. I keep getting the error " 'void servoOne()' redeclared as different kind of symbol " I know this has been asked but I'm not sure how to fix this.
Here is my code.
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Servo.h>
Servo servoOne;
String sharp="";
int piso=0;
int lima=0;
int sampu=0;
String input="";
String remlast = "";
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);//RS,EN,D4,D5,D6,D7
const byte Rows= 4; //number of rows on the keypad i.e. 4
const byte Cols= 3; //number of columns on the keypad i,e, 3
//we will definne the key map as on the key pad:
char keymap[Rows][Cols]={
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rPins[Rows]= {3,4,5,6}; //Rows 0 to 3
byte cPins[Cols]= {7,8,9}; //Columns 0 to 2
Keypad kpd= Keypad(makeKeymap(keymap), rPins, cPins, Rows, Cols);
void setup() {
// put your setup code here, to run once:
lcd.begin(20,4);
servoOne.attach(10);
}
void loop() {
char key2 = kpd.getKey();
if (key2 != NO_KEY)
{
lcd.print(key2);
if (sharp == "")
{
input+=key2;
remlast = input;
remlast.replace("*","");
remlast.replace("#","");
piso = remlast.toInt();
}
else if (sharp == "five")
{
input+=key2;
remlast = input;
remlast.replace("*","");
remlast.replace("#","");
lima = remlast.toInt();
}
else if (sharp == "ten")
{
input+=key2;
remlast = input;
remlast.replace("*","");
remlast.replace("#","");
sampu = remlast.toInt();
}
if(key2=='*' && sharp!=NULL)
{
lcd.rightToLeft();
sharp="";
piso=0;
lima=0;
sampu=0;
input="";
remlast="";
}
if (sharp=="ten" && key2=='#')
{
sharp = "out";
lcd.clear();
lcd.print(piso);
lcd.print(lima);
lcd.print(sampu);
servoOne();
}
else if (sharp=="five" && key2=='#')
{
lcd.clear();
lcd.print("10-peso=");
lcd.setCursor(0,1);
lcd.print("(*)Erase (#)Enter");
lcd.setCursor(8,0);
sharp="ten";
input = 0;
}
else if (key2=='#')
{
lcd.clear();
lcd.print("5-peso=");
lcd.setCursor(0,1);
lcd.print("(*)Erase (#)Enter");
lcd.setCursor(7,0);
sharp="five";
input = 0;
}
if (key2=='*')
{
lcd.clear();
lcd.print("1-peso=");
lcd.setCursor(0,1);
lcd.print("(*)Erase (#)Enter");
lcd.setCursor(7,0);
}
}
}
//--------------------SERVO ONE--------------------//
void servoOne()
{
servoOne.write(70);
delay(10);
while(piso>0)
{
int x = piso;
while(x>0)
{
servoOne.write(170);
delay(200);
servoOne.write(40);
delay(200);
x--;
}
}
}
It occurs as it clashes between servoOne in Servo servoOne; and void servoOne(). Please replace servoOne in void servoOne() by some other name.
(don't forget to replace the function name in function call by your new function name)

why the output not follow the setcursor?

Why is the output of the function does not follow the lcd.setCursor position? When type in, the output pops out at a different position instead of the determined setcursor. I need to use this function multiple times for different variables that hold a different number for a different purpose. However, I need the display of the numbers on the LCD according to the set position.
Here is the code:
#include <Keypad.h>
#include <LiquidCrystal_I2C.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 = 3; //three columns
char keys[ROWS][COLS] =
{
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {9,8,7,6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5,4,3}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup()
{
Serial.begin(9600);
lcd.begin(20,4);
}
void loop()
{
lcd.setCursor(2,0);
int stage1speed = getnumber();
lcd.setCursor(5,0);
lcd.print("sv");
lcd.setCursor(2,1);
int stage1time = getnumber();
lcd.setCursor(5,1);
lcd.print("sec");
lcd.setCursor(2,2);
int stage2speed = getnumber();
lcd.setCursor(5,2);
lcd.print("sec");
lcd.setCursor(2,3);
int stage2time = getnumber();
lcd.setCursor(5,3);
lcd.print("sec");
}
int getnumber()
{
static char buffer[4];
static byte i = 0;
char key = keypad.getKey();
// i < 3: prevent buffer overflow
if ('0' <= key && key <= '9' && i < 3)
{
buffer[i] = key;
++i;
} else if (key == '#' && i > 0)
{
buffer[i] = '\0'; // null-terminate buffer
int value = atoi(buffer);
lcd.print(buffer);
i = 0;
}
}

Resources