LoginSignup
1
0

More than 1 year has passed since last update.

LRA1 で CO2 センサ SCD41 を使ってみる

Posted at

株式会社アイツーの LoRa 無線モジュール LRA1 に、 SCD41 を使ってみました。

「SCD41 を ESP32 で 動かすスニペット」
https://qiita.com/nanbuwks/items/788c8b6eec8e68639751
において、ライブラリなどを使わずに直接I2Cを制御して動かしてみたスケッチがあるので、それを LRA1 に応用します。

Spansion の CO2 センサは精度がいいですが、その中でもSCD41 は以下のように低消費電力に対応しています。

測定範囲 測定精度 低消費電力
SCD40 400-2000ppm ±50 ppm
SCD41 400-5000ppm ±40 ppm 対応
SCD42 400-1000ppm ±75 ppm

省電力の LRA1 に組み合わせてみましょう。

テストベッド

image.png

こんな感じで試してみました。奥が SCD41 モジュールです。ヒゲが出ているのは、実験中にロジアナをつなげていたためです。

試した動作

先のESP32の例では、以下のコマンドを試してました。

  • 動作確認として get_serial_number 0x3682
  • 基本的な測定として read_measurement 0xec05
  • 省電力測定として measure_single_shot 0x219d

これを LRA1 で動かしてみましたがこのうち get_serial_number と measure_single_shot は問題なく動きましたが、 read_measurement はうまくいかななかった? (検証不足)

measure_single_shot のサンプルプログラム

10 _start
15 Print "start"
20 Catch _ERRORHANDLER
30 ' I2cD(-1)=100
40 ' 0x36f6 wake_up
50 I2cD(0)=$36
60 I2cD(1)=$F6
70 I2cW $62,-1,2
80 '0x3682 get_serial_number
90 I2cD(0)=$36
100 I2cD(1)=$82
110 Catch _ERRORHANDLER
120 I2cW $62,-1,2
130 I2cR $62,-1,9
140 ' gosub _PRINT9BYTES
150 Gosub _crccheck
160 ' measure 5 times
170 For K=1 To 5
180 ' 0X219d measure_single_shot
190 I2cD(0)=$21
200 I2cD(1)=$9D
210 I2cW $62,-1,2
220 Delay 5000
230 ' 0xe4b8 get_data_ready_status
240 I2cD(0)=$E4
250 I2cD(1)=$B8
260 ' wait loop
270 I2cW $62,-1,2
280 Delay 10
290 I2cR $62,-1,3
300 If $80=I2cD(0)&&$0=I2cD(1)Then Goto 280:End EndIf
310 'Gosub _PRINT9BYTES
320 Gosub _crccheck
330 ' read_measurement
340 I2cD(0)=$EC
350 I2cD(1)=$5
360 I2cW $62,-1,2
370 I2cR $62,-1,9
380 'gosub _PRINT9BYTES
390 Gosub _PRINTCO2TEMPRH
400 Next
410 I2cD(0)=$36
420 I2cD(1)=$E0
430 I2cW $62,-1,2
440 ' sleep 
445 Print "sleep"
450 Sleep 270
460 Goto _start
470 End
480 '==== ERROR HANDLER=====
490 _ERRORHANDLER
500 Print "ERROR NO=";Error;" AT ";Error#
510 Catch _ERRORHANDLER
520 If Error=12 Then Delay (1000):Goto Error#End EndIf
530 End
540 '======subroutine=============
550 _PRINT9BYTES
560 ' print return 9 bytes
570 Print Form("X02",I2cD(0))Form("X02",I2cD(1))Form("X02",I2cD(2))Form("X02",I2cD(3))Form("X02",I2cD(4))Form("X02",I2cD(5))Form("X02",I2cD(6))Form("X02",I2cD(7))Form("X02",I2cD(8))
580 ' 9C6EDCB707293BFF85
590 U=9
600 Gosub _crccheck
610 If U=-1 Then Print "error":End EndIf
620 Print "serial:";:Print Form("X02",I2cD(0))Form("X02",I2cD(1))Form("X02",I2cD(3))Form("X02",I2cD(4))Form("X02",I2cD(6))Form("X02",I2cD(7))
630 Return
650 _crccheck
660 ' use revariant : datacoutnt : U return; -1; error
670 For I=0 To U/3-1
680 C=$FF^I2cD(I*3)
690 For J=0 To 7
700 If (127<C)Then C=((C<<1)&$FF)^$31 Else C=((C<<1)&$FF)EndIf
710 'Print "J:";:Print J;:Print " ";:Print Form("X02",C)
720 Next
730 C=C^I2cD(I*3+1)
740 For J=0 To 7
750 If (127<C)Then C=((C<<1)&$FF)^$31 Else C=((C<<1)&$FF)EndIf
760 Next
770 If I2cD(I*3+2)<>C Then U=-1:Print "CRC ERROR":Return EndIf
780 'print "CRC OK"
790 Next
800 Return
810 _PRINTCO2TEMPRH
820 Print "CO2:";:Print I2cD(0)*256+I2cD(1);
830 T=(I2cD(3)*256+I2cD(4))*175/65535-45
840 Print " TEMP:";:Print T;
850 H=(I2cD(6)*256+I2cD(7))*100/65535
860 Print " RH:";:Print H;:Print "%"
870 Return


やっていること

  • writeSCD4X(0x36f6 ); WakeUp
  • readSCD4X(0x3682,9) get_serial_number
  • 5回繰り返し{
  • writeSCD4X(0x219d ); measure_single_shot
  • readSCD4X(0xe4b8,3) get_data_ready_status が 0 になるまで繰り返し
  • readSCD4X(0xec05,9) read_measurement
  • }
  • writeSCD4X(0x36e0 ); power down

実行結果


>>run
start
CO2:526 TEMP:14 RH:42%
CO2:526 TEMP:14 RH:42%
CO2:511 TEMP:14 RH:42%
CO2:535 TEMP:14 RH:42%
CO2:516 TEMP:14 RH:42%
sleep
start
ERROR NO=12 AT 70
CO2:565 TEMP:14 RH:43%
CO2:547 TEMP:14 RH:43%
CO2:535 TEMP:14 RH:43%
CO2:552 TEMP:14 RH:43%
CO2:553 TEMP:15 RH:42%
sleep
start
ERROR NO=12 AT 70
CO2:554 TEMP:14 RH:42%
CO2:559 TEMP:14 RH:42%
CO2:529 TEMP:14 RH:42%
CO2:525 TEMP:14 RH:42%
CO2:551 TEMP:14 RH:42%
sleep

うまくいきました・・・
が、途中で ERROR NO=12 AT 70 というのがありますね。

ERROR 12 とは、Device access error となり、 Wake Up のコマンド I2C でが書き込めないエラーです。ESP32 ではエラーが無いのになと思ったら、ロジアナで調べてみると ESP32 でもI2Cバス上でエラーが発生た時に再送して取り直していて、ソフトウェアにエラーが出てきてないだけでした。

LRA1 では、アクセスエラーが起こるとそのままではプログラムが停止してしますので、エラーハンドラを用いてリトライするようにしています。

おまけ うまくいかなかったサンプルプログラム

以下は read_measurement でうまくいかなかったプログラムです。
ちゃんとトラブルシュートしてませんが、後々のために残しておきます。

1 Catch 1000
10 I2cD(-1)=100
20 ' 0x36f6 wake_up
30 I2cD(0)=$36
40 I2cD(1)=$F6
50 I2cW $62,-1,2
60 '0x3682 get_serial_number
70 I2cD(0)=$36
80 I2cD(1)=$82
85 Catch 1000
90 I2cW $62,-1,2
100 I2cR $62,-1,9
110 Gosub 240
120 ' 0x21ac start_low_power_periodic_measurement
130 I2cD(0)=$21
140 I2cD(1)=$B1
150 I2cW $62,-1,2
160 ' 0xec05 read_measurement
170 I2cD(0)=$EC
180 I2cD(1)=$5
190 I2cW $62,-1,2
195 Delay 10
200 I2cR $62,-1,9
210 Gosub 240
220 End
230 '======subroutine=============
240 ' print return 9 bytes
250 Print Form("X02",I2cD(0))Form("X02",I2cD(1))Form("X02",I2cD(2))Form("X02",I2cD(3))Form("X02",I2cD(4))Form("X02",I2cD(5))Form("X02",I2cD(6))Form("X02",I2cD(7))Form("X02",I2cD(8))
260 ' 9C6EDCB707293BFF85
270 U=9
280 Gosub _crccheck
290 If U=-1 Then Print "error":End EndIf
300 Print "serial:";:Print Form("X02",I2cD(0))Form("X02",I2cD(1))Form("X02",I2cD(3))Form("X02",I2cD(4))Form("X02",I2cD(6))Form("X02",I2cD(7))
310 Return
320 '=========subroutine ==============
330 _crccheck
340 ' use revariant : datacoutnt : U return; -1; error
350 For I=0 To U/3-1
360 C=$FF^I2cD(I*3)
370 For J=0 To 7
380 If (127<C)Then C=((C<<1)&$FF)^$31 Else C=((C<<1)&$FF)EndIf
390 'Print "J:";:Print J;:Print " ";:Print Form("X02",C)
400 Next
410 C=C^I2cD(I*3+1)
420 For J=0 To 7
430 If (127<C)Then C=((C<<1)&$FF)^$31 Else C=((C<<1)&$FF)EndIf
440 Next
450 If I2cD(I*3+2)<>C Then U=-1:Print "CRC ERROR":Return EndIf
460 'print "CRC OK"
470 Next
480 Return
1000 Print "ERROR NO=";Error;" AT ";Error#
1005 Catch 1000
1010 If Error=12 Then Goto Error#


これを実行すると、

>run
C5AEBFB707293BE1D9
serial:C5AEB7073BE1
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200
ERROR NO=12 AT 200

となりました。

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