인터넷 온도계

일반 가정에서의 IoT를 생각했을 때, 데이터의 흐름에 주목하면 IN과 OUT이 있다고 생각한다.



IN은 정보 제공 등의 기능이 해당하고, OUT은 어떤 정보 공유를 위한 기능이 해당되는 것은 아닐까.

IN의 모델로서 인터넷에 연결된 온도계를 만들어 보고 싶다. 이것은 온도의 계측은 자전으로 행하고, 그물로부터 그 날의 최고 최저 기온을 입수해 표시하는 대물을 생각하고 있다.

플랫폼은 이전에 소개한 FreeBSD/mruby와 Arudino를 사용한다.



mruby on FreeBSD는 ZRouter 빌드하고 하드 오프로 구입한 AR2315인 정크 라우터에서 움직이고 있다. 전파법의 겸용도 있으므로 WIFI는 사용하지 않고 Ethernet으로의 접속으로 하고 있다.

우선 mruby에서 인터넷에서 그날 최고 최저 기온을 얻는 코드를 만들어 보자. 이것은 야후 날씨의 RSS에서 데려오기로 한다.
loc = "4410"
#loc = "3530"
h = HttpRequest.new()
r = h.get("http://rss.weather.yahoo.co.jp/rss/days/"+loc+".xml");
s = r.body
pos = s.index('description')
pos = s.index('description', pos+1)
pos = s.index('description', pos+1)
pos = s.index(' - ', pos+1)
npos = s.index('℃', pos+1)
hi = s[pos+3..npos-1]
pos = s.index('/', pos+1)
npos = s.index('℃', pos+1)
lo = s[pos+1..npos-1]
p hi + " " + lo

mruby에는 지금까지 xml의 파서가 없는 것 같기 때문에, 꽤 무리야리 스크래핑 하고 있다. 이것을 이 페이지에 쓴 I2C 모듈을 사용하여 Arduino에 보내는 코드는 다음과 같다.
t = BsdIic.new(0)
t.write(8,0,hi.to_i)
t.write(8,1,lo.to_i)
p t.read(8,0)

마지막 행은 덤으로, Arduino에서 현재 기온을 주워하고 있습니다.

Arudino는 Aitendo의 병으로 좋기 때문에 온도 센서는 LM61로 7세그는 수중에 있던 TOD-5261B라고 하는 부품을 사용했다.



Arduino의 프로그램은 「키무 차 공방 차고」씨의 I2C 페이지LM61 페이지 과 「초보자이지만, 한 걸음씩 Arduino 초소형 마이크로컴퓨터 전자 공작」씨의 7세그 페이지 를 참고하게 했다.
#include <MsTimer2.h>
#include <Wire.h>

//グローバル変数を宣言
int Digit1=0; //左側7セグLED表示用LED
int Digit2=0; //右側7セグLED表示用LED
int Dp;

byte dt[2] ;

int temp;
int hi, lo;

// データを受信すると処理される割込み関数
void receiveEvent(int howMany) 
{
  int count = 0;
  while(Wire.available()) {   // 書き込みの時は2バイトで読み込みの時は1バイト
    dt[count] = Wire.read();
    ++count;
  }
  if(count == 2) {
    //書き込みで1バイト目が0が最高気温,1が最低気温
    if(dt[0] == 0) {
      hi = dt[1];
    } 
    else {
      lo = dt[1];
    }
  }
}

// データ要求を受信すると処理される割込み関数
void requestEvent() 
{
  Wire.write(temp) ;   // LM61で測定した温度を送信
}

//LEDレイアウトを定義
boolean Num_Array[10][7]={
  {
    0,0,0,0,0,0,1    }
  ,{
    1,0,0,1,1,1,1    }
  ,{
    0,0,1,0,0,1,0    }
  ,{
    0,0,0,0,1,1,0    }
  ,
  {
    1,0,0,1,1,0,0    }
  ,{
    0,1,0,0,1,0,0    }
  ,{
    1,1,0,0,0,0,0    }
  ,{
    0,0,0,1,1,1,1    }
  ,
  {
    0,0,0,0,0,0,0    }
  ,{
    0,0,0,1,1,0,0    }
};

//LED表示関数を定義
void NumPrint(){
  static int DigitFlag=2; //表示している桁 1の時は左側、2の時は右側
  int Number;
  if(DigitFlag==1){
    digitalWrite(9,HIGH);
    digitalWrite(10,LOW);
    Number=Digit1;
    DigitFlag=2;
  }
  else{
    digitalWrite(9,LOW);
    digitalWrite(10,HIGH);
    Number=Digit2;
    DigitFlag=1; 
  }
  // 数字表示
  for (int w=0; w<=6; w++){
    digitalWrite(w+1,Num_Array[Number][w]);
  }
  // ドット表示
  digitalWrite(8,Dp == DigitFlag ? 0 : 1);
}

//LED2桁表示
//dotは右が1で左が2で無しが0
void NumPrintEx2(int Number, int dot){
  Digit1=Number / 10; //十の位を指定
  Digit2=Number % 10; //一の位を指定 %は余りを計算
  Dp = dot;
}

void setup(){
  //1~8番ピン デジタル出力へセット
  for (int i=1; i<=8; i++){
    pinMode(i,OUTPUT);
  }
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);

  MsTimer2::set(10, NumPrint); // 10ms period
  MsTimer2::start();

  Wire.begin(8) ;                    // I2Cの初期化、マイアドレスは8とする
  Wire.onRequest(requestEvent) ;     // 割込み関数の登録
  Wire.onReceive(receiveEvent) ;     // 割込み関数の登録
}

void loop(){
  int ans , tv ;

  ans = analogRead(0) ;              // アナログ0番ピンからセンサー値を読込む
  tv  = map(ans,0,1023,0,5000) ;     // センサー値を電圧に変換する
  temp = map(tv,300,1600,-30,100) ;  // 電圧から温度に変換する

  NumPrintEx2(temp, 0);
  delay(5000);
  NumPrintEx2(hi, 2);
  delay(5000);
  NumPrintEx2(lo, 1);
  delay(5000);
}

현재 기온, 최고 기온, 최저 기온 순으로 표시한다. 점에서 최저 최고 기온을 나타내도록 하고 있다.



라우터는 3.3V계로, 병보로 좋은 것은 5V계이므로 아키즈키 전자에서 구입한 PCA9306을 사용한 레벨 변환 모듈로 접속하고 있습니다. 이 모듈에는 풀업 저항도 포함되어 있습니다.

기온 데이터를 인터넷에 보내는 것(OUT)도 할 수 있습니다만, 이용 가치가 있는 아이디어가 없습니다. 자신의 방의 온도를 타인에게 알게 해도 그다지 기쁘지 않네요.

IoT는 인터넷에 연결되어 있는지 여부는 의식하지 않고 사용되는 것인 것이 좋은 것인지 생각하기도 합니다.

실은 이 구조의 데이터의 흐름은 여기 과 거의 같습니다만, 사용하고 있는 기술이 조금 다릅니다.

좋은 웹페이지 즐겨찾기