IoT何をいまさら(60) Blynkで遠隔AnalogRead

Joseph Halfmoon

さて前回はBlynkを使って、Arduino互換に見えるArmコア端末Seeed社Wio TerminalのGroveコネクタに接続されたLEDをスマホから遠隔で点灯させてみました。今回は逆方向です。Groveコネクタに接続されたポテンショメータを「アナログ」で遠隔読み取りしてみようと思います。

さて、アナログ的に値を読み取る対象は以下に写真を掲げますポテンショメータ・モジュールです。SeeedStudio製Grove Beginner Kit搭載のモジュールであります。上部に見える白の4ピンコネクタがGrove端子です。電源ーGND間にポテンショメータの「固定」された両端の端子が接続されており、中間のしゅう動端子をアナログ入力として読み取るもの。

これを読み取れれば、他のアナログ出力センサも遠隔で読めるんでないかい。

という目論見でございます。

Grove Potentiometer接続先のHost側は、Wio Terminalのデジタル/アナログ兼用のGroveコネクタであります(正面向かって右側のコネクタ。)以下の投稿で調べましたとおり、

部品屋根性(28) Groveコネクタ、電源とIO電圧の組み合わせ

Wio Terminalの場合、通常のArduino Unoと異なり、電源電圧、IO電圧ともに3.3Vです。今回使用しているArduino Uno互換のソフト開発環境でアナログ値を読み取るのに使用する以下の関数は

analogRead()

ほぼ0V~電源電圧間を10ビット(0から1023)までの整数値として読み取るものなので、振り切ったときが3.3Vになる筈。

さて、まずはBlynkのクラウドに接続せず、単体でポテンショメータを読み取るサンプルプログラムはこちら。後でデバッグ用のシリアルポートはBlynkに渡したいので、値はWio TerminalのカラーLCDに書きだすことにいたします(黒地に白字の地味な配色だけれども。)

#include "TFT_eSPI.h"
#define LCD_BACKLIGHT (72Ul)

TFT_eSPI tft;

char txtBuffer[32];

void setup() {
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(4);
  digitalWrite(LCD_BACKLIGHT, HIGH);
  pinMode(A0, INPUT);
}

void loop() {
  int analogValue = analogRead(A0);
  sprintf(txtBuffer, "A0 : %4d", analogValue); 
  tft.fillScreen(TFT_BLACK);
  tft.drawString(txtBuffer, 0, 0);
  delay(1000);
}

ほとんどが画面書き出しのための設定で、アナログ値(ADコンバータによる読み取り)の取り込みは簡単。まあ、裏で皆やってくれるArduino環境のお陰です。なお、Wio Terminalの正面右のGroveコネクタはArduino的端子名称A0に接続しているので、A0を読めば良いです。

上記のプログラムを走らせている様子がこちら。ポテンショメータは大体真ん中辺です。Wio Terminal上、フォントサイズを多少大きめの4に指定してこんな感じ。WioTerminal_Potentiometer

さて、上のようにGroveポートに接続されたモジュールからアナログデータを読み取ることができることが確かめられました。これをベースに、クラウド上のBlynkを経由して、スマホのBlynkアプリから遠隔でアナログデータを読み取れるように改造してみます。その方法としては、大きく以下の2つの方法があるということです。詳しくはこちら

  • PULL
  • PUSH

PULLは、Blynk側からデータを頂戴とマイコンボード側にリクエストを出し、その時の値を「引っ張って」くるもの。PUSHは、マイコンボード側が何らかの周期とかイベントとかに基づいて「自主的に」値をクラウドに「押し込めて」くるもの。当然、一長一短あり、作成するアプリによって使い分ける必要があります。

今回は、先に簡単なPULLの方を実験してみます。そのコードがこちら。

#include "TFT_eSPI.h"
#include <rpcWiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleWioTerminal.h>

#define LCD_BACKLIGHT (72Ul)
#define BLYNK_PRINT Serial

char auth[] = "~ここにAuthコード記入~";
char ssid[] = "~ここにWiFiのSSID記入~";
char pass[] = "~ここにWiFiのPassコード記入~"; 

TFT_eSPI tft;

char txtBuffer[32];

int analogValue;

BLYNK_READ(V0)
{
  analogValue = analogRead(A0);
  sprintf(txtBuffer, "A0 : %4d", analogValue); 
  tft.fillScreen(TFT_BLACK);
  tft.drawString(txtBuffer, 0, 0);
  Blynk.virtualWrite(V0, analogValue);
}

void setup() {
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(4);
  digitalWrite(LCD_BACKLIGHT, HIGH);
  pinMode(A0, INPUT);
  
  Serial.begin(9600); 
  Blynk.begin(auth, ssid, pass);

}

void loop() {
  Blynk.run();
}

先ほどの単体動作サンプルプログラムからすると、ちょっと長くなったとは言え、loop()関数などはBlynk.run()だけになって返って「超シンプル」になっています。肝心の測定はというと、BLYNK_READ()という関数の中に押し込められています。

  1. Blynk側でアナログデータを読もうとする場合、仮想ピンV0を読む
  2. クラウドからWio TerminalにBLYNK_READ(V0)を起動するように要求
  3. 上記のコードがWio内で走ってアナログデータが読み取られ、仮想ピンV0に送られる
  4. そのデータがクラウドからスマホ上のBlynkアプリに伝達され、スマホに値が表示される

こんな動作が上のコードの裏側で起きるようです。スマホのアプリ上では、Value Displayウイジットという部品を1個おいて、それに接続する仮想V0ピンは0から1023までの値を取ること、今回は5秒に1回PULLすることを指定しています。実際に動作しているところのスマホ画面のスナップショットがこちら。VirtualPort AnalogRead

ちょっと写真が汚いですけれど、実際にスマホとWio Terminalの間で通信しているところをアイキャッチ画像に貼り付けてあります。

や~Blynk、ホントお手軽IoTだわな。。。

IoT何をいまさら(60) BlynkでIoT一撃? へ戻る

IoT何をいまさら(62) Wio Terminal、スクロールするテキスト表示 へ進む