お知らせ

  • らずぱいでIoT

らずぱいでIoT 第7回(温度、気圧、湿度の計算準備)

noimage

らずぱいでIoT 第7回(温度、気圧、湿度の計算準備)

以前に、awkで計算した際に計算式で使用したdig_T1~dig_T3の算出を行いましたがBME280のチップ説明書によるとawkのプロラム内でdig_T2とdig_T3はsigned shortのためマイナスの0x8000の符号ビットが1の場合マイナスで扱う必要があるため正常な計算ができない可能性があります。 ただし、何度か読みだしたdig_T2,dig_T3はマイナスの値になることはなく常温程度ならマイナスにはならないのかもしれません。 awkではビット演算がサポートされてないためShift Rotateのような演算関数を作りそのうえでビット演算関数を作らない限り演算できないので実現は難しい(アセンブラにできて高級言語でできないことはあり得ないですが)のですが、pythonの場合は温度、気圧、湿度を計算するためのパラメータを求めるときにビット演算が可能なため肩を合わせることも可能になります。 上の表は各パラメータの算出を行うため、レジスタのどの位置を読むとどのパラメータになるかを示しています。前回のプログラムではcalib をDictにしたのはこのデータを読み出すためにはアドレスを指定して読みだしたほうがわかりやすいプログラムになるためです。 で今回追加した部分は以下のようになります。 ーーーーーーーーーーーーーーーーーーーーーーーー以下プログラム dig_T[1] = (calib[0x89] << 8 | calib[0x88]) dig_T[2] = (calib[0x8B] << 8 | calib[0x8A]) dig_T[3] = (calib[0x8D] << 8 | calib[0x8C]) dig_P[1] = (calib[0x8F] << 8 | calib[0x8E]) dig_P[2] = (calib[0x91] << 8 | calib[0x90]) dig_P[3] = (calib[0x93] << 8 | calib[0x92]) dig_P[4] = (calib[0x95] << 8 | calib[0x94]) dig_P[5] = (calib[0x97] << 8 | calib[0x96]) dig_P[6] = (calib[0x99] << 8 | calib[0x98]) dig_P[7] = (calib[0x9B] << 8 | calib[0x9A]) dig_P[8] = (calib[0x9D] << 8 | calib[0x9C]) dig_P[9] = (calib[0x9F] << 8 | calib[0x9E]) dig_H[1] = calib[0xA1] dig_H[2] = (calib[0xE2] << 8 | calib[0xE1]) dig_H[3] = (calib[0xE3]) dig_H[4] = (calib[0xE4] << 4 | calib[0xE5] & 0xf) dig_H[5] = (calib[0xE6] << 4 | calib[0xE5] >> 4) dig_H[6] = (calib[0xE7]) ーーーーーーーーーーーーーーーーーーーーーーーーここまで 前回は、dig_T,dig_P,dig_HはListで初期化していましたがプログラムを書く際これらもDictで初期化しておいたほうがわかりやすくかけるため初期化部分をDictにしている事に注意してください。 今回の全体ソースと日本語のチップ説明書をZIPにしてありますのでここからダウンロードしてください。    

  • らずぱいでIoT

らずぱいでIoT 第5回(awkで計算してみる)

noimage

らずぱいでIoT 第5回(awkで計算してみる)

前回は、i2c-toolsのコマンドを使い気圧、温度、湿度のRawデータを読取ってみました。 今回は、Rawデータと補正値を読取ってそれをファイルに取り古くからあるフィルタープログラムのawkで連想配列を駆使して温度計算をしてみようと思います。 --------------------- 以下 ReadTemp シェルスクリプト側 #!/bin/bash i2cset -y 1 0x77 0xF5 0xA0 b i2cset -y 1 0x77 0xF2 0x01 b i2cset -y 1 0x77 0xF4 0x25 b sleep 0.1 i2cdump -y -r 0x88-0xA1 1 0x77 b >RT.dat i2cdump -y -r 0xE1-0xFE 1 0x77 b >>RT.dat awk -f CalcT.awk RT.dat ------------------------ ここまで 最後に awk -f でawkスクリプトを読んでいます。 ------------------------ 以下 awk スクリプト BEGIN { for(i=0; i<=15; i++) { hex[sprintf("%X",i)]=i; if (i>9) hex[sprintf("%x",i)]=i; } } /^[89aef]0:/ { split($0,dat,":"); line[dat[1]]=dat[2]; } END { dig_T1=shiftL(getByte(toHex("8"),toHex("9")),8) dig_T1+=getByte(toHex("8"),toHex("8")); dig_T2=shiftL(getByte(toHex("8"),toHex("B")),8) dig_T2+=getByte(toHex("8"),toHex("A")); dig_T3=shiftL(getByte(toHex("8"),toHex("D")),8) dig_T3+=getByte(toHex("8"),toHex("C")); temp_r = shiftL(getByte(toHex("F"),toHex("A")),12); temp_r += shiftL(getByte(toHex("F"),toHex("B")),4); var1 = shiftR(temp_r, 3) - shiftL(dig_T1,1); var1 *= shiftR(dig_T2,11); var2 = shiftR(temp_r, 4) - dig_T1; var2 *= shiftR(shiftR(temp_r,4)-dig_T1,12); var2 *= shiftR(dig_T3,14); printf("Temperature = %2.2f\n",shiftR((var1+var2)*5+128,8)/100); } function getByte(hiA,lwA) { r=0; Ads=sprintf("%x0",hiA); r = toHex(substr(line[Ads],3*(lwA+1)-1,1))*16+toHex(substr(line[Ads],3*(lwA+1),1)); return r; } function shiftR(v,r) { return int(v/(2^r)); } function shiftL(v,r) { return int(v*(2^r)); } function toHex(c) { if (length(c)==1 && (c ~ /[0123456789ABCDEFabcdef]/)) return hex[c]; else return -1; } ------------------------ ここまで でそれらしい値が表示されています。 なので今回使っている温度・湿度・気圧センサーは、シェルスクリプトからでも制御可能なデバイスです。 以上のスクリプトとサンプルデータはこちらからダウンロードできます。