LoginSignup
2
0

More than 1 year has passed since last update.

CO2センサー(MG-812)を買ったので、CO2濃度測ってみた

Last updated at Posted at 2022-07-28

秋葉原の秋月電子通商さんで以下のCO2センサーを売ってたので、買ってみた。
https://akizukidenshi.com/catalog/g/gK-16446/

ブレッドボードに差して、arduinoにつなぐ所までは順調。
5VとGNDとA0をそれぞれ繋ぐだけ
arduino

問題は、センサーから来るアナログデータをどう二酸化炭素濃度にするかわからないという・・・
(公式には計算式など無くイケて無いグラフだけ・・・)

なので先ずCSVデータをグラフから目と手で主観的に作ります💢
graph

Pythonでそれっぽい式が出るよう計算させます。

import pandas as pd;
import matplotlib.pyplot as plt;
import numpy as np;
import scipy.optimize as opt;
from scipy.optimize import curve_fit
from scipy.stats import linregress;
def func(x, a, b, c):
    return a**(x+b)+c
df = pd.read_csv('mg812.csv', header=0, names=['x','y']);
plt.plot(df['x'], df['y'], label='');
plt.xlabel('x');
plt.ylabel('y');
plt.title('MG812 CO2 ppm vs Output mV');
tmp = df.to_numpy();
X = tmp[:,0];
print("X values");
print(X);
y = tmp[:,1];
print("Y values");
print(y);
params, cov = curve_fit(func, X, y);
plt.plot(X, func(X, *params), 'r-', label='fit');
print('Parameters:', params);
plt.legend();
plt.show();
graph

Arduinoでセンサーからの値を二酸化炭素濃度値ppmに変換させてシリアルで読めるようにします。

int mg812 = 14; // MG812 connected to A0

const uint32_t SERIAL_SPEED{115200};  ///< Set the baud rate for Serial I/O
void setup() {
  Serial.begin(SERIAL_SPEED);  // Start serial port at Baud rate
#ifdef __AVR_ATmega32U4__      // If this is a 32U4 processor, then wait 3 seconds to init USB port
  delay(3000);
#endif
}  // of method setup()
void loop() {
  static char     buf[16];                        // sprintf text buffer
  static uint16_t loopCounter = 0;                // Display iterations
  static int32_t  analog_v;
  static float    output_mv, co2;
  if (loopCounter % 25 == 0) {     // Show header @25 loops
    Serial.print(F("\nLoop  CO2 ppm\n"));
    Serial.print(F("==== ======\n"));  
  }                                                     // if-then time to show headers
  analog_v = analogRead(mg812);
  //Sensor value = analogRead * 5V / 1023 * 1000 / 10(which akizuki made)
  output_mv = analog_v*(5.0 / 1023.0) * (1000 / 10); 
  co2 = pow(0.94831961, (output_mv-438.34187965))-184.81299894;
  if (loopCounter++ != 0) {                             
    sprintf(buf, "%4d", (loopCounter - 1) % 9999); 
    Serial.print(buf);
    sprintf(buf, "%6d\n", (int16_t)(co2));
    Serial.print(buf);
    delay(1000);  // Wait 10s
  }                // of ignore first reading
}  // of method loop()

これにて完了。
p.s. BME680という温湿度・気圧・悪性ガスセンサーとか言うスーパーマルチセンサーも同じブレッドボードに載せてますが、気が向いたらそれに関しても書こうかと。

2
0
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0