macsbug

Just another WordPress.com site

Weather meter on iPad

leave a comment »

iPad を気象計にしました。                                                         2017.01.29
構成は ESP8266 + BME280 + iPad Pro + TouchOSC です。


.
費用は 既に ハードをお持ちでしたら TouchOSC アプリのみで 600円 です。
構成は ESP8266(881円) + BME280(442円) + TouchOSC(600円) で総計1923円です。
ESP8266 に接続した BME280 温度、湿度、気圧センサーの値を iPad へ表示します。

左上:緑のLEDは TouchOSC が受信し処理中を示しています。
右上:時刻表示。その左:バッテリー量。その左:表示装置のテストボタン。
左下:スライドバーで ESP8266 に接続している LEDランプの明るさを変えます。
_  下にあるトグルスイッチは 出力を スライドバーか温度に切り換えます。
_  温度の場合は ESP8266 に接続している LED の明るさが温度で変化します。
中央:温度、湿度、気圧は デジタル表示とロータリーのアナログ表示にしました。


.
TouchOSC
iPad や iPhone , Android のタッチインターフェースを利用して トグルスイッチ、
プッシュスイッチ、フェーダー、ロータリーフェーダー、XYパッド、ラベル、LED
などを、様々な大きさで、いくらでも画面に配置し、ESP8266 と連携させ 表示装置
や コントロール装置を 楽しく容易に作る事ができます。
双方向通信: iPad Wifi と ESP8266 Wifi 間で 双方向通信 が可能です。
.
TouchOSC Editor:iPad の画面作りをします。
ご自身のデザインで「世界で1つだけのパネル」が作れます。
画面のデザインは iMac の TouchOSC Editor で行います。( Win, Linux 用もあります)
以下の画面にある部品が用意されておりドラッグ&ドロップで作ります。
「部品配置」と「部品名称」と「動作数値」を入力するのみで「プログラムは不要」。
ESP8266 は今回のサンプルで短時間に作り、デザインに時間をかけると見事なパネル
が出来ます。奇麗な仕上がりは 楽しく美しさが出てきます。
素敵な「上島珈琲」や「スタバ」で 優雅な気分で過ごせます。


.
準備:ESP8266 + BME280 + TouchOSC で 1923円。
1. ESP8266 with TELEC:881 円。
2. BME280センサー:ebay で 442円。
3. LED:必要に応じて装着。D1 mini は 本体に LED が着いています。
4. iPad pro, iPad, iPhone, Androide:既にお持ちの物を使用します。0円。
5. github:CNMAT / OSC:ダウンロードしライブラリーへ入れる。Adrian Freed氏に感謝。
6. iPad アプリ:TouchOSC:600円。
7. TouchOSC Editor:Mac OS X。0円。マックの編集アプリです。上記 TouchOSCに記載。
_  
ESP8266 + BME280 のハードの構成は 以下を参照ください。
macsbug:ESP8266+BME280+OLED+BOX
macsbug:ESP8266 + AE-BME280 + ThingSpeak
macsbug:ESP8266+BME280+IR LED+Air Con+ThigSpeak
macsbug:Environmental Sensor (環境センサー)


.
TouchOSC Editor:
参考:hexler.net:TouchOSC | Editing layouts
_  YouTube:OSC Tutorial #1
iMac TouchOSC Editor で作成した レイアウト は WiFi (LAN経由) で iPad ( Layout, add )
_  へ 即 転送できます。


.

信号の流れ:

①:I2C で計測を要求。 ②:計測。 ③:計測値を I2C で送る。
④:ESP8266でOSC信号に変換する。 ⑤:WiFi UDP で直接通信する。
⑥:OSC:名前から Control interface を選択し 数量表示 又は 文字表示する。

UDP通信: ESP8266 と iPad 間の 直接通信を 行います。
_ macsbug:Communicate ESP8266 and iPad directly with UDP を参照してください。

ライブラリー:

#include <OSCMessage.h>
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>

TouchOSC:受信する方法。
_ 1. OSCMessage mIN
_ 2. udp.parsePacket())>0 で受信。
_ 3. mIN.route ( 部品名, サブルーチン);
_ 4. 部品毎の操作を行う。 トグルスイッチ や LEDの操作方法 を参照の事。

#include <OSCMessage.h> 

OSCMessage mIN;
int size;
if((size = udp.parsePacket())>0){
 while(size--)
  mIN.fill(udp.read());
   if(!mIN.hasError()){
    mIN.route("/1/push1", test);              // ** iPad -> ESP8266 **
    mIN.route("/1/fader", led_fade);          // ** iPad -> ESP8266 **
    mIN.route("/1/toggle",led_temp);          // ** iPad -> ESP8266 **
   } 
} 

TouchOSC:送信する方法。
_ 1. OSCMessage msg ( 部品の名前 );
_ 2. msg.add ( 数値 又は 文字 );
_ 3. UDP 送信。

OSCMessage msg(c);                             // c = name
msg.add(d);                                    // d = value
udp.beginPacket(udp.remoteIP(),txp);           // udp
msg.send(udp);                                 // udp
udp.endPacket();                               // udp end 
msg.empty();                                   // OSC end

トグルスイッチの操作方法:

mIN.route("/1/toggle",led_temp); 

void led_temp(OSCMessage &msg, int addrOffset){  // toggle
  int ledState = (boolean) msg.getFloat(0);      // get state of toggle
  if ( ledState == 1 ){ ind = 1;}                // fader switch on
  if ( ledState == 0 ){ ind = 0;}                // fader switch off
}                                                //

フェーダーの操作方法:

mIN.route("/1/fader", led_fade); 

void led_fade(OSCMessage &msg, int addrOffset){  // fader
  ledValue = msg.getFloat(0);                    // get value of fader
  if (ind == 1){analogWrite(led, ledValue);}     // BUILTIN_LED controll
}                                                //

LEDの操作方法:

led_sw( "/OnOff/led9", "ON");

void led_sw(char led[], String sw){
  float v;
  if ( sw == "ON" ){ v = 1.0 ;}
  if ( sw == "OF" ){ v = 0.0 ;}
  OSCMessage msg(led);
  msg.add(v);
  Udp.beginPacket(Udp.remoteIP(),txp);
  msg.send(Udp);
  Udp.endPacket();
  msg.empty();
}

ESP8266 スケッチ:
上記の様に モジュールを コピー&ペースト すると 短時間に簡単 に出来ます。


.
参考:
1. h e x l e r . n e t | TouchOSC:TouchOSC の 本家です。
2. github:CNMAT / OSC:OSCライブラリーがあります。
3. facebook:TouchOSCでプロジェクションマッピングもできています。
4. TouchOSCとOSCuino:丁寧に説明しているサイト。
5. YouTube:Controlling a dc motor with ESP8266-12E + TouchOSC:リスト未公開。
_  ESP8266 でモーターコントロール:今回の送受信の方法で可能です。
6. YouTube:esp8266 OSC spotlight:リスト未公開。
_  ESP8266 でロボットコントロール:今回の送受信の方法で可能です。
7. YouTube:controlling an Arduino with an iPad:Fader が高速で動き
_  アナログアナライザーが出来ています。
8. fabifiess / NodeMCU_OSC
9. Tuna Knobs
_ 


.
感想:
1. 過去の記事:以下では TouchOSCでの 受信方法が不明で 出来ませんでした。
_  macsbug:ESP8266 for Arduino ことはじめ。
_   ESP8266 で受信方法を公開されているサイトは見つかりませんでした。
_   YouTube:受信し画面表示している例があり可能な事が判明しました。
_   ただし YouTube では リストは公開されていません。
_   最も丁寧に説明されているサイトがありました。TouchOSCとOSCuino
_  この記事を基に 林 伸夫氏が UDP方式変換とOSCを連結し動作が可能になりました。
_  林 伸夫氏に感謝!
2. 表示装置:現在 ESP8266で実現している TFT解像度は 340×240 が限界です。
_   iPad Proなら 2048×2732 の高解像度を電子工作で利用できる訳です。
3. 工作時間:パネルのデザインをするだけで表示装置が完成します。
_  これをHTMLで記述する事は恐らく無理です。
4. メモ:BME280 ライブラリー:
_   BME280_MOD_1022.h と BME280_MOD-1022.h とがあり注意が必要。
_   – が使用され Arduino IDE のバージョンによりエラーが出る時があります。
5. ライブラリー:受信の メッセージ ライブラリーを作り始めました。
_   少し出来て動き始めましたが、これではダメな事に気づきました。
_   ライブラリーは OSCMessage だけでは無く 他の機能も必要です。
_   実際 github:CNMAT / OSCを見ると OSCBundle, OSCData, OSCMatch, OSCTiming 等
_  の機能が必要である事。よって 上記のOSCライブラリを使いこなす事ですね。
6. 事例:ESP8266 に接続している LED を PWM コントロールできる装置、
_   XL4001(387円)。秋月:LEDドライバモジュール (140円) を使用して 部屋
_  のライト等をコントロールする事ができます。
7. UDP直接通信:
_   照明器具をネット経由で操作するものがありますが ふと疑問に思います。
_   「何故 目の前のライトをネット経由で操作する必要があるのか」
_   手で直接操作するか UDPで直接通信すれば良いのではと思っています。
_   温度変化をネット経由でグラフ化できる ThingSpeak も経験してみました
_   が 日常生活では さほどグラフを見る必要性が無い事を体験しています。
8. 美しさ:
_  電子工作の完成品は 見た目 奇麗でない場合が多いですが、表示を iPad や
_  iPhone にして素敵なデザインをすると 見事に奇麗なものが出来ます。
_  機能も大切ですが デザインはそれ以上に大切かと思っています。 


.
TouchOSC のリスト:GitHub を使用していない為、リストアップできません。
以下を参考に「素敵なデザイン」を組み上げてください。
右上の Tx は TouchOSC の送信ランプ、Rx は受信ランプです。
Tx は送信時「緑」に点灯、Rx は受信時「赤」に点灯します。

左上から右下に Control interface の内容を列記します。

LED:led,0,1
Label V:Color=Brown,Text="Temp,,,",Size=32
Push Button:Name=push1,Color=Gray,Value Range=0 To 1
Battery V:Color=Green,Outline,Size=24
Time V:Color=Orange,Outline,Size=24
Label V:Name=disp,Color=Gray,Size=24
fader V:NAme=fader,Color=Brown,Value Range=1023 To 0
Toggle Button:Color=Brown
Rotary V:Name=tr,Color=Red,Value Range=0 to 40
Label V:Text="Temp,,",Color=Brown,Size=32
Label V:Name=t,Color=Red,Text=88,Size=66
Label V:Text="Humi,,",Color=Brown,Size=32
Rotary V:Name=hr,Color=Green,Value Range=20 to 60
Label V:Name=h,Color=Green,Text=88,Size=66
Label V:Text="Pres,,",Color=Brown,Size=32
Rotary V:Name=pr,Color=Blue,Value Range=990 to 1030
Label V:Name=p,Color=Blue,Text=88,Size=66
Label V:Color=red,Text=0,Size=24

.
ESP8266 スケッチ:
1. SSID は各自好みの名前にしてください。
2. ESP8266 に接続する LED のピン番号は 各自の使用GPIOにしてください。
_  int led = BUILTIN_LED;
3. ESP8266 に接続する BME280 のピン番号は 各自の使用GPIOにしてください。
_  Wire.begin(SDA, SCL);
_  5sec 毎に送信します。必要に応じて 初期値の rm = 5000 を変えてください。
4. UDP送受信の PORT 番号は好みの数値に変更可能です。
_  ESP8266 と iPad TouchOSC の outgoing と incoming を合わせてください。
.

// ESP8266 + BME280 + TouchOSC + iPad            // 2017.01.29 macsbug
// BME280 : Temperature,Humidity,Pressure Sensor //
// UDP communication
// ESP8266(ip:192.168.4.1,port:9000) transmit ---|
// ipad   (ip:192.168.4.2,port:9000) receive  <--|
// ipad   (ip:192.168.4.2,port:8000) transmit ---|
// ESP8266(ip:192.168.4.1,port:8000) receive  <--|
#include <BME280_MOD_1022.h>                     // BME280_MOD-1022.h
#include <Wire.h>                                //
#include <OSCMessage.h>                          //
#include <ESP8266WiFi.h>                         //
#include <WiFiUDP.h>                             //
static WiFiUDP udp;                              //
const char *ssid = "a10";                        // SSID
const char *pass = "";                           // password
#define rxp 8000                                 // ESP Rx Port:TouchOSC=outgoing
#define txp 9000                                 // ESP Tx Port:TouchOSC=incoming
IPAddress ESP8266_IP;                            // ESP8266 IP = 192.168.4.1
IPAddress ipad_RX_IP;                            // iPhone  IP = 192.168.4.2
long ta =  -5.3;                                 // temperatue adjust
long ha = +16.7;                                 // humidity   adjust
long pa =  +3.5;                                 // press      adjust
int rt,count,rm = 5000,ind = 0;                  // time count, 5sec
int led = BUILTIN_LED;                           // 15 BUILTIN_LED
float ledValue = 1023;                           // led fader

void setup(){                                    //
  pinMode(led, OUTPUT);                          // GPIO Conttroll
  analogWrite(led, 1023);                        // LED Illuminance OFF
  Serial.begin(115200);Serial.println();         //
  //---------------------------------------------// BME280 setup
  Wire.begin(D6, D7); delay(10);                 // SDA, SCL 12,13
  BME280.readCompensationParams();               // read the NVM param
  BME280.writeOversamplingTemperature(os1x);     // 1x over sampling
  BME280.writeOversamplingHumidity(os1x);        // 1x over sampling
  BME280.writeOversamplingPressure(os1x);        // 1x over sampling
  //---------------------------------------------// WiFi setup
  WiFi.mode(WIFI_AP);                            // AP setup
  WiFi.softAP(ssid, pass);                       //
  ESP8266_IP = WiFi.softAPIP();                  // 192.168.4.1  localIP
  udp.begin(rxp);                                // iPad -> ESP8266 Rx Port
  rt = millis();                                 // save time
}                                                //
 
void loop(){                                     //
  OSCMessage mIN;                                //
  int size;                                      //
  if((size = udp.parsePacket())>0){              //
   while(size--)                                 //
    mIN.fill(udp.read());                        //
     if(!mIN.hasError()){                        //
      mIN.route("/1/push1", test);               // ** iPad -> ESP8266 **
      mIN.route("/1/fader", led_fade);           // ** iPad -> ESP8266 **
      mIN.route("/1/toggle",led_temp);           // ** iPad -> ESP8266 **
     }                                           //
  }                                              //
  count = int( millis() - rt );                  // read time
  if ( count > rm ){                             // time check
    sensor();                                    // ** ESP8266 -> iPad **
    count = 0; rt = millis();                    // reset time
  }                                              //
}                                                // 

void tx(String s, float f, int t ){              // OSCMessage + UDP
  char c[12];                                    // char
  int len = s.length() + 1;                      // string length
  s.toCharArray(c, len);                         // c = string to char 
  OSCMessage msg(c);                             // name
  msg.add(f);                                    // value
  udp.beginPacket(udp.remoteIP(),txp);           // udp
  msg.send(udp);                                 // udp
  udp.endPacket();                               // udp end 
  msg.empty();                                   // OSC end
  if ( t != 0 ){ delay(t);}                      // delay
}                                                //

void txchr(String s, String f, int t ){          // OSCMessage + UDP
  char c[12], d[40];                             // char
  int len = s.length() + 1;                      // string length
  s.toCharArray(c, len);                         // c = string to char 
  len = f.length() + 1;                          // string length
  f.toCharArray(d, len);                         // c = string to char 
  OSCMessage msg(c);                             // name
  msg.add(d);                                    // value
  udp.beginPacket(udp.remoteIP(),txp);           // udp
  msg.send(udp);                                 // udp
  udp.endPacket();                               // udp end 
  msg.empty();                                   // OSC end
  if ( t != 0 ){ delay(t);}                      // delay
}                                                //

void sensor(){                                   //
  //---------------------------------------------// BME280 sensor
  BME280.writeMode(smForced);  delay(50);        // chip goes back to sleep
  while (BME280.isMeasuring()){delay(50);}       // BME280 check
  BME280.readMeasurements();                     // read out the data
  float t = BME280.getTemperature()+ta;          // Temperature
  float h = BME280.getHumidity()   +ha;          // Humidity
  float p = BME280.getPressure()   +pa;          // Pressure 
  int   c = int(millis()/1000);                  // count
  //---------------------------------------------// 
  tx( "/1/led",    1 , 300 );                    // LED ON
  tx( "/1/t",  int(t), 300 );                    // Temperature digital
  tx( "/1/h",  int(h), 300 );                    // Humidity    digital
  tx( "/1/p",  int(p), 300 );                    // Presuure    digital
  tx( "/1/tr",     t , 300 );                    // Temperature roter
  tx( "/1/hr",     h , 300 );                    // Humidity    roter
  tx( "/1/pr",     p , 300 );                    // Presuure    roter
  if (ind==0){analogWrite(led,1023-t*1023/40);}  // temp -> led
  if (ind==1){analogWrite(led,ledValue);}        // temp -> led
  tx( "/1/led",    0 , 300 );                    // LED OFF
  //---------------------------------------------//
}

void test(OSCMessage &msg, int addrOffset){      //
  txchr("/1/disp", "Indicator Test",50);         //
  for(int i=   0;i<=  41;i++){tx("/1/t" ,i,50);} //
  for(int i=  40;i>=   0;i--){tx("/1/t" ,i,50);} //
  for(int i=  20;i<=  60;i++){tx("/1/h" ,i,50);} //
  for(int i=  60;i>=  20;i--){tx("/1/h" ,i,50);} //
  for(int i= 990;i<=1030;i++){tx("/1/p" ,i,50);} //
  for(int i=1030;i>= 990;i--){tx("/1/p" ,i,50);} //
  for(int i=   0;i<=  40;i++){tx("/1/tr",i,50);} //
  for(int i=  40;i>=   0;i--){tx("/1/tr",i,50);} //
  for(int i=  20;i<=  60;i++){tx("/1/hr",i,50);} //
  for(int i=  60;i>=  20;i--){tx("/1/hr",i,50);} //
  for(int i= 990;i<=1030;i++){tx("/1/pr",i,50);} //
  for(int i=1030;i>= 990;i--){tx("/1/pr",i,50);} //
  txchr("/1/disp", "",50);                       //
}                                                //

void led_fade(OSCMessage &msg, int addrOffset){  // fader
  ledValue = msg.getFloat(0);                    // get value of fader
  if (ind == 1){analogWrite(led, ledValue);}     // BUILTIN_LED controll
}                                                //

void led_temp(OSCMessage &msg, int addrOffset){  // toggle
  int ledState = (boolean) msg.getFloat(0);      // get state of toggle
  if ( ledState == 1 ){ ind = 1;}                // fader switch on
  if ( ledState == 0 ){ ind = 0;}                // fader switch off
}                                                //
広告

Written by macsbug

1月 29, 2017 @ 1:56 pm

カテゴリー: Apple, ESP8266

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。