How to write a state change (edge detection) using analogRead() on Arduino? - arduino

I'm having trouble creating a toggle switch using an analog input connected to an RF receiver. I'm attempting to make a servo turn 180 degrees when the voltage reads higher than 800 and stay at 180 degrees until the button is pressed again. It only reads higher than 800 when I press a button on my key fob (RF transmitter). In my code it does this, but it doesn't hold at 180 degrees and wait until the button is pressed again to go back to 0 degrees.
#include <Servo.h>
Servo myservo;
const int analogInPin = A0;
int led = 13;
float sensorValue = 0;
void setup(){
Serial.begin(2400);
pinMode(led, OUTPUT);
myservo.attach(6);
myservo.write(0);
}
void loop(){
sensorValue = analogRead(analogInPin);
Serial.print("Voltage Output = ");
Serial.print(sensorValue);
Serial.println(" ");
delay(100);
if (sensorValue > 800) {
digitalWrite(led, HIGH);
myservo.write(180);
delay(100);
}
else{
digitalWrite(led, LOW);
myservo.write(0);
delay(100);
}
}
EDIT: I'm pretty close with this edited code. I added a variable and an if statement. It turns the LED on and it stays on, but when pressed again it doesn't turn off. So close...
const int analogInPin = A0;
int led = 13;
int ledState = 0;
float sensorValue = 0;
void setup(){
Serial.begin(2400);
pinMode(led, OUTPUT);
}
void loop(){
sensorValue = analogRead(analogInPin);
Serial.print("Voltage Output = ");
Serial.print(sensorValue);
Serial.println(" ");
delay(100);
if (sensorValue < 400 && ledState == 0) {
digitalWrite(led, HIGH);
delay(500);
ledState == 1;
}
if (sensorValue < 400 && ledState == 1) {
digitalWrite(led, LOW);
delay(500);
ledState == 0;
}
}

OK. I think I solved it! Take a look. It now turns the LED on when the button is pressed and stays on until the button is pressed again. This is how to create a switch using an analog input reading.
const int analogInPin = A0;
int led = 13;
int ledState = 0;
float sensorValue = 0;
void setup(){
Serial.begin(2400);
pinMode(led, OUTPUT);
}
void loop(){
sensorValue = analogRead(analogInPin);
Serial.print("Voltage Output = ");
Serial.print(sensorValue);
Serial.println(" ");
delay(100);
if (sensorValue < 400 && ledState == 0) {
digitalWrite(led, HIGH);
delay(100);
ledState = 1;
Serial.println(ledState);
delay(500);
}
else {
if (sensorValue < 400 && ledState == 1) {
digitalWrite(led, LOW);
delay(100);
ledState = 0;
Serial.println(ledState);
delay(500);
}
}
}

Related

Switching on the diode for some time, as well as execution of the next program in Arduino

The circuit made in tinkercad
I use the relay, because I have only 4 wires to led diode and this two switches.
int led = 12; // red led
int s1 = 9; //switch 1
int s2 = 10; //switch 1
int k1 = 3; // first blue led
int k2 = 2; // second blue led
int y1 = 11; // relay
unsigned long startTime1 = 0;
unsigned long startTime2 = 0;
const int led1Duration = 6000; // first blue led time
const int led2Duration = 12000; // second blue led time
void setup()
{
pinMode(led, OUTPUT);
pinMode(k1, OUTPUT);
pinMode(k2, OUTPUT);
pinMode(y1, OUTPUT);
pinMode(s1, INPUT);
pinMode(s2, INPUT);
}
void loop()
{
if (digitalRead(s1) == HIGH and digitalRead(s2) == LOW)
{
digitalWrite(k1, HIGH);
digitalWrite(y1, HIGH);
startTime1 = millis();
}
else
{
digitalWrite(led, LOW);
}
if (digitalRead(s2) == HIGH and digitalRead(s1) == LOW)
{
digitalWrite(k2, HIGH);
digitalWrite(y1, HIGH);
startTime2 = millis();
}
else
{
digitalWrite(led, LOW);
}
if (digitalRead(k1) == HIGH && (millis() - startTime1 >= led1Duration))
{
digitalWrite(k1, LOW);
digitalWrite(y1, LOW);
}
if (digitalRead(k2) == HIGH && (millis() - startTime2 >= led2Duration))
{
digitalWrite(k2, LOW);
digitalWrite(y1, LOW);
}
if (digitalRead(k1) == HIGH and digitalRead(k2) == LOW)
{
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
delay(200);
}
if (digitalRead(k2) == HIGH and digitalRead(k1) == LOW)
{
digitalWrite(led, HIGH);
delay(500);
digitalWrite(led, LOW);
delay(500);
}
if (digitalRead(k2) == HIGH and digitalRead(k1) == HIGH)
{
digitalWrite(led, HIGH);
}
}
Is there easier way to do that, cause when I assembled it the switches work very slow that blue led turn on after some time. Next I use the esp2866 but the relay for 3V doesn't turn on. How can I make it to work?
#Peter is true : avoid blocking delay code.
here is an example : I have a little simplified your code and added else if to make it more readable.
update1 :
int led = 12; // red led
int s1 = 9; //switch 1
int s2 = 10; //switch 1
int k1 = 3; // first blue led
int k2 = 2; // second blue led
int y1 = 11; // relay
unsigned long startTime1 = 0;
unsigned long startTime2 = 0;
unsigned long t200 = 200;
unsigned long t500 = 500;
const int led1Duration = 6000; // first blue led time
const int led2Duration = 12000; // second blue led time
void setup()
{
pinMode(led, OUTPUT);
pinMode(k1, OUTPUT);
pinMode(k2, OUTPUT);
pinMode(y1, OUTPUT);
pinMode(s1, INPUT);
pinMode(s2, INPUT);
}
void loop()
{
if (digitalRead(s1) && !digitalRead(s2)) {
digitalWrite(k1, HIGH);
digitalWrite(y1, HIGH);
startTime1 = millis();
blinkLed200();
} else if (!digitalRead(s1) && digitalRead(s2)) {
digitalWrite(k2, HIGH);
digitalWrite(y1, HIGH);
startTime2 = millis();
blinkLed500();
}
if (digitalRead(k1) && (millis() - startTime1 >= led1Duration)) {
digitalWrite(k1, LOW);
digitalWrite(y1, LOW);
digitalWrite(led, LOW);
}
if (digitalRead(k2) && (millis() - startTime2 >= led2Duration)) {
digitalWrite(k2, LOW);
digitalWrite(y1, LOW);
digitalWrite(led, LOW);
}
}
void blinkLed200() {
if (millis() - t200 > 200) { //tick every 200mS
t200 = millis();
digitalWrite(led, !digitalRead(led));
}
}
void blinkLed500() {
if (millis() - t500 > 500) { //tick every 500mS
t500 = millis();
digitalWrite(led, !digitalRead(led));
}
}
The 3V relays have a very low resistance and I am not sure that the digital outputs are powerful enough. Personally I always switch relays via a transistor.

Arduino Nano and analog joystick

I have a game that consist of 4 direction of movement (up down left and right)
using Arduino Nano and analog joystick, seems like code is right as check before other posts.
This is the Arduino code:
byte x_axis = A3;
byte y_axis = A1;
byte btn1 = 8;
byte btn2 = 9;
byte btn3 = 10;
byte btn4 = 11;
byte btn5 = 12;
byte led = 13;
void setup(){
pinMode(x_axis, INPUT);
pinMode(y_axis, INPUT);
pinMode(btn1, INPUT);
pinMode(btn2, INPUT);
pinMode(btn3, INPUT);
pinMode(btn4, INPUT);
pinMode(btn5, INPUT);
digitalWrite(btn1, HIGH);
digitalWrite(btn2, HIGH);
digitalWrite(btn3, HIGH);
digitalWrite(btn4, HIGH);
digitalWrite(btn5, HIGH);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
Serial.begin(9600);
}
void loop(){
Int read_x = analogRead(x_axis);
int read_y = analogRead(y_axis);
if(read_x > 600){
Serial.println("R");
digitalWrite(led, HIGH);
}
if(read_x < 400){
Serial.println("L");
digitalWrite(led, HIGH);
}
if(read_y > 600){
Serial.println("D");
digitalWrite(led, HIGH);
}
if(read_y < 400){
Serial.println("U");
digitalWrite(led, HIGH);
}
if(digitalRead(btn1) == LOW){
Serial.println("1");
digitalWrite(led, HIGH);
}
if(digitalRead(btn2) == LOW){
Serial.println("2");
digitalWrite(led, HIGH);
}
if(digitalRead(btn3) == LOW){
Serial.println("3");
digitalWrite(led, HIGH);
}
if(digitalRead(btn4) == LOW){
Serial.println("4");
digitalWrite(led, HIGH);
}
if(digitalRead(btn5) == LOW){
Serial.println("5");
digitalWrite(led, HIGH);
}
delay(10);
digitalWrite(led, LOW);
}
But when I use serial monitor to check it, it non stop show me U and L even without touching the joystick.
How can I fix this problem?
I'm feeling generous, so you have some jitter issues in the code and you really could use some cleanup. This code compiles. Ok now when a joystick is 0,0 in x/y physically it jitters in code. One thing you could do is remap out the jitter to give a wider center. print the raw analog values to the serial monitor and then map them out to your 0 point with a little padding. reference: https://www.arduino.cc/reference/en/language/functions/math/map/
byte x_axis = A3;
byte y_axis = A1;
byte btn[] = {8, 9, 10, 11, 12}; // 2,3,4,5,6
byte stat[] = {1, 2, 3, 4, 5};
byte led = 13;
int dval = 50;
void setup() {
pinMode(x_axis, INPUT);
pinMode(y_axis, INPUT);
for (int i = 0; i < 5; i++) {
pinMode(btn[i], INPUT);
digitalWrite(btn[i], HIGH);
}
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
Serial.begin(9600);
}
void loop() {
int read_x = analogRead(x_axis);
delay(dval);
int read_y = analogRead(y_axis);
delay(dval);
if (read_x > 600) {
Serial.println("R");
digitalWrite(led, HIGH);
}
if (read_x < 400) {
Serial.println("L");
digitalWrite(led, HIGH);
}
if (read_y > 600) {
Serial.println("D");
digitalWrite(led, HIGH);
}
if (read_y < 400) {
Serial.println("U");
digitalWrite(led, HIGH);
}
for (int i = 0; i < 5; i++) {
if (digitalRead(btn[i]) == LOW) {
Serial.println(stat[i]);
digitalWrite(led, HIGH);
}
}
delay(10);
digitalWrite(led, LOW);
}
Emad joon:
1- Check that the ground of your joy stick and the Vdd is connected to your arduino.
2- connect the x and y of the joy stick to the arduino analog inputs.
use this code as starter:
#define X_AXIS A1
#define Y_AXIS A3
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("X = ");
Serial.println(analogRead(X_AXIS);
Serial.print("Y = ");
Serial.println(analogRead(Y_AXIS);
delay(150);
}
See what values you get when your Joy Stick is at initial position. You can build up on this code for buttons.
Also, do not forget to use debouncing for your button readings:
if(digitalRead(Button1)==0){
delay(40);
if(digitalRead(Button1==0){
buttonPressed=true;
}
}

How do I make the buzzer stay on (LDR Alarm)?

I have a program in Arduino that checks an LDR sensor. If it goes over the set values it will trigger an alarm. How do I set it so once triggered it stays on until say a button push is detected to disarm it?
Code:
const int ledPin = 8;
const int buzzerPin = 4;
const int ldrPin = A0;
void setup () {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(ldrPin, INPUT);
}
void loop() {
int ldrStatus = analogRead(ldrPin);
if (ldrStatus >= 30) {
noTone(buzzerPin);
digitalWrite(ledPin, LOW);
} else {
tone(buzzerPin, 100);
digitalWrite(ledPin, HIGH);
delay(100);
noTone(buzzerPin);
digitalWrite(ledPin, LOW);
delay(100);
Serial.println("----------- ALARM ACTIVATED -----------");
}
}
You should use a FLAG to fire the alarm instead of using threshold directly.
if (ldrStatus >= 30) {
AlarmFlag = true; //Set alarm
}
...
if (digitalRead(pushButton) == LOW){
AlarmFlag = false; //Turn off alarm
}
...
if (AlarmFlag == true){
Serial.println("ALARM ON");
...
}

how to control door using SIM900a

I need help I'm doing project about opening and closing the door using SIM900a.. it says that no errors but it doesn't work !! I used AT commands and it supposes to send notification to the user using sms when theres knocking, motion at home, high temperature and when theirs smoke please help please please
#include <SoftwareSerial.h>
#include "pins_arduino.h"
#include <String.h>
SoftwareSerial SIM900(7, 8); //tx & rx pins
String msg = String("");
char inchar;
int x = 0;
int y = 0;
float z =0;
int PIR_sensor = 12;
int door_lock = 4 ; //close the door
int door_lock1 = 5 ;
int led = 11;
int led1 = 10; //red led
int mic= 6;
int Gas_sensor = A0;
float Tem_sensor = A1;
float temp =0.0;
String textForGAS ;
String textForPIR ;
String textForTAM ;
void setup()
{
Serial.begin(19200);
pinMode(PIR_sensor, INPUT);
pinMode(door_lock, OUTPUT);
pinMode(door_lock1, OUTPUT);
pinMode(led, OUTPUT);
pinMode(led1, OUTPUT);
digitalWrite(door_lock, LOW);
digitalWrite(door_lock1, LOW);
digitalWrite(led, LOW);
digitalWrite(led1, LOW);
// wake up the GSM shield
SIM900.begin(19200);
delay(20000); // give time to log on to network.
SIM900.print("AT+CMGF=1r"); // set SMS mode to text
delay(100);
SIM900.print("AT+CNMI=2,2,0,0,0r");
// blurt out contents of new SMS upon receipt to the GSM shield’s serial out
delay(100);
Serial.println("Ready…");
}
void sendSMS(String message)
{
SIM900.print("AT+CMGF=1\r");
delay(100);
SIM900.println("AT + CMGS = \"+96896089681\"");
delay(100);
SIM900.println(message);
delay(100);
SIM900.println((char)26);
delay(100);
SIM900.println();
delay(5000);
}
void loop()
{
//If a character comes in from the cellular module…
if (SIM900.available())
{
inchar = SIM900.read();
Serial.println(inchar);
if (inchar == '#')
{
delay(10);
inchar = SIM900.read();
if (inchar == 'a')
{
delay(10);
inchar = SIM900.read();
if (inchar == '0')
{
digitalWrite(door_lock, HIGH);
digitalWrite(led1, HIGH);
digitalWrite(led, LOW);
}
else if (inchar == '1')
{
digitalWrite(door_lock1, HIGH);
digitalWrite(led, HIGH);
digitalWrite(led1, LOW);
}
delay(10);
inchar = SIM900.read();
if (inchar == 'b')
{
inchar = SIM900.read();
if (inchar == '0')
{
digitalWrite(PIR_sensor, LOW);
}
else if (inchar == '1')
{
digitalWrite(PIR_sensor, HIGH);
}
}
SIM900.println("AT+CMGD=1,4"); // delete all SMS
}
}
}
Gas_sensor = (analogRead(A0));
PIR_sensor = (digitalRead(12));
Tem_sensor = (analogRead(A1));
temp = Tem_sensor * 0.48828125;
//program for GAS sensor
if (temp > 70.0)
{
textForTAM = "Alarm ! The degree of Tamperture is :n ";
textForTAM.concat(temp);
textForTAM = textForTAM +"C";
Serial.println(textForTAM);
sendSMS(textForGAS);
delay(1000);
do {
z = (analogRead(A0));
}
while (z >= 141.312);
}
//program for GAS sensor
if (Gas_sensor > 500)
{
textForGAS = "Alarm ! there is Gas by rate :n ";
textForGAS.concat(Gas_sensor);
Serial.println(textForGAS);
sendSMS(textForGAS);
delay(1000);
}
//program for PIR sensor
if (digitalRead(12) == HIGH)
{
textForPIR = "Warnning ! n theres's a motion ";
textForPIR.concat(PIR_sensor);
Serial.println(textForPIR);
sendSMS(textForPIR);
delay(1000);
}
}
thank you

Arduino, if else LED "stuck"

So the code is not working properply, there are two leds that wont turn off "highliten" the problem. when i run the Else part of the program. i want to turn them off in the else part. :)
include
byte ledPin[] = {8, 9, 10, 11, 12, 13}; //--------------------------------.
int ledDelay; // Del 1
int direction = 1;
int currentLED = 0;
unsigned long changeTime;
int potPin = 0;
Servo myservo; // create servo object to control a servo
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
int va;
void setup()
{
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, INPUT);
myservo.attach(3); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
for (int x=0; x<6; x++) {
pinMode(ledPin[x], OUTPUT); }
changeTime = millis();
}
void loop() {
int on = digitalRead(6);
if (on == HIGH)
{
myservo.attach(3);
// Here is the problem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if va < 523)
{
digitalWrite(5, HIGH);
}
else if (va > 555)
{
digitalWrite(4, HIGH);
}
else
{
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
// Here is the problem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
va = analogRead(potPin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(va, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
delay(1); // waits for the servo to get there
}
else
{
myservo.detach();
digitalWrite(5, LOW);
digitalWrite(4, LOW);
ledDelay = analogRead(potPin) / 4;
if ((millis() - changeTime) > ledDelay)
{
changeLED();
changeTime = millis();
}
}
}
void changeLED() {
for (int x=0; x<6; x++)
{
digitalWrite(ledPin[x], LOW);
}
digitalWrite(ledPin[currentLED], HIGH);
currentLED += direction;
if (currentLED == 6) {direction = -1;}
if (currentLED == 0) {direction = 1;}
}
in advance Thank you!
Right at the end of the sketch you have the following line:
if (currentLED == 6) { direction = -1; }
I think, without actually running the program, that the problem is here. In the previous line you have added one to the value of currentLED and you are checking to see if you have gone off the end of the ledPin array. You change the direction but you don't reset the currentLED position to be back inside the ledPin range.
The next time changeLED is called it tries to call digitalWrite(ledPin[currentLED], HIGH); but the value of currentLED is 6, which is outside the ledPin array. The Arduino probably gets upset at this point.
I think you simply need to change the statement to check whether currentLED == 5 rather than 6. This will mean that next time that changeLED is called the last LED will be turned on and the value of currentLED will be decremented (direction == -1), keeping it inside the ledPin range.

Resources