I am new to arduino and am trying to make a for loop in it which just prints "Blink" using Serial.println(); command 3 times, however it isn't working properly and it just prints "Blink" forever and doesn't stop at all. What am I doing wrong in the code below? Would be grateful to any help.
void setup() {
Serial.begin(9600);
}
void loop() {
for(int i=0; i<3; i++){
Serial.println("Blink");
delay(500);
}
}
You put the for-loop inside the loop() function which runs endlessly.
Simply move it to setup():
void setup() {
Serial.begin(9600);
for(int i=0; i<3; i++){
Serial.println("Blink");
delay(500);
}
}
void loop() {
}
The arduino code is not a regular program. you have to keep in mind that the arduino code is an operation system which has to run endlessly Otherwise the arduino will stop. therefore there are 2 functions, the setup() that runs one time and the loop() that runs infinity times.
Related
I have a simple app to count water flux using a sensor that is equipped with a reed switch.
So the app should only count the number of times the switch closes.
My first code was:
const int sensorPin = 2;
volatile int counter = 0;
void setup() {
Serial.begin(115200);
pinMode(sensorPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensorPin), sensorISR, FALLING);
}
void loop() {
Serial.print("Counter: ");
Serial.println(counter);
}
void sensorISR() {
counter++;
}
And once a bottle of 20 liters was full the counter would show something like 120.
Then I changed the code as follows:
const int sensorPin = 2;
volatile int counter = 0;
void setup() {
Serial.begin(115200);
pinMode(sensorPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensorPin), sensorISR, FALLING);
}
void loop() { }
void sensorISR() {
counter++;
Serial.print("Counter: ");
Serial.println(counter);
}
And counter went down to 40 (using the same 20 liters bottle).
The count should be 20L but that is not my problem as it results from bouncing of the reed switch (I will address that latter).
As the project will have 3 sensors and 3 ISRoutines I wonder why putting the Serial.print() command into the main loop can result in such strange results.
Thanks
Paulo
Serial print statements rely on interrupts that are disabled during your ISR. So Serial.print statements don't belong in an ISR.
The reason your count went down is that now your ISR takes longer to execute and it covers up some of the bounce. There are innumerable tutorials on how to debounce something with an Arduino. You can surely find one.
The two easiest are to use a capacitor between the pin and ground for a hardware debounce or to just use millis or micros to note the time that an interrupt occurs and ignore any interrupts that occur within some small time of that.
I am making a smoke detector.
When it detects smoke iz should alert with buzzer.
Is there any way I could make it to buzz forever until external interupt such as restart pin?
Or could I just remove timing from tone() function.
Here is the code I use.
int sensorValue;
int digitalValue;
int green = 8;
int red = 7;
void setup(){
Serial.begin(9600);
pinMode( 0, INPUT);
pinMode(green, OUTPUT);
pinMode(red, OUTPUT);
}
void start(){
digitalWrite(green, HIGH);
}
void loop() {
sensorValue = analogRead(0);
digitalValue = digitalRead(0);
Serial.println(sensorValue,DEC);
Serial.println(digitalValue,DEC);
delay(2000);
if(analogRead(0) < 100){
tone(9,200,1000);
digitalWrite(red,HIGH);
}
}
Playing a sound "forever" is straightforward:
if(analogRead(A0) < 100 ) {
tone(9,2000); // once triggered, will play the sound forever
}
To switch it off, you seem to like the RESET button. So there's no need to ever call
noTone(9);
BTW: what about reading the reference ?
There is lots of ways:
Change your logic that activate the buzzer.
while (analogRead(0) < 100){
tone(9,200,1000);
}
Just use an infinite loop:
while (1) {
tone(9,200,1000);
}
Reset the Arduino to get out of the infinite loop.
An variation on this would be to replace (1) with the code that checks a pin to exit the loop or reads the sensor.
if you're really bent on using interrupts
you didn't specify what board you're working with but
for uno the 2 3 pins can be attached as interrupts and just trigger a function that turns off the tone
check out this:
attachinterrupt
EDITED: I got the program to complete the loop, now it's just that it gives me a bunch of 0's before it completes the loop - so here's an updated version of my code.
Trying to create a program that first turns LEDs on one after one, and once they're all lit up - turns them off one after one, and keeps turning them on and off. I have succeeded in lighting them up and turning them off, but the program seems to get stuck for a bit when it's turned them all off before it completes the loop and starts over.
int t=1000;
unsigned long time;
int pin;
int value;
int a;
int b;
void setup() {
// put your setup code here, to run once:
for(pin=2; pin<8; pin++){
pinMode(pin, OUTPUT);
}
Serial.begin(9600);
}
void more(){
for(int i=1; i<8; i++){
for(pin=i; pin<8; pin++){
digitalWrite(pin,HIGH);
a=bitRead(PORTD,7);
b=bitRead(PORTD,2);
for(pin=2; pin<8; pin++){
value=bitRead(PORTD,pin);
if(value==1){
Serial.print("1 ");
}
else{
Serial.print("0 ");
}
}
Serial.println();
Serial.println();
delay(t);
}
}
}
void less(){
for(int j=7; j>=2; j--){
for(int p=j; p>1; p--){
digitalWrite(p,LOW);
a=bitRead(PORTD,7);
b=bitRead(PORTD,2);
for(pin=2; pin<8; pin++){
value=bitRead(PORTD,pin);
if(value==1){
Serial.print("1 ");
}
else{
Serial.print("0 ");
}
}
Serial.println();
Serial.println();
delay(t);
}
}
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("Time: ");
time=millis();
Serial.println(time);
a=bitRead(PORTD,7);
b=bitRead(PORTD,2);
do{
more();
}while(a==0);
do{
less();
}while(b==1);
}
a=0 is always false and b=1 is always true because they do assignment and evaluated as what is assigned.
Use == operator to compare numbers.
I'm trying to communicate between a Raspberry Pi and Arduino with USB serial, but I only want the Arduino to write when the RPI sends a signal.
My arduino code is as follows:
int sensorPin = A0;
int sensorValue = 0;
void setup(){
Serial.begin(9600);
}
void loop(){
sensorValue = analogRead(sensorPin);
if (Serial.available() > 0) {
Serial.read();
Serial.println(sensorValue,DEC);
Serial.flush();
}
}
Once i do one call from the RPI of:
serial.write('hey')
The arduino writes repeatedly. I thought Serial.available would return 0 most of the time because the buffer is cleared by the read, but it seems like it never gets cleared. I thought flush() might do it but it doesn't really have any effect.
That's odd.. Serial.read() should remove the bytes from the buffer after reading them.
Note: Keep in mind that Serial.read() only reads one byte at a time, this could be your issue since you're sending 'hey' from the Raspberry Pi it'll take 3 iterations of the loop the completely empty the buffer.
If this is not the issue you could try the serialEvent() function wich is called each time something arrives trough serial.
Your code would be like this:
int sensorPin = A0;
int sensorValue = 0;
void setup(){
Serial.begin(9600);
}
void loop(){
//Any other logic here
}
void serialEvent() {
sensorValue = analogRead(sensorPin);
Serial.read();
Serial.println(sensorValue,DEC);
}
By using the serialEvent() event, your loop looks cleaner. That's always nice.
I'm wondering if there are any reasons not to loop inside the loop() function.
To illustrate my question, let's say I want to make a LED blink a thousand times.
Here are two ways to do it with the Arduino.
In the following one, I make sure not to "lock" the loop() function :
const int PIN_LED = 2;
const int BLINKING_LIMIT = 1000;
int blinkCount = 0;
void setup() {
// initialize serial:
pinMode(PIN_LED, OUTPUT);
}
// Here, I make sure not to "lock" the loop() function
void loop() {
blinkCount++;
if (blinkCount < BLINKING_LIMIT) {
digitalWrite(PIN_LED, HIGH);
delay(200);
digitalWrite(PIN_LED, LOW);
delay(200);
}
}
In the second one, there is a long loop (which could last even longer) in the loop() function. The Arduino is "locked" inside the for loop :
// Here, I make sure not to "lock" the loop() function
void loop() {
for (int i = 0; i < BLINKING_LIMIT; i++) {
digitalWrite(PIN_LED, HIGH);
delay(200);
digitalWrite(PIN_LED, LOW);
delay(200);
}
}
What is the best practice ? Should I care not to "lock" the loop() function, or can I just don't care ? Would an infinite loop inside the loop() function be acceptable ?
loop() and setup() are just 2 functions defined for Arduino. It will be compiled with the main code for your board.
The code of the Arduino board will be something like:
void main()
{
setup();
for(;;) {
loop();
}
}
And you just have the possibility to write the code for setup and loop.
It is like #Piglet said. It is your code and you can write it how you want.
You can not "lock" the loop, since it is not an interrupt and there is no OperatingSystem behind your loop.
Once the loop is terminated, it is called automatically again. So you can also write:
void loop()
{
for(;;) {
// your code
}
}
If you like it, so the loop will never terminate and you can write it like on a 8051 processor ;)
Just don't care. Nesting loops is super common practice in programming. Many problems cannot be solved efficiently without it.
It is your program. You may stay within a loop as long as you wish. Your Arduino won't timeout or anything.
Personally, I would use the second code. It's precise and short. Who wants to make the code long and boring. Loop will stop when you want to stop just add a condition, so don't care until and unless your code works perfectly.
If you just want to make a LED blink, it's not important but if you want to add something to your code, the behavior will be different:
void loop() {
blinkCount++;
if (blinkCount < BLINKING_LIMIT) {
digitalWrite(PIN_LED, HIGH);
delay(200);
digitalWrite(PIN_LED, LOW);
delay(200);
}
//ANYTHING ELSE
}
In this part, your LED will blink and the rest of your code will be executed in each 400ms about.
void loop() {
for (int i = 0; i < BLINKING_LIMIT; i++) {
digitalWrite(PIN_LED, HIGH);
delay(200);
digitalWrite(PIN_LED, LOW);
delay(200);
}
//ANYTHING ELSE
}
In this part, your LED will blink "BLINKING_LIMIT" times and only after, the rest of your code will be executed.
Just be careful if you want to add something.