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?
Related
I have a really simple code that is not behaving how I would expect it to.
Here's the code:
int i;
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
}
void loop() {
//digitalWrite(13, HIGH);
i = random(1,5);
Serial.println(i);
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
}
With this code the LED only blinks when Serial Monitor is on and stays on while Serial Monitor is off. Another problem I have is that if I comment out the current digitalWrite(LED_BUILTIN, HIGH) and replace it with the one I have commented out then the LED wont blink even if Serial Monitor is off.
I have Arduino Micro
If you want to blink a LED, you need to add an extra delay when the LED is going from OFF to ON.
Currently you have:
LED ON -> wait -> LED OFF -> (instantly) LED ON -> wait etc
So what you see is just the LED continuously ON, to make it work add another delay(1000) before digitalWrite(13, HIGH) for example:
int i;
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
}
void loop() {
//digitalWrite(13, HIGH);
i = random(1,5);
Serial.println(i);
delay(1000);
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
}
I tested it on my Arduino Nano and it worked fine.
Note: The code is designed to run on a Particle Photon. Please keep this in mind while reading my question.
I want to make a led blink based on a variable called blink_type this variable will be changed dynamically in a later stage when I implement the API call to fetch the status of something else. I'm currently simulating this behaviour in the loop() function (also tried a thread but that also didn't work).
The blinking works fine until the variable changes from 0 to 1, after that it never blinks again until I do a reset.
Below you will find my code:
// This #include statement was automatically added by the Particle IDE.
#include <httpsclient-particle.h>
// Base variables.
int led = D0;
int buzzer = D1;
// Defining blink types. 0 is normal, 1 is breathe.
int blink_type = 0;
// Set the threads
Thread *normalBlinkThread;
Thread *ledBreatherThread;
void setup() {
// Setup the outputs.
pinMode(led, OUTPUT);
pinMode(buzzer, OUTPUT);
// Create the required threads.
normalBlinkThread = new Thread("rest_status_light", normalBlink);
ledBreatherThread = new Thread("rest_status_light", hearthBeatBlink);
}
os_thread_return_t normalBlink(void*) {
// Start never ending loop
for(;;) {
if(blink_type == 0) {
// Blink led
digitalWrite(led, HIGH);
delay(3000);
digitalWrite(led, LOW);
delay(3000);
}
}
}
os_thread_return_t hearthBeatBlink(void*) {
// Start never ending loop
for(;;) {
if(blink_type == 1) {
// Blink led
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
delay(500);
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
delay(3000);
}
}
}
void loop() {
delay(10000);
switch (blink_type) {
case 0:
blink_type = 1;
break;
case 1:
blink_type = 0;
break;
}
}
To not get confused, the "buzzer" output (D1) is currently also wired to an LED.
If there would be a better approach to blink a led in two different ways based on a dynamic variable I'm happy to adopt to this sollution!
normalBlink() and hearthBeatBlink() have delays only when (blink_type == 1). When blink_type becomes 0 there are no delays in the for loops and one of them, the first which evaluates the variable change, happily spins for eternity. Try to add a small delay in the case blink_type is 0. Hope this helps!
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.
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);
}
}
My problem is that I am making an alarm that goes off when the temperature is greater than a preset amount. however the Arduino is going past the if statement and not stopping at the gate.
I have tried looking up different syntax however it keeps going through the if statement like it is not there while it still serial prints.
//naming the led's left to right defining the pin and the constant int
//coded by luke
// the breadboard has 6 leds lined up by order 1,2,3,4,5,6 on the corresponding pins
//6.28.2014
// second program written from scratch
// !buzzer pin 8!
// integers
const int led1=(1);
const int led2=(2);
const int led3=(3);
const int led4=(4);
const int led5=(5);
const int led6=(6);
const int buzzer=(8);
const int temp=(0);
int maxtemp=(80);
// place the buzzer at pin 8 for sound
void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
pinMode(led6, OUTPUT);
pinMode(temp, INPUT);
Serial.begin(9600);
}
void loop()
{
delay (1000);
analogRead(temp);
delay (100);
Serial.print(analogRead(temp)/2.05);
delay (10);
if(analogRead(temp/2.05) > maxtemp)
{
tone (buzzer, 440);
delay (100); // wait to turn on the second
digitalWrite(led2, HIGH);
delay (100);
digitalWrite(led1, LOW);
delay (100);
digitalWrite (led3, HIGH);
delay (100);
digitalWrite (led2, LOW);
delay (100);
tone (buzzer, 450);
digitalWrite (led4, HIGH);
delay (100);
digitalWrite (led3, LOW);
delay (100);
digitalWrite (led5, HIGH);
delay (100);
digitalWrite (led4, LOW);
delay (100);
digitalWrite (led6, HIGH);
delay (100);
digitalWrite (led5, LOW);
delay (100);
digitalWrite (led6, LOW);
}
}
// put your main code here, to run repeatedly:
What you're printing to serial is not the same as what you're comparing to maxtemp in the if statement:
Serial.print(analogRead(temp)/2.05);
if(analogRead(temp/2.05) > maxtemp)
The former has /2.05 outside the analogRead call, the latter has it inside. Assuming the former is reporting what you expect to see, changing the if statement to:
if((analogRead(temp) / 2.05) > maxtemp)
Should fix the problem.