弘毅 发表于 2011-7-14 20:01:02

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

水乐天 发表于 2011-12-23 16:30:09

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);

}

Jacky 发表于 2012-1-16 23:19:20

107行:delay(100);//延时200ms

应该是100ms吧???

弘毅 发表于 2012-1-16 23:34:44

Jacky 发表于 2012-1-16 23:19 static/image/common/back.gif
107行:delay(100);//延时200ms

应该是100ms吧???

:lol是100ms,现在改正过来了

树·水·风 发表于 2012-2-10 16:41:32

上面是按住开关数字停止,有没有可能按一下开关数字停止,再按一下数字接着跳动,我自己试了很多次,可还是不会。下面是我的代码: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帮帮忙。

我的想法是需要两个线程,一个实时检测开关是否按下,一个控制数字不断跳动,可不知道怎么做到。

弘毅 发表于 2012-2-10 16:55:55

这个按键实验中,有按一下开始,按一下停止的代码,你把里面的这个代码和数码管的结合一下,就ok了

http://www.geek-workshop.com/forum.php?mod=viewthread&tid=74

树·水·风 发表于 2012-2-10 20:49:03

弘毅 发表于 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想设多大就设多大。

河山 发表于 2012-4-14 17:04:34

不错,小白学习了~

自由创客 发表于 2012-5-9 00:29:14

请问不能像51那样用一个P1或P2口这样给一个16进制的数去定义吗,版主一个个设,很麻烦

弘毅 发表于 2012-5-9 07:53:26

自由创客 发表于 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

colonne 发表于 2012-11-22 03:44:33

我是个初学者这个代码在arduino uno板卡上用吗?还是说我没有设置好 怎么数码管没反应呀?求教急!

弘毅 发表于 2012-11-22 09:43:07

colonne 发表于 2012-11-22 03:44 static/image/common/back.gif
我是个初学者这个代码在arduino uno板卡上用吗?还是说我没有设置好 怎么数码管没反应呀?求教急!

uno可用,数码管分共阴和共阳,不知道你的和帖子里使用的是不是一个型号的。

低调、人生 发表于 2013-2-15 16:00:47

按键不用消抖么?

弘毅 发表于 2013-2-17 16:00:15

低调、人生 发表于 2013-2-15 16:00 static/image/common/back.gif
按键不用消抖么?

如果使用起来有抖动还是需要消抖的。。。如果使用起来没异常,不用消抖也没事。

低调、人生 发表于 2013-2-17 21:04:48

弘毅 发表于 2013-2-17 16:00 static/image/common/back.gif
如果使用起来有抖动还是需要消抖的。。。如果使用起来没异常,不用消抖也没事。

但目前为止,我用的按键都需要消抖的啊
页: [1] 2 3
查看完整版本: arduino学习笔记8 - 数字骰子实验