LoginSignup
0
0

More than 3 years have passed since last update.

modbus-serialでCO2センサ(Senseair Sunrise)を使う

Posted at

要旨

Node.jsでmodbus-serialを使用し、Raspberry PiからCO2センサにmodbusのシリアル通信を行なった。

背景

D4D1145E-21E0-440D-AB27-3092C7EAAF70.jpeg

在宅勤務が始まり、換気環境がオフィスより劣る自宅で最高のパフォーマンスを出すためにCO2濃度管理が必要不可欠!
などと論理武装し、一般人が買える最高性能っぽいCO2センサSenseair Sunriseを購入。
しかし、Raspberry PiのIC2接続で読み出すことに挫折(ArduinoのIC2は成功)。
1年ほど積んでいたCO2センサをUARTにより使用することを試みるのであった。

事前準備

ホストにRaspberry Pi Zero Wを用いたので、以下の工程を事前に行っています。

  • Raspberry Piのセットアップ
  • シリアル通信の有効化
  • Node.jsのインストール

配線

ホストであるRaspberry PiからSenseair Sunriseに配線しました。
詳細は公式データシートを参照してください。

No Sunrise Raspberry Pi 使用機能
1 GND GND P6 グラウンド
2 VBB 3.3V P1 センサ電源
3 VDDIO 3.3V P1 I/O電源
4 RxD/SDA TXD P8 (GPIO14) UART receive input
5 TxD/SCL RXD P10 (GPIO15) UART transmit output
6 COMSEL - HIGH: UART(floating可)
7 nRDY - 電圧
8 DVCC - 内部電源出力
9 EN 3.3V P1 HIGH: Enable(稼働)

コード

node moduleのmodbus-serialを使用しています。
インストールは以下のコマンドです。

modbus-serialのインストール
npm install modbus-serial

modbus-serialのライブラリのexamplesを参考に作成しています。
公式データシート[Modbus on Senseair Sunrise TDE5514]の該当項番を値のコメントに記載しています。
他のセンサを使用される方は設定値の変更が必要です。
正常動作の動作確認以外は行っていないので、参考程度でお願いします。

printCo2AndTemperature.js
const ModbusRTU = require('modbus-serial')
let client

const serialPort = '/dev/serial0'
const repeatCount = 10
const sleepMilliseconds = 1000

const networkErrors = [
  'ESOCKETTIMEDOUT',
  'ETIMEDOUT',
  'ECONNRESET',
  'ECONNREFUSED',
  'EHOSTUNREACH',
  'ENETRESET',
  'ECONNABORTED',
  'ENETUNREACH',
  'ENOTCONN',
  'ESHUTDOWN',
  'EHOSTDOWN',
  'ENETDOWN',
  'EWOULDBLOCK',
  'EAGAIN'
]

const connect = () => {
  client = new ModbusRTU()
  // 2.1 Modbus settings -> Default slave address
  client.setID(104)
  // 1.2 Bus timing -> Response time-out
  client.setTimeout(180)
}

const reconnect = () => {
  console.warn('reconnect!')
  client.close()
  connect()
}

const run = async () => {
  for (let i = 0; i < repeatCount; i++) {
    try {
      const result = await getCo2AndTemperature()
      console.log(result != null ? result : 'Error!')
      await sleep(sleepMilliseconds)
    } catch (e) {
      console.error(e)
    }
  }
  // 無限ループ
  // setImmediate(() => {
  //   run();
  // })
}

const getCo2AndTemperature = async () => {
  try {
    if (!client.isOpen) {
      // 2.1 Modbus settings
      await client.connectRTUBuffered(serialPort, {
        baudRate: 9600,
        parity: 'none',
        dataBits: 8,
        stopBits: 1
      })
    }
    // Table 1:Input Registers(IR)
    // IR4 0x03 CO2 Value Filtered Pressure Compensated [ppm]
    // IR5 0x04 Temperature [℃×100]
    const response = await client.readInputRegisters(3, 2)
    return {
      co2: response.data[0],
      temperature: response.data[1]
    }
  } catch (e) {
    console.error(e)
    if (e.errno && networkErrors.includes) reconnect()
  }
}

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))

const main = async () => {
  connect()
  await run()
  client.close()
}

main()

終わり

CO2センサの値読み取りに成功したので、次は以下を考えています。

  • Cloud DBにCO2濃度をPOST
  • ブラウザで閲覧可能なサイト作成
0
0
0

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
0
0