I want to change LED blinking pattern and delay period using serial monitor in Arduino.
first pattern: 1 LED moves sideway
second pattern: 2 LED moves sideway
third pattern: 3 LED moves sideway
fourth pattern: 4 LED moves sideway
period 1: 500 ms
period 2: 300 ms
period 3: 100 ms
period 4: 50 ms
When I enter a, b, c, d, change LED pattern. If I enter c when pattern a is in progress, but it will be proceeded with two leads added on the spot. And I want when I enter 1, 2, 3, 4, delay period is changed.
Next, I've made as many codes as I can, but I don't think I can do it anymore, so I'm posting a question.
char pattern[4][8] = {
{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80},
{0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x81},
{0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0x83},
{0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xE1, 0xC3, 0x87}
};
char data = ' ';
char count = 0;
void setup()
{
Serial.begin(115200);
for(int i=14; i<21; i++) pinMode(i, OUTPUT);
}
void loop()
{
if(Serial.available()>0)
{
data = Serial.read();
Serial.println(data);
switch(data)
{
case 'a':
{
for(int i=count; i<7; i++) digitalWrite(i+14, pattern[1][count] & 1<<i);
count++;
if(count==7) count = 0;
delay(100);
if(data == !'a')
{
break;
}
}
case 'b':
{
for(int i=count; i<7; i++) digitalWrite(i+14, pattern[2][count] & 1<<i);
count++;
if(count==7) count = 0;
delay(500);
if(data == !'b')
{
break;
}
}
case 'c':
{
for(int i=0; i<7; i++) digitalWrite(i+14, pattern[3][count] & 1<<i);
count++;
if(count==7) count = 0;
delay(500);
if(data == !'c')
{
break;
}
}
case 'd':
{
for(int i=0; i<7; i++) digitalWrite(i+14, pattern[4][count] & 1<<i);
count++;
if(count==7) count = 0;
delay(500);
if(data == !'d')
{
break;
}
}
}
}
}
There were several small errors in your code that I try to explain to you step by step. The finished code can be tested (and visualized) here.
for(int i=14; i<21; i++) pinMode(i, OUTPUT);
Here you only initialize 7 out of 8 pins. You need to change i<21
to i<=21
or i<22
. You can count them if you want: 14, 15, 16, 17, 18, 19, 20
would be the case for i<21
, but those are only 7 pins.
for(int i=count; i<7; i++) digitalWrite(i+14, pattern[1][count] & 1<<i);
You want to set all 8 LEDs, so you need to initialize i
to 0
and count to i<8
or i<=7
. Also you start with pattern[1]
, the first pattern needs to have the address pattern[0]
.
if(count==7) count = 0;
Same thing here, if you want to have all 8 cases, you need to count from 0 to 7. If you reset count
at 7, you won't have the last LED state. Change it to count==8
.
if(data == !'a')
{
break;
}
Don't put your break into a condition, simply use break
without if
.
if(Serial.available()>0)
...
switch()
You want to change the LEDs on every iteration of loop()
. If your switch is inside if(Serial.available()>0)
, you only change your LED states when a serial message arrives. This is the reason your LEDs change "randomly". They only get an update, if you actively send a message, not cyclically.
I would recommend to use a variable for delay
and move it outside the switch, same goes with if(count==8) count = 0
.
The final code would be this:
char pattern[4][8] = {
{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80},
{0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x81},
{0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0x83},
{0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xE1, 0xC3, 0x87}
};
char data = ' ';
char count = 0;
int mode = 0;
int delayTime = 500;
void setup()
{
Serial.begin(9600);
Serial.println("Start application");
for(int i=14; i<22; i++) pinMode(i, OUTPUT); //Initialize all 8 pins
}
void loop()
{
if(Serial.available()>0) //Get's only executed if a serial message arrives
{
data = Serial.read();
Serial.println(data);
switch (data) {
case 'a': mode = 0; break;
case 'b': mode = 1; break;
case 'c': mode = 2; break;
case 'd': mode = 3; break;
case '1': delayTime = 500; break;
case '2': delayTime = 250; break;
case '3': delayTime = 100; break;
case '4': delayTime = 50; break;
default: break;
}
}
switch(mode) //Get's executed on every call of loop()
{
case 0:
for(int i=0; i<8; i++) digitalWrite(i+14, pattern[0][count] & 1<<i);
break;
case 1:
for(int i=0; i<8; i++) digitalWrite(i+14, pattern[1][count] & 1<<i);
break;
case 2:
for(int i=0; i<8; i++) digitalWrite(i+14, pattern[2][count] & 1<<i);
break;
case 3:
for(int i=0; i<8; i++) digitalWrite(i+14, pattern[3][count] & 1<<i);
break;
}
delay(delayTime); //Always wait for delayTime ms
count++;
if(count==8) count = 0; //Reset count if it is >7
}