ADコンバーター / 二酸化炭素(CO2)センサー

テキストは応用例として温度センサーを試しているが、ここではGravity - 赤外線CO2センサ/メーター - スイッチサイエンスを使ってみる。
f:id:ti-nspire:20200703085708j:plain:w500

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include "LCDClass.h"

const uint16_t mVref = 4800; // 実測値

int main(){
    LCDClass lcd("PB0","PD7","PD6","PD5","PB7","PB6"); // (RS,EN,D4,D5,D6,D7)の順番で指定する。
    lcd.init();
    
    ADMUX |= (1 << REFS0);         // 基準電圧はAVCC
    ADCSRA |= 0b111 | (1 << ADEN); // 128分周。ADCペリフェラルをオン。

    while(1){
        ADCSRA |= (1 << ADSC);                 // 変換を開始して、
        loop_until_bit_is_clear(ADCSRA, ADSC); // 変換開始ビットがクリアされるのを待って、
        uint16_t adVal = ADC;                  // AD変換値を取得する。

        uint16_t mV = (uint16_t)((float)mVref / 1024.0 * (float)adVal + 0.5); // +0.5は小数点以下を四捨五入するため。
        //uint16_t mV = (47 * adVal + 10/2) / 10; // 47 ≒ (mVref / 1024) * 10。+10/2は小数点以下を四捨五入するため。
        uint16_t ppm = (25 * (mV - 400) + 8/2) / 8; // +8/2は小数点以下を四捨五入するため。

        lcd.gotoRowCol(1,  1); lcd.print("AD:");
        lcd.gotoRowCol(1,  4); lcd.print(adVal);
        lcd.gotoRowCol(1,  9); lcd.print("mV:");
        lcd.gotoRowCol(1, 12); lcd.print(mV);
        lcd.gotoRowCol(2,  1); lcd.print("ppm:");
        lcd.gotoRowCol(2,  5); lcd.print(ppm);

        _delay_ms(1000);
    }

    return 0;
}