別棟備忘録4

*

つぶやき良純(Processing Report.3)

      2015/10/24

Processingに慣れることをテーマに作成した問題作「黒板五郎」。ProcessingとArduinoのリンクに挑戦し、「1種類」のデータをArduino→Processingに送った「亀田○毅」。それに続く第三弾はProcessingからArduinoに複数のデータを送り、かつそれをTwitterにつぶやくスケッチ、その名も「つぶやき良純」

・参考にさせていただいたページ・

Arduino→Processingに複数のデータを送る
http://d.hatena.ne.jp/qt_fb/20110806/1312621700

Processing 2.0とTwitter4Jで、ProcessingからTweetしてみる
http://yoppa.org/blog/3972.html

TwitterとArduinoやProcessingの連携については参考ページが複数あるが、記述がやや古く通用しないもの(ex Japanino特設ページの風力ロガーのもの)もあり四苦八苦。2013年5月末現在少なくとも↑のページはOKでした。要するにTwitterアカウントから開発者ページにアクセスして、4つの情報を取得する、と。あとは、ライブラリTwitter4Jを読み込むべし、ということですね。

・回路とスケッチ・

センサーはとりあえず光センサー(Cds)と温度センサーLM35を使用。LM35はJapaninoを用いると挙動が安定しなかったので、Arduinoを使いました。図。

by Fritzing(Free)

 

スケッチはやはりArduinoとProcessingそれぞれについて作成する必要あり。

Arduino側のスケッチ(一部改)

int windPin = 0;
int ondoSensorPin = 1;
int cdsPin = 2;
double temperatureVal;
unsigned long int sumOndoVal,sumCdsVal;
unsigned long int loopCnt;
unsigned long int lastMillis;
unsigned long int interval = 1200000;//20分に1回プロセッシングに送信
void setup() {
  Serial.begin(9600);
pinMode(13,OUTPUT);
}
void loop() {
//温度センサの値を取得
 int ondoSensorVal = analogRead(ondoSensorPin);
//温度センサの値を摂氏にする
 int temperature = (ondoSensorVal* 500 / 1024 );
 temperatureVal += temperature;
//CdS(明るさ)センサの値を取得
  int cdsVal = analogRead(cdsPin);
  sumCdsVal += cdsVal;
//平均値をとるためのカウンター
  loopCnt++;
//インターバルをこえるとPCに送信
  if(millis()-lastMillis>interval){
//ループ数で割った平均値
      int aveTemperature = temperatureVal/loopCnt;
      int aveCdsVal = sumCdsVal/loopCnt;
      Serial.print(aveTemperature,DEC);//温度センサの平均値を送信
      Serial.print(",");
      Serial.println(aveCdsVal,DEC);//cdsの平均値を送信
      //Serial.read();
      sumOndoVal=0;
      sumCdsVal=0;
      loopCnt = 0;
      temperatureVal=0;
digitalWrite(13,HIGH);
delay(300);
digitalWrite(13,LOW);
      lastMillis = millis();
  }
}

とにかく、大人の科学の風力ロガーのものに忠実であります。

一方でProcessing側のスケッチ。細かい説明はひとまず省略。

import twitter4j.conf.*;
import twitter4j.internal.async.*;
import twitter4j.internal.org.json.*;
import twitter4j.internal.logging.*;
import twitter4j.internal.util.*;
import twitter4j.api.*;
import twitter4j.util.*;
import twitter4j.internal.http.*;
import twitter4j.*;
import processing.serial.*;
Serial myPort;
int portIndex = 0;
String msg = "物理室の";
String consumerKey = "***ここに***";
String consumerSecret = "***4つの***";
String accessToken = "***値を***";
String accessSecret = "***入力****";
Twitter myTwitter;
int ms;
String temp = "";
String akarusa = "";
color bg = color(0, 0, 0);
void serialEvent (Serial port) {
  String inString = port.readStringUntil('\n');
  if(inString != null) {
    inString = trim(inString);
    String [] value = split(inString, ',');
    if(value.length > 1) {
      println(value[0]);
      println(value[1]);
      temp = value[0];
      akarusa = value[1];
    }
  }
}
void setup() {
  size(200, 200);
  frameRate(60);
  ConfigurationBuilder cb = new ConfigurationBuilder();
  cb.setOAuthConsumerKey(consumerKey);
  cb.setOAuthConsumerSecret(consumerSecret);
  cb.setOAuthAccessToken(accessToken);
  cb.setOAuthAccessTokenSecret(accessSecret);
  myTwitter = new TwitterFactory(cb.build()).getInstance();
  //シリアルポートの設定
   if(portIndex==-1){
    //portIndexを変更していないときに実行される
    for(int i=0, l=Serial.list().length ; i < l; i++){
      println(i+" : "+Serial.list()[i]);
    }
    exit();
  }else{
   myPort = new Serial(this, Serial.list()[portIndex], 9600);
}
}
 
void draw() {
  background(bg);
  if (millis() - ms > 1000) {
    bg = color(0, 0, 0);
  }
}
 
void mousePressed() {
  try {
    Status st = myTwitter.updateStatus(msg +  "温度" + temp + "℃ / 明るさ:" + akarusa + " "+ getDate());
    println("Successfully updated the status to [" + st.getText() + "].");
    ms = millis();
    bg = color(0, 0, 255);
  }
  catch (TwitterException e) {
    println(e.getStatusCode());
    bg = color(255, 0, 0);
  }
}
 
String getDate() {
  String monthStr, dayStr, hourStr, minuteStr, secondStr;
  if (month() < 10) {
    monthStr = "0" + month();
  }
  else {
    monthStr = "" + month();
  }
  if (day() < 10) {
    dayStr = "0" + day();
  }
  else {
    dayStr = "" + day();
  }
  if (hour() < 10) {
    hourStr = "0" + hour();
  }
  else {
    hourStr = "" + hour();
  }
  if (minute() < 10) {
    minuteStr = "0" + minute();
  }
  else {
    minuteStr = "" + minute();
  }
  if (second() < 10) {
    secondStr = "0" + second();
  }
  else {
    secondStr = "" + second();
  } 
  return monthStr + "/" + dayStr + ", " + hourStr + ":" + minuteStr + ":" + secondStr;
}

・お天気実況風景・

現状は、定期的にデータを読み取ってTwitterにつぶやくのみ。そして、なんだか動作不安定。明るさの数値と温度が独立の挙動になっていない疑い。

たとえば大きな変化が生じたときにつぶやくとか、別のスイッチを備えるといった工夫はあまり難しくなく加えられそう。以上、入善高校自然科学コースとの合作でありました。

 - Arduino+Processing