14.4.CO2センサー
CO2センサーモジュール MH-Z19C
https://akizukidenshi.com/catalog/g/gM-16142/
プロジェクト概要
MH-Z19Cセンサを使用したCO2計測のプロジェクトです。MH-Z19CはNDIR(非分散型赤外)方式の二酸化炭素のセンサです。
電源電圧:DC5±0.1V
消費電流:40mA以下、最大125mA
インターフェース電圧:3.3V(5V互換)
検出範囲:400~5000ppm
出力:シリアルポート(UART、TTLレベル3.3V)、PWM
Model No. MH-Z19C
Detection Gas CO2
Working voltage 5.0±0.1V DC
Average current < 40mA (@5V power supply)
Peak current 125mA (@5V power supply)
Interface level 3.3 V (Compatible with 5V)
Detection Range 400~10000ppm(optional)
Output signal
Serial Port (UART) (TTL level 3.3V)
PWM
Preheat time 1 min
Response Time T90 < 120 s
Working temperature -10 ~ 50 ℃
Working humidity 0 ~ 95% RH (No condensation)
Storage temperature -20~60 ℃
Weight 5 g
Lifespan > 10 years
MH-Z19C NDIR 赤外線ガスモジュールは一般的なタイプで小型です。非分散赤外線(NDIR)原理を使用して空気中のCO2の存在を検出します。選択性が高く、酸素に依存せず、長寿命です。 温度補償機能を内蔵。 UART出力とPWM出力を備えています。
部品リスト
CO2センサーモジュールMH-Z19C 1 秋月電子通商
GROVEの16 x 2 LCD 1 スイッチサイエンス
配線図

ソースリスト
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/rtc.h"
#include "hardware/uart.h"
//#define PICO_DEFAULT_LED_PIN 25
#define LED_PIN PICO_DEFAULT_LED_PIN
#define I2C_PORT i2c0
#define I2C_SDA 8
#define I2C_SCL 9
//UART -----------------------
#define UART_ID uart1
#define BAUD_RATE 9600
#define DATA_BITS 8
#define STOP_BITS 1
#define PARITY UART_PARITY_NONE
#define UART_TX_PIN 4
#define UART_RX_PIN 5
//set up --------------------
//rtc -----------------------------------
//lcd -------------------------------
//CO2 sensor -----------------
bool ReadCo2Concentration(int *co2value)
{
*co2value = 0;
uint8_t sendBuf[9];
sendBuf[0] = 0xFF; //start byte
sendBuf[1] = 0x01; //reserved
sendBuf[2] = 0x86; //command
sendBuf[3] = 0x00;
sendBuf[4] = 0x00;
sendBuf[5] = 0x00;
sendBuf[6] = 0x00;
sendBuf[7] = 0x00;
sendBuf[8] = 0x79; //checksum
uart_write_blocking(UART_ID, sendBuf, 9);
sleep_us(100);
uint8_t receiveBuf[9];
uart_read_blocking(UART_ID, receiveBuf, 9);
//receiveBuf[0] = 0xFF; start byte
//receiveBuf[1] = 0x86; command
//receivebuf[2] = 0x**; data high
//receiveBuf[3] = 0x00; data low
//receiveBuf[8] = 0x79; checksum
uint8_t i;
uint8_t checksum;
checksum = 0;
for(i = 0; i < 7; i++)
{
checksum += receiveBuf[i + 1];
}
checksum = 0xff - checksum;
checksum = checksum + 1;
if(checksum != receiveBuf[8]){
return false;
}
uint16_t value = (receiveBuf[2] << 8) | receiveBuf[3];
*co2value = value;
return true;
}
int main()
{
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_put(LED_PIN, 0);
i2c_init(I2C_PORT, 400*1000);
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
gpio_pull_up(I2C_SDA);
gpio_pull_up(I2C_SCL);
uart_init(UART_ID, BAUD_RATE);
uart_set_translate_crlf(UART_ID, false);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
WaitTerminalStartup(30*1000);
printf("\nTerminal connected\n");
ScanI2CBus();
printf("I2C Scan completed\n");
lcd_init();
InitRtc();+
printf("Preheat time 1 min\n");
printf("Response Time T90 < 120s\n");
char buf[128];
datetime_t nowdt;
int presec = -1;
int co2Consentration;
while (1) {
rtc_get_datetime(&nowdt);
if(presec != nowdt.sec)
{
sprintf(buf, "%02d/%02d %02d:%02d:%02d",
nowdt.month, nowdt.day, nowdt.hour,nowdt.min, nowdt.sec);
lcd_set_cursor(0, 0);
lcd_string(buf);
if(!ReadCo2Concentration(&co2Consentration)) {
lcd_set_cursor(1, 0);
lcd_string(" CO2:CRC ERROR");
printf("%4d/%02d/%02d %02d:%02d:%02d CO2:CRC ERROR\n",
nowdt.year, nowdt.month, nowdt.day,
nowdt.hour,nowdt.min, nowdt.sec);
} else {
sprintf(buf, " CO2:%5dppm", co2Consentration);
lcd_set_cursor(1, 0);
lcd_string(buf);
printf("%4d/%02d/%02d %02d:%02d:%02d CO2:%5dppm\n",
nowdt.year, nowdt.month, nowdt.day,
nowdt.hour,nowdt.min, nowdt.sec, co2Consentration);
}
}
presec = nowdt.sec;
sleep_ms(200);
}
return 0;
}

コメントをお書きください