chottoshitahanashi’s diary

基本的に間違ったことばかり書いてるブログ。検索ひっかかるな

できた

www.youtube.com

// #include<avr/io.h>
// #include<avr/wdt.h>
// #include <avr/interrupt.h>
#include <avr/sleep.h>

#ifdef ARDUINO_AVR_UNO
#define PWM_PIN A0
#define LED_PIN1 3 // 1, 2 for Serial
#define LED_PIN2 4
#define LED_PIN3 5
#define LED_PIN4 6
#else
#define PWM_PIN  4
#define LED_PIN1 0
#define LED_PIN2 1
#define LED_PIN3 2
#define LED_PIN4 3
#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(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
  // WGM02 WGM01 WGM00
  //    モード CTCとかPWMとか。
  //    CTCではカウンタレジスタTCNT0とOCR0Aが一致するとカウンタリセット
  // CS02 CS01 CS00
  //    分周
  // OCIE0B OCIE0A
  //    タイマ/カウンタ比較B, A割り込み許可。
  //    CTCではOCR0Aが使われるのにOCIE0Bがあるのはと思ったがCTCはカウンタリセットのみで、
  //    割り込みタイミングとは別ということか?
  //    CTCでOCIE0BセットならカウンタリセットにはOCR0Aが、割り込みにはOCIE0Bが使われると予想(要確認) 
  // TOIE0
  //    タイマ/カウンタオーバーフロー割り込み許可
  // FOCOA FOCOA
  //    強制コンペアマッチ、たぶんセットした瞬間に割り込み発生
  // 動作クロック1.2MHz (9.6MHzをFUSE設定で8分周=1.2)
  // クロック当たり1.0/(1.2*1.0e6)秒、8分周すると1.0/(1.2*1.0e6)*8秒でカウントアップ
  // 75カウントで割り込みをかけると1.0/(1.2*1.0e6)*8*150=0.001秒で割り込み
  TCCR0A = 0b00000010; // COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
  TCCR0B = 0b00000010; // FOC0A FOC0B - - WGM02 CS02 CS01 CS00.
  OCR0A  = 150 - 1; // 0.001 sec
  TIMSK0 = 0b00000100; // - - - - OCIE0B OCIE0A TOIE0 0 : タイマ/カウンタ比較A割り込み許可
#endif

  set_sleep_mode(SLEEP_MODE_IDLE);
  sei();
}

long ppm;
int isLedOn = false;
int ledInterval = 200;
int timer = 0;
bool buzzer = false;

void loop()
{
  sleep_mode();
}

long lowCount = 0;
long highCount = 0;
int prevValue = LOW;

#ifdef ARDUINO_AVR_UNO
ISR(TIMER2_COMPA_vect)
{
#else
ISR(TIM0_COMPA_vect)
{
#endif

  if (buzzer)
  {
    digitalWrite(LED_PIN4, !digitalRead(LED_PIN4));
  }
  else
  {
    digitalWrite(LED_PIN4, LOW);
  }

  int pwmValue = digitalRead(PWM_PIN);

  if (pwmValue == HIGH)
  {
    if (prevValue == pwmValue)
    {
      ++highCount;
    }
    else
    {
      ppm = 5000 * (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);

  ledInterval = 1000;
  buzzer = false;

  if (ppm > 1000)
  {
    buzzer = true;
  }
  else if (ppm > 800)
  {
    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;
  }
}