Raspberry PI 高精度I2C温度センサーMCP9808で温度を記録
Raspberry PIを買って以来、Linuxサーバとしてしか使用していないので、
電子工作っぽいことをしたくなり、I2Cの温度センサーで温度を記録するプログラムを作ることにしました。
- 出版社/メーカー: raspberrypi.org
- メディア: エレクトロニクス
- この商品を含むブログ (1件) を見る
とりあえず、安くて精度も高い(±0.25%,最大±0.5%)高精度I2C温度センサーMCP9808を
スイッチサイエンスで購入しました。
とりあえずMCP9808とピンをハンダ付けしておきます。
・VDDとRaspiの1番(3.3V)
・GNDとRaspiの6番(GND)
・SDAとRaspiの3番
・SCLとRaspiの5番
につなげます。
写真を見ると変な繋げ方になっていますが、単にメスメスのジャンパケーブルがなかっただけです。
40 X 10CM メス to メス デュポン ジャンパー ワイヤー ケーブル
- 出版社/メーカー: Apps Tradings
- メディア:
- この商品を含むブログを見る
ここからはRaspberry PIのコンソール上での作業
/etc/modulesを編集し、以下を追加
i2c-bcm2708
i2c-dev
/etc/modprobe.d/raspi-blacklist.confを編集し、i2c-bcm2708をコメントアウト
# blacklist spi and i2c by default (many users don't need them)
blacklist spi-bcm2708
#blacklist i2c-bcm2708
ここで一旦再起動。
sudo shutdown -r now
i2c-toolsと開発用のライブラリのインストール
#sudo apt-get install i2c-tools libi2c-dev
MCP9808のアドレスの確認
sudo i2cdetect -y 1
pi@raspberrypi ‾ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
MCP9808のデータシートを見る
http://www.farnell.com/datasheets/1522173.pdf
5.1 Registersを見ると、温度を取得するには、
0101 = Temperature register (TA)
と書いてあるので、0x05(0b0101)を書き込めばいいことがわかります。
i2cgetを使用した簡単な温度の取得
pi@raspberrypi ‾ $ sudo /usr/sbin/i2cget -y 1 0x18 0x05 w
0xe4c1 <---結果
この結果をバイトスワップして、0x0FFFでマスクして、16で割ると、温度(摂氏)が出ます。(マイナスの場合はMSBの4bit目が符号)
上の結果、0xe4c1の場合、
1.バイトスワップ 0xc1e4
2.0x0FFFでマスク 0x01e4
3.16で割る 0x01e4 / 16 = 30℃
C言語で書くとこうです。ちなみに、sudoで実行しないと読めません。
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <linux/i2c-dev.h> // I2C用インクルード #include <fcntl.h> #include <sys/ioctl.h> int main(int argc, char **argv) { char *i2cFileName = "/dev/i2c-1"; const unsigned char i2cAddress = 0x18; const __u8 t_reg = 0x05; int i2c_fd; if((i2c_fd = open(i2cFileName,O_RDWR)) < 0){ fprintf(stderr,"Faild to open i2c port¥n"); return 1; } if (ioctl(i2c_fd, I2C_SLAVE,i2cAddress) < 0) { fprintf(stderr,"Unable to get bus access to talk to slave¥n"); return 1; } __s32 res = i2c_smbus_read_word_data(i2c_fd,t_reg); if(res < 0){ fprintf(stderr,"Error i2c_smbus_read_word_data()¥n"); return 1; } float temp; { __u16 t = res << 8 | res >> 8;//byte swap temp = t & 0x0FFF; //mask temp /= 16; if(t & 0x1000){ //sign or unsigned temp -= 256; } } time_t t; time(&t); struct tm *m; m = localtime(&t); printf("%d/%d/%d-%d:%d:%d,%.2f¥n",m->tm_year+1900,m->tm_mon+1,m->tm_mday,m->tm_hour,m->tm_min,m->tm_sec,temp); return 0; }
cronで10分毎に記録する
*/10 * * * * cd /home/pi/templogger;sudo ./templogger 2>&1 1>>temp.csv | logger -t templogger
※ログのローテーションとか考えてないです。エラーはsyslog行き。
約一日間、記録を取った結果はこんな感じ。
急激に温度が下がってる部分は、エアコン付けたからです。
上がってる部分は、おそらく、TV録画のためPCが稼働しているからです。
参考:http://www.raspberrypi.org/forums/viewtopic.php?t=40831&p=540457
参考:http://openrtm.org/openrtm/ja/content/pirt-unit_with_i2cdevices