远古警告:这是一篇很久以前的文章。曾经写在微信公众号上,特此复制粘贴。所列代码仅供参考,不一定可以运行。
背景
番茄钟,是指把任务分解成半小时左右,集中精力工作/学习25分钟后休息5分钟,如此视作种一个“番茄”。哪怕工作/学习没有完成,也要定时休息,然后再进入下一个番茄时间。
每天工作/学习之前,先把一天的工作/学习任务划分若干个 “番茄钟”,规定好每个“番茄钟”内要完成的小目标,然后尽量心无旁骛地工作/学习,这种“番茄工作/学习法”的流程,也被称为拖延症“自救攻略”之一。
番茄钟实质上就是计时器,平时手表倒计时繁琐、手机计时分散注意力,DIY的番茄钟插电即可计时,采用Arduino进行控制,可以在电脑端更改计时时间,番茄钟的背面可以DIY自定义。
不带外壳的实物图如下:
简介
功能
- 该装置具有计时功能,默认状态下:插入电源即是25分钟工作倒计时,倒计时的最小单位为秒;到25分钟,倒计时结束之后,会开始进行五分钟休息倒计时。
- 该装置具有提醒功能,默认状态下:25分钟倒计时结束之后蜂鸣器会响三声;五分钟倒计时结束之后,蜂鸣器会响三声;蜂鸣器响声的频率可以在IDE中调节。
- 该装置的时间计数器的上方和下方分别有两盏led灯,在默认状态下:当计数器为25分钟倒计时时,上方led灯亮;当计数器为五分钟倒计时时,下方led灯亮。
外形
- 外形有两种制作材料:两毫米的亚克力板或两毫米的木板。
- 在靠近上下两个led灯的面板处可以贴不同字样的字条,样例如下:“离休息还有:”;“离工作还有:”;“离下课还有:”。
- 在番茄钟的背面可以自定义图案,通过激光雕刻机,在背面刻上自己喜欢的文字和图案。
- 在番茄钟的背面留有reset孔,当按下此键时,所有计时从头开始。
附录
番茄钟接线图
参考代码
/*
Arduino 番茄钟,电源将其激活后倒数25分钟,在此25分钟内专注工作、学习;25分钟之后,开始进入5分钟休息时间;循环往复25-5-25-5-25-5-25……
*/
int ledCount=8; //数码管的其他针脚数量
int segCount=4; //4位数码管控制针脚数量
int lednotice[]={A0,A1};//两个LED的针脚
int sound[]={A2};//蜂鸣器的针脚
long previousMillis = 0; //初始时间0
const unsigned char DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴极4位数码管0~9
const unsigned char DuanMa1[10]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF};//共阴极4位数码管0~9,加点
const unsigned char rest[4]={0x50,0x79,0x6D,0x78};//休息提示
const unsigned char star[4]={0x6D,0x78,0x77,0x50};//开始提示
int ledPins[] = { 12,8,5,3,2,11,6,4}; //数码管的其他针脚
int segPins[] = {13,10,9,7};//4位数码管控制针脚
unsigned char displayTemp[4];//显示缓冲区
int count=0;
static unsigned int num1=2700;//定义一个数据,工作时间
static unsigned int num2=900;//定义一个数据,休息时间
static unsigned long lastTime=0;
void setup() {
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
pinMode(ledPins[thisLed], OUTPUT); } //分别定义针脚
for (int thisSeg = 0; thisSeg < segCount; thisSeg++) {
pinMode(segPins[thisSeg], OUTPUT);
pinMode(lednotice[0], OUTPUT);
pinMode(lednotice[1], OUTPUT);
pinMode(sound[0], OUTPUT);
}
}
void deal(unsigned char value){
for(int i=0;i<8;i++)
digitalWrite(ledPins[i],bitRead(value,i));
}
//工作程序
void work(){
if (millis() - lastTime >= 1000) {
lastTime = millis();//serialOutput();
num1--;
}
displayTemp[0]=DuanMa[num1/600];
displayTemp[1]=DuanMa1[(num1/60)%10];
displayTemp[2]=DuanMa[(num1%60)/10];
if ((((num1%1000)%100)%10)%2==0){
displayTemp[3]=DuanMa[((num1%1000)%100)%10];}
else {
displayTemp[3]=DuanMa1[((num1%1000)%100)%10];
}
static int i;
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > 0) {
previousMillis = currentMillis;
deal(0);// 清屏
for(int a=0;a<4;a++)
digitalWrite(segPins[a],1);//
digitalWrite(segPins[i],0);//
deal(displayTemp[i]);//读取对应的段码值
i++;
if(i==4) //4位结束后重新循环
i=0;
}
if(num1==0){ //如果工作时间计时至0,则蜂鸣器响,启动休息时间
deal(0);
for(int k=0;k<3;k++){ //蜂鸣器响3声,k为次数
for(int j=0;j<100;j++)//输出一个频率的声音,j为频率调节
{
digitalWrite(A2,HIGH);//发声音
delay(1);//延时1ms
digitalWrite(A2,LOW);//不发声音
delay(1);//延时ms
}
delay(1000);
}
num2=900; //调整下一个休息时间
count=1;
}
}
//休息程序
void rest5(){
if (millis() - lastTime >= 1000) {
lastTime = millis(); //serialOutput();
num2--;
}
displayTemp[0]=DuanMa[num2/600];
displayTemp[1]=DuanMa1[(num2/60)%10];
displayTemp[2]=DuanMa[(num2%60)/10];
if ((((num2%1000)%100)%10)%2==0){
displayTemp[3]=DuanMa[((num2%1000)%100)%10];}
else {
displayTemp[3]=DuanMa1[((num2%1000)%100)%10];
}
static int i;
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > 0) {
previousMillis = currentMillis;
deal(0);// 清屏
for(int a=0;a<4;a++)
digitalWrite(segPins[a],1);
digitalWrite(segPins[i],0);
deal(displayTemp[i]);//读取对应的段码值
i++;
if(i==4) //4位结束后重新循环
i=0;
}
if(num2==0){ //和上方相同
deal(0);
for(int k=0;k<3;k++){
for(int j=0;j<100;j++)//输出一个频率的声音
{
digitalWrite(A2,HIGH);//发声音
delay(1);//延时1ms
digitalWrite(A2,LOW);//不发声音
delay(1);//延时ms
}
delay(1000);
}
num1=2700;
count=0; //count为0时为工作时间,为1时为休息时间
}
}
//主程序循环
void loop() {
// put your main code here, to run repeatedly:
if(count==0){ //当是工作时间时
digitalWrite(A1,LOW); //下方LED灯暗
digitalWrite(A0,HIGH); //上方LED灯亮
work(); //启动工作程序
}
else{ //同上
digitalWrite(A0,LOW);
digitalWrite(A1,HIGH);
rest5();
}
}