2014-8-27 13:26:47 [显示全部楼层]
9963浏览
查看: 9963|回复: 11

二进制时钟(原型机)

[复制链接]
本帖最后由 nille 于 2014-8-27 13:26 编辑

前几天在makerpapa(创客老爹)搞的活动上,哥们王建伟过来说想做一个二进制的时钟,就是那种一看上去要算半天的时钟。比如有4个灯,第一个表示1,第二个表示2,第三个表示4,第4个表示8。这样的话,如果是2点就第二个灯亮,如果是5点就第一个和第三个灯亮,了解二进制的人都知道4个灯能表示的最大数是15,所以小时用4个灯就可以了。

至于分钟的话就需要6个灯,6个灯最大能表示的数是63。你要是带着这个表上街就能充分体现你程序猿的身份了。当时我立马被这个想法打动了,我说我要用护腕做一个,不但体现身份,还属于可穿戴,到时候撸开袖子开时间,还算半天,太拉风了。建伟同学立刻反驳了我的想法,说他要做个挂着的。最后我们求同存异,决定先把原型搭出来。
器件用的就是DFRobot的Arduino入门套件,里面刚好有10个5mm的LED,数量刚刚好。

二进制时钟(原型机)图2
先用Fritzing画个接线示意图吧,要不然这么多线,一会就插乱了。完成后的示意图如下所示。
二进制时钟(原型机)图7
其实就是LED灯的标准接发,正极接Arduino的IO口,负极串电阻接GND,只不过这里重复了10次。套件包里是红黄绿的LED个3个,还有一个全彩LED,这里我把这个全彩LED当作了红色LED使用,在图中我使用白色表示的这个全彩LED。

为了方便观看,我定义上面的LED表示小时,从左到右依次表示1、2、4、8,分别连接Arduino的2、3、4、5引脚。而下面的6个LED表示分钟,从左到右依次表示1、2、4、8、16、32,分别连接Arduino的6、7、8、9、10、11引脚。

如果大家想先验证一下硬件连接是否正确,可以自己写一个Arduino的程序测试一下,这里我就不测试了。完成后的实物图如下。

二进制时钟(原型机)图4
是不是感觉乱糟糟的一堆,图片中后面的4个LED都快看不见了。接下来就开始程序部分,这里我让计算机直接发送时间给Arduino,Arduino接收到之后再用二进制的方式显示出来。计算机端我用的是processing。

打开processing的软件后,我们在example中找到一个叫Clock的例子。

二进制时钟(原型机)图5
打开后processing界面如下所示
二进制时钟(原型机)图1
这个例子的功能就是获取计算机的时间,然后用钟表的形式显示出来,例子的运行效果如下图所示。
二进制时钟(原型机)图6
我们就在这个例子的基础上修改一下吧,让它在显示时间的时候顺便把时间通过串行通信发送给Arduino。首先我们要在代码中import 串口的类库,并且定义一个串口对象myPort。
  1. import processing.serial.*;
  2. Serial myPort;  // Create object from Serial class
  3. 在setup函数中添加初始化串口的代码,设置波特率为9600。
  4.   String portName = Serial.list()[0];
  5.   myPort = new Serial(this, portName, 9600);<span style="font-family: 宋体; "></span>
复制代码
最后在draw函数的末端添加发送时间的代码,为了减少数据的发送频率,我们用一个变量oldMinute来保存当前的分钟数,这样只有分钟数变化的情况下,计算机才会发送一遍时间,发送的内容是一个字母T,加上小时和分钟的数据。T在这里充当了一个数据头的作用,Arduino也只有接收到T之后,才会处理后面的数据。

  1. if(minute()!= oldMinute)
  2.   {
  3.     oldMinute = minute();
  4.     myPort.write('T');
  5.     myPort.write(hour());
  6.     myPort.write(oldMinute);
  7.   }
复制代码
完成processing的代码后我们来书写Arduino的代码。首先要定义小时和分钟两个变量,还要有一些说明和辅助变量。内容如下

  1. //created 2014 by nille
  2. //二进制时钟
  3. //hour
  4. //1、2、4、8对应端口2、3、4、5
  5. //minute
  6. //1、2、4、8、16、32对应端口6、7、8、9、10、11
  7. int hour,minute;
  8. int i;
  9. 在setup函数中将2到11的端口都设置为OUTPUT,同时设置串口波特率为9600。
  10. void setup()
  11. {
  12.   for(i=2;i<12;i++)
  13.   {
  14.     pinMode(i,OUTPUT);
  15.   }
  16.   Serial.begin(9600);
  17. }
复制代码
在loop函数中接收数据,只有接收的字母T的时候才处理后面的数据,因为计算机的时间是24小时制,所以数据接收完成后要对小时数做一个判断,当小时数大于12的时候要将其转换的12小时以内。最后调用showTime函数显示二进制时间。

  1. void loop()
  2. {
  3.   if ( Serial.available())
  4.   {
  5.     if('T'== Serial.read())
  6.     {
  7.       while(!Serial.available());  //hour
  8.       hour= Serial.read() ;
  9.       while(!Serial.available());  //min
  10.       minute= Serial.read();
  11.         
  12.       if(hour>12)
  13.       hour = hour-12;
  14.       
  15.       showTime();
  16.     }
  17.   }
  18. }
复制代码
showTime函数实现时间的二进制转换,这里我们用了一个除2将变量右移的技巧,大家都知道数据在计算机里是以二进制的形式存在的,假设5在计算机就存储为00000101,所以要显示5这个数就要点亮第一个和第三个灯,那程序会如何处理呢?

首先判断变量是奇数还是偶数,如果是奇数就要点亮第一个灯,实际上就是要判断最后一位是0还是1。判断完成后将变量除2,数据就变成了00000010,大家发现了吗,除2这个操作在二进制中就是将整个数列向由移动的一位。这样我们再判断数据的奇偶性就能决定是否点亮第二个LED,后面的以此类推,这样我们通过一个for循环就能快速的实现数据到二进制的转换。showTime函数如下。
  1. void showTime()
  2. {
  3.   for(i=2;i<6;i++)
  4.   {
  5.     if(hour%2 == 1)
  6.     {
  7.       digitalWrite(i,HIGH);
  8.     }
  9.     else
  10.     {
  11.       digitalWrite(i,LOW);
  12.     }
  13.     hour = hour/2;
  14.   }
  15.   
  16.   for(i=6;i<12;i++)
  17.   {
  18.     if(minute%2 == 1)
  19.     {
  20.       digitalWrite(i,HIGH);
  21.     }
  22.     else
  23.     {
  24.       digitalWrite(i,LOW);
  25.     }
  26.     minute = minute/2;
  27.   }
  28. }
复制代码
将程序下载到Arduino中,运行processing中的Clock程序,显示二进制时间的效果如下图所示


二进制时钟(原型机)图3
图中的二进制时钟原型机中上面一排的第三个灯亮,对应的时间是4点,而下面一排的LED是第二个和第四个灯亮,对应的时间是10分,所以当时的时间就是4点10分。原型机完成了,大家期待我的可穿戴式二进制手表吧。

To be continued...






liangzi  初级技师

发表于 2014-8-27 13:32:28

本帖最后由 liangzi 于 2014-8-27 13:33 编辑

你在感叹时间都去哪儿了,我还在计算现在到底几点啦
回复

使用道具 举报

jnhawk  见习技师

发表于 2014-8-27 14:38:00

巧妙,受教了。
回复

使用道具 举报

OvO  见习技师

发表于 2014-8-30 10:51:43

你在感叹时间都去哪儿了,我还在计算现在到底几点啦
回复

使用道具 举报

drink  中级技师

发表于 2014-9-1 14:57:12

做个这样的手表吧,用个赞一点LED屏,四种颜色光点表示时间,分布在表盘上。用力摇就显示正常表面,平时就是2进制点,随机分布。
回复

使用道具 举报

Ricky  NPC

发表于 2014-9-1 19:56:58

可以做个贴片的3色表盘。。。。超薄。。哈哈
回复

使用道具 举报

nille  高级技师
 楼主|

发表于 2014-9-2 18:12:00

drink 发表于 2014-9-1 14:57
做个这样的手表吧,用个赞一点LED屏,四种颜色光点表示时间,分布在表盘上。用力摇就显示正常表面,平时就 ...

为什么要4个光点
回复

使用道具 举报

nille  高级技师
 楼主|

发表于 2014-9-2 18:12:42

drink 发表于 2014-9-1 14:57
做个这样的手表吧,用个赞一点LED屏,四种颜色光点表示时间,分布在表盘上。用力摇就显示正常表面,平时就 ...

为什么要4种颜色
回复

使用道具 举报

nille  高级技师
 楼主|

发表于 2014-9-2 18:14:21

Ricky 发表于 2014-9-1 19:56
可以做个贴片的3色表盘。。。。超薄。。哈哈

还是喜欢大个LED的,感觉有电子的性感。:P
回复

使用道具 举报

Ricky  NPC

发表于 2014-9-2 18:53:46

nille 发表于 2014-9-2 18:14
还是喜欢大个LED的,感觉有电子的性感。

可以大,但是要薄。。。。
回复

使用道具 举报

nille  高级技师
 楼主|

发表于 2014-9-3 11:17:15

在用SD2403 高精度实时时钟模块TOY0020 ,但是返回的时间一直都是0。:L
Sec = 0   Min = 0   H = 0   W = 0   D = 0   M = 0   Y = 0

回复

使用道具 举报

冰渕  中级技师

发表于 2014-11-18 10:56:10

实用型的~~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail