為了確定大太陽底下車廂溫度最高會到多少而弄的小玩意....
設計理念來說,
溫度精準度不用太過計較,MCU有內建最好,
能保存一定數量的溫度紀錄(好畫線XD)
然後使用的東西要儘量簡單&少....
看了看自己手上的MCU:
名稱 | 溫度計 | EEPROM | 操作溫度°C |
---|---|---|---|
LPC1114 | no | 用flash代替 | -40~85 |
LPC812 | no | 用flash代替 | -40~105 |
STM32F103C8T6 | yes | 用flash代替 | -40~105 |
Atmega328P(pro mini) | yes | yes | -40~85 |
嚴格說起來STM32F103C8T6是最符合需求的,
只是...手上只有一片&基礎功能都還沒玩過= =
所以就先pass....拿Arduino來繼續偷懶了XD
假設溫度不會到85度....那麼這個裝置就不會有問題....
可是超過85度的話....我想應該會GG吧= =
(至少確定他超過datasheet的工作範圍了...
希望不會超過85度吧....
操作方式:
接上電源自動開始紀錄,最多紀錄169筆,
每5分鐘紀錄一次(第92行可以改)
要讀取的話,
先接好UART轉USB,
然後按一下reset,
會自動跳到顯示模式,
輸入"C"會讓記錄從0開始記;
輸入"F"會把EEPROM設成0xFF;
輸入"D"會把EEPROM裡面所有的資料列出來.
輸出格式為: 時間\t溫度\t電壓
時間為開機後第幾次紀錄,
溫度是攝氏溫度*10(256等於25.6度)
電壓為mV
code:
(使用這個函式庫:http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/)
- #include <EEPROM.h>
- #include "LowPower.h"
- int led = 13;
- struct Temp{
- unsigned int t;
- int temp;
- unsigned int Vcc;
- };
- struct Temptab{
- unsigned int num;
- Temp max;
- };
- char print = 0;
- char cmd = 0x00;
- Temptab status;
- int total = 0;
- int offset = sizeof(Temptab);
- unsigned int cont = 0;
- Temp work;
- Temp max = {
- 0,
- -64,
- 0
- };
- void setup()
- {
- pinMode(led, OUTPUT);
- EEPROM.get( 0, status );
- total = status.num;
- offset = sizeof(Temptab) + status.num * sizeof(Temp);
- if(MCUSR & _BV(EXTRF)){
- Serial.begin(115200);
- print = 1;
- Serial.println( "Read status from EEPROM: " );
- Serial.print( "total\t" );Serial.println( status.num );
- Serial.print( "max_t\t" );Serial.println( status.max.t );
- Serial.print( "max_temp\t" );Serial.println( status.max.temp );
- Serial.print( "max_Vcc\t" );Serial.println( status.max.Vcc );
- if(status.num){
- dump();
- }
- }else{
- LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);
- total++;
- rec();
- }
- }
- // https://code.google.com/p/tinkerit/wiki/SecretVoltmeter
- // The voltage is returned in millivolts. So 5000 is 5V, 3300 is 3.3V.
- unsigned int vccVoltage() {
- unsigned int result;
- // Read 1.1V reference against AVcc
- ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
- delay(2); // Wait for Vref to settle
- ADCSRA |= _BV(ADSC); // Convert
- while (bit_is_set(ADCSRA,ADSC));
- result = ADCL;
- result |= ADCH << 8;
- result = 1126400L / result; // Back-calculate AVcc in mV
- return result;
- }
- // https://code.google.com/p/tinkerit/wiki/SecretThermometer
- // Temperature is returned in 10x°C. So 250 is 25°C.
- int readTemp() {
- long result;
- // Read temperature sensor against 1.1V reference
- ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3);
- delay(50); // Wait for Vref to settle
- ADCSRA |= _BV(ADSC); // Convert
- while (bit_is_set(ADCSRA,ADSC));
- result = ADCL;
- result |= ADCH << 8;
- //result = (result*1000 - 324310L) / 122;
- result = ((result*2000 - 648620L) / 144 + 1) >> 1;
- return result;
- }
- void sleepMinutes()
- {
- for (unsigned int i = 0; i < 150; i++) {
- LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);
- }
- cont++;
- }
- void blinkLed(){
- digitalWrite(led, HIGH);
- delay(100);
- digitalWrite(led, LOW);
- }
- void rec(){
- work.t = cont;
- work.temp = readTemp();
- work.Vcc = vccVoltage();
- if(work.temp > status.max.temp){
- status.max.t = work.t;
- status.max.temp = work.temp;
- status.max.Vcc = work.Vcc;
- }
- status.num = total;
- EEPROM.put( offset, work );
- EEPROM.put( 0, status );
- total++;
- offset += sizeof(Temp);
- if(offset >= EEPROM.length()){
- total = 0;
- offset = sizeof(Temptab);
- }
- }
- void dump(){
- unsigned int i = 0;
- EEPROM.get( 0, status );
- Serial.print( "max_time\t" );Serial.println( status.max.t );
- Serial.print( "max_temp\t" );Serial.println( status.max.temp );
- Serial.print( "max_Vcc\t" );Serial.println( status.max.Vcc );
- for(offset=sizeof(Temptab); offset+sizeof(Temp)<=EEPROM.length(); offset+=sizeof(Temp)){
- EEPROM.get( offset, work);
- Serial.print( i++ );Serial.print( "\t" );
- Serial.print( work.t );Serial.print( "\t" );
- Serial.print( work.temp );Serial.print( "\t" );
- Serial.print( work.Vcc );Serial.println();
- }
- }
- void loop()
- {
- if(print == 0){
- blinkLed();
- sleepMinutes();
- rec();
- }else{
- if(Serial.available()){
- cmd = Serial.read();
- if(cmd == 'C'){
- Serial.print( "clear EEPROM..." );
- status.num = 0;
- status.max.t = 65535;
- status.max.temp = -63;
- status.max.Vcc = 65535;
- EEPROM.put( 0, status );
- Serial.println( "done" );
- }
- if(cmd == 'F'){
- Serial.print( "set EEPROM to 0xFF..." );
- for(offset=sizeof(Temptab); offset<EEPROM.length(); offset++){
- EEPROM.write(offset, 0xFF);
- }
- Serial.println( "done" );
- }
- if(cmd == 'D'){
- Serial.println( "Read status from EEPROM: " );
- Serial.print( "total\t" );Serial.println( status.num );
- Serial.println( "dump EEPROM..." );
- dump();
- }
- if(cmd == 'N'){
- Serial.print( "now_temp\t" );Serial.println( readTemp() );
- Serial.print( "now_Vcc\t" );Serial.println( vccVoltage() );
- }
- }
- }
- }
沒有留言:
張貼留言