ATTiny13Aにはタイマーが一つしかなくてのでLED blinkのために調整するとdelay()が影響を受けて計算が面倒/コードが煩雑になるのでdelay()をなくした。Arduino UNOとATTiny13Aでコードを共通化させた。スリープ機能を使った・・と思う。スリープとATTiny13Aの分周についてもちゃんと調べねば。ハードウェアやるつもりが組み込みソフトやってるけどまあいいか、楽しいから。
昨日まで大丈夫だったのに今朝動かすとCO2濃度1300ppmとかあり得ない数値出たんでてっきりバグかと思って数時間頑張ってたら結局風呂場の換気扇を動かしてなかったからだった。
// #include<avr/io.h> // #include<avr/wdt.h> // #include <avr/interrupt.h> #include <avr/sleep.h> #ifdef ARDUINO_AVR_UNO #define PWM_PIN A5 #define LED_PIN1 3 #define LED_PIN2 4 #define LED_PIN3 5 #define LED_PIN4 6 #define LED_PIN5 7 #else #define PWM_PIN A0 #define LED_PIN1 0 #define LED_PIN2 1 #define LED_PIN3 2 #define LED_PIN4 3 #define LED_PIN5 4 #endif void setup() { #ifdef ARDUINO_AVR_UNO Serial.begin(9600); #endif pinMode(LED_PIN1, OUTPUT); pinMode(LED_PIN2, OUTPUT); pinMode(LED_PIN3, OUTPUT); pinMode(LED_PIN4, OUTPUT); pinMode(LED_PIN5, OUTPUT); pinMode(PWM_PIN, INPUT); #ifdef ARDUINO_AVR_UNO TCCR2A = (1<<WGM21); // CTC mode TCCR2B = (1<<CS22); // 64 Division OCR2A = 250 - 1; // 1ms TIMSK2 |= (1 << OCIE2A); #else DDRB = 0b00000001;//PORTB出力設定 PORTB = 0b00000000;//PORTB_LOW TCCR0A = 0b00000010;//CTC TCCR0B = 0b00000101;//1024分周 OCR0A = 117;//0.0998sec TIMSK0 |= 0b00000100;//比較A割り込み #endif set_sleep_mode(SLEEP_MODE_IDLE); sei(); } long ppm; int isLedOn = false; int ledInterval = 200; int timer = 0; void loop() { sleep_mode(); } int lowCount = 0; int highCount = 0; int prevValue = LOW; #ifdef ARDUINO_AVR_UNO ISR(TIMER2_COMPA_vect) { #else ISR(TIM0_COMPA_vect) { #endif int pwmValue = digitalRead(PWM_PIN); if (pwmValue == HIGH) { if (prevValue == pwmValue) { ++highCount; } else { ppm = 5000 * float((highCount - 2)) / (lowCount + highCount - 4); #ifdef ARDUINO_AVR_UNO Serial.println(ppm); #endif lowCount = 0; highCount = 0; } } else { ++lowCount; } prevValue = pwmValue; ++timer; if (timer > ledInterval) { timer = 0; userDisplay(); } } void userDisplay() { isLedOn = !isLedOn; digitalWrite(LED_PIN1, LOW); digitalWrite(LED_PIN2, LOW); digitalWrite(LED_PIN3, LOW); digitalWrite(LED_PIN4, LOW); digitalWrite(LED_PIN5, LOW); ledInterval = 1000; if (ppm > 1000) { digitalWrite(LED_PIN5, HIGH); ledInterval = 200; } else if (ppm > 900) { digitalWrite(LED_PIN5, isLedOn); } else if (ppm > 800) { digitalWrite(LED_PIN4, isLedOn); } else if (ppm > 700) { digitalWrite(LED_PIN3, isLedOn); } else if (ppm > 600) { digitalWrite(LED_PIN2, isLedOn); } else if (ppm > 500) { digitalWrite(LED_PIN1, isLedOn); } else { digitalWrite(LED_PIN1, isLedOn); ledInterval = (isLedOn)? 1000 : 3000; } }