I am using keypad 4*4 with an Arduino Mega, I have sensors connected to the Arduino I want to press a key from the keypad and have response in the same time, I don't want to wait till the loop continue, I want to save up to 10 numbers entered from the keypad, so is there a way to make the keypad as an interrupt for my code?
void loop()
{
char key = kpd.getKey();
if (key != NO_KEY) {
if (key == 'C') //clear the array
{
index = 0;
numbers[index] = '\0';
}
else if (key == '.') {
numbers[index++] = '.';
numbers[index] = '\0';
}
else if (key >= '0' && key <= '9') {
for (int z = 0; z == 10; z++) {
numbers[index++] = key;
numbers[index] = '\0';
}
}
else if (key == 'A') {
float len = atof(numbers); //conversion from string to numeric
if (fona.callPhone(numbers)) {
Serial.println(F("RING!"));
Serial.print(F("Phone Number: "));
Serial.println(numbers); //print out on serial monitor
}
}
else if (key == 'D') {
if (fona.pickUp()) {
Serial.println(F("Failed"));
}
}
else if (key == '#') {
if (fona.hangUp()) {
Serial.println(F("Failed"));
}
}
}
gas = analogRead(gasPin);
dtostrf(gas, 4, 2, gass);
Serial.println(gas);
delay(1000); // Print value every 1 sec.
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn LED ON
delay(150);
if (pirState == LOW) {
// we have just turned on
Serial.println("Motion detected!");
// We only want to print on the output change, not state
pirState = HIGH;
}
}
else {
digitalWrite(ledPin, LOW); // turn LED OFF
delay(300);
if (pirState == HIGH) {
// we have just turned off
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState = LOW;
}
}
int ldrStatus = analogRead(ldrPin);
if (ldrStatus <= 550) {
digitalWrite(led, HIGH);
Serial.println("LDR is DARK, LED is ON");
}
else {
digitalWrite(led, LOW);
}
valee = analogRead(tempPin);
float cel = (valee * 0.48828125) / 2.12304;
dtostrf(cel, 4, 2, temp);
Serial.print("TEMPRATURE = ");
Serial.print(cel);
Serial.print("*C");
Serial.println();
delay(1000);
Related
#define CLK 2
#define DT 3
#define SW 4
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27);
int counter = 0;
int currentStateCLK;
int lastStateCLK;
int lastCLK,cnt=0,btnState,lastPress=0;
String currentDir ="";
unsigned long lastButtonPress = 0;
char *mainmenu[] ={"SET MODE","SET TEMP","SET HUMD","SERVO","RESET"};
char *setmode[] ={"INCUBATOR","HATCHER","BACK"};
void setup() {
// Set encoder pins as inputs
Wire.begin();
Wire.beginTransmission(0x27);
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
pinMode(SW, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.setBacklight(255);
lcd.home(); lcd.clear();
Serial.begin(9600);
lastStateCLK = digitalRead(CLK);
delay(100);
if(EEPROM_READ(0)==NULL){
SET_MODE();
}
Serial.print(EEPROM_READ(0));
}
void loop(){
disp();
rot();
}
void disp(){
lcd.setCursor(0,0);
lcd.print(" KGF");
}
void rot() {
int lim=sizeof(mainmenu)/2;
Serial.print(lim);
currentStateCLK = digitalRead(CLK);
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
lcd.clear();
lcd.setCursor(0, 1);
if (digitalRead(DT) != currentStateCLK) {
counter --;
if(counter<0){
counter=lim-1;
}
}
else {
// Encoder is rotating CW so increment
counter ++;
if(counter>lim-1){
counter=0;
}
lcd.print(mainmenu[counter]);
}
lastStateCLK = currentStateCLK;
int btnState = digitalRead(SW);
if (btnState == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
if(counter==0){
SET_MODE();
}
}
}
lastButtonPress = millis();
}
delay(1);
}
void SET_MODE(){
int lim=sizeof(setmode)/2;
int currentCLK = digitalRead(CLK);
if (currentCLK != lastCLK && currentCLK == 1){
lcd.clear();
lcd.setCursor(0, 1);
if (digitalRead(DT) != currentCLK) {
cnt --;
if(cnt<0){
cnt=lim-1;
}
}
else {
// Encoder is rotating CW so increment
cnt ++;
if(cnt>lim-1){
cnt=0;
}
}
lcd.print(setmode[cnt]);
}
lastCLK = currentCLK;
btnState = digitalRead(SW);
if (btnState == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
if(setmode[cnt]=="BACK"){
exit(0);
}
lcd.clear();
lcd.setCursor(0, 1);
EEPROM_WRITE(0,setmode[cnt]);
lcd.print("DONE");
}
lastPress = millis();
}
delay(1);
}
void EEPROM_WRITE(int addrOffset, const String &strToWrite)
{
byte len = strToWrite.length();
EEPROM.write(addrOffset, len);
for (int i = 0; i < len; i++)
{
EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
}
}
String EEPROM_READ(int addrOffset)
{
int newStrLen = EEPROM.read(addrOffset);
char data[newStrLen + 1];
for (int i = 0; i < newStrLen; i++)
{
data[i] = EEPROM.read(addrOffset + 1 + i);
}
data[newStrLen] = '\0';
return String(data);
}
I want to call the SET_MODE() function in the loop from rot() function, I am building a menu based program so the SET MODE menu should redirect to the SET_MODE() function, and as I will be adding more menu and sub-menus how can I perform this task.
The SET_MODE() function doesn't work in loop I do not know why, it only works when I all it under void loop() directly.
This is my code for an Arduino, I think the problem is the input(//nr1 and //nr2) because it worked before changing it to its current state. Thank you for helping in advance!
int nr1 = 0;
int nr2 = 0;
int rs = 0;
void setup() {
// put your setup code here, to run once:
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
}
void loop()
{
//nr1
if(digitalRead(11)==LOW && digitalRead(12)==LOW)
{
nr1 = 0;
} else if(digitalRead(11)==LOW && digitalRead(12)==HIGH)
{
nr1 = 1;
} else if(digitalRead(11)==HIGH && digitalRead(12)==LOW)
{
nr1 = 2;
} else if(digitalRead(11)==HIGH && digitalRead(12)==HIGH)
{
nr1 = 3;
}
//nr2
if(digitalRead(9)==LOW && digitalRead(10)==LOW)
{
nr1 = 0;
} else if(digitalRead(9)==LOW && digitalRead(10)==HIGH)
{
nr1 = 1;
} else if(digitalRead(9)==HIGH && digitalRead(10)==LOW)
{
nr1 = 2;
} else if(digitalRead(9)==HIGH && digitalRead(10)==HIGH)
{
nr1 = 3;
}
//rs
rs= nr1 + nr2;
if(rs>4)
{
digitalWrite(2, HIGH);
}else
{
digitalWrite(2, LOW);
}
if(rs%4==2)
{
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
}
if(rs%4==1)
{
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
}
if(rs%4==0)
{
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
delay(1000);
nr1=0;
nr2=0;
rs=0;
}
In your loop, you never assign nr2 a value.
Maybe you want this:
const unsigned int pin9 = (digitalRead(9) == LOW) ? 0 : 1;
const unsigned int pin10 = (digitalRead(10) == LOW) ? 0 : 1;
nr2 = pin10 << 1 | pin9;
The above code fragment reads pin 9 and 10 once, converts them into a one or zero, then calculates nr2 based on the values of pin 9 and 10.
You can try to assign the digitalRead values to a variable and use it within the ifs, this will cause you to read the digital pin value previously, start by trying something like state12 = digitalRead (12); and inside the if do something like
if (state12 == HIGH)...
I have a project I'm working on with an LCD screen, two buttons, and a potentiometer, it's a binary calculator. When I reach screenState == 3 I am attempting to change the digits so i can keep track of them and add an 8 bit number with another 8 bit number, while tracking overflow. However, whenever I begin to use the button which the input == 0 it moves the cursor, and then my next button cycles through the screens again. Input == 0 should only change the value between 0 and 1 for whatever lcd.cursor value I'm. How can i adjust that one value without changing screens?
#include <LiquidCrystal.h>
LiquidCrystal lcd(11, 10, 5, 4, 3, 2);
const int numInputs = 2;
const int inputPins[numInputs] = {13, 12};
// tracks screen state
int screenState = 0;
int prevScreenState = 0;
int binaryValue = 0;
// tracks if we are on the right screen to acceptInput and if our value is 0 or 1
bool canAcceptInput = false;
bool valIsZero = false;
int inputState[numInputs];
int lastInputState[numInputs] = {LOW,LOW};
bool inputFlags[numInputs] = {LOW,LOW};
int inputCounter[numInputs];
int cursorPosX = 0;
int cursorPosY = 0;
int blinkingPosX = cursorPosX;
int blinkingPosY = cursorPosY;
unsigned long lastDebounceTime[numInputs] = {0,0};
long debounceDelay = 50;
void setup() {
for(int i = 0; i < numInputs; i++) {
pinMode(inputPins[i], INPUT);
digitalWrite(inputPins[i], HIGH); // pull-up 20k
}
Serial.begin(9600);
lcd.begin(16, 2);
}
void loop() {
setInputFlags();
resolveInputFlags();
}
void setInputFlags() {
for(int i = 0; i < numInputs; i++) {
int reading = digitalRead(inputPins[i]);
if (reading != lastInputState[i]) {
lastDebounceTime[i] = millis();
}
if ((millis() - lastDebounceTime[i]) > debounceDelay) {
if (reading != inputState[i]) {
inputState[i] = reading;
if (inputState[i] == HIGH) {
inputFlags[i] = HIGH;
}
}
}
lastInputState[i] = reading;
}
}
void resolveInputFlags() {
for(int i = 0; i < numInputs; i++) {
if(inputFlags[i] == HIGH) {
// Input Toggle Logic // all invoked upon bttn press
inputCounter[i]++;
updateScreenState(i);
printString(i);
inputFlags[i] = LOW;
}
}
}
void updateScreenState(int input) {
// input 0 = State 0 and 1
if(input == 0) {
if(screenState > 2 & screenState < 19) {
canAcceptInput = true;
binaryValue = 1;
updateScreenValues();
}
else if (screenState == 1) {
//screenState = 0;
binaryValue = 0;
updateScreenValues();
}
else {
//screenState = 2;
binaryValue = 1;
}
// input 1 = State 2 to 6
}else if(input == 1) {
// we have 20 max screen states, this cycles through them using button 2
if(screenState == 0 || screenState == 1 || screenState > 19) {
screenState = 2;
updateScreen();
}else{
screenState++;
updateScreen();
}
}
}
void setCursorValues( int cursorX, int cursorY) {
lcd.setCursor(cursorX, cursorY);
cursorPosX = cursorX;
cursorPosY = cursorY;
}
void updateScreenValues() {
if(canAcceptInput == true) {
if(binaryValue == 0 ){
lcd.print("0");
}
if(binaryValue == 1) {
lcd.print("1");
binaryValue = 0;
}
}
}
// void update -----------------------------------------------------------------------------
void updateScreen() {
// welcome screen -----------------------------
if(screenState == 2){
canAcceptInput = false;
lcd.clear();
setCursorValues(0, 0);
lcd.print("Welcome Screen");
setCursorValues(0, 1);
lcd.print("Press Bttn 1");
}
// start of byte 1 screen ----------------------------------------------------------------
if(screenState == 3){
canAcceptInput = true;
lcd.clear();
setCursorValues(0, 0);
lcd.print("Byte 1 Screen");
setCursorValues(0, 1);
lcd.print(" 0000 0000 ");
//move cursor to MSD and blink
setCursorValues(3, 1);
lcd.blink();
}
//if screenState changes, so will the cursorValues-----------
if(screenState == 4) {
setCursorValues(4, 1);
}
if(screenState == 5) {
setCursorValues(5, 1);
}
if(screenState == 6) {
setCursorValues(6, 1);
}
if(screenState == 7) {
setCursorValues(9, 1);
}
if(screenState == 8) {
setCursorValues(10, 1);
}
if(screenState == 9) {
setCursorValues(11, 1);
}
if(screenState == 10) {
setCursorValues(12, 1);
}
//start of byte 2 screen -------------------------------------------------------
if(screenState == 11){
lcd.clear();
setCursorValues(0, 0);
lcd.print("Byte 2 Screen");
setCursorValues(0, 1);
lcd.print(" 0000 0000 ");
setCursorValues(3, 1);
lcd.blink();
}
//if screenState changes, so will the cursorValues-----------
if(screenState == 12) {
setCursorValues(4, 1);
}
if(screenState == 13) {
setCursorValues(5, 1);
}
if(screenState == 14) {
setCursorValues(6, 1);
}
if(screenState == 15) {
setCursorValues(9, 1);
}
if(screenState == 16) {
setCursorValues(10, 1);
}
if(screenState == 17) {
setCursorValues(11, 1);
}
if(screenState == 18) {
setCursorValues(12, 1);
}
if(screenState == 19){
lcd.clear();
setCursorValues(0, 0);
lcd.print("Solution Screen");
lcd.noCursor();
}
if(screenState == 20){
lcd.clear();
setCursorValues(0, 0);
lcd.print("Contrast Screen");
}
}
void printString(int output) {
Serial.print("Input ");
Serial.print(output);
Serial.print(" was pressed ");
Serial.print(inputCounter[output]);
Serial.println(" times.");
Serial.print("screenState = ");
Serial.println(screenState);
Serial.print("binaryValue = ");
Serial.println(binaryValue);
Serial.print("cursorPosX = ");
Serial.print(cursorPosX);
Serial.print(" cursorPosY = ");
Serial.println(cursorPosY);
Serial.print('\n');
}
I am new to Arduino and I'm trying to make a program that receives IR codes from a TV remote, uses them as a 4 number pass code lighting up a LED as you press each button. And then comparing the code to a hard-coded one. In this case 1234.
I made a function to verify that the value entered is equal to the pass. If so, light up a green LED and else, light up a red one.
However, even if I input the correct code, only the red led lights up.
Here is my whole code as I'm not sure which part of it is the one causing problems:
const int pass[4] = {1, 2, 3, 4};
int value[4] = {};
int digitNum = 0;
int input;
void loop()
{
value[digitNum] = input; //where input is a number between 0 and 9
digitNum++;
if(digitNum == 1){
lightFirstLed();
}
else if(digitNum == 2){
lightSecondLed();
}
else if(digitNum == 3){
lightThirdLed();
}
else if(digitNum == 4){
lightFourthLed();
verify();
}
}
void verify()
{
bool falseCharacter = false;
for(int i = 0; i <= 4; i++){
if(value[i] != pass[i]){
falseCharacter = true;
}
}
if(!falseCharacter){
lightGreenLed();
}
else{
lightRedLed();
}
}
Functions in the form of light*Led actually do what they're supposed to do.
I tried changing the verify function around, that ended up making the green LED the one that always shone. I've been doing this for hours and I'm starting to feel disparate.
I would really appreciate any help. And please tell me if anything I'm doing does not comply with best practices even if it's out of the scope of this question.
For full code and design, here's a link to autodesk's simulator: https://www.tinkercad.com/things/0keqmlhVqNp-mighty-leelo/editel?tenant=circuits?sharecode=vVUD2_4774Lj4PYXh6doFcOqWUMY2URIfW8VXGxutRE=
EDIT: Now reset doesn't work
Your for loop in verify is accessing outside the array:
const int pass[4] = {1, 2, 3, 4};
int value[4] = {};
for(int i = 0; i <= 4; i++){
if(value[i] != pass[i]){
falseCharacter = true;
}
}
Change i <= 4 to i < 4. Also, when falseCharacter is set to true, break from the loop:
for(int i = 0; i < 4; i++)
{
if(value[i] != pass[i])
{
falseCharacter = true;
break;
}
}
Update
You need an else statement in loop:
void loop(void)
{
if(irrecv.decode(&results))
{
if (results.value == powBtn)
{
reset();
}
else if (results.value == zeroBtn)
{
input = 0;
}
else if (results.value == oneBtn)
{
input = 1;
}
else if (results.value == twoBtn)
{
input = 2;
}
else if (results.value == threeBtn)
{
input = 3;
}
else if (results.value == fourBtn)
{
input = 4;
}
else if (results.value == fiveBtn)
{
input = 5;
}
else if (results.value == sixBtn)
{
input = 6;
}
else if (results.value == sevenBtn)
{
input = 7;
}
else if (results.value == eightBtn)
{
input = 8;
}
else if (results.value == nineBtn)
{
input = 9;
}
else
{
return; /*** !!! Unrecognized Value !!! ***/
}
value[digitNum] = input;
digitNum++;
if(digitNum == 1)
{
digitalWrite(LED1, HIGH);
}
else if(digitNum == 2)
{
digitalWrite(LED2, HIGH);
}
else if(digitNum == 3)
{
digitalWrite(LED3, HIGH);
}
else if(digitNum == 4)
{
digitalWrite(LED4, HIGH);
verify();
}
else
{
if (results.value == powBtn)
{
reset();
}
}
// Receive the next value
irrecv.resume();
}
}
HI I would like to control 8 x Pumps with Bluetooth on my arduino... I whant to change number '1' for 'ON' to '1on' and '2' for 'OFF' to '1off', than
'2on' , '2off' ,
'3on' , '3off' etc. but I don't know how because I'm not a coder... Here is my code:
int PUMP1 = 2;
int PUMP2 = 3;
char value = 0;
void setup()
{
Serial.begin(9600);
pinMode(PUMP1, OUTPUT);
pinMode(PUMP2, OUTPUT);
}
void loop()
{
if (Serial.available())
{
value = Serial.read();
if (value == '1') digitalWrite(PUMP1, LOW); //relay1 on
else if (value == '0') digitalWrite(PUMP1, HIGH); //relay1 off
if (value == '3') digitalWrite(PUMP2, LOW); //relay2 on
else if (value == '2') digitalWrite(PUMP2, HIGH); //relay2 off
}
}
You need to replace Serial.read() with Serial.readStringUntil('\n'). The strings will need to be sent with a trailing new line character.
void loop()
{
if (Serial.available())
{
String value = Serial.readStringUntil('\n');
if (value == "1on") digitalWrite(PUMP1, LOW); //relay1 on
else if (value == "1off") digitalWrite(PUMP1, HIGH); //relay1 off
else if (value == "2on") digitalWrite(PUMP2, LOW); //relay2 on
else if (value == "2off") digitalWrite(PUMP2, HIGH); //relay2 off
// and so on
}
}
Serial.readString() was suggested in the comments, but that will lead to 1 sec of delay (by default). In this case the string is considered complete when there is no data for certain amount of time. And it will be impossible to control multiple relays at the same time.