此次加上了行人过街按钮与数码管,一下子代码的复杂度就提高了不少。
1.主要是多任务的问题。
使用millis()函数进行多任务处理,而不是使用delay();
使用delay()可能会阻止我们在“等待”时运行代码,比如这里就是我们的按钮,它是需要时刻待命的。而且millis()具有更加准确的时间安排,这里不再多说。
2.数码管显示的信息与led灯(信号灯)显示的信息应该同步
这里就需要设置一个好的出发点,比如我们的
if(nowtime-pretime1>1000&&(i==0))
与
else if(nowtime-pretime2>1000)
正好都是一秒后才开始的。
下图为连接图,与实际有一点出入,实际是用4位的。(但是我找不到4位的数码管了)
(因为比较懒,所以使用了宏定义)
#define red 11
#define yellow 9
#define green 10
#define button 12
#define dw digitalWrite
#define pm pinMode
unsigned long nowtime=0,pretime1=0,pretime2=0;
int state=0,i=0,j=0,j_pre=0,k=3,temp=0,t=1;
void setup() {
pm(red,OUTPUT);
pm(yellow,OUTPUT);
pm(green,OUTPUT);
pm(button,INPUT);
for(int m=2;m<=8;m++)
pm(m,OUTPUT);//2-8 a-g
}
void loop() {
nowtime=millis();
state=digitalRead(button);
if(nowtime-pretime1>1000&&(i==0))
{//只执行一次!!
pretime1=nowtime;
i=1;//红灯亮完之后i=1;
dw(red,1);dw(yellow,0);dw(green,0);
}
if(nowtime-pretime1>3000&&(i==1))
{
pretime1=nowtime;
i=2;//green灯亮完之后i=2;
dw(green,1);dw(yellow,0);dw(red,0);
}
if(nowtime-pretime1>3000&&(i==2))
{
pretime1=nowtime;
i=0;//y灯亮完之后i=0;,yellow begin to light
dw(yellow,1);dw(green,0);dw(red,0);
}
if(state==1)
{
cross();
}
if(i==0)//yellow on ,数码管不亮。
{
for(int m=2;m<=8;m++)
dw(m,0);
k=3;
}
else if(nowtime-pretime2>1000)
{//虽然off但是仍然在运行
pretime2=nowtime;
j++;
j_pre++;
displayDigit(k);
k--;//点亮数码管。should from 3 to 1 repeatedly.
if(k==0) k=3;
}
}
void cross()
{
dw(green,1);dw(red,0);dw(yellow,0);
i=2;//skip to yellow
pretime1=nowtime;// 重新3s
k=3;
}
void displayDigit(unsigned char digit)//digit ->we want show the num on digitalscreen
{
unsigned char abcdefgh[][8] = {
//a b c d e f g
{1,1,1,1,1,1,0,0},
{0,1,1,0,0,0,0,0}, //1
{1,1,0,1,1,0,1,0},//2
{1,1,1,1,0,0,1,0}, // 3
};
//a b c ...
//2 3 4 ...
for (unsigned char x=0; x<7; x++)
dw( 2+x, abcdefgh[digit][x] );
}
最后,
演示视频