RFM12B + MCP9701
2012.01.27 · 1044 words · 3 minute read
久々のRFM12Bネタ。
微弱無線モジュール RFM12B と 温度センサー MCP9701 を使った遠隔計測。
温度センサーは特に指定した訳ではなく、たまたまあったやつ(MCP9701)を使うことに。
センサー側はこんな感じ。MCP9701を5V、GND、アナログ5ピンに接続し、RFM12Bも前の記事の通りに接続。
受信側はRFM12Bのみ、同様に接続。
MCP9701は0℃の時400mVなので0.4Vのオフセット、1℃あたりの電圧の変化は19.53mVである。
アナログ入力は0〜5Vを0〜1023の1024段階で表現するので、以上を踏まえて下記のような感じで温度を得られる。
double sensorVal;
double temp = 0;
double offset = 0.4; //オフセット(V)
double tc = 19.53; //温度係数(mV)
temp = (( 5.0 / 1024 * sensorVal ) - offset ) / ( tc / 1000 );
これを前のプログラムに適当に突っ込むと完成。とっても簡単。
センサー側のプログラムはこんな感じ。
#include <rf12.h>
#include <ports.h>
#define NODE_ID 1
#define LED_PIN 7
#define TEMP_SENSOR 5
#define LED_OUTPUT() pinMode(LED_PIN,OUTPUT)
#define LED_ON() digitalWrite(LED_PIN, HIGH)
#define LED_OFF() digitalWrite(LED_PIN, LOW)
MilliTimer sendTimer;
byte needToSend;
double sensorVal;
double temp = 0;
double offset = 0.4; //オフセット(V)
double tc = 19.53; //温度係数(mV)
void setup () {
Serial.begin(9600);
rf12_initialize(NODE_ID, RF12_433MHZ, 33);
}
void loop () {
sensorVal = analogRead( TEMP_SENSOR ); //温度取得
temp = (( 5.0 / 1024 * sensorVal ) - offset ) / ( tc / 1000 );
if (rf12_recvDone() && rf12_crc == 0 && *(int*) rf12_data) {
LED_ON();
Serial.println("Send check OK!");
Serial.println();
delay(200);
LED_OFF();
}
if (sendTimer.poll(3000)) // ポーリングタイマー3000ミリ秒
needToSend = 1;
if (needToSend && rf12_canSend()) {
LED_ON();
Serial.print("send temp:");
Serial.println(temp);
rf12_sendStart(0, &temp, sizeof temp);
delay(200);
needToSend = 0;
LED_OFF();
}
}
受信側のプログラム(一部省略)はこんな感じ。
温度を受信したら1を送信。
int num = 1;
void loop () {
if (rf12_recvDone() && rf12_crc == 0) {
LED_ON();
Serial.print("receive temp:");
Serial.println(*(double*) rf12_data);
delay(200);
LED_OFF();
}
if (sendTimer.poll(3000)) // ポーリングタイマー3000ミリ秒
needToSend = 1;
if (needToSend && rf12_canSend() && *(double*) rf12_data) {
LED_ON();
rf12_sendStart(0, &num, sizeof num);
Serial.println("receive check send.");
Serial.println();
delay(200);
needToSend = 0;
LED_OFF();
}
}
コンパイルして転送。
とりあえず両方ともMacBook Airの2つのUSBポートに接続。
CoolTermで9600を見る。
↑receiveの綴りが間違っている事に今更気づく(;゜ロ゜)
やりとりの内容は至って簡単。
送信側が気温を送信(send temp)→受信側が気温を受信(receive temp)→受信側が1を返信(receive check send.)→送信側が受信側の受信を確認(Send check OK!)
Arduino UNO(ATmega328)だとアナログ入力が0〜5ピンの6個あるので、単純なセンサー(温度、照度、気圧 etc…)を6個接続できる。
ここまでで創造実験は一旦終了。
ADKでAndroidから値の読み出しなど、続きは卒業研究。
のつもりだったんだけど、学生研究奨励金で3万取れたのでUNOとMegaとEthernet Shield*2個で少しだけ発展したものを作るつもり。
具体的なことは進捗状況と一緒に書いていく予定です。