The Firebase function doesn't work for Arduino? - c++

Hope you are well.
I have a problem with my Arduino code.
I have LED_Function() which is working fine, what I want, when I send “ON” from the firebase the LED_Function() is stop working and execute the (DeviceStatus.stringData() == "ON") conditions (continuous working till I send OFF). When I send “OFF”, LED_Function() is stop working and the code execute (DeviceStatus.stringData() == "OFF") conditions. If I didn’t send anything, the LED_Function() is working continuously. Please, I appreciate if you could help me in this matter.
void loop() {
LED_Function();
Firebase.getString(DeviceStatus, "LED_STATUS/LED");
Serial.print("The signal is: ");
Serial.println(DeviceStatus.stringData());
if (DeviceStatus.stringData() == "ON") {
Firebase.setFloat(DeviceStatus, "LED_STATUS/LED", 55);
digitalWrite(led2, HIGH);
digitalWrite(led, LOW);
Serial.println("Led Turned ON");
}
if (DeviceStatus.stringData() == "OFF") {
Firebase.setFloat(DeviceStatus, "LED_STATUS/LED", 55);
digitalWrite(led2, LOW);
digitalWrite(led, HIGH);
Serial.println("Led Turned OFF");
}
}
void LED_Function() {
int Detect = analogRead(SensorRec);
if (isnan(Detect)) {
Serial.println(F("Failed to read from Laser sensor!"));
return;
}
if (Detect < 300) {
Serial.println("Laser Cut. Data is disptched to the Firebase!");
digitalWrite(led5, LOW);
digitalWrite(led7, LOW);
float val = 1.0;
Serial.println(val);
}
else {
float val = 2.0;
digitalWrite(led, HIGH);
digitalWrite(led7, HIGH);
Serial.println(val);
}
}
Thanks in advance........

Related

Read a Flashing Led in Arduino

So it's a simple problem, I have several LEDs on a board where depending on their states it will trigger a command to fire a relay. Where I am stuck is figuring out how to get the Arduino to see a blinking LED, I have tried to bypass it all together but the code got larger than we wanted so it was scrapped and I am starting all over. Any ideas would be most helpful. Here is the basic code:
int Relay = 2;
int Led = 7;
int Ball = 8;
void setup()
{
Serial.begin(115200);
pinMode(Relay, OUTPUT);
pinMode(Led, INPUT);
pinMode(Ball, OUTPUT);
}
void loop()
{
digitalWrite (Relay, HIGH);
delay (500);
digitalWrite (Relay, LOW);
delay(300);
digitalRead(Led);
if(Led == HIGH)
{
digitalWrite(Ball, HIGH);
}
if(Led == LOW)
{
digitalWrite(Ball, LOW);
}
}
digitalRead(Led) throws away the value you are reading, and if (Led == LOW) is comparing a pin number with a voltage level, which is meaningless. You mean:
level = digitalRead(Led);
if (level == HIGH) { ...

Arduino - Running an if condition for a certain amount of time

Currently working on a project where I need to turn on the motor for just 1 second if my rain sensor detects any rain. if no rain I will again rote backward for 1 second.
sensor and device that I'm using
Arduino MEGA
Rain Sensor
L298N Motor driver
but the problem is I'm unable to run the condition for 1 second.
Here is my current Arduino sketch
const int IN1 = 7;
const int IN2 = 6;
const int ENA = 9;
const int capteur_A = A0;
int val_analogique;
void setup() {
Serial.begin(9600);
pinMode(capteur_A, INPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (ENA, OUTPUT);
}
void forward(){
analogWrite(ENA, 60);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}
void loop() {
val_analogique=analogRead(capteur_A);
Serial.println(val_analogique);
if(val_analogique<=300){
forward();
Serial.println("Going Forward");
}
else{
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}
}
To let the Motor rotate for 1 second, you just have to wait and then stop it. You can use the delay() function to wait a specific number of milliseconds. The forward function would be:
void forward() {
analogWrite(ENA, 60); // Set power and direction for the motor
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
delay(1000); // Wait for 1000 milliseconds
digitalWrite(ENA, 0); // Stop the motor
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}
And for the other direction it would be exactly the same, just with the two direction ports swapped:
void backward() {
analogWrite(ENA, 60); // Set power and direction for the motor
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
delay(1000); // Wait for 1000 milliseconds
digitalWrite(ENA, 0); // Stop the motor
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}
Oh, and by the way, it would also be nice to call the ports OUT and not IN, as they're outputs and not inputs :)
You have to implement a simple state machine pseudo code as a starter:
long timer = 0;
bool conditionRain = false;
bool conditionNoRain = true;
setup() {}
loop() {
...
if(val_analogique<=300 && conditionRain == false) { // Condition rain detected
timer = millis(); // we start the timer
conditionRain = true; // set the state
conditionNoRain = false; // set the state
}
if (conditionRain == true && millis()-timer < 1000) { // Here is the timer check
... do motor for rain ...
}
// Assumption Since the motor should run for one second when the rain stops
if(val_analogique>=850 && conditionNoRain == false){ // Condition rain detected
timer = millis();
conditionRain = false; // set the state
conditionNoRain = true; // set the state
}
if (conditionNoRain == true && millis()-timer<1000){ // Here is the timer check
... do motor for no rain ...
}
Simple switching between states with timer function -there is no else because we always check the states if these are not fulfilled nothing should happen

Segmentation fault with wiringPi

I'm fairly new to coding, and I've been trying to write something to write a placeholder to a text document whenever a button attached to a GPIO pin on my RasPi is pressed:
//Write date function//
void record() {
ofstream myFile;
myFile.open("report.txt");
myFile << "Input at SPAM \n";
myFile.close();
}
//myRead function//
void myRead(int i){
if((digitalRead(4) == HIGH) && (i<5)) {
record();
digitalWrite(14, HIGH);
delay(500);
digitalWrite(14, LOW);
++i;
delay(500);
myRead(i);
}
else{
if((digitalRead(4) != HIGH) && (i<5)){
myRead(i);
}
}
}
int main() {
wiringPiSetup();
pinMode(12, OUTPUT);
pinMode(14, OUTPUT);
pinMode(4, INPUT);
digitalWrite(12, HIGH);
digitalWrite(14, LOW);
myRead(1);
digitalWrite(14, HIGH);
delay(5000);
digitalWrite(14, LOW);
return 0;
}
The code compiles without any complaints, but if I run it in terminal without a sudo command, I get a "segmentation fault" error.
When I run it with a sudo command, the program starts and then ends almost immediately.
For reference:
Pin 12 is providing power to a potential divider on the breadboard.
Pin 4 should take the input from this divider.
Pin 14 causes an LED to light whenever there is an input on pin 4.
Whenever I run the program and VERY QUICKLY press the button on the potential divider, the LED will light if I hold the button.
How can I get this to run properly without it stopping as soon as it starts?
I think there are several possible problems with myRead.
A minor rewrite could be:
void myRead(int i)
{
if((digitalRead(4) == HIGH) && (i<5)) {
record();
digitalWrite(14, HIGH);
delay(500);
digitalWrite(14, LOW);
++i;
delay(500);
myRead(i);
} else if((digitalRead(4) != HIGH) && (i<5)) {
myRead(i);
}
}
Notice that you have two calls to digitalRead -- this may lead to problems since the first one my return something different from HIGH and the second may return HIGH, meaning neither conditions are true.
You make a call to myRead with the same i in the alternative branch as the original call. If digitalRead returns something different from HIGH suffeciently many times, your stack will be full very fast and you'll get a segfault.
I'll propose a different version, that should be identical (baring any misunderstanding on my part):
void myRead(int i)
{
// as long as i is less than 5
while (i < 5) {
// busy wait for digitalRead(4) to be HIGH
while (digitalRead(4) != HIGH);
// do the main thing
record();
digitalWrite(14, HIGH);
delay(500);
digitalWrite(14, LOW);
++i;
delay(500);
}
}
Also please note that this is just plain C, not C++ (well, technically it's valid C++, but it's making no use of C++)

Stuck before delay in sub program

I have the task to program two timers, where I display something on my LCD-Display. I have a matrix keyboard where I can type in some basic things like numbers and some letters with this code:
void keyboard_read()
{
digitalWrite(s1, LOW);
digitalWrite(s2, HIGH);
digitalWrite(s3, HIGH);
digitalWrite(s4, HIGH);
if(digitalRead(r1) == LOW){lcd.print("1"); delay(200);k++;feld[k]=1;}
if(digitalRead(r2) == LOW){lcd.print("4"); delay(200);k++;feld[k]=4;}
if(digitalRead(r3) == LOW){lcd.print("7"); delay(200);k++;feld[k]=7;}
if(digitalRead(r4) == LOW){lcd.print("A"); delay(200);k++;feld[k]='A';}
digitalWrite(s1, HIGH);
digitalWrite(s2, LOW);
digitalWrite(s3, HIGH);
digitalWrite(s4, HIGH);
if(digitalRead(r1) == LOW){lcd.print("2"); delay(200);k++;feld[k]=2;}
if(digitalRead(r2) == LOW){lcd.print("5"); delay(200);k++;feld[k]=5;}
if(digitalRead(r3) == LOW){lcd.print("8"); delay(200);k++;feld[k]=8;}
if(digitalRead(r4) == LOW){lcd.print("0"); delay(200);k++;feld[k]=0;}
digitalWrite(s1, HIGH);
digitalWrite(s2, HIGH);
digitalWrite(s3, LOW);
digitalWrite(s4, HIGH);
if(digitalRead(r1) == LOW){lcd.print("3"); delay(200);k++;feld[k]=3;}
if(digitalRead(r2) == LOW){lcd.print("6"); delay(200);k++;feld[k]=6;}
if(digitalRead(r3) == LOW){lcd.print("9"); delay(200);k++;feld[k]=9;}
if(digitalRead(r4) == LOW){lcd.print("B"); delay(200);k++;feld[k]='B';}
digitalWrite(s1, HIGH);
digitalWrite(s2, HIGH);
digitalWrite(s3, HIGH);
digitalWrite(s4, LOW);
if(digitalRead(r1) == LOW){lcd.print("F"); delay(200);k++;feld[k]='F';}
if(digitalRead(r2) == LOW){lcd.print("E"); delay(200);k++;feld[k]='E';}
if(digitalRead(r3) == LOW){lcd.print("D"); delay(200);k++;feld[k]='D';}
if(digitalRead(r4) == LOW){lcd.print("C"); delay(200);k++;feld[k]='C';}
}
When I type in the first Timer (Timer0) keyboard_read() works just fine, but when I go into the second Timer (Timer2) keyboard_read() stops at the delay command. When I tried to put keyboard_read() in the loop() it still stops at the delay command (There isn't this command in the loop at the moment).
Code for Timer0:
ISR(TIMER0_COMPA_vect) //Durchlaufendes Menü
{
cnt0++;
//Tastatureingabe_______________________________________________________________
keyboard_read();
if(feld[k]=='A') //Abfrage nach AutoStart
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("AutoStart");
TCCR0B = 0x00; //Timer0 ausschalten
TCCR2B = 0x07; //Timer2 einschalten
}
else if(feld[k]=='E') //Abfrage nach Einstellungen
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("Einstellungen");
TCCR0B = 0x00; //Timer0 ausschalten
//TCCR1B = 0x00; //Timer1 einschalten (not declared yet)
k=0;
}
else if((feld[k]!=NULL)) //Falsche Eingabe Abfrage
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("Falsche Eingabe");
} //other things are not necessary
Code for Timer2:
ISR(TIMER2_COMPA_vect) //Ausgabe der Parameter
{
cnt2++;
loop();
//Tastatureingabe_________________________________________________________
keyboard_read();
if(feld[k]=='B') //Abfrage nach AutoStart
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("Zuruek");
TCCR0B = 0x0D; //Timer0 einschalten
TCCR2B = 0x00; //Timer2 ausschalten
}
else if((feld[k]!=NULL))
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("Falsche Eingabe");
}
Do I have to change something in the keyboard_read() sub program or the Timers to make it work?
Thanks in advance for any help.
You can read long article about interrupts: How do interrupts work on the Arduino Uno and similar boards? on Arduino SE by Nick Gammon
And in short:
Interrupt must be as short as possible. If you need delay, you are doing it wrong and you can handle it in loop later. Just set some flag (or you can use COMPA overflow flag directly without its interrupt, you just have to check this flag and clear it by writing logic 1 into it)
You can't use Arduinos delay as it needs Timer/Counter 0 overflow interrupt running. And all interrupts are blocked in the ISR handler automatically. So you are waiting for changing millis that never happen.
Also you can't use anything else that could relly on another interrupt. For example Serial.write/print works until the send buffer gets filled and then deadlock will appear.
Why are you calling loop()? It'll return back to the interrupted code right after the handler finishes the job.

Arduino blinking led issue

Ok, so I have started my Project 2 on Arduino Uno. It involves 3 blinking leds. The original idea is that the green led will be lit until a switch is pressed which will make the other two leds blink consecutively. However, I have tried to make the green led keep blinking until I press the switch (instead of it just being lit passively prior to the pressing of the switch). So I made one small adjustment to the if statement, however this didn't work (the led blinked once and then continued being lit).
int switchState=0;
void setup() {
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(2, INPUT);
// put your setup code here, to run once:
}
void loop() {
switchState= digitalRead(2);
if (switchState==LOW) {
digitalWrite(3, HIGH);
delay(1000);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
else {
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5, HIGH);
delay(250);
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
delay(250);
}
// put your main code here, to run repeatedly:
}
The green LED is assigned to pd3 and the two other leds to pd4 and pd5.
So why, upon the verification of the condition, (whether the switch was pressed or not), does the led blink only once- shouldn't it continue blinking? However when I inserted another delay after the 2nd digitalWrite(3, LOW), it worked. Whats the explanation for this? I'm new to this so please make your explanation clear.
Case 1:
The user does not press switch the switch for at least > delay(1000); to run again.
In this section:
switchState= digitalRead(2);
if (switchState==LOW) // <---- User is not pressing switch so we
{ // enter the if.
digitalWrite(3, HIGH);
delay(1000);
digitalWrite(3, LOW);
// Adding delay here makes it blink.
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
Once you have done the digitalWrite(3, LOW); , it is in micro/miliseconds before the loop is repeated and you enter the if again. The LED actually did blink, but it is so fast you can't see it. The LED would stay on as long as the user didn't press the the button.
Case 2:
User pressed button and after running through the if statement at least once. The LED is left OFF as it enters the else.
else
{
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5, HIGH);
delay(250);
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
delay(250);
}
The LED is set again to LOW and then remains OFF.
Does that help?