要旨
Node.jsでmodbus-serialを使用し、Raspberry PiからCO2センサにmodbusのシリアル通信を行なった。
背景
在宅勤務が始まり、換気環境がオフィスより劣る自宅で最高のパフォーマンスを出すために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
ブラウザで閲覧可能なサイト作成
↧