|
好東東啊,樓主的諾基亞5110屏碼表源程序如下:
- /*=========自行車碼表=========*/
- #include "Arduino.h"
- #include "U8glib.h"
- #include <Wire.h>
- #include <EEPROM.h>
- #include <DS1307.h>
- //#include <IRremote.h>
- //#define LCD_CMD 0
- #define zdpin 1 //中斷源可選值為0或1,分別對(duì)應(yīng)2號(hào)和3號(hào)引腳
- #define timeOUT 3000 //檢測(cè)速度超時(shí)
- #define EEPDELAY 5000 //EEPROM更新檢測(cè)
- #define refresh 5 //刷新圈數(shù)
- #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);}
- int adc_key_val[5] ={50, 200, 400, 600, 800 };
- int NUM_KEYS = 5;
- int adc_key_in;
- int key = -1;
- int oldkey = -1;
- #define jsLCD 6000 //設(shè)置時(shí)顯示時(shí)間
- boolean lcda = false; //boolean 數(shù)據(jù)類型 boolean 變量存儲(chǔ)為 8 位(1 個(gè)字節(jié))的數(shù)值形式,但只能是 True 或是 False
- boolean lcdb = false;
- long TIMELCDa; //長(zhǎng)整數(shù)型變量 可以存儲(chǔ)32位(4字節(jié))
- long TIMELCDb;
- int LCDSW=0;//整數(shù)數(shù)據(jù)類型占用2字節(jié),范圍-32768到32767
- int lcdSW=0;
- int R; //cm
- int V; //km/h
- boolean Rsetup,Vsetup; //半徑數(shù)值
- long CACHEDELAY;
- int Reep; //xxeep判斷數(shù)值是否更改,set為設(shè)置值
- int Veep;
- float MILEeep; //浮點(diǎn)型數(shù)據(jù),就是有小數(shù)點(diǎn)的數(shù)字,經(jīng)常被用來(lái)模擬連續(xù)值
- struct config_type
- {
- int EEPROMMILE;
- int EEPROMMILEs;
- int EEPROMR;
- int EEPROMV;
- };
- /*-------lcd------*/
- U8GLIB_PCD8544 u8g(5, 6, 8, 7, 9); // SPI Com: CLK = 5, DIN = 6, CE = 8, DC = 7, Reset = 9
- int BGKEY = 10;//背光燈按鍵引腳
- int SUM = 0; //背光燈亮度值
- int Flag_up = 1; //按鍵掃描
- int beeppin = 12; //蜂鳴器引腳定義
- int num;
- float SPEED;
- float MSPEED; //平均速度
- float ALLMILE; //所有的里程
- float ONEMILE,ONEMILEcache;
- long RPM; //每分鐘的旋轉(zhuǎn)次數(shù)
- /*------計(jì)時(shí)-----*/
- long timea,timeb;
- long time,timecache;
- boolean timeSTA;
- //*----time----*/
- String comdata = ""; //串口數(shù)據(jù)緩存
- int numdata[7] = {0}, j = 0, mark = 0;
- int rtc[7];
- int TIMEshi, TIMEfen, TIMEmiao; //時(shí)鐘
- #define SHEtimeOUT 6000
- int sheshi, shefen;
- int shenum;
- boolean shesta = false, shesw, sheDOWN = false, sheUP = false;
- long SHEtime;
- /*----MENU----*/
- //#define MENUtimeOUT 5000
- boolean MENUup = false, MENUdown = false;//MENUsta = false, MENUsw = false, MENUup10x = false, MENUdown10x = false;
- //int MENUswNUM = 0;
- //long MENUtime;
- /*-------ir------*/
- //int RECV_PIN = A0; //紅外輸入
- //IRrecv irrecv(RECV_PIN);//定義IRrecv對(duì)象來(lái)接收紅外線信號(hào)
- //decode_results results;//解碼結(jié)果放在decode_results構(gòu)造的對(duì)象results里
- /*-----------------按鍵設(shè)置-----------------*/
- //將adc(模數(shù)轉(zhuǎn)換器)值轉(zhuǎn)換為鍵號(hào)
- int get_key(unsigned int input)
- {
- int k;
- for (k = 0; k < NUM_KEYS; k++)
- {
- if (input < adc_key_val[k])
- return k;
- }
- if (k >= NUM_KEYS)k = -1; // 未按有效鍵
- return k;
- }
- /*利用芯片內(nèi)部1.1v基準(zhǔn)電壓反算出電源電壓(模擬輸入端口A7)*/
- unsigned int ADCValue;
- double Voltage;
- double Vcc;
- //讀取vcc電壓
- long readVcc() {
- long result;
- // Read 1.1V reference against AVcc 讀取1.1V AVcc
- ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
- delay(2); // Wait for Vref to settle 等待Vref解決
- ADCSRA |= _BV(ADSC); // Convert 轉(zhuǎn)換
- while (bit_is_set(ADCSRA,ADSC));
- result = ADCL;
- result |= ADCH<<8;
- result = 1125300L / result; // Back-calculate AVcc in mV 反算出AVcc 為mv
- return result;
- }
- void setup ()
- {
- u8g.setContrast(140);//設(shè)置對(duì)比度0-255
- pinMode(BGKEY, INPUT_PULLUP); //按鍵IO設(shè)定為帶上拉輸入
- pinMode(11,OUTPUT); //該端口需要選擇有~號(hào)標(biāo)識(shí)的數(shù)字口(有~號(hào)表示是支持PWM的引腳)*/
- pinMode(beeppin, OUTPUT);//蜂鳴器輸出
-
- /*按著背光燈按鍵同時(shí)上電,開(kāi)機(jī)后數(shù)據(jù)清零*/
- if(digitalRead(BGKEY) == LOW)
- {
- for (int i = 0 ; i < EEPROM.length() ; i++) {
- EEPROM.write(i, 0);
- }
- }
- 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;
- V = config_readback.EEPROMV;
- Reep = config_readback.EEPROMR;
- Veep = config_readback.EEPROMV;
- attachInterrupt(zdpin,light,FALLING); //檢測(cè)中斷
- /*中斷函數(shù)(attachInterrupt):attachInterrupt(interrupt,function,mode)
- interrupt:中斷源(在Arduino中,中斷源可選值為0或1,一般分別對(duì)應(yīng)2號(hào)和3號(hào)引腳)
- function:需要中斷的函數(shù)名
- mode:LOW(低電平觸發(fā))、CHANGE(變化時(shí)觸發(fā))、
- RISING(低電平變?yōu)楦唠娖接|發(fā))、FALLING(高電平變?yōu)榈碗娖接|發(fā))
- 注意:在寫代碼時(shí),interrupt處要寫成0或1,不能寫成2或3*/
- CACHEDELAY=millis();
- ONEMILEcache=ALLMILE;
-
- RTC.SetOutput(DS1307_SQW32KHZ);
- // irrecv.enableIRIn(); //啟動(dòng)紅外解碼 開(kāi)始采集
-
- adc_key_in = analogRead(0); //從傳感器讀取值
- key = get_key(adc_key_in); //轉(zhuǎn)換成按鍵
- }
-
- void loop()
- {
- Rsetup = false;
- Vsetup = 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];
- /*----------背光燈亮度調(diào)整----------*/
- if ( ScanKey() == 1) //當(dāng)有按鍵按下時(shí)
- {
- SUM+=63; //SUM加一
- tone(beeppin,4000);
- delay(30);
- noTone(beeppin);
- }
- if (SUM >252)
- {
- SUM = 0;
- }
- /*=================紅外控制=================*/
- //if (irrecv.decode(&results))
- // {
- // voir();
- //}
- /*=================按鍵控制=================*/
- adc_key_in = analogRead(0); //從傳感器讀取值
- key = get_key(adc_key_in);
- if (key != oldkey) //如果檢測(cè)到按鍵
- {
- delay(50); //去抖動(dòng)時(shí)間
- tone(beeppin,4000);
- delay(30);
- noTone(beeppin);
- voir();
- }
-
- /*=======碼表=======*/
- if(num>refresh)
- {
- jisuan();
- timea=millis();
- num=1;
- }
- ONEMILE=ALLMILE-ONEMILEcache;
- if(millis()-timeb>timeOUT)
- {
- RPM=0; //每分鐘圈數(shù)=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||Veep!=V) //判斷EEPROM是否有改變
- {
- eeprom_write();
- MILEeep = ALLMILE;
- Reep = R;
- Veep =V;
- }
- CACHEDELAY=millis();
- }
- /*==============半徑設(shè)置=================*/
- if(Rsetup==true)
- R++;
- if(R>50)
- R=1;
- // if(R<10)
- // R=60;
- /* ==============限速警報(bào)設(shè)置================= */
- if(Vsetup==true)
- V += 5; //每按一次加 5 km/h
-
- if(V>120) //大于120 km/h 返回 5km/h
- V=5;
- /*==================Time======================*/
- if(shesta == true) //進(jìn)入設(shè)置狀態(tài)
- {
- 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 ) //半徑設(shè)置觸發(fā)
- {
- TIMELCDa = millis();
- lcda = true;
-
- }
- if(lcda == true)
- {
- voLCDadelay();
- }
-
- if( Vsetup == true) //限速報(bào)警設(shè)置觸發(fā)
- {
- TIMELCDb = millis();
- lcdb = true;
-
- }
- if(lcdb == true)
- {
- voLCDbdelay();
- }
-
- u8g.firstPage();
- do {
- draw();
- }
- while( u8g.nextPage() );
-
- if(SPEED > V) //
- {
- baojing();
- }
- else
- {
- digitalWrite(beeppin, LOW);
- }
- }
- void jisuan()
- {
- ALLMILE+=((float(refresh)*(2.0*3.1416*(R/100.0))))/1000.0; //總里程累加
- RPM=60000/((millis()-timea)/refresh); //轉(zhuǎn)速
- SPEED=((RPM*(2.0*3.14159*(R/100.0)))*60.0)/1000.0; //速度
- }
- void light() //計(jì)數(shù)
- {
- num++;
- timeb=millis();
- }
- void eeprom_write()
- {
- config_type config; // 定義結(jié)構(gòu)變量config,并定義config的內(nèi)容
- config.EEPROMMILE = int(ALLMILE);
- config.EEPROMMILEs = int(ALLMILE*10)%10;
- config.EEPROMR = R;
- config.EEPROMV = V;
- EEPROM_write(0, config); // 變量config存儲(chǔ)到EEPROM,地址0寫入
- }
-
- void voadd(int add)
- {
- if (add < 10)
- u8g.print("0");
- }
- void voLCDadelay() //顯示超時(shí)
- {
- if (millis() - TIMELCDa > jsLCD && lcda == true) //設(shè)置刷新頻率
- {
- lcda = false;
- }
- }
- void voLCDbdelay()
- {
- if (millis() - TIMELCDb > jsLCD && lcdb == true) //設(shè)置刷新頻率
- {
- lcdb = false;
- }
- }
- void voir()
- {
- switch(key)
- {
- case 0:
- Rsetup = true;
- LCDSW=1;
- break;
- case 1:
- Vsetup = true;
- lcdSW=1;
- break;
- case 2:
- shesw = true;
- voshe();
- voshesta();
- break;
- case 3:
- MENUdown = true;
- break;
- case 4:
- MENUup = true;
- break;
- }
-
- delay(100);
- }
- //將ADC值轉(zhuǎn)換為鍵號(hào)
- /*
- unsigned long remote = results.value; //設(shè)紅外信號(hào)為remote
- if(remote == (-1)) //溢出時(shí)
- {
- Serial.print(results.value, HEX); //輸出紅外線解碼結(jié)果(十六進(jìn)制)
- }
- switch (remote)
- {
- case 0xFD6897: //CH+
- Rsetup = true;
- LCDSW=1;
- break;
- case 0xFDE817: //CH-
- Rsetdown = true;
- LCDSW=1;
- break;
- case 0xFDA857: //EQ
- shesw = true;
- voshe();
- voshesta();
- break;
- case 0xFD9867: //-
- MENUdown = true;
- break;
- case 0xFD18E7: //+
- MENUup = true;
- break;
- case 0xFD12ED: //PREV
- MENUdown10x = true;
- break;
- case 0xFD48B7: //NEXT
- MENUup10x = true;
- break;
- }
- irrecv.resume(); // 返回值
- }
- */
- void draw() {
- Vcc = readVcc()/1000.0;//將讀取的vcc電壓mv轉(zhuǎn)換為v
- ADCValue = analogRead(7);
- Voltage = (ADCValue / 1023.0) * Vcc;
- MSPEED=(ONEMILE/time)*1000*60*60;
- u8g.setDefaultForegroundColor();
- u8g.drawLine(0, 19, 83, 19);
- u8g.drawLine(0, 27, 83, 27);
- u8g.drawLine(27, 28, 27, 40);
- u8g.drawLine(0, 41, 84, 41);
-
- u8g.setFont(u8g_font_ncenB08r);
- u8g.setPrintPos(45, 18);
- u8g.print("Km/h");
- /*--------電量顯示--------*/
- if (Voltage >=3.9){
- u8g.drawLine(80, 2, 81, 2);
- u8g.drawFrame(78,3,6,15);//電池外形
- u8g.drawBox(80,5,2,2);//電池電量段
- u8g.drawBox(80,8,2,2);
- u8g.drawBox(80,11,2,2);
- u8g.drawBox(80,14,2,2);
- }
- if (Voltage <3.9 && Voltage >=3.7 ){
- u8g.drawLine(80, 2, 81, 2);
- u8g.drawFrame(78,3,6,15);//電池外形
- u8g.drawBox(80,8,2,2);//電池電量段
- u8g.drawBox(80,11,2,2);
- u8g.drawBox(80,14,2,2);
- }
- if (Voltage <3.7 && Voltage>=3.5 ){
- u8g.drawLine(80, 2, 81, 2);
- u8g.drawFrame(78,3,6,15);//電池外形
- u8g.drawBox(80,11,2,2);//電池電量段
- u8g.drawBox(80,14,2,2);
- }
- if (Voltage <3.5 && Voltage >=3.2){
- u8g.drawLine(80, 2, 81, 2);
- u8g.drawFrame(78,3,6,15);//電池外形
- u8g.drawBox(80,14,2,2);//電池電量段
- }
- if (Voltage <3.2 && Voltage >=3.0 ){
- u8g.drawLine(80, 2, 81, 2);
- u8g.drawFrame(78,3,6,15);//電池外形
- }
- if (Voltage < 3.0 ) { //當(dāng)VCC電壓小于3v時(shí)圖標(biāo)閃爍,電池電量不足警告
- if(millis()/1000%2!=0){
- u8g.drawLine(80, 2, 81, 2);
- u8g.drawFrame(78,3,6,15);//電池外形
- u8g.drawLine(79, 4, 82, 17);
- }
- else{
- u8g.setPrintPos(80, 2); //只要是不影響其他顯示此位置可任選
- u8g.print("");
- }
- }
- /*背光燈4檔可調(diào),當(dāng)電池電壓低于3.2v時(shí)背光燈熄滅,節(jié)約電能*/
- if(Voltage >=3.2){
- analogWrite(11,SUM);//使用PWM控制11號(hào)口輸出,變量n的取值范圍是0-255
- }
- else{
- digitalWrite(11, LOW);
- }
-
- u8g.setPrintPos(47, 7);
- if(shesta == true) //進(jìn)入設(shè)置狀態(tài)
- {
- 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 //正常顯示時(shí)間
- {
- 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(1, 26);
- {
- u8g.setDefaultForegroundColor();
- u8g.drawBox(0, 20, 84, 8);
- u8g.setDefaultBackgroundColor();
- u8g.setFont(u8g_font_chikitar);
- u8g.print("MSPEED:");//平均時(shí)速
- u8g.setPrintPos(40, 26);
- voadd(MSPEED);
- u8g.print(int (MSPEED*10)/10);
- u8g.print(".");
- u8g.print(int (MSPEED*10)%10);
- }
- u8g.setFont(u8g_font_04b_03b);
- u8g.setPrintPos(62, 26);
- u8g.print("km/h");
- u8g.setDefaultForegroundColor();
- u8g.setPrintPos(0, 39); //單次里程
- u8g.setFont(u8g_font_6x13);
- u8g.print("ONCE");
- u8g.setPrintPos(32, 34);
- {
- u8g.setFont(u8g_font_chikitar);
- voadd(ONEMILE);
- u8g.print((int)ONEMILE);
- u8g.print(".");
- u8g.print(int(ONEMILE*10)%10);
- u8g.print(int(ONEMILE*100)%10);
- }
- u8g.setPrintPos(32, 40); //單次時(shí)間
- {
- u8g.setFont(u8g_font_chikitar);
- voadd(time/1000/60/60);
- u8g.print(time/1000/60/60);
- u8g.print(" hr ");
-
- voadd(time/1000/60%60);
- u8g.print(time/1000/60%60);
- }
- u8g.setFont(u8g_font_chikitar);
- u8g.setPrintPos(70, 34);
- u8g.print("km");
- u8g.setPrintPos(70, 40);
- u8g.print("min");
-
- if (lcda == true) //半徑設(shè)置
- {
-
- if(LCDSW==1)
- {
- u8g.setDefaultForegroundColor();
- u8g.drawBox(0, 42, 84, 6);
- u8g.setDefaultBackgroundColor();
- u8g.setFont(u8g_font_chikitar);
- u8g.setPrintPos(1, 47);
- u8g.print("Wheel radius: ");
- voadd(R);
- u8g.print(R);
- u8g.setPrintPos(72, 47);
- u8g.print("cm");
- }
- }
- else
- {
- u8g.setDefaultForegroundColor();
- u8g.setFont(u8g_font_chikitar);
- u8g.setPrintPos(0, 48);
- u8g.print("MILE: "); //總里程
- u8g.setPrintPos(32, 48);
- 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.print(int(ALLMILE*10)%10);
- u8g.setPrintPos(70, 48);
- u8g.print("km");
- }
- if (lcdb == true) //報(bào)警設(shè)置
- {
- if(lcdSW==1)
- {
- u8g.setDefaultForegroundColor();
- u8g.drawBox(0, 0, 44, 19);
- u8g.setDefaultBackgroundColor();
- u8g.setFont(u8g_font_5x8);
- u8g.setPrintPos(5, 8);
- u8g.print("SPEED/L");
- u8g.setPrintPos(4, 18);
- voadd(V);
- u8g.print(V);
- u8g.setPrintPos(21, 18);
- u8g.print("km/h");
- }
- }
- else
- {
- u8g.setDefaultForegroundColor();
- u8g.setFont(u8g_font_timB18r);
- u8g.setPrintPos(0, 18);
- voadd(int(SPEED*10)/10);
- if(SPEED >=100){
- u8g.print(int(SPEED*10)/10); //SPEED
- }
- else{
- u8g.print(int(SPEED*10)/10); //SPEED
- u8g.print(".");
- u8g.print(int(SPEED*10)%10);
- }
- }
- }
- void voshe()
- {
- if(shenum == 0) //初始賦值
- {
- sheshi = TIMEshi;
- shefen = TIMEfen;
- }
- RTC.stop(); //準(zhǔn)備寫入時(shí)間
- if(millis() - SHEtime > SHEtimeOUT) //超時(shí)
- {
- shesta = false; //退出設(shè)置
- 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 //觸發(fā)時(shí)
- {
- 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() //觸發(fā)時(shí)間設(shè)置狀態(tài)
- {
- SHEtime = millis();
- shesta = true;
- }
- int ScanKey() //按鍵掃描程序,返回鍵值
- {
- if (Flag_up && digitalRead(BGKEY) == LOW) //當(dāng)Flag_up = 1并且按鍵按下時(shí)
- {
- Flag_up = 0; //清空Flag_up
- delay(20); //延時(shí)去抖動(dòng)
- if (digitalRead(BGKEY) == LOW) //按鍵按下
- {
- return 1; //返回鍵值1
- }
- }
- if (digitalRead(BGKEY) == HIGH) //按鍵松開(kāi)時(shí)候
- {
- Flag_up = 1; //置位Flag_up
- }
- return 0; //返回鍵值0
- }
- void baojing()
- {
- tone(beeppin,4500);
- delay(50);
- noTone(beeppin);
- tone(beeppin,4500);
- delay(50);
- noTone(beeppin);
- }
復(fù)制代碼 |
|