时光葫芦
来自Labplus盛思维基百科
概述
本作品实现模拟沙漏倒计时功能,并用LED灯带模拟沙漏中沙子向下滴落的效果。使用时先根据制作说明将 作品组装完整,然后接上电源(9V电池或USB供电),打开主控板开关,正立放置在桌面即可。四位数码管作 为显示装置,可设置0-9999,流水灯每完成一次循环,显示值减1,到0后自动停止;需要重置或启动沙漏 时,将作品倒立一秒后再正立。DIY动手组装,锻炼动手能力,了解智能创意电子套件的使用,激发创新思 维,增加学习乐趣。
使用教程
组装说明
电子模块清单
| 模块名称 | 数量 |
|---|---|
| W1主控板 | x1 |
| 倾斜开关 | x1 |
| 数码管 | x1 |
| RGB灯带(8颗) | x1 |
电子模块连接说明
| 模块 | 引脚 | 说明 |
|---|---|---|
| 倾斜开关 | W1-3/11接口 | |
| 数码管 | W1-7/8接口 | |
| RGB灯带 | W1-UART(0/1)接口 |
Arduino程序/图形化程序
| 时光葫芦程序包 |
#include "Wire.h"
#include "TM1650.h"
#include "Adafruit_NeoPixel.h"
#include "FlexiTimer2.h"
#include "TM1637x.h"
#include "TM1650.h"
// #define CLK 7
// #define DATA 8
#define xinhao 3
#define MAX_LEN 8 //LED灯数量
uint32_t LED[MAX_LEN] = {0x000000ff,0x00000080,0x00000040,0x00000010,0x00000000,0x00000000,0x00000000}; //LED泪滴式亮灯正向数组(蓝灯)
uint32_t LED1[MAX_LEN] = {0x00000000,0x00000000,0x00000000,0x00000010,0x00000040,0x00000080,0x000000ff}; //LED1泪滴式亮灯反向数组(蓝灯)
int val,vall;
int16_t temp = 0;
TM1650 d;
char line[] = {"----"};
unsigned long blanktime;
unsigned long blanktime1;
long int number=6000; /* 代表那个非常大的数字 */
long int number1=0; /* 代表那个非常大的数字 */
unsigned char ge,shi,bai,qian,wan; /* 代表提取结果:个,十,百,千,万 */
int8_t DispData[5]; //数据缓冲数组
int ks=0;
int flag=0;
int flag1=1;
int flag2=0;
int numpixelsPin = 0;
#define nusec 5
#define NUMPIXELS 8
Adafruit_NeoPixel pixels1 = Adafruit_NeoPixel(NUMPIXELS, numpixelsPin, NEO_GRB + NEO_KHZ800);
TM1637 digitalDis; //创建一个数码管显示对象
char getTochar(uint8_t bcd)//正显示,取得正显示码
{
char c;
switch (bcd)
{
case 0:
c = '0';
break;
case 1:
c = '1';
break;
case 2:
c = '2';
break;
case 3:
c = '3';
break;
case 4:
c = '4';
break;
case 5:
c = '5';
break;
case 6:
c = '6';
break;
case 7:
c = '7';
break;
case 8:
c = '8';
break;
default:
c = '9';
break;
}
return c;
}
char getTochar1(uint8_t bcd)//反显示,取得反显示码
{
char c;
switch (bcd)
{
case 0:
c = '0';
break;
case 1:
c = '1';
break;
case 2:
c = '2';
break;
case 3:
c = 'E';
break;
case 4:
c = 'h';
break;
case 5:
c = '5';
break;
case 6:
c = '9';
break;
case 7:
c = 'L';
break;
case 8:
c = '8';
break;
default:
c = '6';
break;
}
return c;
}
void hexToBCD(unsigned long int val)//正显示
{
int i;
unsigned long int num = val;
if (num > 6000) num = 6000;
for (i=0; num > 999; i++) num -= 1000;
if(i != 0)
{
line[1] = getTochar(i);
}
else
{
line[1] = ' ';
}
for (i=0; num > 99; i++)
{
num -= 100;
}
if(i != 0)
{
line[2] = getTochar(i);
}
else
{
if(line[1]==' ')
{
line[2] = ' ';
}
}
for (i=0; num > 9; i++)
{
num -= 10;
}
line[3] = getTochar(i);
line[4] = getTochar(num);
line[0] = ' ';
}
void hexToBCD1(unsigned long int val)//反显示
{
int i;
unsigned long int num = val;
if (num > 6000) num = 6000;
for (i=0; num > 999; i++) num -= 1000;
if(i != 0)
{
line[2] = getTochar1(i);
}
else
{
line[2] = ' ';
}
for (i=0; num > 99; i++) num -= 100;
if(i != 0)
{
line[1] = getTochar1(i);
}
else
{
if(line[2] == ' ')
{
line[1] = ' ';
}
else
{
line[1] = getTochar1(i);
}
}
for (i=0; num > 9; i++) num -= 10;
line[0] = getTochar1(i);
line[4] = getTochar1(num);
line[3] = ' ';
}
/**********************************************************************************
*
**********************************************************************************/
/******************************************
泪滴灯光算法(正向)
******************************************/
void LedDropPattern(void)
{
static uint8_t start = 0;
int i,m;
for(i = 0; i < 8; i++)
{
m = i + start;
m = m % 8;
pixels1.setPixelColor(i, LED[m]);
}
pixels1.show();
start++;
start = start % 8;
}
/******************************************
泪滴灯光算法(反向),反向时数据类型要定义成uint8
数据类型的定义影响取值结果。
******************************************/
void LedDropPattern1(void)
{
static uint8_t start1 = 0;
int i,m;
for(i = 0; i < 8; i++)
{
m = i + start1;
m = m % 8;
pixels1.setPixelColor(i, LED1[m]);
}
pixels1.show();
start1--;
start1 = start1 % 8;
}
/******************************************
系统初始化配置
******************************************/
void setup()
{
pinMode(numpixelsPin,OUTPUT);
pinMode(xinhao,INPUT);
digitalWrite(numpixelsPin,LOW);
Wire.begin(); // join i2c bus (address optional for master)
d.init();
d.displayOff();
blanktime = millis();
// Serial.begin(115200);
}
/**********************************************************************************
*
**********************************************************************************/
void loop()
{
unsigned int Light_sr;
Light_sr = digitalRead(xinhao);
// Serial.println(Light_sr);
//当沙漏正放时,倾斜开关输出为“0”电平,倒放放时输出为“1”电平。
if((Light_sr==0)&&(ks==0))//沙漏正放时,Light_sr读到0
{
ks=1;
if((number==6000))
{
for(int i=0; i<4; i++) line[i] ='-';
d.displayString(line);
d.setBrightness(TM1650_MIN_BRIGHT);
d.displayOn();
}
while(digitalRead(xinhao) == 1);
delay(50);
while(digitalRead(xinhao) == 1);
}
if((Light_sr==1)&&(ks==0))//沙漏倒放时,Light_sr读到1
{
ks=1;
if((number==6000))
{
for(int i=0; i<4; i++) line[i] ='-';
d.displayString(line);
d.setBrightness(TM1650_MIN_BRIGHT);
d.displayOn();
}
while(digitalRead(xinhao) == 1);
delay(100);
while(digitalRead(xinhao) == 1);
}
if(ks)
{
if(digitalRead(xinhao))//1时,倒放
{
LedDropPattern();
if(number1 >0)
{
number1--;
number++;
ge = (unsigned char)(number1%10);
wan = (unsigned char)((number1/10)%10);
qian = (unsigned char)((number1/100)%10);
bai = (unsigned char)((number1/1000)%10);
shi = (unsigned char)((number1/10000)%10);
hexToBCD1(number1);
d.displayString(line);
d.setBrightness(1);
d.displayOn();
delay(110);
}
else
{
number1 = 0;
for(int i=0; i<4; i++) line[i] ='-';
d.displayString(line);
d.setBrightness(TM1650_MIN_BRIGHT);
d.displayOn();
}
}
else//0时,正放
{
LedDropPattern1();//正向沙漏效果
if(number>0)//修改为:大于等于0时,可以显示
{
number--;//正变量从最大6000减减
number1=(6000-number);//反变量从0加加
ge= (unsigned char)(number%10);
shi= (unsigned char)((number/10)%10);
bai= (unsigned char)((number/100)%10);
qian= (unsigned char)((number/1000)%10);
wan= (unsigned char)((number/10000)%10);
hexToBCD(number);
d.displayString(line);
d.setBrightness(1);
d.displayOn();
delay(110);
}
else//小于0时,显示“----”
{
LedDropPattern1();
number = 0;
for(int i=0; i<4; i++) line[i] ='-';
d.displayString(line);
d.setBrightness(TM1650_MIN_BRIGHT);
d.displayOn();
}
}
}
}
FAQ
版本历史记录
| Version | Date | 新增/删除/修复 |
|---|---|---|

