How to independently check more than one variable? - c++

This is the part of the code with the error:
int value = analogRead(LM351);
float Temperature = value * 500.0 / 1023.0;
lcd.setCursor(6,0);
lcd.print(Temperature);
lcd.setCursor(11,1);
int value1 = analogRead(LM352);
float Humidity = value1 * 500.0 / 1023.0;
lcd.setCursor(10,1);
lcd.print(Humidity);
if (Temperature > 24){
digitalWrite(motor, HIGH);
digitalWrite(LedRed, HIGH);
digitalWrite(LedGreen, LOW);
lcd.print("");
}
else {
digitalWrite(motor, LOW);
digitalWrite(LedRed, LOW);
digitalWrite(LedGreen, HIGH);
lcd.print("");
}
if (Humidity > 10){
digitalWrite(motor, HIGH);
lcd.print("");
}
else {
digitalWrite(motor, LOW);
lcd.print("");
}
delay(1000);
}
By right, the motor should spin if the temperature is more than 24 or humidity is more than 10. But when I ran this code, the motor only spun if the humidity was more than 10. But when humidity was less than 10 and temperature was more than 24, motor did not spin.
The reason for this is as I am checking one variable after the other, is there a way in which I can check each variable independentaly from the other?

Your logic checks one thing and reacts, then checks the other thing.
You can either check both things at once, identify one among 4 situations and then react,
or check one thing after the other, but only make decisions instead of reacting immediatly, then react later.
I think you ask specifically about checking separatly, so go with decision making.
// no decisions yet
bool NeedMotor = false;
if (Temperature > 24)
{
NeedMotor = true;
digitalWrite(LedRed, HIGH);
digitalWrite(LedGreen, LOW);
lcd.print("");
} else
{
digitalWrite(LedRed, LOW);
digitalWrite(LedGreen, HIGH);
lcd.print("");
}
if (Humidity > 10){
NeedMotor = true;
lcd.print("");
} else
{
lcd.print("");
}
if (NeedMotor)
{
digitalWrite(motor, HIGH);
} else
{
digitalWrite(motor, LOW);
}
This way the humidity decision does not overwrite the temperature decision, it just potentially decides to use the motor if the temperature did not cause that yet. If the motor is needed it will be switched on, otherwise off.
Note, I am unsure about the purpose of the lcd printing. I left it as it is in your code.

You could include both conditions in the first if-else statement:
if (Temperature > 24 || Humidity > 10){
digitalWrite(motor, HIGH);
digitalWrite(LedRed, HIGH);
digitalWrite(LedGreen, LOW);
lcd.print("");
}
else {
digitalWrite(motor, LOW);
digitalWrite(LedRed, LOW);
digitalWrite(LedGreen, HIGH);
lcd.print("");
}

The issue here is that both statements are in if...else clause.
Let's take the case when temperature is above 24 and humidity is below 10.
The program enters temperature if block, checks the condition, it passes, so it executes the block within the if clause, the one below:
if (Temperature > 24){
digitalWrite(motor, HIGH);
digitalWrite(LedRed, HIGH);
digitalWrite(LedGreen, LOW);
lcd.print("");
Next it checks the condition in humidity if clause, it does not pass because the humidity is below 10 so it executes the else block:
else {
digitalWrite(motor, LOW);
lcd.print("");
}
So the motor does start spining but is almost immediatly stoped by the else block in humidity if...else clause.
To fix this you would need to refactor the code to check both condition with OR ( || ).
If ( Temperature > 24 || Humidty > 10 )
{
//spin
if ( Temperature > 24 )
{
//set LEDs
}
}
else
{
// do not spin
}
You will also require a nested if clause to set the LEDs only in case the Temperature >24.
This way the code will be executed everytime either
Temparature > 24 or Humidty > 10

I would start by inverting logic, the two things that the conditions have in common is that they are both off when they are below threshold, if the condition is met when neither is below threshold then turn on the fans, and then have a nested conditional statement which checks if it's the temperature.
Disclaimer: There is probably a cleaner way of doing this.
//If the temperature or humidity are below threshold then
//turn off the motor and the red LED, and turn on the green LED
if(Temperature <= 24 && Humidity <= 10)
{
digitalWrite(motor, LOW);
digitalWrite(LedRed, LOW);
digitalWrite(LedGreen, HIGH);
}
else //the temperature or humidity are above threshold
{
//turn on the motor
digitalWrite(motor, HIGH);
//if the temperature is above threshold turn off the Green LED
//and turn on the red led
if (Temperature > 24)
{
digitalWrite(LedRed, HIGH);
digitalWrite(LedGreen, LOW);
}
//if the humidity and temperature are both above threshold and the
//temperature falls back below threshold, invert the LEDs.
else
{
digitalWrite(LedRed, LOW);
digitalWrite(LedGreen, HIGH);
}
//clear the LCD
lcd.print("");
}

You literally described required code but you didn't implement it in actual code.
bool MotorRequired = (Temperature > 24) || (Humidity >10);
Or separately:
bool MotorRequired = (Temperature > 24);
MotorRequired = MotorRequired || (Humidity >10);
when reaching point where motor can be used
if(MotorRequired)
// power motor on
else
// power motor off
Which can be shorter branch-free:
digitalWrite(motor, (MotorRequired) ? HIGH : LOW );
That is just same as
if(Temperature > 24 || Humidity >10)
So whole logic looks like
digitalWrite(motor, (Temperature > 24 || Humidity >10) ? HIGH : LOW );
Those conditions are independent but your action depends on BOTH of them, so you have to perform logical operation on both.

Related

How to make an event logger loop work with other loop for arduino uno?

I'm fairly new to this but I've been researching for a while now and no conclusive answer.
How do I make a loop that constantly outputs Serial.println of changes in digitalWrite.
Background info; I am making a traffic light with buttons and pedestrian lights too. I have a sequence for when one of the buttons is pressed but I need a separate loop that outputs changes in lights- which lights are on or which button is pressed. Essentially an event logger that loops throughout the entire script constantly.
**
Sorry, I should have specified; when the button is clicked it goes through a whole sequence, its blocking code. More specifically it's blocking the loop i have for the event logger. How do I work them side-by-side? Whatever I try, it's either the light sequence works or the event logger works but never together. My research indicated that I should use the millis function but I don't know how to implement it.
const int red = 8;
const int yellow = 2;
const int green = 3;
const int p_red = 5;
const int p_green = 6;
const int button1 = 4;
const int button2 = 7;
const int state1 = digitalRead(button1);
const int state2 = digitalRead(button2);
unsigned long waitTime = 500;
void setup() {
pinMode(8, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, INPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, INPUT);
Serial.begin(9600);
}
void loop() {
// turn on the default lights (traffic green and pedestrian red)
digitalWrite(green, HIGH);
digitalWrite(p_red, HIGH);
if(millis() >= waitTime) {
Serial.print("state: ");
Serial.println(state1);
//delay(1000);
}
if(state1 || state2 == HIGH) {
// State 1 // ID Sequence: 3, 5, 6, 1, 5, 2, 10,
digitalWrite(green, HIGH);
digitalWrite(p_red, HIGH);
delay(3000);
digitalWrite(green, LOW);
// State 2
digitalWrite(yellow, HIGH);
delay(5000);
digitalWrite(yellow, LOW);
// State 3
digitalWrite(red, HIGH);
delay(6000);
digitalWrite(p_red, LOW);
// State 4
digitalWrite(p_green, HIGH);
delay(1000);
digitalWrite(p_green, LOW);
// State 5 - Flashing red v 5 cycles (200ms)
for (int x=0+1; x<5; x++) {
digitalWrite(p_red, HIGH);
delay(200);
digitalWrite(p_red, LOW);
delay(200);
} // State 6
digitalWrite(red, HIGH);
digitalWrite(p_red, HIGH);
delay(2000);
// State 7
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(p_red, HIGH);
delay(10000);
// State 8
digitalWrite(green, HIGH);
digitalWrite(p_red, HIGH);
delay(8000);
}
}
the problem with this current code is the if statement for the lights not working

Problem with multiple Parallax PING))) Ultrasonic Sensors

I'm trying to make an AGV(automated guided vehicle) which I wanna use 4 parallax ultrasonic sensors for but there is a problem when I'm using 1 of them its all okay and works perfectly fine, but when I add 1 or more my output on serial monitor says 0cm. I just can't figure it out
I have read lots of forums already but nothing works yet. Here is the code I'm using for 1:
// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 7;
void setup() {
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// establish variables for duration of the ping, and the distance result
// in inches and centimeters:
long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
}
long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are 73.746
// microseconds per inch (i.e. sound travels at 1130 feet per second).
// This gives the distance travelled by the ping, outbound and return,
// so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the object we
// take half of the distance travelled.
return microseconds / 29 / 2;
}
And here when I use more than 1
// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 7;
const int pingPin2 = 6;
const int pingPin3 = 5;
const int pingPin4 = 4;
void setup() {
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// establish variables for duration of the ping, and the distance result
// in inches and centimeters:
long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
digitalWrite(pingPin2, LOW);
digitalWrite(pingPin3, LOW);
digitalWrite(pingPin4, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
digitalWrite(pingPin2, HIGH);
digitalWrite(pingPin3, HIGH);
digitalWrite(pingPin4, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
digitalWrite(pingPin2, LOW);
digitalWrite(pingPin3, LOW);
digitalWrite(pingPin4, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
pinMode(pingPin2, INPUT);
pinMode(pingPin3, INPUT);
pinMode(pingPin4, INPUT);
duration = pulseIn(pingPin, HIGH);
duration = pulseIn(pingPin2, HIGH);
duration = pulseIn(pingPin3, HIGH);
duration = pulseIn(pingPin4, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
}
long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are 73.746
// microseconds per inch (i.e. sound travels at 1130 feet per second).
// This gives the distance travelled by the ping, outbound and return,
// so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the object we
// take half of the distance travelled.
return microseconds / 29 / 2;
}
when I use 1 sensor it gives me the right values like expected and when I use 2 or more sensors the a value of 0cm
thanks i just copy paste the code for a single sensor 4 times after each other and made each of them for another sensor there is just a small delay in each sensor but thats alright. new code is as following:
// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 7;
const int pingPin2= 6;
const int pingPin3 = 5;
const int pingPin4 = 4;
void setup() {
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// establish variables for duration of the ping, and the distance result
// in inches and centimeters:
long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(400);
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin2, OUTPUT);
digitalWrite(pingPin2, LOW);
delayMicroseconds(2);
digitalWrite(pingPin2, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin2, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin2, INPUT);
duration = pulseIn(pingPin2, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(400);
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin3, OUTPUT);
digitalWrite(pingPin3, LOW);
delayMicroseconds(2);
digitalWrite(pingPin3, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin3, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin3, INPUT);
duration = pulseIn(pingPin3, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(400);
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin4, OUTPUT);
digitalWrite(pingPin4, LOW);
delayMicroseconds(2);
digitalWrite(pingPin4, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin4, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin4, INPUT);
duration = pulseIn(pingPin4, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(400);
}
long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are 73.746
// microseconds per inch (i.e. sound travels at 1130 feet per second).
// This gives the distance travelled by the ping, outbound and return,
// so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the object we
// take half of the distance travelled.
return microseconds / 29 / 2;
}

How to display "accident alert" on LCD display after timer times out

I'm making a simple program that that runs traffic lights in a loop and has an ultrasonic sensor and a 16x2 LCD. The concept is that if the ultrasonic reads a distance value equal to or below a preset value it is detecting obstruction in an intersection and it starts a timer. When that timer expires, the LCD display's an alert. But if the distance value goes above the preset value while the timer is active it stops. For the traffic light loop I'm using the standard Arduino "delay" function e.g. delay(3000);. The issue I'm having is the once the timer finishes the LCD does not display anything. For the alert timer in the program I'm using a library called millisDelay. This library allows the timer to run without stopping the program.
I have tried using the millisDelay library to run the traffic lights instead of the standard delay function. But that does not work as it puts the traffic lights in a constant loop.
Libraries used:
millisDelay.h and liquidCrystal.h
#include <millisDelay.h>
#include <LiquidCrystal.h>
int red = 22;
int yellow = 23;
int green = 24;
int red2 = 25;
int yellow2 = 26;
int green2 = 27;
const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 6; // Echo Pin of Ultrasonic Sensor
long duration, inches, cm;
millisDelay alertdelay;
millisDelay ledDelay;
const int rs = 36, en = 38, d4 = 40, d5 = 42, d6 = 44, d7 = 46;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
// put your setup code here, to run once:
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(red2, OUTPUT);
pinMode(yellow2, OUTPUT);
pinMode(green2, OUTPUT);
pinMode(pingPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600); // Starting Serial Terminal
}
void loop() {
lcd.clear();
lcd.begin(16,2);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin, LOW);
duration = pulseIn(echoPin, HIGH);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
if (cm>=11){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
}
else if (cm<7){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
alertdelay.start(7000);
Serial.println("delay started");
}
if (alertdelay.isFinished()) {
Serial.println("There is a crash up ahead");
lcd.setCursor(0,0);
lcd.print("Crash Up Ahead");
lcd.setCursor(0,1);
lcd.print("Use Caution");
}
delay(1000);
//'2'refers to intersection number 2
//green off,red2 on, yellow on for 3 seconds
digitalWrite(red2, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
delay(3000);
// turn off yellow1, then turn red on for 3 seconds
digitalWrite(yellow, LOW);
digitalWrite(red, HIGH);
delay(3000);
//after 3 seconds keep red 1 on and turn red2 off and green2 on,
//green2 stays on for 15 seconds to let traffic through
digitalWrite(red2, LOW);
digitalWrite(green2, HIGH);
delay(15000);
//after 15 seconds green2 turns off, yellow 2 turns on
//yellow2 turns on for 3 seconds,
digitalWrite(green2, LOW);
digitalWrite(yellow2, HIGH);
delay(3000);
//after 3 seconds, yellow2 turns off, and red 2 turns on
digitalWrite(yellow2, LOW);
digitalWrite(red2, HIGH);
delay(3000);
//3 seconds after red2 turns on, red 1 turns off and
//green 1 turns on for 3 seconds
//red2 stays on
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
delay(14000);
}
long microsecondsToCentimeters(long microseconds) {
return microseconds / 29 / 2;
}
These are the issues with what you are doing.
1) The code that you have written takes 42 seconds to iterate through the loop. So you check if the alertDelay has finished once ever 42 seconds.
2) The second time around the code reaches the back to the start of the loop, you first end up setting the alertDelay again before checking if it is running or is finished, which resets it, as such, your code never reaches the part where it displays the crash.
This is how I would have done things
#include <LiquidCrystal.h>
int red = 22;
int yellow = 23;
int green = 24;
int red2 = 25;
int yellow2 = 26;
int green2 = 27;
const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 6; // Echo Pin of Ultrasonic Sensor
long duration, inches, cm;
long alertDisplayTime = millis(), nextLedSwitchTime = millis();
bool displayAlert = false;
int switch_number=-1;
const int rs = 36, en = 38, d4 = 40, d5 = 42, d6 = 44, d7 = 46;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
// put your setup code here, to run once:
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(red2, OUTPUT);
pinMode(yellow2, OUTPUT);
pinMode(green2, OUTPUT);
pinMode(pingPin, OUTPUT);
pinMode(echoPin, INPUT);
lcd.begin(16,2);
Serial.begin(9600); // Starting Serial Terminal
nextLedSwitchTime=1000+millis();
}
void loop() {
lcd.clear();
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin, LOW);
duration = pulseIn(echoPin, HIGH);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
if (cm>=11){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
displayAlert=false;
}
else if ((cm<7)&&(!displayAlert)){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
alertDisplayTime = millis()+7000;
displayAlert=true;
Serial.println("delay started");
}
if ((displayAlert==true)&&(alertDisplayTime<millis())) {
Serial.println("There is a crash up ahead");
lcd.setCursor(0,0);
lcd.print("Crash Up Ahead");
lcd.setCursor(0,1);
lcd.print("Use Caution");
displayAlert=false;
}
if(nextLedSwitchTime>=millis()){
return;
}
long delay_time=0;
switch_number++;
switch(switch_number){
case 0:
//'2'refers to intersection number 2
//green off,red2 on, yellow on for 3 seconds
digitalWrite(red2, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
delay_time=3000;
break;
case 1:
// turn off yellow1, then turn red on for 3 seconds
digitalWrite(yellow, LOW);
digitalWrite(red, HIGH);
delay_time=3000;
//after 3 seconds keep red 1 on and turn red2 off and green2 on,
break;
case 2:
//green2 stays on for 15 seconds to let traffic through
digitalWrite(red2, LOW);
digitalWrite(green2, HIGH);
//after 15 seconds green2 turns off, yellow 2 turns on
delay_time=15000;
break;
case 3:
//yellow2 turns on for 3 seconds,
digitalWrite(green2, LOW);
digitalWrite(yellow2, HIGH);
//after 3 seconds, yellow2 turns off, and red 2 turns on
delay_time=3000;
break;
case 4:
digitalWrite(yellow2, LOW);
digitalWrite(red2, HIGH);
//3 seconds after red2 turns on, red 1 turns off and
delay_time=3000;
break;
case 5:
//green 1 turns on for 3 seconds
//red2 stays on
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
delay_time = 14000;
switch_number=-1;
}
nextLedSwitchTime = millis()+delay_time;
}
long microsecondsToCentimeters(long microseconds) {
return microseconds / 29 / 2;
}
What this code does is it never blocks the loop funciton, so your pusle in function is carried out almost every second along with the check for the crash.
Also, i have set a bit, which tells the code that the alert delay has already started, which ensures that your code does not reset it.

Multiple if statements and

Thanks in advance for your help.
So I'm working on a pressure sensor. The idea is that when the pressure sensor gets to a certain value, say 10 AND then decreases sharply after it has gotten to 10, activate the buzzer. (So it's like, I pump my car tire to 10 and I want to know if there is a leak)
I just for the life of me can not make this happen. I know I'm just missing something very small but I will greatly appreciate any help.
Below is my code:
#include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// These constants won't change: const int analogPin = A0; // pin that the sensor is attached to const int ledPin = 13; // pin that the LED is attached to const int threshold = 5; // an arbitrary threshold level that's in the range of the analog input const int buzzer = 9; // pin that the buzzer is connected to.
void setup() { // initialize the LED pin as an output: pinMode(ledPin, OUTPUT); // initilizes the pin as an output. pinMode(buzzer, OUTPUT); // Set buzzer - pin 9 as an output
// initialize serial communications: Serial.begin(9600); lcd.begin(16, 2); lcd.print ("Pressure in kpa"); }
void loop() { // read the value of the pressure sensor: float sensorValue = analogRead(analogPin); // int kpa = (((sensorValue*5)/1024)*(120/5)-116); // 116 was subtracted to equilibrate the sensor int kpa = ((sensorValue * 5 / 1024) * (15 / 5) * (6.894 / 1) - 10); // // if the analog value is greater than whatever threshold we use , turn on the LED:
if (kpa > threshold )
{
digitalWrite(ledPin, HIGH);
digitalWrite(buzzer, HIGH);
tone(buzzer, 1000); // this controls the picth of the sound. (Hz)
delay(1000); } else {
digitalWrite(ledPin, LOW);
digitalWrite(buzzer, LOW);
noTone(buzzer); // Stop sound...
delay(1000); }
// print the analog value: Serial.println(kpa); delay(1); // delay in between reads for stability lcd.setCursor (0, 1); lcd.print (kpa);
}
Thanks.
I have edited the code to reflect what you are trying to do.
Essentially you need to check if your pressure is increasing or decreasing.
So for this you can take two readings and compare them; one reading is taken before the other. If the latest reading is higher than the previous then its going up, no cause for alarm.
If the latest reading is less that the previous then the pressure is going down. So, cause for alarm but not just yet...
TWO conditions need to be met before the alarm sounds, the pressure needs to be on a downward path AND the pressure needs to be below the threshold value.
kpa must be going down AND be below threshold:
(val < previous && val < threshold)
See if this works, sorry I rushed it a bit and haven't tested it at all:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// These constants won't change:
const int analogPin = A0; // pin that the sensor is attached to
const int ledPin = 13; // pin that the LED is attached to
const int threshold = 5; // an arbitrary threshold level that's in the range of the analog input
const int buzzer = 9; // pin that the buzzer is connected to.
int val = 0; // store value
int previous; // previous reading
void setup()
{
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
pinMode(buzzer, OUTPUT); // Set buzzer - pin 9 as an output
Serial.begin(9600); // initialize serial communications:
lcd.begin(16, 2);
lcd.print ("Pressure in kpa");
}
void loop() {
float sensorValue = analogRead(analogPin); // read the value of the pressure sensor:
int kpa = ((sensorValue * 5 / 1024) * (15 / 5) * (6.894 / 1) - 10);
// we want to check if this is going up or down.
previous = val;
val = kpa;
if (val > previous) {
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, HIGH); // make LED flashy-flashy if its going up
delay(1000);
}
else if (val < previous && val < threshold) {
digitalWrite(ledPin, LOW); // ... and we switch off the LED
tone(buzzer, 1000); // WEE WAH WEE WAH WEE WAH
delay(1000);
}
}
I added a flashing LED to the code because flashing LEDs are just better.
I also used an else...if statement.
Hopefully this will work.
Cheers,
Ingwe.

Distance controlled led

I'm trying to create a distance controlled LED that turns off at a certain distance. I'm using an arduino Leonardo and a distance sensor. At the moment when I plug in my board the led stays on permanently and doesn't turn off when the distance reduces. Please can you tell me what needs changing in order for this to work?
const int TrigPin = 2;
const int EchoPin = 3;
float cm;
int ledPin = 12; //define ledPin12 is the output port of led’s level.
int val = 0; //define original of val.
void setup()
{
Serial.begin(9600);
pinMode(TrigPin, OUTPUT);
pinMode(EchoPin, INPUT);
pinMode(ledPin, OUTPUT); //set ledPin output
}
void loop()
{
digitalWrite(TrigPin, LOW); //Low-high-low level sent a short time pulse to TrigPin
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(TrigPin, LOW);
cm = pulseIn(EchoPin, HIGH) / 58.0; //Echo time converted into cm
cm = (int(cm * 100.0)) / 100.0; // retain two decimal places
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(1000);
val = analogRead(EchoPin); //get the value from sensor
if(val<=1)
{
//512=2.5V, if want the sensor be more sensitive, increase the number, or lese low the number.
digitalWrite(ledPin, HIGH); //when the value of val is less than 512(2.5V), light up led lamp
}
else
{
digitalWrite(ledPin, LOW);
}
}
I am guessing the sensor is similar to an SRF005. You should include that detail in your question.
The trigger looks okay, but there is no harm in pulsing a little longer, say 20 us, to make sure. The capturing of the echo looks right, except that that datasheet I found says to divide by 5.8, not 58.0, and the return value is an unsigned long, not float..
But you shouldn't be using analogRead() on the echo pin. It will be 0 at that point. Rather, you already have the distance in the cm variable.
(There are sensors which use pin voltage to indicate distance as well, but they don't have trigger and echo pins. Which kind are you actually using?)
void loop()
{
int cm = 0;
digitalWrite(TrigPin, LOW); //Low-high-low level sent a short time pulse to TrigPin
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(10); // <<<<<<<<<<<<<<<<<<<<<<<< Change to 20
digitalWrite(TrigPin, LOW);
cm = (int)(pulseIn(EchoPin, HIGH) * 10 / 58); //Echo time converted into cm <<<<<<<<< 5.8 ????
Serial.print(cm);
Serial.print("cm");
Serial.println();
if(cm < 50)
{
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
}
delay(1000);
}