I have tried several ways to get this to happen but to no avail. I am a newbe and was pleased to get my basic sketch to work fine but adding the blink in several different ways didn't work. i have spent two weeks trying to find a solution. It must be right under my nose. I'm 62 yo and this is my first programming effort my brain must be atrophying. Code follows.
/*Sequence 7-10 lights from bottom to top of driveway
or top to bottom from PIR input at top or bottom.
If top sequences is initiated first the top most
and bottom most light will light first,
then top to bottom sequence will continue
until complete then remain on for one minute
then all will go off. The same if the bottom
sequence is initiated first only in reverse. */
/*Added whistle blink the led at the oppisite end of
the driveway to indicate if soomeone is coming up,
or down as the case may be*/
// Initialize pins as input and output
int topPir = 2; //digital input for top pir
int bottomPir = 3; //digital input for bottom pir
int outPin4 = 4; //output for bottom light or relay
int outPin5 = 5;
int outPin6 = 6;
int outPin7 = 7;
int outPin8 = 8;
int outPin9 = 9;
int outPin10 = 10;
int outPin11 = 11;
int outPin12 = 12; //output for top light or relay
void setup()
{
pinMode(topPir, INPUT); //declare topPir as input
pinMode(bottomPir, INPUT); //declare bottomPir as input
pinMode(outPin4, OUTPUT); // declare outPin4 as output
pinMode(outPin5, OUTPUT); // declare outPin5 as output
pinMode(outPin6, OUTPUT); // declare outPin6 as output
pinMode(outPin7, OUTPUT); // declare outPin7 as output
pinMode(outPin8, OUTPUT); // declare outPin8 as output
pinMode(outPin9, OUTPUT); // declare outPin9 as output
pinMode(outPin10, OUTPUT); // declare outPin10 as output
pinMode(outPin11, OUTPUT); // declare outPin11 as output
pinMode(outPin12, OUTPUT); // declare outPin12 as outputq
}
void loop ()
{
if (digitalRead(topPir) == HIGH)//checks topPir condition
{
digitalWrite(outPin4, HIGH); //turns output outPin4 on
digitalWrite(outPin12, HIGH); //I want to blink this one
delay(1000); //delays for one second
digitalWrite(outPin5, HIGH); //turn on output outPin5
delay(1000); //delay
digitalWrite(outPin6, HIGH); //same as above until end of
delay(1000); //loop
digitalWrite(outPin7, HIGH);
delay(1000);
digitalWrite(outPin8, HIGH);
delay(1000);
digitalWrite(outPin9, HIGH);
delay(1000);
digitalWrite(outPin10, HIGH);
delay(1000);
digitalWrite(outPin11, HIGH);
delay(1000);
digitalWrite(outPin12, HIGH);
delay(60000); //all outputs on for one minute
digitalWrite(outPin4, LOW); //turns all outPins off
digitalWrite(outPin5, LOW);
digitalWrite(outPin6, LOW);
digitalWrite(outPin7, LOW);
digitalWrite(outPin8, LOW);
digitalWrite(outPin9, LOW);
digitalWrite(outPin10, LOW);
digitalWrite(outPin11, LOW);
digitalWrite(outPin12, LOW);
}
if (digitalRead(bottomPir) == HIGH)//checks bottomPir condition
{
digitalWrite(outPin12, HIGH); //turns output outPin12 on
digitalWrite(outPin4, HIGH); // blink this while rest of code runs
delay(1000); //delays for one second
digitalWrite(outPin11, HIGH); //turn on output outPin12
delay(1000); //delay
digitalWrite(outPin10, HIGH); //same as above until end of
delay(1000); //loop
digitalWrite(outPin9, HIGH);
delay(1000);
digitalWrite(outPin8, HIGH);
delay(1000);
digitalWrite(outPin7, HIGH);
delay(1000);
digitalWrite(outPin6, HIGH);
delay(1000);
digitalWrite(outPin5, HIGH);
delay(1000);
digitalWrite(outPin4, HIGH);
delay(60000); //all outputs on for one minute
digitalWrite(outPin4, LOW); //turns all outPins off
digitalWrite(outPin5, LOW);
digitalWrite(outPin6, LOW);
digitalWrite(outPin7, LOW);
digitalWrite(outPin8, LOW);
digitalWrite(outPin9, LOW);
digitalWrite(outPin10, LOW);
digitalWrite(outPin11, LOW);
digitalWrite(outPin12, LOW);
}
}
Thanks Duff
Blinking without stoping the code.
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- westfw
- Posts: 2008
- Joined: Fri Apr 27, 2007 1:01 pm
Re: Blinking without stoping the code.
There is the "blink without delay" example sketch...
Many of the examples are missing a description of the thought process that leads to the code they contain. The basic strategy for blinking is essentially
BlinkWithoutDelay is an example of a way to implement this.
Many of the examples are missing a description of the thought process that leads to the code they contain. The basic strategy for blinking is essentially
Code: Select all
if (time_to_change_ledstate(which_led) {
change_led_state(which_led);
set_new_time_to_change(which_led);
}
-
- Posts: 3
- Joined: Thu Feb 10, 2011 2:37 pm
Re: Blinking without stoping the code.
I'm sorry. I don't understand.
Would I place this statement below my initial if statement or inside of it?
if (time_to_change_ledstate(which_led) {
change_led_state(which_led);
set_new_time_to_change(which_led);
}
Does "time_to_change_ledstate" refer to a number of milliseconds or a point at which I want the blinking to start? i.e. topPir==HIGH?
I would think (which_led) in my case would be outPin12.
Is change_led_state some sort of command that I need to declare as a variable and give an initial value?
Lastly (I hope) set_new_time_to_change would be the rate of change i.e. 300milliseconds?
I really feel dumb but I am trying.
Thanks, Duff
Would I place this statement below my initial if statement or inside of it?
if (time_to_change_ledstate(which_led) {
change_led_state(which_led);
set_new_time_to_change(which_led);
}
Does "time_to_change_ledstate" refer to a number of milliseconds or a point at which I want the blinking to start? i.e. topPir==HIGH?
I would think (which_led) in my case would be outPin12.
Is change_led_state some sort of command that I need to declare as a variable and give an initial value?
Lastly (I hope) set_new_time_to_change would be the rate of change i.e. 300milliseconds?
I really feel dumb but I am trying.
Thanks, Duff
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: Blinking without stoping the code.
The "BlinkWithoutDelay" example sketch in the IDE is a good place to start. This uses a system timer (millis) to figure out when it is time to change the state of the LED. Once you understand how it works for one LED, you should be able scale it up to sequence multiple LEDs.
Code: Select all
/* Blink without Delay
Turns on and off a light emitting diode(LED) connected to a digital
pin, without using the delay() function. This means that other code
can run at the same time without being interrupted by the LED code.
The circuit:
* LED attached from pin 13 to ground.
* Note: on most Arduinos, there is already an LED on the board
that's attached to pin 13, so no hardware is needed for this example.
created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/
// constants won't change. Used here to
// set pin numbers:
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop()
{
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
- floresta
- Posts: 223
- Joined: Thu Jul 31, 2008 10:27 am
Re: Blinking without stoping the code.
Don't feel bad, it's what is called pseudo code and it is supposed to make things easier to understand. You can't just paste it into your program but you can use it as a model to construct your own code.I'm sorry. I don't understand.
Would I place this statement below my initial if statement or inside of it?
if (time_to_change_ledstate(which_led) {
change_led_state(which_led);
set_new_time_to_change(which_led);
}
Don
-
- Posts: 6
- Joined: Thu Feb 17, 2011 10:30 am
Re: Blinking without stoping the code.
Hi Duffkindt,
I like the sound of your project. Are you controlling relays linked to proper drive way lights?
With all those delays in there your not going to be able to get anything blink so I'm afraid to say you'll need to modify your code a fair bit. For starters I will describe the changes that you'll need to do.
First, Rather than declaring all your pins for your lights as separate variables declare it as a single array variable. (the topPir and bottomPir are fine as is). Having an array will make it a lot easier to set the state of the pins and reduces the size of your code. To declare an array you simply state the type, the variable name followed by square brackets. you can then set the contents of your array in braced brackets. in you case it would be:
with your pins for your lights in an array you can now simplify the code in your setup (keeping the topPir and bottomPir as is)
the code above will loop 9 times incrementing i each time. the value of each element in the array will be used to set the pin as output.
now the main loop. What you want to do in here is ensure the loop is free to execute as frequently as possible (Don't use delay as this is in effect pausing the code)
Because it is our aim to have the loop run freely, you will need to firstly add a check if the Arduino is already running a light sequence. to do this add a new boolean variable to keep track of this and then setup your if block. You'll need both an if else (if it is running you need to check if the next light of the sequence is due else you will be checking the state of the PIR's)
in the header:
in the loop:
in the else part of your code you will need to add the checks you already have. if either are HIGH then you will enable the sequence and setup the variables used to control it.
a point to note in the above code. If both PIR's are HIGH when the arduino checks this code it will be the code in the bottomPir if statement that will set the variables as it is the last to execute. if you want it to be the other way around then re-arrange the if blocks.
There were also new variables defined:
seqDirection is an int that describes the direction the lights will be lite (positive or negative)
seqPosition is an int which is the pin position in our array of lights that is next to be actioned. it's worth pointing out that we are setting this to either one less or one more than the size of our array. as you will read later we first increment or decrement this position when progressing the sequence. it is also worth noting that because the array structure is 0 based (the first element is accessed as position 0) our seqPosition is set to either 0 (the beginning) or 8 (the end).
seqTime is an unsigned long that captures the current time in ms from when the arduino was last reset
seqDelayNextAction is an int that is used to determine when the next action should occur (in Ms). by setting it to the 0 we are wanting the light sequence to start straight away. if you want the start with a delay then you would add it here.
if for example a sequence is not running and the bottomPir is HIGH then the loop will fall in to the else block and then the setup for the bottomPir. the code will then get to the end of the loop and start again at the top. because the sequence is now running the first condition is true. The next step is to build out the code here to progress the sequence.
first thing to do is to check if an action needs to occur. we have 2 variables that were setup seqTime and seqDelayNextAction to help us determine this.The code to do this is as follows. The code to blink the light would be outside of the if block.
To progress the sequence we first add the seqDirection to seqPosition. This gives us the new position in our array of lights that will be triggered in the sequence.
After incrementing the seqPosition we need to check that we are still in bounds and haven't got to the end of the sequence.
If still in bound then set the pin to high and setup the delay
The last item of code to tackle is the blinking lights that you would insert where it says //Blink lights goes here...
the logic for this is simple. if the seqDirection is -1 then the topPir intiated the cycle so we want to flash pin 12 else we will flash pin 4. in our array pin 12 is array position 8 and pin 4 is array position 0 , so:
Blink is a state variable that is declared as a boolean and set to FALSE.
What you will find in the above code is that the state will change quickly..
You will need to create a seperate time control for the blink effect in order to slow it down.
Please bare in mind that whilst this code should work it hasn't been tested as it was written adhoc straight in to forum editor so I'm sure it can be optimised further.. Let me know if you need any further pointers .
I like the sound of your project. Are you controlling relays linked to proper drive way lights?
With all those delays in there your not going to be able to get anything blink so I'm afraid to say you'll need to modify your code a fair bit. For starters I will describe the changes that you'll need to do.
First, Rather than declaring all your pins for your lights as separate variables declare it as a single array variable. (the topPir and bottomPir are fine as is). Having an array will make it a lot easier to set the state of the pins and reduces the size of your code. To declare an array you simply state the type, the variable name followed by square brackets. you can then set the contents of your array in braced brackets. in you case it would be:
Code: Select all
int lightPins[] = {4,5,6,7,8,9,10,11,12};
Code: Select all
for (i = 0; i < 9; i = i + 1) {
pinMode(lightPins[i], OUTPUT)
}
now the main loop. What you want to do in here is ensure the loop is free to execute as frequently as possible (Don't use delay as this is in effect pausing the code)
Because it is our aim to have the loop run freely, you will need to firstly add a check if the Arduino is already running a light sequence. to do this add a new boolean variable to keep track of this and then setup your if block. You'll need both an if else (if it is running you need to check if the next light of the sequence is due else you will be checking the state of the PIR's)
in the header:
Code: Select all
boolean seqRunning = false;
Code: Select all
if (seqRunning == TRUE)
{
// check if sequence need to be moved on
}
else
{
// check state of PIR's
}
Code: Select all
// check state of PIR's
if (digitalRead(topPir) == HIGH)//checks topPir condition
{
seqRunning = TRUE;
seqDirection = -1;
seqPosition = 8;
seqTime = millis();
seqDelayNextAction = 0;
}
if (digitalRead(bottomPir) == HIGH)//checks bottomPir condition
{
seqRunning = TRUE;
seqDirection = +1;
seqPosition = 0;
seqTime = millis();
seqDelayNextAction = 0;
}
There were also new variables defined:
seqDirection is an int that describes the direction the lights will be lite (positive or negative)
seqPosition is an int which is the pin position in our array of lights that is next to be actioned. it's worth pointing out that we are setting this to either one less or one more than the size of our array. as you will read later we first increment or decrement this position when progressing the sequence. it is also worth noting that because the array structure is 0 based (the first element is accessed as position 0) our seqPosition is set to either 0 (the beginning) or 8 (the end).
seqTime is an unsigned long that captures the current time in ms from when the arduino was last reset
seqDelayNextAction is an int that is used to determine when the next action should occur (in Ms). by setting it to the 0 we are wanting the light sequence to start straight away. if you want the start with a delay then you would add it here.
if for example a sequence is not running and the bottomPir is HIGH then the loop will fall in to the else block and then the setup for the bottomPir. the code will then get to the end of the loop and start again at the top. because the sequence is now running the first condition is true. The next step is to build out the code here to progress the sequence.
first thing to do is to check if an action needs to occur. we have 2 variables that were setup seqTime and seqDelayNextAction to help us determine this.The code to do this is as follows. The code to blink the light would be outside of the if block.
Code: Select all
//Blink lights goes here...
//---
timeNow = millis();
if (seqTime + seqDelayNextAction <= timeNow)
{
// record the current time as the sequence time for future checks.
seqTime = timeNow;
// Progress Sequence
//..
}
After incrementing the seqPosition we need to check that we are still in bounds and haven't got to the end of the sequence.
If still in bound then set the pin to high and setup the delay
Code: Select all
// Progress Sequence
seqPosition += seqDirection;
if (seqPosition>=0 & seqPosition<=8)
{
//set the next light in sequence
digitalWrite(lightPins[seqPosition],HIGH);
//set the delay until the next sequence cycle
if (seqPosition = 0 | seqPosition = 8) //Last lights lite
{
seqDelayNextAction = 60000; //All the lights have been lite. wait a minute before turning off
}
else
{
seqDelayNextAction = 1000; //delay 1 second until next sequence cycle.
}
}
else //cycle out of bounds. shutdown
{
for (i = 0; i < 9; i = i + 1) {
digitalWrite(lightPins[i],LOW);
}
}
The last item of code to tackle is the blinking lights that you would insert where it says //Blink lights goes here...
the logic for this is simple. if the seqDirection is -1 then the topPir intiated the cycle so we want to flash pin 12 else we will flash pin 4. in our array pin 12 is array position 8 and pin 4 is array position 0 , so:
Code: Select all
//Blink lights goes here...
Blink=!Blink
if (seqDirection=-1)
{
digitalWrite(lightPins[8],Blink);
}
else
{
digitalWrite(lightPins[0],Blink);
}
What you will find in the above code is that the state will change quickly..
You will need to create a seperate time control for the blink effect in order to slow it down.
Please bare in mind that whilst this code should work it hasn't been tested as it was written adhoc straight in to forum editor so I'm sure it can be optimised further.. Let me know if you need any further pointers .
-
- Posts: 2
- Joined: Sun Mar 11, 2012 12:14 pm
Re: Blinking without stoping the code.
Hi
I know this is an old thread but im trying to learn about arrays and delay without using delay for a project im working on
Im getting some error, I spend a good 3+ hours going over it and missing something simple. The second one I really dont understand
: In function 'void loop()':
: lvalue required as left operand of assignment
: 'i' was not declared in this scope
: expected `}' at end of input
If anyone as the time to just look over it for me and put me right i would really appreciate it.
Thanks in advance
I know this is an old thread but im trying to learn about arrays and delay without using delay for a project im working on
Im getting some error, I spend a good 3+ hours going over it and missing something simple. The second one I really dont understand
: In function 'void loop()':
: lvalue required as left operand of assignment
: 'i' was not declared in this scope
: expected `}' at end of input
If anyone as the time to just look over it for me and put me right i would really appreciate it.
Thanks in advance
Code: Select all
nt topPir = 2; //digital input for top pir
int bottomPir = 3; //digital input for bottom pir
int lightPins[] = { 4,5,6,7,8,9,10,11,12};
boolean seqRunning = false;
boolean Blink = false;
int seqDirection = 0;
int seqPosition = 0;
long seqTime = 0;
int seqDelayNextAction = 0;
long timeNow = 0;
void setup()
{
for (int i = 0; i <9; i = i + 1){
pinMode(lightPins[i], OUTPUT);
}
pinMode(topPir, INPUT); //declare topPir as input
pinMode(bottomPir, INPUT); //declare bottomPir as input
}
void loop ()
{
// check state of PIR's
if (digitalRead(topPir) == HIGH)//checks topPir condition
{
// seqRunning = TRUE;
seqDirection = -1;
seqPosition = 8;
seqTime = millis();
seqDelayNextAction = 0;
}
if (digitalRead(bottomPir) == HIGH)//checks bottomPir condition
{
// seqRunning = TRUE;
seqDirection = +1;
seqPosition = 0;
seqTime = millis();
seqDelayNextAction = 0;
}
//Blink lights goes here...
Blink=!Blink;
if (seqDirection=-1)
{
digitalWrite(lightPins[8],Blink);
}
else
{
digitalWrite(lightPins[0],Blink);
}
timeNow = millis();
if (seqTime + seqDelayNextAction <= timeNow)
{
// record the current time as the sequence time for future checks.
seqTime = timeNow;
// Progress Sequence
seqPosition += seqDirection;
if (seqPosition>=0 & seqPosition<=8)
{
//set the next light in sequence
digitalWrite(lightPins[seqPosition],HIGH);
//set the delay until the next sequence cycle
if (seqPosition = 0 | seqPosition = 8) //Last lights lite
{
seqDelayNextAction = 60000; //All the lights have been lite. wait a minute before turning off
}
else
{
seqDelayNextAction = 1000; //delay 1 second until next sequence cycle.
}
}
else //cycle out of bounds. shutdown
{
for (i = 0; i < 9; i = i + 1) {
digitalWrite(lightPins[i],LOW);
}
}
}
- danmalec
- Posts: 13
- Joined: Fri Nov 18, 2011 3:53 pm
Re: Blinking without stoping the code.
Hi s7eve, the three compiler errors are caused by the following:
The short answer is that you're using a bitwise OR (single pipe) instead of logical OR (double pipe) and assignment (single equal) instead of comparison (double equal). You probably want:
The longer answer for the lvalue error is that it comes down to operator precedence http://en.wikipedia.org/wiki/C_operator ... precedence, with the bitwise OR being evaluated prior to the assignments. So the compiler thinks you're asking to put the value 8 into the result of doing a bitwise OR on 0 and seqPosition.
You haven't declared a variable i in the global scope or the scope of the loop function, only in the setup function. A quick fix is to do the following:
You need one more closing brace } at the end of your sketch.
Caused by:lvalue required as left operand of assignment
Code: Select all
if (seqPosition = 0 | seqPosition = 8)
Code: Select all
if (seqPosition == 0 || seqPosition == 8)
Caused by:'i' was not declared in this scope
Code: Select all
for (i = 0; i < 9; i = i + 1) {
Code: Select all
for (int i = 0; i < 9; i = i + 1) {
Looks like the cause is the following block being opened, but never closed.expected `}' at end of input
Code: Select all
if (seqTime + seqDelayNextAction <= timeNow)
{
-
- Posts: 2
- Joined: Sun Mar 11, 2012 12:14 pm
Re: Blinking without stoping the code.
Dan
Thank you, think its called looking at this screen for to long, I just couldnt see the this missing bit and as for " if (seqPosition == 0 || seqPosition == " I wouldnt have had a clue so a BIG thank you for your time
Cheers Steve
Thank you, think its called looking at this screen for to long, I just couldnt see the this missing bit and as for " if (seqPosition == 0 || seqPosition == " I wouldnt have had a clue so a BIG thank you for your time
Cheers Steve
- danmalec
- Posts: 13
- Joined: Fri Nov 18, 2011 3:53 pm
Re: Blinking without stoping the code.
Steve
Glad to help; I've been there too - after looking at the same code for a long amount of time, things stop standing out
- Dan
Glad to help; I've been there too - after looking at the same code for a long amount of time, things stop standing out
- Dan
- henry.best
- Posts: 13
- Joined: Sat Mar 03, 2012 9:37 pm
Re: Blinking without stoping the code.
Agreed. I find that errors in my own code are much harder to find than errors in someone else's codeDan Malec wrote:Steve
Glad to help; I've been there too - after looking at the same code for a long amount of time, things stop standing out
- Dan
-
- Posts: 1
- Joined: Mon Nov 12, 2012 5:10 pm
Re: Blinking without stoping the code.
Can this array be used to blink 6 leds at six different frequencies?
And if so will it work in micros instead of millis?
And if so will it work in micros instead of millis?
Please be positive and constructive with your questions and comments.