I am wondering if i can get some help. I have been stuck on this for a little bit now. So what im trying to do is run 3 different patterns. Random LED, Chaser Left to Right, and Chaser Right to Left. for the most part this code works but im running into some issues. Im wondering if i could get some help with.
sometimes it skips the 1st pattern when button is pressed
after it reaches the 3rd pattern it wont loop around again to pattern 1
it wont let me change patterns or speed mid pattern i have to wait until its finished
sometimes it wont change the patterns when the button is pressed
pattern 3 chaser right to left does not work
Thank you for any help i can get with this.
int Pin = 0, Locpct = 0, activeLED = 0, onTime = 10, potPin = 0;
int button = 13;
int buttonState = 0;
int p=0;
int val = 0;
int ledMode = 0; //Cycle between LED states
boolean lastButton = LOW; //Last Button State
boolean currentButton = LOW; //Current Button State
void setup(){
// set pin mode and lights each led in sequance
pinMode (button, INPUT); //Set button as input (not required)
Serial.begin(9600);
uint16_t chase2 = 13; // keeps track of second LED movement
for(Pin = 2; Pin < 14; Pin++){
pinMode(Pin,OUTPUT);
digitalWrite(Pin,HIGH);
delay(500);
digitalWrite(Pin,LOW);
}
}
boolean debounce(boolean last)
{
boolean current = digitalRead(button); //Read the button state
if (last != current) //if it's different...
{
delay(5); //wait 5ms
current = digitalRead(button); //read it again
}
return current;
}
void loop(){
buttonState = digitalRead(button);
if (buttonState == HIGH)
{
p++;
delay(50);
}
if (p==1)
{
Serial.print("Pat1");
//only one random LED on at a time when pot is above center
while(analogRead(2) <= 511){
onTime = map(analogRead(potPin),0,511,2,100);
activeLED = (random(2,13));
digitalWrite(activeLED,HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2,13),LOW);
}
// LEDs on and Off Randomly when pot is below center
while(analogRead(potPin) > 511){
onTime = map(analogRead(2),512,1023,100,2);
digitalWrite(activeLED,HIGH);
delay(random(onTime, onTime *5));
digitalWrite(random(2,13),LOW);
}
}
if(p==2)
{
Serial.print("Pat2");
val = analogRead(potPin); // read the value from the sensor
for (int i = 2; i < 13; i++) {
digitalWrite(i, HIGH); // chaser 1
delay(val);
for (int i = 2; i < 13; i++)
digitalWrite(i, LOW);
delay(val);
}
}
if(p==3)
{
Serial.print("Pat3");
val = analogRead(potPin); // read the value from the sensor
for (int i = 2; i < 13; i--) {
digitalWrite(i, HIGH); // chaser 2
delay(val);
for (int i = 2; i < 13; i--)
digitalWrite(i, LOW);
delay(val);
}
p=0;
}
}
int Pin = 0, Locpct = 0, activeLED = 0, onTime = 10, potPin = 0;
int button = 13;
int buttonState = 0;
int p = 0;
int val = 0;
int ledMode = 0; //Cycle between LED states
boolean lastButton = LOW; //Last Button State
boolean currentButton = LOW; //Current Button State
void setup() {
// set pin mode and lights each led in sequance
pinMode (button, INPUT); //Set button as input (not required)
Serial.begin(9600);
uint16_t chase2 = 13; // keeps track of second LED movement
for (Pin = 2; Pin < 14; Pin++) {
pinMode(Pin, OUTPUT);
digitalWrite(Pin, HIGH);
delay(500);
digitalWrite(Pin, LOW);
}
}
boolean debounce(boolean last)
{
boolean current = digitalRead(button); //Read the button state
if (last != current) //if it's different...
{
delay(5); //wait 5ms
current = digitalRead(button); //read it again
}
return current;
}
void loop() {
buttonState = digitalRead(button);
if (buttonState == HIGH)
{
p++;
delay(50);
}
if (p == 1)
{
Serial.print("Pat1");
//only one random LED on at a time when pot is above center
while (analogRead(2) <= 511) {
onTime = map(analogRead(potPin), 0, 511, 2, 100);
activeLED = (random(2, 13));
digitalWrite(activeLED, HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2, 13), LOW);
}
// LEDs on and Off Randomly when pot is below center
while (analogRead(potPin) > 511) {
onTime = map(analogRead(2), 512, 1023, 100, 2);
digitalWrite(activeLED, HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2, 13), LOW);
}
}
if (p == 2)
{
Serial.print("Pat2");
val = analogRead(potPin); // read the value from the sensor
for (int i = 2; i < 13; i++) {
digitalWrite(i, HIGH); // chaser 1
delay(val);
for (int i = 2; i < 13; i++)
digitalWrite(i, LOW);
delay(val);
}
}
if (p == 3)
{
Serial.print("Pat3");
val = analogRead(potPin); // read the value from the sensor
for (int i = 2; i < 13; i--) {
digitalWrite(i, HIGH); // chaser 2
delay(val);
for (int i = 2; i < 13; i--)
digitalWrite(i, LOW);
delay(val);
}
p = 0;
}
}
sometimes it skips the 1st pattern when button is pressed
You need to detect the button changing state from not being pressed to being pressed. You can't just change the pattern when the button is pressed. Even if you press the button only for a short time, it will change pattern at high speed and skip patterns.
This line of code
if (buttonState == HIGH)
only checks that the button is pressed. It does not check that the button was not already pressed.
after it reaches the 3rd pattern it wont loop around again to pattern 1
You need to write some code to make that happen.
This line of code:
p++;
can increase the variable p from 3 to 4, 5, 6... There is no check to stop that and put it back to 1 (or zero?)
it wont let me change patterns or speed mid pattern i have to wait until its finished
This is the biggest change you must make. You need to learn to code in a whole new way. Using delay(), especially inside loops, will have this effect. You need to study the "blink without delay" example sketch to begin to learn this new way of coding.
sometimes it wont change the patterns when the button is pressed
Could variable p have gone past 3?
pattern 3 chaser right to left does not work
This line of code is wrong:
for (int i = 2; i < 13; i--)
The values of i will be 2, 1, 0, -1, -2, -3.... and so on. It won't stop, because all those values are less than 13. Only when i gets to -32768 will it wrap around to +32767, and then the loop will stop because 32767 is not less than 13.
Sometimes it skips the 1st pattern when button is pressed.
I'm still trying to figure this one out. My theory on this one is that Pattern 1 is a random pattern that moves so fast and it only lets me change pattern after it completes it cycle ever Blink in a LED is considered a new Cycle. Thus the change is so quick it skips pattern 1 and moves to pattern 2. I'm not sure how to fix this yet.
After it reaches the 3rd pattern it wont loop around again to pattern 1.
What i ended up doing is creating a 4th Pattern. Then added P = 0; to that pattern which then looped me back to the top with pattern 1 again.
it wont let me change patterns or speed mid pattern i have to wait until its finished
taking into consideration what you said i figured its best to get this working. once i have that i would look into "blink without delay" coding.
sometimes it wont change the patterns when the button is pressed
this seems to stem from #3 as well as im only able to change patterns when the cycle is over. which im not sure the best way to fix this yet. I find my self missing the end cycle time and waiting a whole other cycle to try and go to the next pattern.
pattern 3 chaser right to left does not work
did some research and fixed this. thank you
Updated Code
int Pin = 0, Locpct = 0, activeLED = 0, onTime = 10, potPin = 0;
int button = 13;
int buttonState = 0;
int p = 0;
int val = 0;
int lastButtonState = 0;
int ledMode = 0; //Cycle between LED states
boolean lastButton = LOW; //Last Button State
boolean currentButton = LOW; //Current Button State
void setup() {
// set pin mode and lights each led in sequance
pinMode (button, INPUT); //Set button as input (not required)
Serial.begin(9600);
uint16_t chase2 = 13; // keeps track of second LED movement
for (Pin = 2; Pin < 14; Pin++) {
pinMode(Pin, OUTPUT);
digitalWrite(Pin, HIGH);
delay(500);
digitalWrite(Pin, LOW);
}
}
boolean debounce(boolean last)
{
boolean current = digitalRead(button); //Read the button state
if (last != current) //if it's different...
{
delay(5); //wait 5ms
current = digitalRead(button); //read it again
}
return current;
}
void loop() {
buttonState = digitalRead(button);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
p++;
delay(50);
}
else {
lastButtonState = buttonState;
}
}
if (p == 0)
{
Serial.print("Pat1");
//only one random LED on at a time when pot is above center
while (analogRead(2) <= 511) {
onTime = map(analogRead(potPin), 0, 511, 2, 100);
activeLED = (random(2, 13));
digitalWrite(activeLED, HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2, 13), LOW);
}
// LEDs on and Off Randomly when pot is below center
while (analogRead(potPin) > 511) {
onTime = map(analogRead(2), 512, 1023, 100, 2);
digitalWrite(activeLED, HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2, 13), LOW);
}
}
if (p == 1)
{
Serial.print("Pat2");
val = analogRead(potPin); // read the value from the sensor
for (int i = 2; i < 13; i++) {
digitalWrite(i, HIGH); // chaser 1
delay(val);
for (int i = 2; i < 13; i++)
digitalWrite(i, LOW);
delay(val);
}
}
if (p == 2)
{
Serial.print("Pat3");
val = analogRead(potPin); // read the value from the sensor
for (int i = 13; i >=2; i--) {
digitalWrite(i, HIGH); // chaser 2
delay(val);
for (int i = 13; i >=2; i--)
digitalWrite(i, LOW);
delay(val);
}
}
if (p == 3)
{
Serial.print("restart");
p = 0;
}
}
You seem to have updated this function since the previous post:
boolean debounce(boolean last)
{
boolean current = digitalRead(button); //Read the button state
if (last != current) //if it's different...
{
delay(5); //wait 5ms
current = digitalRead(button); //read it again
}
return current;
}
But its not used. It does not add much to the sketch anyway, so you can delete it.
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
p++;
delay(50);
}
else {
lastButtonState = buttonState;
}
}
lastButtonState will only be updated when buttonState is HIGH. When buttonState is LOW, it won't get updated. The "else" part is attached to the second "if". You really want it to be attached to the first "if". You can do that like this:
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
p++;
delay(50);
}
}
else {
lastButtonState = buttonState;
}
I fixed the indentation also. This illustrates why indentation is important. Indentation does not affect how the code works, but it is not just about being OCD. indentation helps you spot your own errors. You can see in my changes above that the "else" lines up with the first "if". If you had indented your version, you would see that the "else" lines up with the second "if", i.e. the wrong one.
Seeing it that way i can understand now why indentation is so important. I'll have to work on that. I'm more of a visual learner so that helped a lot.
So i'll have to do some more research on this but for the most part its doing everything i want to do as long as i am holding down the button when the pattern ends. But like you said i would have to learn to code it differently "blink without delay".
The one thing i am noticing is that when restarting the loop it goes from restart to pattern 2. It skips pattern 1 altogether. Any thought as to what is making this happen?
int Pin = 0, Locpct = 0, activeLED = 0, onTime = 10, potPin = 0;
int button = 13;
int buttonState = 0;
int p = 0;
int val = 0;
int lastButtonState = 0;
int ledMode = 0; //Cycle between LED states
boolean lastButton = LOW; //Last Button State
boolean currentButton = LOW; //Current Button State
void setup() {
// set pin mode and lights each led in sequance
pinMode (button, INPUT); //Set button as input (not required)
Serial.begin(9600);
uint16_t chase2 = 13; // keeps track of second LED movement
for (Pin = 2; Pin < 14; Pin++) {
pinMode(Pin, OUTPUT);
digitalWrite(Pin, HIGH);
delay(500);
digitalWrite(Pin, LOW);
}
}
void loop() {
buttonState = digitalRead(button);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
p++;
delay(50);
}
}
else {
lastButtonState = buttonState;
}
if (p == 0)
{
Serial.print("Pat1");
//only one random LED on at a time when pot is above center
while (analogRead(2) <= 511) {
onTime = map(analogRead(potPin), 0, 511, 2, 100);
activeLED = (random(2, 13));
digitalWrite(activeLED, HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2, 13), LOW);
}
// LEDs on and Off Randomly when pot is below center
while (analogRead(potPin) > 511) {
onTime = map(analogRead(2), 512, 1023, 100, 2);
digitalWrite(activeLED, HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2, 13), LOW);
}
}
if (p == 1)
{
Serial.print("Pat2");
val = analogRead(potPin); // read the value from the sensor
for (int i = 2; i < 13; i++) {
digitalWrite(i, HIGH); // chaser 1
delay(val);
for (int i = 2; i < 13; i++)
digitalWrite(i, LOW);
delay(val);
}
}
if (p == 2)
{
Serial.print("Pat3");
val = analogRead(potPin); // read the value from the sensor
for (int i = 13; i >=2; i--) {
digitalWrite(i, HIGH); // chaser 2
delay(val);
for (int i = 13; i >=2; i--)
digitalWrite(i, LOW);
delay(val);
}
}
if (p == 3)
{
Serial.print("restart");
p = 0;
}
}
I must have been half asleep when I suggested that change before. Now, we are only updating lastButtonState when it is the same as buttonState. Either take that line out of the "if/else" completely, or move it inside the first "if" (but not inside the second "if"). The "else" part won't be needed.
I'm working with Tinkercad i dont think that has that option at least not that i have found yet.
PaulRB:
Getting the indentation right is easy. Just click Tools->Auto Format.
I'm working with Tinkercad i dont think that has that option at least not that i have found yet.
PaulRB:
I must have been half asleep when I suggested that change before. Now, we are only updating lastButtonState when it is the same as buttonState. Either take that line out of the "if/else" completely, or move it inside the first "if" (but not inside the second "if"). The "else" part won't be needed.
Yeah i just noticed that today. I have been playing around with " Blink without delay" stumbled across that.
I'm still trying to chip away at this and doing some research
After some research and looking at how other people have done this i was able to adjust the code so that every time i hit the button it changes pattern even in the middle of a pattern. But now that brings me to 2 new issues.
when i move from Pattern 1 a random pattern to pattern 2 a left to right chaser pattern all the LEDs from Pattern 1 stay on where they left off at until Pattern 2 goes by them.
so i know i need to write a code that turns off the LEDs, but im not sure where to input it and how to write it yet. If possible i think a code that clears all LEDs every time the button is hit would be ideal.
the chaser for pattern 3 is left to right and needs to be right to left but im not sure how to adjust that yet.
int Pin = 0, Locpct = 0, activeLED = 0, onTime = 10, potPin = 0;
int button = 13;
int buttonState = 0;
int p = 0;
int val = 0;
int lastButtonState = 0;
int i = 0;
boolean lastButton = LOW;
boolean currentButton = LOW;
boolean delay_without_delaying(unsigned long time) {
// return false if we're still "delaying", true if time ms has passed.
// this should look a lot like "blink without delay"
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= time) {
previousMillis = currentMillis;
return true;
}
return false;
}
void setup() {
pinMode (button, INPUT);
Serial.begin(9600);
uint16_t chase2 = 13;
for (Pin = 2; Pin < 14; Pin++) {
pinMode(Pin, OUTPUT);
digitalWrite(Pin, HIGH);
delay(500);
digitalWrite(Pin, LOW);
}
}
void loop() {
buttonState = digitalRead(button);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
p++;
delay(1000);
}
}
if (p == 0)
{
Serial.print("Pat1");
//only one random LED on at a time when pot is above center
while (analogRead(2) <= 511) {
onTime = map(analogRead(potPin), 0, 511, 2, 100);
activeLED = (random(2, 13));
digitalWrite(activeLED, HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2, 13), LOW);
}
// LEDs on and Off Randomly when pot is below center
while (analogRead(potPin) > 511) {
onTime = map(analogRead(2), 512, 1023, 100, 2);
digitalWrite(activeLED, HIGH);
delay(random(onTime, onTime * 5));
digitalWrite(random(2, 13), LOW);
}
}
if (p == 1)
{
Serial.print("Pat2");
val = analogRead(potPin);
if (delay_without_delaying(val)) {
digitalWrite(i++, LOW);
if (i >= 13)
i = 1;
digitalWrite(i, HIGH);
}
}
if (p == 2)
{
Serial.print("Pat3");
val = analogRead(potPin);
if (delay_without_delaying(val)) {
digitalWrite(i++, LOW);
if (i >= 13)
i = 1;
digitalWrite(i, HIGH);
}
}
if (p == 3)
{
Serial.print("restart");
p = 0;
}
}