#include // PIC送信用 #define CLK 1 #define DAT 0 #define WAIT 5 #define FIG4(X) (((X) & 0xf000) >> 12) #define FIG3(X) (((X) & 0xf00) >> 8) #define FIG2(X) (((X) & 0xf0) >> 4) #define FIG1(X) ((X) & 0xf) volatile uint16_t adin; ISR(ADC_vect) { adin = ADCL; adin |= ADCH << 8; } void setup() { DDRB = 0b00000011; // PB0/PB1出力 PORTB = 0b00000011; // 省エネ設定 ACSR |= _BV(ACD); // アナログ比較器電力削減 DIDR0 |= _BV(ADC3D); // ADC3(PB3)デジタル入力禁止 // AD変換 ADMUX |= _BV(REFS0) | _BV(MUX1) | _BV(MUX0); // 内部1.1V基準電圧 ADC3(PB3)入力 ADCSRA |= _BV(ADEN) | _BV(ADIE) | _BV(ADPS1); // 分周値1/4 クロック600kHz→150kHz // スリープ設定 set_sleep_mode(SLEEP_MODE_ADC); // A/D変換雑音低減動作 sleep_enable(); // スリープ許可 sei(); // 割り込み許可 } void loop() { ADCSRA |= _BV(ADSC); // A/D変換開始 sleep_mode(); // 温度算出&PICへ送信 calcTemp(adin); delay(500); } void calcTemp(uint16_t ain) { uint16_t one, hundred; uint8_t c, n, temp; // 0℃のとき500mV 温度係数10.0mV/℃ // A/D入力値を電圧に変換 電圧 = A/D入力値 * 1100 / 1024 // 電圧を温度に変換 温度 = (電圧 - 500) / 10 // アナログ入力値 * 323 // アナログ入力値 * 107 1100 / 1024 = 1.07421875を100倍 one = hex2dec(ain * 7); // アナログ入力値 * 1の位 hundred= hex2dec(ain); // アナログ入力値 * 100の位 // 10進数に変換(小数点以下は四捨五入) n = FIG3(one) + FIG1(hundred); c = n / 10; // 繰り上げ if((n % 10) > 4) // 四捨五入 ++c; n = FIG4(one) + FIG2(hundred) + c; temp = n % 10; c = n / 10; // 繰り上げ n = FIG3(hundred) + c; temp += (n - 5) * 10; // 500mVのオフセット (計算結果は0〜49℃のとき有効) sendByte(temp); } // 16進数→10進数 uint16_t hex2dec(uint16_t hex) { uint16_t dec = 0, d = 1, n; n = hex; while(true) { dec += (n % 10) * d; n /= 10; if(n == 0) break; d *= 16; } return dec; } void sendByte(uint8_t bt) { digitalWrite(CLK, LOW); //スタートビット delay(WAIT); digitalWrite(CLK, HIGH); delay(WAIT); for(int n = 0; n < 8; n++) { digitalWrite(DAT, (bt >> n) & 1); delay(WAIT); digitalWrite(CLK, LOW); delay(WAIT); digitalWrite(CLK, HIGH); } }