Hello everybody, I’m working in a project where a group of 14 LEDS turn on in sequence from pin 2 to A2 after A4 input button is pressed down, and then they will turn OFF in the same order as they turn ON; also a second button A5 will do the same but in opposite direction from pin A2 to pin 2.
The two ON sequences will run uninterrupted; mean no button input will be read at the moment of either sequence execution, (I’m using delay() on this two ).
Now the two OFF sequences are running with millis(), to allow me to send inputs using either A4 or A5 buttons to interrupt either of the two OFF sequences at any point of it execution, this input will start any of the two ON sequences again.
A4 Button
From 2 to A2 ON
From 2 to A2 OFF
A5 Button
From A2 to 2 ON
From A2 to 2 OFF
The problem: when either of the two OFF sequences start (2toA2) or (A2to2) , rather that start as they showed above, the will start in between at the point where the input buttons was triggers last time. As an example 2,3,4,5,6,7,8,9,10,11,12,13,A0,A1,A2, say last time we stop it at OFF sequence pin 10, it will turn OFF from 10 to the right and from 10 to the left, rather that 2 to A2.
I will add the code so you guys have a better idea of what I’m trying to do here.
I’m new to electronics and programming and English is my second language, please be patient.
Thank you in advance.
const int buttonPin1 = A4; //button up
const int buttonPin2 = A5; //button down
//Varaibles
int buttonState1 = 0; //state of the button up
int buttonState2 = 0; //state of the button down
int pirState1 = LOW;
int pirState2 = LOW;
int timer = 100; //the higher the number, the slower the timing.
int timer2 = 2000;
unsigned long interval = 100;
unsigned long currentMillis = millis();
unsigned long previousMillis = 0;
int led=2;
int led2=A2;
////////////////////////////////////////////////////////////////////////////////////////
void setup() {
for(int x=2;x<A2;x++){
pinMode(x,OUTPUT);
}
pinMode(buttonPin1, INPUT); //it make the pin A5 input
pinMode(buttonPin2, INPUT); //it make the pin A4 input
}
////////////////////////////////////////////////////////////////////////////////////////
void loop(){
currentMillis = millis();
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
if (buttonState1 == HIGH && pirState1 == LOW ) {
UpSecuenceOn();
}
if (buttonState1 == LOW && pirState1 == HIGH ) {
UpSecuenceOff();
}
if (buttonState2 == HIGH && pirState2 == LOW ) {
DownSecuenceOn();
}
if (buttonState2 == LOW && pirState2 == HIGH ) {
DownSecuenceOff();
}
}
////////////////////////////////////////////////////////////////////////////////////////////
void UpSecuenceOn (){
for (int thisPin1 = 2; thisPin1 < A2; thisPin1++) {
digitalWrite(thisPin1, HIGH);
delay(timer);
pirState1 = HIGH; }
{delay(timer2);}
}
///////////////////////////////////////////////////////////////////////////////////////////
void UpSecuenceOff(){
unsigned long currentTime = millis();
if(currentTime - previousMillis > interval){
previousMillis = currentTime;
digitalWrite(led,LOW);
led++;
if(led==A2){
led=2;
previousMillis= currentTime;
pirState1 = LOW;}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
void DownSecuenceOn(){
for (int thisPin2 =A2; thisPin2 >= 2; thisPin2--) {
digitalWrite(thisPin2, HIGH);
delay(timer);
pirState2 = HIGH; }
{delay(timer2);}
}
///////////////////////////////////////////////////////////////////////////////////////////
void DownSecuenceOff(){
unsigned long currentTime = millis();
if(currentTime - previousMillis > interval){
previousMillis = currentTime;
digitalWrite(led2,LOW);
led2--;
if(led2==1){
led2=A2;
previousMillis= currentTime;
pirState2 = LOW;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
When you use millis(), you should check the time over and over again. You can check it once a second or a million times a second. It is like looking at the clock all the time, waiting until it is time to do something.
You do not want to turn a single led on or off as in the many examples for millis(), but you want a certain sequence. Every step in that sequence has a certain timing. You have to remember the current state, to know what the next step should be. At this moment you use 'led' and 'led2' to remember the state.
Someone else might have a smart solution to make it work, but I like to make code that is easier to understand.
Could you seperate your code in the sketch from the pins to the leds ?
For example with an array: const int ledPin[] = { 2,3,4,5,6,7,8,9,10,11,12,13,A0,A1,A2 }; // pin 2 to A2 are 15 leds !! ??
In your code you use ledpin[0] for the first led, and ledpin[14] for the 15th led.
What do you want to do ?
Perhaps there is a good library for you, which you can use for the sequence. Those libraries need an array with the timing, and act upon the data in the array.
Or you can write it yourself. You could have a variable to remember the current state (for example the index to ledPin[]) and a variable for the direction (for example +1/-1 and 0 for not active).
The "UpSecuenceOff()" would no longer do the sequence, it would start the sequence. You have to do the actual code for the sequence elsewhere in the loop() function.
I hope this all makes sense. If you don't understand something, just ask.
simplifying the ledPins with an array is a good idea.
getting the for() loops indexing the same will simplify your code tremendously.
I like getting rid of the delays, and we can work on that, but does this now do what you want?
notice the if, else if, else if in your loop() function....
untested:
const int ledPin[15] = {
2,3,4,5,6,7,8,9,10,11,12,13,A0,A1,A2 };
const int buttonPin1 = A4; //button up
const int buttonPin2 = A5; //button down
int buttonState1 = 0; //state of the button up
int buttonState2 = 0; //state of the button down
int pirState1 = LOW;
int pirState2 = LOW;
int timer = 100; //the higher the number, the slower the timing.
int timer2 = 2000;
unsigned long interval = 100;
unsigned long currentMillis = millis();
unsigned long previousMillis;
int led=2;
int led2=A2;
//
void setup()
{
for(int x = 0; x < 15; x++)
{
pinMode(x,OUTPUT);
}
pinMode(buttonPin1, INPUT); //it make the pin A5 input
pinMode(buttonPin2, INPUT); //it make the pin A4 input
}
void loop()
{
currentMillis = millis();
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
if (buttonState1 == HIGH && pirState1 == LOW )
{
UpSecuenceOn();
}
else if (buttonState1 == LOW && pirState1 == HIGH )
{
UpSecuenceOff();
}
else if (buttonState2 == HIGH && pirState2 == LOW )
{
DownSecuenceOn();
}
else if (buttonState2 == LOW && pirState2 == HIGH )
{
DownSecuenceOff();
}
}
//
void UpSecuenceOn () // Start at pin 2 and illuminate them in order without interruption
{
for (int i = 0; i < 15; i++)
{
digitalWrite(ledPin[i], HIGH);
delay(timer); // if you have these....
pirState1 = HIGH;
}
delay(timer2);// do really need these?
}
//
void DownSecuenceOn() // start at pin A2 and turn them on in order, without interruption
{
for (int i = 0; i < 15; i++)
{
digitalWrite(ledPin[15 - i], HIGH);
delay(timer);
pirState2 = HIGH;
}
delay(timer2);
}
//
void UpSecuenceOff()
{
for (int i = 0; i < 15; i++)
{
digitalWrite(ledPin[i], LOW);
delay(timer);
pirState1 = HIGH;
}
delay(timer2);
}
//
void DownSecuenceOff()
{
for (int i = 0; i < 15; i++)
{
digitalWrite(ledPin[15 - i], LOW);
delay(timer);
pirState2 = HIGH;
}
delay(timer2);
}
/*
void UpSecuenceOff() //as long as the button is pressed, it will turn off the leds from 2 to A2
{
static int index = 0;
unsigned long currentTime = millis();
if(currentTime - previousMillis > interval)
{
previousMillis = currentTime;
digitalWrite(ledPin[index],LOW);
index++;
if(index >= 15)
{
index = 0;
//previousMillis= currentTime;
pirState1 = LOW;
}
}
}
//
void DownSecuenceOff() //as long as the button is pressed, it will turn off the leds from A2 to 2
{
static int index = 0;
unsigned long currentTime = millis();
if(currentTime - previousMillis > interval)
{
previousMillis = currentTime;
digitalWrite(ledPin[15 - index], LOW);
index++;
if(index >= 15) index = 0;
pirState2 = LOW;
//previousMillis= currentTime;
}
}
*/