二进制时钟(原型机)
本帖最后由 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,数量刚刚好。
先用Fritzing画个接线示意图吧,要不然这么多线,一会就插乱了。完成后的示意图如下所示。其实就是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个LED都快看不见了。接下来就开始程序部分,这里我让计算机直接发送时间给Arduino,Arduino接收到之后再用二进制的方式显示出来。计算机端我用的是processing。
打开processing的软件后,我们在example中找到一个叫Clock的例子。
打开后processing界面如下所示。这个例子的功能就是获取计算机的时间,然后用钟表的形式显示出来,例子的运行效果如下图所示。我们就在这个例子的基础上修改一下吧,让它在显示时间的时候顺便把时间通过串行通信发送给Arduino。首先我们要在代码中import 串口的类库,并且定义一个串口对象myPort。import processing.serial.*;
Serial myPort;// Create object from Serial class
在setup函数中添加初始化串口的代码,设置波特率为9600。
String portName = Serial.list();
myPort = new Serial(this, portName, 9600);<span style="font-family: 宋体; "></span>最后在draw函数的末端添加发送时间的代码,为了减少数据的发送频率,我们用一个变量oldMinute来保存当前的分钟数,这样只有分钟数变化的情况下,计算机才会发送一遍时间,发送的内容是一个字母T,加上小时和分钟的数据。T在这里充当了一个数据头的作用,Arduino也只有接收到T之后,才会处理后面的数据。
if(minute()!= oldMinute)
{
oldMinute = minute();
myPort.write('T');
myPort.write(hour());
myPort.write(oldMinute);
}完成processing的代码后我们来书写Arduino的代码。首先要定义小时和分钟两个变量,还要有一些说明和辅助变量。内容如下
//created 2014 by nille
//二进制时钟
//hour
//1、2、4、8对应端口2、3、4、5
//minute
//1、2、4、8、16、32对应端口6、7、8、9、10、11
int hour,minute;
int i;
在setup函数中将2到11的端口都设置为OUTPUT,同时设置串口波特率为9600。
void setup()
{
for(i=2;i<12;i++)
{
pinMode(i,OUTPUT);
}
Serial.begin(9600);
} 在loop函数中接收数据,只有接收的字母T的时候才处理后面的数据,因为计算机的时间是24小时制,所以数据接收完成后要对小时数做一个判断,当小时数大于12的时候要将其转换的12小时以内。最后调用showTime函数显示二进制时间。
void loop()
{
if ( Serial.available())
{
if('T'== Serial.read())
{
while(!Serial.available());//hour
hour= Serial.read() ;
while(!Serial.available());//min
minute= Serial.read();
if(hour>12)
hour = hour-12;
showTime();
}
}
}showTime函数实现时间的二进制转换,这里我们用了一个除2将变量右移的技巧,大家都知道数据在计算机里是以二进制的形式存在的,假设5在计算机就存储为00000101,所以要显示5这个数就要点亮第一个和第三个灯,那程序会如何处理呢?
首先判断变量是奇数还是偶数,如果是奇数就要点亮第一个灯,实际上就是要判断最后一位是0还是1。判断完成后将变量除2,数据就变成了00000010,大家发现了吗,除2这个操作在二进制中就是将整个数列向由移动的一位。这样我们再判断数据的奇偶性就能决定是否点亮第二个LED,后面的以此类推,这样我们通过一个for循环就能快速的实现数据到二进制的转换。showTime函数如下。
void showTime()
{
for(i=2;i<6;i++)
{
if(hour%2 == 1)
{
digitalWrite(i,HIGH);
}
else
{
digitalWrite(i,LOW);
}
hour = hour/2;
}
for(i=6;i<12;i++)
{
if(minute%2 == 1)
{
digitalWrite(i,HIGH);
}
else
{
digitalWrite(i,LOW);
}
minute = minute/2;
}
}将程序下载到Arduino中,运行processing中的Clock程序,显示二进制时间的效果如下图所示
图中的二进制时钟原型机中上面一排的第三个灯亮,对应的时间是4点,而下面一排的LED是第二个和第四个灯亮,对应的时间是10分,所以当时的时间就是4点10分。原型机完成了,大家期待我的可穿戴式二进制手表吧。
To be continued...
static/image/hrline/5.gif
相关链接:Arduino入门套件,时钟模块
本帖最后由 liangzi 于 2014-8-27 13:33 编辑
你在感叹时间都去哪儿了,我还在计算现在到底几点啦 巧妙,受教了。 你在感叹时间都去哪儿了,我还在计算现在到底几点啦 做个这样的手表吧,用个赞一点LED屏,四种颜色光点表示时间,分布在表盘上。用力摇就显示正常表面,平时就是2进制点,随机分布。 可以做个贴片的3色表盘。。。。超薄。。哈哈 drink 发表于 2014-9-1 14:57
做个这样的手表吧,用个赞一点LED屏,四种颜色光点表示时间,分布在表盘上。用力摇就显示正常表面,平时就 ...
为什么要4个光点 drink 发表于 2014-9-1 14:57
做个这样的手表吧,用个赞一点LED屏,四种颜色光点表示时间,分布在表盘上。用力摇就显示正常表面,平时就 ...
为什么要4种颜色 Ricky 发表于 2014-9-1 19:56
可以做个贴片的3色表盘。。。。超薄。。哈哈
还是喜欢大个LED的,感觉有电子的性感。:P nille 发表于 2014-9-2 18:14
还是喜欢大个LED的,感觉有电子的性感。
可以大,但是要薄。。。。 在用SD2403 高精度实时时钟模块TOY0020 ,但是返回的时间一直都是0。:L
Sec = 0 Min = 0 H = 0 W = 0 D = 0 M = 0 Y = 0
实用型的~~
页:
[1]