How to clear the bytes of Serial interface in an Arduino? - c++

I'm trying to interrupt the serial monitor to execute a certain function and continue with the previous function after completion of the interrupted function, my code is as bellow
#define red1 13
#define amber1 12
#define green1 11
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(red1, OUTPUT);
pinMode(amber1, OUTPUT);
pinMode(green1, OUTPUT);
}
void Delay(int sec) {
for(int i=0;i<sec;i++){
if (Serial.available())
{
Button();
break;
}
delay(1);
}
}
void Light()
{
digitalWrite(red1,HIGH);
Delay(5000);
digitalWrite(red1,LOW);
digitalWrite(amber1,HIGH);
Delay(5000);
digitalWrite(amber1,LOW);
}
void Button()
{
digitalWrite(red1,LOW);
digitalWrite(amber1,LOW);
digitalWrite(green1,HIGH);
delay(1000);
digitalWrite(green1,LOW);
}
void loop()
{
Light();
}
Whenever I enter a value in serial monitor Button() function is executed, it should end as soon as function completes due to a break, but this function keeps repeating continuously? How can I fix this such that whenever a serial monitor is interrupted, Button() is executed onetime and then continues with Light().
I tried using a break but the serial interface buffer is not cleared so its keep continuing this function also it exits if loop, so I tried using return
void Delay(int sec) {
for(int i=0;i<sec;i++){
if (Serial.available())
{
Button();
return;
}
delay(1);
}
}
the same thing happens
the function doesn't exit it keeps repeating the same since the serial interface is not cleared from an earlier encounter, I could've used serial.available in void loop() but whenever Arduino is at delay function its sleeping so it doesn't read a serial interrupter, so I created separate Delay()
so how can I change the code to end this function and go back to Light()

but the serial interface buffer is not cleared
Then you have to clear it:
while (Serial.available())
Serial.read(); // remove 1 character

Related

Arduino, code hangs in weird way when a function is invoked

I have the following code behaving in a weird way, when I make a method call
#include <TimerOne.h>
#include <cppQueue.h>
#include <Arduino.h>
typedef struct Diagnostic {
String entityName;
uint16_t pin;
} Diag;
// Global setup
cppQueue q(sizeof(Diag *), 10, FIFO, false);
int ctr = 0;
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
}
// Add to queue
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(2000); // wait for a second
Serial.println("After high");
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
// Critical Section
Diag d;
Serial.println("String assignment");
d.entityName = "Front Door";
d.pin = LED_BUILTIN;
d_ptr = &d;
Serial.println("Enqueuing one");
q.push(&d);
Serial.println("Enqueued one");
Serial.println(freeMemory());
//q.pop(&d);
//Serial.println("Dequeued one" + d.entityName);
DequeueIsr();
//Serial.println("Atomic block");
//Serial.println(q.getCount());
//Serial.println("Loop end");
}
void DequeueIsr() {
Diag di;
if (!q.isEmpty())
{
Serial.println("Queue not empty");
q.pop(&di);
Serial.println("Dequeued one" + di.entityName);
Serial.println(freeMemory());
}
}
Whenever I try to pop my object in the DequeueIsr function, the code hangs after 2 or 3 iterations, there is no output on the serial monitor after that. If I just copy the code in the Dequeue method and run it in the main loop it works, it doesn't get stuck. Also this happens when I work with strings, if I remove the entityName field from Diag, it works inside the method.
Am I missing something crucial ?
What I really wanted to do was, dequeue the queue using an interrupt method using the TimerOne library. I have removed all timer related code and even a simple method call isn't working.
It looks like cppQueue copies objects using memcpy so it only works with trivially copyable objects, String is not trivially copyable so your code has undefined behaviour

Set up loop keeps looping (Adurino)

I am currently troubleshooting a code in Arduino for a temperature and humidity project. There is a line in the void setup(), Serial.println("Feather LoRa TX Test!");, which keeps popping up. My ideal code is to run that particular line once in the output and that will be it. However, the current code keeps repeating that line again, and again. May I know how do I rectify this issue (The whole code is below)? Thanks in advance!!
#include <RH_RF95.h>
#include <DHT.h>
#define DHTPIN 7 // what digital pin we're connected to
#define DHTTYPE DHT22 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
#define RFM95_CS 10
#define RFM95_RST 9
#define RFM95_INT 3
// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);
int node = 3; // to change based on node deployment
void setup()
{
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
while (!Serial);
Serial.begin(9600);
delay(100);
Serial.println("Feather LoRa TX Test!");
digitalWrite(RFM95_RST, LOW);
delay(100);
digitalWrite(RFM95_RST, HIGH);
delay(100);
while (!rf95.init()) {
Serial.println("LoRa radio init failed");
while (1);
}
Serial.println("LoRa radio init OK!");
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
if (!rf95.setFrequency(RF95_FREQ)) {
Serial.println("setFrequency failed");
while (1);
}
Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);
dht.begin();
rf95.setTxPower(23, false);
}
void loop()
{
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
delay(1000);
return;
}
String d = "{\"Node\":"+ String (node) +",";
d += "\"Temp\":"+ String (t)+",";
d += "\"Hum\":"+ String (h);
d += "} "; // Add a trailing space is necessary
Serial.println("Transmitting...");
char data[d.length()];
d.toCharArray(data,d.length());
Serial.println(d);
rf95.send((uint8_t*)data, sizeof(data));
Serial.println("Waiting for packet to complete...");
delay(1000);
rf95.waitPacketSent();
Serial.println(" complete...");
delay(57000); // delay 1 minute
}
You have an infinite loop before you do any initialization. This will be detected because Arduino have a watchdog timer, and the system will reset.
And on reset setup is called again, and you again enter the infinite loop.
The loop it's about:
while (!Serial);
You must call Serial.begin(...) before that loop:
Serial.begin(9600);
while (!Serial);
Something is resetting your MCU before the code reaches the loop function. Therefore the setup function gets executed again and again. You can add more print messages in between lines so you'll know where it breaks.

Arduino, potentiometer goes crazy

I am executing a block of code every certain period of time. The time is indicated by the value of the potentiometer. Everything works well. But in some parts of the potentiometer it is as if the value were 0 or a very low number that makes the code block run continuously.
Here the piece of code:
const int p = A0;
unsigned long t = 0;
void start(){
Serial.begin(9600);
}
void loop(){
if(millis() > t+(analogRead(p)*100)){
t = millis();
Serial.println("Something...");
}
}
Your start() function is wrong, it should be setup() and should include pin mode declaration.
void setup(){
Serial.begin(9600);
pinMode(p, INPUT);
}

How to break the loop in an Arduino?

I'm trying to write a simple program in Arduino, blinking of a LED.
Program is as shown below.
#define red1 13
#define amber1 12
#define green1 11
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(red1, OUTPUT);
pinMode(amber1, OUTPUT);
pinMode(green1, OUTPUT);
}
void Delay(int sec) {
for(int i=0;i<sec;i++){
if (Serial.available())
{
Button();
break;
}
delay(1);
}
}
void Light()
{
digitalWrite(red1,HIGH);
Delay(5000);
digitalWrite(red1,LOW);
digitalWrite(amber1,HIGH);
Delay(5000);
digitalWrite(amber1,LOW);
}
void Button()
{
digitalWrite(red1,LOW);
digitalWrite(amber1,LOW);
digitalWrite(green1,HIGH);
delay(1000);
digitalWrite(green1,LOW);
}
void loop()
{
Light();
}
When ever I enter a value in serial monitor Button() function is executed, it should end as soon as function completes due to a break, but this function keeps repeating continuously? How can I fix this such that whenever a serial monitor is interrupted, Button() is executed onetime and then continues with Light().
Try to replace
break;
with
return;
This will terminate the function instantly since you won't be executing other statements after the loop.
You can look at https://www.arduino.cc/reference/en/language/structure/control-structure/return/ for more info about return
As some others have briefly alluded to, you call Button many times due to the fact that you don't clear the serial interface.
Right now what happens is Delay is called, and let's say there's information available on the interface, then you call Button and break as expected, but since you don't clear the interface by reading the available information, you call Button again on the next call to Delay.
To fix this, you need to read the information from the serial interface either in the Button function or in the if statement before calling Button.

Arduino Loop Error: Waits several seconds to respond to input change

I am trying to write a simple control program for an Arduino Uno for an experiment I'm running at work. Quite simply it just needs to read if an input pin is high, if it is wait 10 milliseconds to turn an output pin high, hold for 10 milliseconds then go low, else the output pin is low.
My problem is that when I run this it ignores the initial delay altogether, and the output pin stays high for several seconds before going low. (using delayMicroseconds)
void setup()
{
pinMode(8, INPUT);
pinMode(13, OUTPUT);
}
void loop()
{
if (digitalRead(8) == HIGH)
{
delayMicroseconds(10000); //wait 10 milliseconds
digitalWrite(13, HIGH); // Pump on
delayMicroseconds(10000); // holds for pulse width of 10 millisecond
digitalWrite(13, LOW); // Pump off
}
else
{
}
}
I've tried setting up something simpler for debugging using the delay function to wait for a second, then turn output pin high, wait for a seconds, then turn output pin low. I did this so I could visually debug using the arduino's built in LED. the result is that it actually continues to run the loop 3 times after the input pin goes low. (using delay)
void setup()
{
pinMode(8, INPUT);
pinMode(13, OUTPUT);
}
void loop()
{
if (digitalRead(8) == HIGH)
{
delay(1000); //wait 1 second
digitalWrite(13, HIGH); // Pump on
delay(1000); // hold for 1 second
digitalWrite(13, LOW); // Pump off
}
else
{
}
}
I can't seem to figure out why it's doing this. I've looked all over and can't seem to find information about why this would happen. I might be missing something really simple, I am not an experienced coder, I just write what I need to run experiments. I've tried reading and writing to the pin register directly using c code, and switching from an if statement to a while loop, none of them fixed the problem. Any insight is greatly appreciated.
You should look at the internal pull-up resistors on the Arduino. You can debounce the signal from your button entirely with software:
void setup() {
pinMode(2, INPUT_PULLUP);
}
void loop() {
if (digitalRead(2) == LOW) // NOTE THAT PULLUPS REVERSE YOUR LOGIC
{
delay(1000); //wait 1 second
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
}
}