楼主前一阵子弄来一块8*8的LED模块,想用来做贪吃蛇或俄罗斯方块吧来玩玩看吧,又觉得似乎有一点老套。思来想去,觉得不如做个小“手表”吧,方方的和现在很多智能手表一样呢 :) ,大小也比较合适。
由于一块点阵上一共只有64个点,楼主只能把表盘浓缩一下,用独特一些的方式来表示时间,来猜猜看下面的视频中显示的是几点吧~
铛铛铛~正确答案是11:59分到12:00的转换!你猜对了嘛~下面就让我来解释一下怎么读懂这块表吧
图中的紫色部分,应该是最好看懂的吧,一亮一灭代表1秒的流逝
而蓝色部分,就如我们日常的表一样,显示的是小时,最顶端为12,最下端为6;
橙色部分所显示的是具体的分钟,范围是0-15;但一小时有60分钟,就用绿色部分显示的是当前时间是一小时内的第几个15分钟,
因此右上角亮为0-14,右下角则代表15-29,左下角20-44,左上角45-59; 60则又会循环回0
视频中左上角的三角亮起,外围红灯亮起14颗,所以代表45+14=59分,跳转后右上角亮起,红灯亮15颗,代表0
在这里楼主选择了用亮15颗代表0/15,是想让在如9:15时灯全部亮起,当然你也可以修改代码用全灭来代表0/15
怎么样,是不是很“搞”啊,楼主其实也是不愿意这样的啊!
在构思这块表盘的时候,楼主可是煞费苦心,要知道,因为8是偶数,只要有一行是亮奇数个像素点的话,就会导致整个图案的不对称,尝试了各种可能性发现如上的排列方式还算不错,不仅15是60的分子,剩下来的像素点也正好分成了四块,真是一件不容易的事情!
废话不多说啦,来看看这个有些小“蛇精”的表是怎么做的吧!
一、所需元件
8*8 双色I2C点阵 *1
Arduino Uno *1
DS1370时钟模块 *1
导线若干
二、连线
将各部件按下图所示连接:
小贴士:Uno上的SCL,SDA在 数字端Aref的左边,可以通过观察UNO的背面找到标识;
三、库文件安装
adafruit_ledbackpack.zip
adafruit_gfx.zip
四、识别点阵模块地址
I2C地址位 模块后有A0 A1 A2三个空焊盘 断开为零 短接为1
A0
A1
A2
地址码
0 0 0 0x70 1 0 0 0x71 0 1 0 0x72 1 1 0 0x73 0 0 1 0x74 1 0 1 0x75 0 1 1 0x76 1 1 1 0x77
五、烧入代码
在理解完以下的代码以后,如果有别的显示时间的想法,比如你有更多的点阵模块的话,你大可以改动代码,做出不同的动画效果,期待更多作品哟~
/*
Finished by YU SUN on 08/11/2015
This is the code for an 8*8 LED Matrix Clock.
The time can be set everytime the program is compiled.
*/
#include <Wire.h>
#include <Adafruit_LEDBackpack.h>
#include <Adafruit_GFX.h>
#include <RTClib.h>
RTC_DS1307 RTC; //utilize the RTC library to keep track of time
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix(); //utilize the Adafruit library to drive the LED matrix
long currentTime=0;
long prevTime=0;
int h =0;//hour
int m =0;//minute
int part=0;//which 15 mins segment it's in
boolean first = true;// the first time to display time
void setup() {
Serial.begin(9600);
RTC.begin();
matrix.begin(0x72); // pass in the address
matrix.clear();
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
}
RTC.adjust(DateTime(2015, 8, 11,16, 16, 10));// manually set the time
DateTime now = RTC.now(); // get the time from RTC
h = (now.hour());
if(h >= 12){
h = (h - 12); //-12 because RTC is 24 Hour but there are only 12 LEDS on inner ring
}
part=((now.minute()/15))%4;// get which 15min section time is in
m=(now.minute());
}
void loop(){
//reset hour once it reaches 12
if (h==12){
h=0;
}
Serial.print("hour");//for debugging purposes
Serial.println(h,DEC);
for(h;h<12;h++){
hoursAnimation(h);// show the animation for hour
//reset minute once it reaches 60
if (m==60){
m=0;
}
for(m;m<60;m++){// the minute loop
//increment part as time passes by
if (first!=true && m%15==0){
part++;
if (part==4){//reset part
part=0;
}
}
minutesAnimation(m%15);//animation for mins
Serial.print("part");
Serial.println(part);
partAnimation(part);//animation for part
// Seconds loop
for(int s=0; s<60; s++){
while(currentTime - prevTime < 0.5){ // waits for RTC to advance 1 second before continuing
DateTime now = RTC.now();
prevTime = currentTime;
currentTime = now.unixtime();
}
if(s != 0 ){
matrix.drawPixel(4,4,LED_GREEN);
matrix.writeDisplay();
delay(500);
matrix.drawPixel(4,4,0);
matrix.writeDisplay();
delay(500);
}
}
}
}
}
void minutesAnimation(int c){
Serial.print("min");
Serial.println(c);
// draw the whole min line if it's the first time operating
if (first== true){
if(0<c&&c<=8){
if (c==1){
clearmin();// clear the min display before writing new ones
}
matrix.drawLine(0,0,c-1,0,LED_GREEN);
matrix.writeDisplay();
}else if (8<c&&c<15){
matrix.drawLine(0,0,7,0,LED_GREEN);
matrix.drawLine(0,0,0,c-8,LED_GREEN);
matrix.writeDisplay();
}else if (c==0){
matrix.drawLine(0,0,0,7,LED_GREEN);
matrix.drawLine(0,0,7,0,LED_GREEN);
matrix.writeDisplay();
}
first = false;
}else {// draw one pixel at one time
if(0<c&&c<=8){
if (c==1){
clearmin();
}
matrix.drawPixel(c-1,0,LED_GREEN);
matrix.writeDisplay();
}else if (8<c&&c<15){
matrix.drawPixel(0,c-8,LED_GREEN);
matrix.writeDisplay();
}else if (c==0){
matrix.drawLine(0,0,0,7,LED_GREEN);
matrix.drawLine(0,0,7,0,LED_GREEN);
matrix.writeDisplay();
}
}
}
void clearmin(){
matrix.drawLine(0,0,0,7,0);
matrix.drawLine(0,0,7,0,0);
matrix.writeDisplay();
}
void hoursAnimation(int a){
//lines for all hour displays
matrix.drawLine(4,1,7,4,0);
matrix.drawLine(7,4,4,7,0);
matrix.drawLine(4,7,1,4,0);
matrix.drawLine(1,4,4,1,0);
matrix.drawLine(4,1,7,4,LED_RED);
matrix.drawLine(7,4,4,7,LED_RED);
matrix.drawLine(4,7,1,4,LED_RED);
matrix.drawLine(1,4,4,1,LED_RED);
matrix.writeDisplay();
Serial.print(a);
//show the exact hour
if (0<=a&&a<=2){
matrix.drawPixel(7-a,4+a,0);
matrix.drawPixel(7-a,a+4,LED_GREEN);
matrix.writeDisplay();
}else if (3<=a&&a<=5){
matrix.drawPixel(4-a%3,7-a%3,0);
matrix.drawPixel(4-a%3,7-a%3,LED_GREEN);
matrix.writeDisplay();
}else if (6<=a&&a<=8){
matrix.drawPixel(1+a%3,4-a%3,0);
matrix.drawPixel(1+a%3,4-a%3,LED_GREEN);
matrix.writeDisplay();
}else{
matrix.drawPixel(4+a%3,1+a%3,0);
matrix.drawPixel(4+a%3,1+a%3,LED_GREEN);
matrix.writeDisplay();
}
}
void partAnimation(int b){
if (b==3){
matrix.fillTriangle(3,1,1,1,1,3,0);
matrix.fillTriangle(5,1,7,1,7,3,LED_YELLOW);
matrix.writeDisplay();
}else if (b ==0){
matrix.fillTriangle(5,1,7,1,7,3,0);
matrix.fillTriangle(7,5,7,7,5,7,LED_YELLOW);
matrix.writeDisplay();
}else if (b ==1){
matrix.fillTriangle(7,5,7,7,5,7,0);
matrix.fillTriangle(1,5,1,7,3,7,LED_YELLOW);
matrix.writeDisplay();
}else if (b ==2){
matrix.fillTriangle(1,5,1,7,3,7,0);
matrix.fillTriangle(3,1,1,1,1,3,LED_YELLOW);
matrix.writeDisplay();
}
}
复制代码