|
|
用328做mcu,ds1307做时钟功能,44e霍尔元件,5110做显示
目前有速度、单次时间、单次里程、总里程、时间显示
设置我采用红外遥控进行,CH+和CH-可以调车轮半径,按EQ进入时间设置,EQ切换,加、减、快进、快退用来调增减
关于电池:
我直接用手机锂电池供电(3.7v),背光关闭电流32ma,背光开启电流42ma,一个电池用几天不是问题
电路以及用到的库在帖子最后面提供下载,我采用了单层pcb,便于大家自己制作
你需要遵循如下协议:
- #include "U8glib.h"
- #include <Wire.h>
- #include <EEPROM.h>
- #include <DS1307.h>
- #include <IRremote.h>
- #define zdpin 1
- #define timeOUT 3000 //检测速度超时
- #define EEPDELAY 5000 //EEPROM更新检测
- #define refresh 5 //刷新圈数
- #define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp[i]);}
- #define EEPROM_read(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp[i]=EEPROM.read(address+i);}
- #define jsLCDa 2000 //设置时显示时间
- boolean lcda = false;
- long TIMELCDa;
- int LCDSW=0;
- int R; //cm
- boolean Rsetup,Rsetdown;
- long CACHEDELAY;
- int Reep; //xxeep判断数值是否更改,set为设置值
- float MILEeep;
- struct config_type
- {
- int EEPROMMILE;
- int EEPROMMILEs;
- int EEPROMR;
- };
- /*-------lcd------*/
- U8GLIB_PCD8544 u8g(5, 6, 8, 7, 9); // SPI Com: CLK = 5, DIN = 6, CE = 8, DC = 7, Reset = 9
- int num;
- float SPEED;
- float ALLMILE;
- float ONEMILE,ONEMILEcache;
- long RPM;
- /*------计时-----*/
- long timea,timeb;
- long time,timecache;
- boolean timeSTA;
- /*----time----*/
- String comdata = ""; //串口数据缓存
- int numdata[7] = {
- 0}
- , j = 0, mark = 0;
- int rtc[7];
- int TIMEshi, TIMEfen, TIMEmiao; //时钟
- #define SHEtimeOUT 6000
- int sheshi, shefen;
- int shenum;
- boolean shesta = false, shesw, sheDOWN = false, sheUP = false;
- long SHEtime;
- /*----MENU----*/
- #define MENUtimeOUT 5000
- boolean MENUsta = false, MENUsw = false, MENUup = false, MENUdown = false, MENUup10x = false, MENUdown10x = false;
- int MENUswNUM = 0;
- long MENUtime;
- /*-------ir------*/
- int RECV_PIN = A0; //红外输入
- IRrecv irrecv(RECV_PIN);
- decode_results results;
- void setup ()
- {
- Serial.begin(9600);
- /*EEPROM读取赋值*/
- config_type config_readback;
- EEPROM_read(0, config_readback);
- ALLMILE = float(config_readback.EEPROMMILE+(config_readback.EEPROMMILEs/10.0));
- MILEeep = config_readback.EEPROMMILE;
- R = config_readback.EEPROMR;
- Reep = config_readback.EEPROMR;
- attachInterrupt(zdpin,light,FALLING); //检测中断
- CACHEDELAY=millis();
- ONEMILEcache=ALLMILE;
- RTC.SetOutput(DS1307_SQW32KHZ);
- irrecv.enableIRIn(); //开始采集
- }
- void loop()
- {
- Rsetup = false;
- Rsetdown = false;
- MENUup = false;
- MENUdown = false;
- MENUup10x = false;
- MENUdown10x = false;
- MENUsw = false;
-
- shesw=false;
- RTC.get(rtc, true);
- TIMEshi = rtc[2];
- TIMEfen = rtc[1];
- TIMEmiao = rtc[0];
- /*=================红外控制=================*/
- if (irrecv.decode(&results))
- {
- voir();
- }
- /*=======码表=======*/
- if(num>refresh)
- {
- jisuan();
- timea=millis();
- num=1;
- }
- ONEMILE=ALLMILE-ONEMILEcache;
- if(millis()-timeb>timeOUT)
- {
- RPM=0;
- SPEED=0;
- timeSTA=false;
- timecache=millis()-time;
- }
- else
- {
- timeSTA=true;
- time=millis()-timecache;
- }
- if(ALLMILE>9999)
- {
- ALLMILE=0;
- }
- /*==========EEPROM==========*/
- if (millis() - CACHEDELAY > EEPDELAY)
- {
- if(MILEeep != ALLMILE||Reep!=R) //判断EEPROM是否有改变
- {
- eeprom_write();
- MILEeep = ALLMILE;
- Reep = R;
- }
- CACHEDELAY=millis();
- }
- /*==============半径设置=================*/
- if(Rsetup==true)
- R++;
- if(Rsetdown==true)
- R--;
- if(R>60)
- R=10;
- if(R<10)
- R=60;
- /*==================Time======================*/
- if(shesta == true) //进入设置状态
- {
- voshe();
- }
- if(shesw == true) //切换
- shenum++;
- if(shenum > 2) //范围
- shenum = 1;
- RTC.get(rtc, true);
- TIMEshi = rtc[2];
- TIMEfen = rtc[1];
- TIMEmiao = rtc[0];
- if (sheshi > 23)
- {
- sheshi = 1;
- }
- if (sheshi < 0)
- {
- sheshi = 23;
- }
- if (shefen > 59)
- {
- shefen = 0;
- }
- if (shefen < 0)
- {
- shefen = 59;
- }
- /*===========LCD===========*/
- if(Rsetup == true || Rsetdown == true) //触发
- {
- TIMELCDa = millis();
- lcda = true;
- }
- if(lcda == true)
- {
- voLCDdelay();
- }
- u8g.firstPage();
- do {
- draw();
- }
- while( u8g.nextPage() );
- }
- void jisuan()
- {
- ALLMILE+=((float(refresh)*(2.0*3.1416*(R/100.0))))/1000.0; //总里程累加
- RPM=60000/((millis()-timea)/refresh); //转速
- SPEED=((RPM*(2.0*3.14159*(R/100.0)))*60.0)/1000.0; //速度
- }
- void light() //计数
- {
- num++;
- timeb=millis();
- }
- void eeprom_write()
- {
- config_type config; // 定义结构变量config,并定义config的内容
- config.EEPROMMILE = int(ALLMILE);
- config.EEPROMMILEs = int(ALLMILE*10)%10;
- config.EEPROMR = R;
- EEPROM_write(0, config); // 变量config存储到EEPROM,地址0写入
- }
- void voadd(int add)
- {
- if (add < 10)
- u8g.print("0");
- }
- void voLCDdelay() //显示超时
- {
- if (millis() - TIMELCDa > jsLCDa && lcda == true) //设置刷新频率
- {
- lcda = false;
- }
- }
- void voir()
- {
- unsigned long remote = results.value; //设红外信号为remote
- if(remote == (-1)) //溢出时
- {
- Serial.print(results.value, HEX); //输出红外线解码结果(十六进制)
- }
- switch (remote)
- {
- case 0xFFE21D: //CH+
- Rsetup = true;
- LCDSW=1;
- break;
- case 0xFFA25D: //CH-
- Rsetdown = true;
- LCDSW=1;
- break;
- case 0xFF906F: //EQ
- shesw = true;
- voshe();
- voshesta();
- break;
- case 0xFFE01F: //-
- MENUdown = true;
- break;
- case 0xFFA857: //+
- MENUup = true;
- break;
- case 0xFF22DD: //PREV
- MENUdown10x = true;
- break;
- case 0xFF02FD: //NEXT
- MENUup10x = true;
- break;
- }
- irrecv.resume(); // 返回值
- }
- void draw() {
- u8g.drawLine(51, 0, 51, 10);
- u8g.drawLine(0, 11, 83, 11);
- u8g.drawLine(0, 29, 83, 29);
- u8g.drawLine(0, 39, 83, 39);
- u8g.setFont(u8g_font_6x13Br);
- u8g.setPrintPos(0, 9);
- voadd(int(SPEED*10)/10);
- u8g.print(int(SPEED*10)/10); //SPEED
- u8g.print(".");
- u8g.print(int(SPEED*10)%10);
- u8g.print(" KPH");
- u8g.setPrintPos(54, 8);
- if(shesta == true) //进入设置状态
- {
- u8g.setFont(u8g_font_6x12);
- switch(shenum)
- {
- case 1:
- {
- if((millis() / 1000) % 2 != 0)
- {
- voadd(sheshi);
- u8g.print(sheshi);
- }
- else
- u8g.print(" ");
- u8g.print(":");
- voadd(shefen);
- u8g.print(shefen);
- }
- ;
- break;
- case 2:
- {
- voadd(sheshi);
- u8g.print(sheshi);
- u8g.print(":");
- if((millis() / 1000) % 2 != 0)
- {
- voadd(shefen);
- u8g.print(shefen);
- }
- else
- {
- u8g.print(" ");
- }
- }
- ;
- break;
- }
- }
- else //正常显示时间
- {
- u8g.setFont(u8g_font_6x12);
- voadd(TIMEshi);
- u8g.print(TIMEshi); //hou
- if(millis()/1000%2!=0)
- u8g.print(":");
- else
- u8g.print(" ");
- voadd(TIMEfen);
- u8g.print(TIMEfen); //min
- }
- u8g.setPrintPos(0, 26);
- u8g.setFont(u8g_font_6x13);
- u8g.print("ONCE");
- u8g.setFont(u8g_font_chikitar);
- u8g.print(": ");
- u8g.setPrintPos(28, 20);
- {
- u8g.setFont(u8g_font_fixed_v0r);
- voadd(ONEMILE);
- u8g.print((int)ONEMILE); //单次里程
- u8g.print(".");
- u8g.print(int(ONEMILE*10)%10);
- u8g.print(int(ONEMILE*100)%10);
- u8g.print("km");
- }
- u8g.setPrintPos(28, 28);
- {
- u8g.setFont(u8g_font_fixed_v0r);
- voadd(time/1000/60/60);
- u8g.print(time/1000/60/60); //单次时间
- u8g.setFont(u8g_font_chikitar);
- u8g.print("hr");
- u8g.setFont(u8g_font_fixed_v0r);
- voadd(time/1000/60%60);
- u8g.print(time/1000/60%60);
- u8g.setFont(u8g_font_chikitar);
- u8g.print("min");
- }
- {
- u8g.setFont(u8g_font_chikitar);
- u8g.setPrintPos(0, 37);
- u8g.print("MILE: "); //总里程
- u8g.setPrintPos(26, 38);
- u8g.setFont(u8g_font_fixed_v0r);
- if(int(ALLMILE*10)/10<10)
- {
- u8g.print("000");
- }
- if(int(ALLMILE*10)/10>10 && int(ALLMILE*10)/10<100)
- {
- u8g.print("00");
- }
- if(int(ALLMILE*10)/10>100 && int(ALLMILE*10)/10<1000)
- {
- u8g.print("0");
- }
- u8g.print(int(ALLMILE));
- u8g.print(".");
- u8g.setFont(u8g_font_fixed_v0r);
- u8g.print(int(ALLMILE*10)%10);
- u8g.setFont(u8g_font_chikitar);
- u8g.print("km");
- }
- u8g.setFont(u8g_font_chikitar);
- u8g.setPrintPos(1, 46);
- if (lcda == true) //半径设置
- {
- if(LCDSW==1)
- {
- u8g.print("Wheel radius: ");
- voadd(R);
- u8g.print(R);
- u8g.print("cm");
- }
- }
- else
- {
- u8g.print("--Design By PKJ--");
- }
- }
- void voshe()
- {
- if(shenum == 0) //初始赋值
- {
- sheshi = TIMEshi;
- shefen = TIMEfen;
- }
- RTC.stop(); //准备写入时间
- if(millis() - SHEtime > SHEtimeOUT) //超时
- {
- shesta = false; //退出设置
- shenum = 0; //初始
- RTC.set(DS1307_HR, sheshi);
- RTC.set(DS1307_MIN, shefen);
- RTC.set(DS1307_SEC, 0);
- RTC.start();
- }
- if(MENUup == true || MENUdown == true || MENUup10x == true || MENUdown10x == true) //触发时
- {
- voshesta();
- }
- switch(shenum) //按键作用
- {
- case 1:
- {
- if(MENUup == true)
- {
- sheshi++;
- }
- if(MENUdown == true)
- {
- sheshi--;
- }
- if(MENUup10x == true)
- {
- sheshi += 10;
- }
- if(MENUdown10x == true)
- {
- sheshi -= 10;
- }
- };
- break;
- case 2:
- {
- if(MENUup == true)
- {
- shefen++;
- }
- if(MENUdown == true)
- {
- shefen--;
- }
- if(MENUup10x == true)
- {
- shefen += 10;
- }
- if(MENUdown10x == true)
- {
- shefen -= 10;
- }
- };
- break;
- }
- }
- void voshesta() //触发时间设置状态
- {
- SHEtime = millis();
- shesta = true;
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|