远古警告:这是一篇很久以前的文章。曾经写在微信公众号上,特此复制粘贴。所列代码仅供参考,不一定可以运行。

背景

番茄钟,是指把任务分解成半小时左右,集中精力工作/学习25分钟后休息5分钟,如此视作种一个“番茄”。哪怕工作/学习没有完成,也要定时休息,然后再进入下一个番茄时间。

/uploads/2016/11/20161103-arduino-tomato-clock00.jpg

每天工作/学习之前,先把一天的工作/学习任务划分若干个 “番茄钟”,规定好每个“番茄钟”内要完成的小目标,然后尽量心无旁骛地工作/学习,这种“番茄工作/学习法”的流程,也被称为拖延症“自救攻略”之一。

/uploads/2016/11/20161103-arduino-tomato-clock01.jpg

番茄钟实质上就是计时器,平时手表倒计时繁琐、手机计时分散注意力,DIY的番茄钟插电即可计时,采用Arduino进行控制,可以在电脑端更改计时时间,番茄钟的背面可以DIY自定义。

不带外壳的实物图如下:

/uploads/2016/11/20161103-arduino-tomato-clock03.png

简介

功能

  • 该装置具有计时功能,默认状态下:插入电源即是25分钟工作倒计时,倒计时的最小单位为秒;到25分钟,倒计时结束之后,会开始进行五分钟休息倒计时。
  • 该装置具有提醒功能,默认状态下:25分钟倒计时结束之后蜂鸣器会响三声;五分钟倒计时结束之后,蜂鸣器会响三声;蜂鸣器响声的频率可以在IDE中调节。
  • 该装置的时间计数器的上方和下方分别有两盏led灯,在默认状态下:当计数器为25分钟倒计时时,上方led灯亮;当计数器为五分钟倒计时时,下方led灯亮。

外形

  • 外形有两种制作材料:两毫米的亚克力板或两毫米的木板。
  • 在靠近上下两个led灯的面板处可以贴不同字样的字条,样例如下:“离休息还有:”;“离工作还有:”;“离下课还有:”。
  • 在番茄钟的背面可以自定义图案,通过激光雕刻机,在背面刻上自己喜欢的文字和图案。
  • 在番茄钟的背面留有reset孔,当按下此键时,所有计时从头开始。

附录

番茄钟接线图

/uploads/2016/11/20161103-arduino-tomato-clock02.jpg

参考代码

/*
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();
}
}

类似文章

发表回复

您的电子邮箱地址不会被公开。