Arduino code — what's the use of while(0)? - c

const int buttonPin = 2;
int buttonState = 0;
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
Serial.println("1");
buttonState=LOW;
delay(20000);
while(0);
}
}
Basically the code works like this:
the number of the pushbutton pin
variable for reading the pushbutton status
initialize the pushbutton pin as an input:
read the state of the pushbutton value:
check if the pushbutton is pressed. If it is, the buttonState is HIGH:
send char 1 via Bluetooth:
I have an Arduino, HC 06 bluetooth module, a button and an app that makes a phonecall when the button is pressed (HC 06 send a byte, 1, to the app)
My question is, what's the while (0); for?
----ORIGINAL CODE----
const int PirSensor = 2;
int motionState = 0;
void setup() {
Serial.begin(9600);
pinMode(PirSensor, INPUT);
}
void loop() {
motionState = digitalRead(PirSensor);
if (motionState == HIGH) {
Serial.println("1");
motionState = LOW;
delay(20000);
// while(0);
}
}

Well if I am not mistaken in this case nothing.
In most computer programming languages, a while loop is a control flow statement that allows code to be executed repeatedly based on a given Boolean condition. The while loop can be thought of as a repeating if statement.
Note that if you do have a condition, a while loop must have an exit option, like this:
const int buttonPin = 2;
int buttonState = 0;
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
Serial.println("1");
buttonState=LOW;
delay(20000);
int a =0;
while(a==0){
if (something)
a=1;
}
}
}
Then on your chosen condition you will exit the loop.

while(0) is most commonly used in macro definitions, specifically in those which are meant to be used like void functions or other instructions, like
#define inc(x) do { x = ((x)+1); } while (0)
The reason to use it is simply to make the use of the macro look like an invocation of a function by forcing the user to append a ; to the macro invocation. In the above example,
inc(a)
a = a*2;
would cause a compile error due to the missing ; after the while(0) the macro expands to, so you have to write
inc(a);
a = a*2;
which makes the code look more like inc was a function. Also, embedding the macro's code in a loop like this helps in preventing accidental use of the macro as an expression, akin to a void function. ( a = ((a)+1) is a valid expression, so b = inc(a) would be valid too (expands to b = a = ((a)+1)) if the macro did not contain the (semantically irrelevant) while loop.)

Related

Arduino serial monitor not showing anything

I'm doing a code where the timer gets triggered by a pushbutton. The problem is that nothing happens, the serial monitor doesn't show anything. I've checked all of the connections and there is no errors in the electronic components. I'm not sure what is wrong.
Thankyou
Here's the code:
int timer;
const int starttrigger = 2;
const int endtrigger = 4;
void setup() {
pinMode(starttrigger, INPUT);
pinMode(endtrigger, INPUT);
pinMode(redled, OUTPUT);
pinMode(greenled, OUTPUT);
}
void loop() {
int start_button_state = digitalRead(starttrigger);
int end_button_state = digitalRead(endtrigger);
if (start_button_state == HIGH) {
while (end_button_state == LOW){
for(timer = 0; end_button_state == HIGH; timer ++) {
Serial.println(timer);
}
}
}
}
You do not see anything in the serial monitor because you have not activating Serial communication in the first place. It needs to be done in the void setup() function.
Please add this line to your void setup function
Serial.begin(9600);

Delay within a timer (what is the correct approach)

I'm in a pickle regarding concepts relating to timers. How can I can I operate a "delay" inside a timer? This is the best way I can frame the question knowing full well what I'm trying to do is nonsense. The objective is: I wish to test the pinState condition 2 times (once initially and then 4 seconds later) but this all needs to happen periodically (hence a timer).
The platform is NodeMCU running a WiFi (ESP8266 chip) and coding done inside Arduino IDE.
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer timer;
char auth[] = "x"; //Auth code sent via Email
char ssid[] = "x"; //Wifi name
char pass[] = "x"; //Wifi Password
int flag=0;
void notifyOnFire()
{
int pinState = digitalRead(D1);
if (pinState==0 && flag==0) {
delay(4000);
int pinStateAgain = digitalRead(D1);
if (pinStateAgain==0) {
Serial.println("Alarm has gone off");
Blynk.notify("House Alarm!!!");
flag=1;
}
}
else if (pinState==1)
{
flag=0;
}
}
void setup()
{
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
pinMode(D1,INPUT_PULLUP);
timer.setInterval(1000L,notifyOnFire);
}
void loop()
{
//Serial.println(WiFi.localIP());
Blynk.run();
timer.run();
}
an easy fix would be to set the periodicity of the timer to be 4000L timer.setInterval(4000L,notifyOnFire); and in notifyOnFire use a static variable and toggle its value whenever notifyOnFire is called
void notifyOnFire()
{
static char state = 0;
if( state == 0)
{
/* Write here the code you need to be executed before the 4 sec delay */
state = 1;
}
else
{
/* Write here the code you need to be executed after the 4 sec delay */
state = 0;
}
}
The nice thing about static variables is that they are initialized only once at compile time and they retain their values after the scope of code changes (In this case function notifyOnFire exits).

Arduino Interrupt with One Button

I am using Arduino Uno, I try to run servo constantly from 0 to 45 degrees when the interrupt button is pressed it should go to -30 degree and wait here. When the same button is pressed again, it should resume the constant action, which is swiping 0 to 45 degrees without <servo.h> library.
I tried to run like this:
const int servo = 11;
const int led = 13;
const int buttonPin = 2;
volatile int buttonState = 1;
void setup() {
Serial.begin(57600);
pinMode(led, OUTPUT);
pinMode(servo, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin),Button,CHANGE);
}
void loop() {
digitalWrite(led,HIGH);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1500);
digitalWrite(servo,LOW);
delayMicroseconds(18500);
}
delay(2000);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1000);
digitalWrite(servo,LOW);
delayMicroseconds(19000);
}
delay(2000);
}
void Button()
{
digitalWrite(led,LOW);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1833);
digitalWrite(servo,LOW);
delayMicroseconds(18167);
}
}
I have no problem coding my own PWM for each case but it turns out, the problem is a bit complicated than I was expecting because when we try to resume, I need to disable the interrupt function when pressing the same an interrupt button somehow.
Is it possible in this way or is there a better way to implement it?

The ISR executed once even when the event not happened

I am using PIC24FJ128GA204 microcontroller in PIC24F Curiosity Development Board.
The ISR is executed at least once even when the event not happened.
Here is the code:
#include <xc.h>
int Random_mode_condition=0;
void __attribute__((__interrupt__, __shadow__)) _INT1Interrupt(void) {
Random_mode_condition = 44;
_INT1IF = 0;
}
void RC9_Switch_Config() {
_TRISC9 = 1; // Switch input
RPINR0bits.INT1R = 25;
IFS1bits.INT1IF=0;//Clear the interrupt flag
IPC5bits.INT1IP1=1;//Choose a priority
INTCON2bits.INT1EP=0;//rising edge
IEC1bits.INT1IE=1;//enable INT1 interrupt
}
int main() {
LATC=0x0000;
RC9_Switch_Config();
while(1){
if(Random_mode_condition==44){ TRISC=0x0000; LATC=0xffff;}
}
return 0;
}
Random_mode_condition will equal 44 then the if statement will be executed.
Please help

Move robot set number of steps (Arduino)

I want to move my robot a set number of steps and then have it stop. However the loop just seems to run on infinitely. Is there a mistake in the way that I am using void loop() or perhaps in the way that I have written my 'for' loop?
// walkerForward.pde - Two servo walker. Forward.
// (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
// updated - Joe Saavedra, 2010
#include <Servo.h>
Servo frontServo;
Servo rearServo;
int centerPos = 90;
int frontRightUp = 75;
int frontLeftUp = 120;
int backRightForward = 45;
int backLeftForward = 135;
void moveForward(int steps)
{
for (int x = steps; steps > 0; steps--) {
frontServo.write(centerPos);
rearServo.write(centerPos);
delay(100);
frontServo.write(frontRightUp);
rearServo.write(backLeftForward);
delay(100);
frontServo.write(centerPos);
rearServo.write(centerPos);
delay(100);
frontServo.write(frontLeftUp);
rearServo.write(backRightForward);
delay(100);
}
}
void setup()
{
frontServo.attach(2);
rearServo.attach(3);
}
void loop()
{
moveForward(5);
}
the loop() function is executed within an infinite loop (if you check the main cpp file that ships with the Arduino IDE, you'll see something like this:
int main()
{
setup();
for (;;) {
loop();
}
return 0;
}
So either put the call to your moveForward() function to setup() and make loop() an empty function, or call exit(0); from within loop() after moveForward(). The first approach looks like this:
void setup()
{
frontServo.attach(2);
rearServo.attach(3);
moveForward(5);
}
void loop()
{
}
And the second one looks like this:
void setup()
{
frontServo.attach(2);
rearServo.attach(3);
}
void loop()
{
moveForward(5);
exit(0);
}
Since you probably will want to eventually do more than move the robot just 5 steps, I'd suggest using a variable flag to hold the robot state. It only executes the movement routine when the flag has been set to true.
If you are using serial, when a move command is received (and the number of steps, direction perhaps?) you set the flag to true and then issue the move command. If you are using sensors or buttons, the same logic applies.
You will need some logic to handle an incoming movement command while a movement is occurring (though with your tight movement loop you actually won't be able to respond to incoming commands unless you use interrupts - but you want to consider this sort of thing if you are planning to build out a full movement bit of firmware).
boolean shouldMove;
void setup()
{
shouldMove = true;//set the flag
}
void loop()
{
if (shouldMove){
moveForward(5);
}
}
void moveForward(int steps)
{
shouldMove = false; //clear the flag
for (int x = steps; steps > 0; steps--) {
// tight loop controlling movement
}
}
}

Resources