arduino学习笔记8 - 数字骰子实验
前几次做了数码管实验和按键控制LED的实验,通过实验大家已经学会了两种器件的基本用法。这次使用数码管与按键进行组合,做一个简易数字骰子。
数字筛子的基本原理是数码管快速在1-8之间循环跳动,当按下按键时,数码管定格在当前的数字上,不再跳动。
先看一下接线图
//设置控制各段的数字IO脚
int a=7;
int b=6;
int c=5;
int d=11;
int e=10;
int f=8;
int g=9;
int dp=4;
//显示数字1
void digital_1(void)
{
unsigned char j;
digitalWrite(c,LOW);//给数字5引脚低电平,点亮c段
digitalWrite(b,LOW);//点亮b段
for(j=7;j<=11;j++)//熄灭其余段
digitalWrite(j,HIGH);
digitalWrite(dp,HIGH);//熄灭小数点DP段
}
//显示数字2
void digital_2(void)
{
unsigned char j;
digitalWrite(b,LOW);
digitalWrite(a,LOW);
for(j=9;j<=11;j++)
digitalWrite(j,LOW);
digitalWrite(dp,HIGH);
digitalWrite(c,HIGH);
digitalWrite(f,HIGH);
}
//显示数字3
void digital_3(void)
{
unsigned char j;
digitalWrite(g,LOW);
digitalWrite(d,LOW);
for(j=5;j<=7;j++)
digitalWrite(j,LOW);
digitalWrite(dp,HIGH);
digitalWrite(f,HIGH);
digitalWrite(e,HIGH);
}
//显示数字4
void digital_4(void)
{
digitalWrite(c,LOW);
digitalWrite(b,LOW);
digitalWrite(f,LOW);
digitalWrite(g,LOW);
digitalWrite(dp,HIGH);
digitalWrite(a,HIGH);
digitalWrite(e,HIGH);
digitalWrite(d,HIGH);
}
//显示数字5
void digital_5(void)
{
unsigned char j;
for(j=7;j<=9;j++)
digitalWrite(j,LOW);
digitalWrite(c,LOW);
digitalWrite(d,LOW);
digitalWrite(dp,HIGH);
digitalWrite(b,HIGH);
digitalWrite(e,HIGH);
}
//显示数字6
void digital_6(void)
{
unsigned char j;
for(j=7;j<=11;j++)
digitalWrite(j,LOW);
digitalWrite(c,LOW);
digitalWrite(dp,HIGH);
digitalWrite(b,HIGH);
}
//显示数字7
void digital_7(void)
{
unsigned char j;
for(j=5;j<=7;j++)
digitalWrite(j,LOW);
digitalWrite(dp,HIGH);
for(j=8;j<=11;j++)
digitalWrite(j,HIGH);
}
//显示数字8
void digital_8(void)
{
unsigned char j;
for(j=5;j<=11;j++)
digitalWrite(j,LOW);
digitalWrite(dp,HIGH);
}
void setup()
{
int i;
for(i=4;i<=11;i++)
{
pinMode(i,OUTPUT);//设置4~11口为输出模式
}
}
void loop()
{
while(1)
{
digital_1();//显示数字1
while(analogRead(0)>1000);//如果读到模拟0口的值1000则说明有按键按下
delay(100);//延时100ms
digital_2();
while(analogRead(0)>1000);
delay(100);
digital_3();
while(analogRead(0)>1000);
delay(100);
digital_4();
while(analogRead(0)>1000);
delay(100);
digital_5();
while(analogRead(0)>1000);
delay(100);
digital_6();
while(analogRead(0)>1000);
delay(100);
digital_7();
while(analogRead(0)>1000);
delay(100);
digital_8();
while(analogRead(0)>1000);
delay(100);
}
}实验的效果如下
http://player.youku.com/player.php/sid/XMjg1MDE1MjA4/v.swf int button=0; //定义按钮
byte seven_seg_digits = { //设置每个数字所对应的开关数组
{ 1,0,0,0,0,1,0,0 },// = 0
{ 1,0,0,1,1,1,1,1 },// = 1
{ 1,1,0,0,1,0,0,0 },// = 2
{ 1,0,0,0,1,0,1,0 },// = 3
{ 1,0,0,1,0,0,1,1 },// = 4
{ 1,0,1,0,0,0,1,0 },// = 5
{ 1,0,1,0,0,0,0,0 },// = 6
{ 1,0,0,0,1,1,1,1 },// = 7
{ 1,0,0,0,0,0,0,0 },// = 8
{ 1,0,0,0,0,0,1,0 } // = 9
};
void setup() { //4-11号端口设定为输出模式
int i;//定义变量
for(i=4;i<=11;i++)
pinMode(i,OUTPUT);//设置4~11引脚为输出模式
}
void sevenSegWrite(byte digit) {//设置通过数组控制引脚开关,顺序为4-11号端口
byte pin = 4;
for (byte segCount = 0; segCount < 8; ++segCount) {
digitalWrite(pin, seven_seg_digits);
++pin;
}
}
void loop() { //设置显示效果为从9开始倒数
for (byte count = 10; count > 0; --count) {
delay(100);
sevenSegWrite(count - 1);
while(analogRead(button)>1000); //如果按键则暂停
}
delay(100);
} 107行:delay(100);//延时200ms
应该是100ms吧??? Jacky 发表于 2012-1-16 23:19 static/image/common/back.gif
107行:delay(100);//延时200ms
应该是100ms吧???
:lol是100ms,现在改正过来了 上面是按住开关数字停止,有没有可能按一下开关数字停止,再按一下数字接着跳动,我自己试了很多次,可还是不会。下面是我的代码:void loop()
{
rad();//随机显示数字
while(analogRead(5)>1000) //当开关按下时
{
onoff = !onoff;//停止标志,true时停止,false时跳动
if(on)//若on 为true
{
while(analogRead(5) < 1000) ; //当读取值小于1000时,保持停止状态,一旦读取值>1000则跳出while循环
}
break;//跳出外层while循环,更新数字
}
delay(1000);//延迟1s
}下载到板上结果不对。
恳请lz帮帮忙。
我的想法是需要两个线程,一个实时检测开关是否按下,一个控制数字不断跳动,可不知道怎么做到。 这个按键实验中,有按一下开始,按一下停止的代码,你把里面的这个代码和数码管的结合一下,就ok了
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=74 弘毅 发表于 2012-2-10 16:55 static/image/common/back.gif
这个按键实验中,有按一下开始,按一下停止的代码,你把里面的这个代码和数码管的结合一下,就ok了
http ...
这是后来写的:int led = 13;
int Button = 11;
boolean on = LOW;
long randNumber;
int pin[] = {1,2,4,5,6,7,9,10};
int digit={
{1,1,1,0,1,1,1,0},
{0,0,1,0,1,0,0,0},
{1,1,0,0,1,1,0,1},
{0,1,1,0,1,1,0,1},
{0,0,1,0,1,0,1,1},
{0,1,1,0,0,1,1,1},
{1,1,1,0,0,1,1,1},
{0,0,1,0,1,1,0,0},
{1,1,1,0,1,1,1,1},
{0,1,1,0,1,1,1,1}
};
void setup()
{
pinMode(Button, INPUT);
pinMode(led, OUTPUT);
for(int i = 0; i < 8; i++)
{
pinMode(pin, OUTPUT);
}
}
void rad() //随机产生0-9
{
randNumber = random(0,10);
for(int j = 0; j < 8; j++)
{
if(digit == 1)
digitalWrite(pin, HIGH);
else
digitalWrite(pin, LOW);
}
}
void loop()
{
if(digitalRead(Button) == LOW)//第一个if——if_1
{
delay(10);//第一个delay——delay_1
if(digitalRead(Button) == HIGH)//第二个if——if_2
{
digitalWrite(led, on);
on = !on;
delay(10);//第二个delay——delay_2
while(digitalRead(Button) == HIGH)
{
delay(1);
}
}
if(on == HIGH) //if_3
{
rad();
delay(10); //第三个delay——delay_3。当delay_3取0或者很小的值时,反应正常,但取50及更大时则按键没效果即无论怎么按,数字都不会停止跳动,而且led13也不会亮。
}
}
}我的分析是这样的:
当delay_3=0时,数码管急速地变化,即整个loop执行地很快,由delay_1知道每隔10ms就检查一次有没有上升沿;而当delay_3取50或者更大的值时,delay_3这段时间的比重就占得很大,倘若在这段时间按下开关,就不能检查到有上升沿事件,进而跳过if_2继续执行if_3。
我在做实验时发现,当delay_3越小,按键灵敏度越高。当delay_3取50时,偶尔还能改变一下on的值,即使数字停止跳动,当取500时,按键就完全没反应了,数字始终按照510ms的频率跳动,led始终灭(led亮时说明数字停止跳动)。
所以想问问lz和各位高手,有没有办法使delay_3想设多大就设多大。 不错,小白学习了~ 请问不能像51那样用一个P1或P2口这样给一个16进制的数去定义吗,版主一个个设,很麻烦 自由创客 发表于 2012-5-9 00:29 static/image/common/back.gif
请问不能像51那样用一个P1或P2口这样给一个16进制的数去定义吗,版主一个个设,很麻烦
可以滴。。。可以参照这个帖子
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=389 我是个初学者这个代码在arduino uno板卡上用吗?还是说我没有设置好 怎么数码管没反应呀?求教急! colonne 发表于 2012-11-22 03:44 static/image/common/back.gif
我是个初学者这个代码在arduino uno板卡上用吗?还是说我没有设置好 怎么数码管没反应呀?求教急!
uno可用,数码管分共阴和共阳,不知道你的和帖子里使用的是不是一个型号的。 按键不用消抖么?
低调、人生 发表于 2013-2-15 16:00 static/image/common/back.gif
按键不用消抖么?
如果使用起来有抖动还是需要消抖的。。。如果使用起来没异常,不用消抖也没事。 弘毅 发表于 2013-2-17 16:00 static/image/common/back.gif
如果使用起来有抖动还是需要消抖的。。。如果使用起来没异常,不用消抖也没事。
但目前为止,我用的按键都需要消抖的啊