/* 小型I2C接続 128x64 OLED ディスプレイの動作確認 2016/07/23 edy このスケッチはu8glibのサンプルをカスタマイズしたものです。 Universal 8bit Graphics Library https://github.com/olikraus/u8glib 2016/07/26 ADT7410を接続、スケッチは「wsnakのブログ」を参考にした。 http://www.wsnak.com/wsnakblog/?p=409 2016/07/31 消費電流を抑えるためにラジオペンチさんの記事にあるdelayWDTを使ってみた。 「消費電流が激減!delayWDT関数を作ってみた」 http://radiopench.blog96.fc2.com/blog-entry-486.html 2016/08/05 OLEDの輝度調整が出来るようにした https://bengoncalves.net/2015/10/01/oled-display-and-arduino-with-power-save-mode/ */ #include "U8glib.h" #include ; #include #include #define ADT7410_addr 0x4b //ATD7410アドレス #define OLED_addr 0x3c U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0); // I2C / TWI float temp; static char buf[8]; static char temp_unit[3]; float mesureTemp() { uint16_t val; long int ival; // ワンショット リトリガ再設定 Wire.beginTransmission(ADT7410_addr); // S.C発行,CB送信 Wire.write(0x03); // Configuration register 選択 Wire.write(0x20 | 0x80); // one-shot mode 設定 Wire.endTransmission(); // ストップ・コンディション delay(240); Wire.requestFrom(ADT7410_addr, 2); // S.C発行,CB送信 val = (uint16_t)Wire.read() << 8; // データの読み出し(上位) val |= Wire.read(); // データの読み出し(下位) //Wire.endTransmission(); ival = (long int)val; if (val & 0x8000) { // 符号判定 // 負数 ival = ival - 65536; } return (float)ival / 128.0; } void draw(void) { dtostrf(temp, 6, 1, buf); strcat(buf, temp_unit); u8g.drawStr(0, 0, buf); dtostrf(temp, 6, 1, buf); strcat(buf, "%"); u8g.drawStr(0, 23, buf); dtostrf(temp + 1000, 6, 1, buf); strcat(buf, "hP"); u8g.drawStr(0, 46, buf); } void setBrightness(uint8_t brightness) { Wire.beginTransmission(OLED_addr); Wire.write(0x00); Wire.write(0x81); Wire.endTransmission(); Wire.beginTransmission(OLED_addr); Wire.write(0x00); Wire.write(brightness); Wire.endTransmission(); } void setup(void) { Wire.begin(); u8g.setColorIndex(1); u8g.setFont(u8g_font_courR18); u8g.setFontPosTop(); // pixel on temp_unit[0] = 0xb0; temp_unit[1] = 'C'; temp_unit[2] = '\0'; setBrightness(0); } void loop(void) { temp = mesureTemp(); // picture loop u8g.firstPage(); do { draw(); } while ( u8g.nextPage() ); setBrightness(0); //u8g.setContrast(0x0); delayWDT(7); } // ここから下を全て使う void delayWDT(unsigned long t) { // パワーダウンモードでdelayを実行 delayWDT_setup(t); // ウォッチドッグタイマー割り込み条件設定 ADCSRA &= ~(1 << ADEN); // ADENビットをクリアしてADCを停止(120μA節約) set_sleep_mode(SLEEP_MODE_PWR_DOWN); // パワーダウンモード sleep_enable(); sleep_mode(); // ここでスリープに入る sleep_disable(); // WDTがタイムアップでここから動作再開 ADCSRA |= (1 << ADEN); // ADCの電源をON (|=が!=になっていたバグを修正2014/11/17) } void delayWDT_setup(unsigned int ii) { // ウォッチドッグタイマーをセット。 // 引数はWDTCSRにセットするWDP0-WDP3の値。設定値と動作時間は概略下記 // 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms // 6=1sec, 7=2sec, 8=4sec, 9=8sec byte bb; if (ii > 9 ) { // 変な値を排除 ii = 9; } bb = ii & 7; // 下位3ビットをbbに if (ii > 7) { // 7以上(7.8,9)なら bb |= (1 << 5); // bbの5ビット目(WDP3)を1にする } bb |= ( 1 << WDCE ); MCUSR &= ~(1 << WDRF); // MCU Status Reg. Watchdog Reset Flag ->0 // start timed sequence WDTCSR |= (1 << WDCE) | (1 << WDE); // ウォッチドッグ変更許可(WDCEは4サイクルで自動リセット) // set new watchdog timeout value WDTCSR = bb; // 制御レジスタを設定 WDTCSR |= _BV(WDIE); } ISR(WDT_vect) { // WDTがタイムアップした時に実行される処理 // wdt_cycle++; // 必要ならコメントアウトを外す }