https://blog.with2.net/link/?1965529

TouchOSCでスマホからリモコン

https://blog.with2.net/link/?1965529

スイッチサイエンス The Arduino Starter Kit(日本語版)

価格:12,731円
(2020/2/28 17:31時点)
感想(0件)

以前に投稿したこともある内容ですが、TouchOSCというアプリを使ってスマホでリモコンが出来ます。そのやり方について備忘録の意味も兼ねて解説しておきます。

以前の投稿記事は以下です。 https://makers.jpn.org/2018/05/27/post-529/

まず最初に、TouchOSCには Android版とiOS版がありますが、筆者はAndroid環境しかありませんのでAndroid版をスマホにインストールします。詳細な使い方は色々なサイトで公開されているのでそちらを参考にしてください。

前提としてリモコンされる側のロボット車両のスケッチを搭載した回路は完成しているとして、この回路を起ち上げて、スマホのWiFi設定を開けば利用可能なネットワークのなかにそのスケッチで指定した名前、今回はOLDMAKERSが現れているはずですので、接続できることを確認しておきます。

次に、スマホのリモコン操作画面を作るには「touchOSC Editor」というUIエディットツールが必要なのでこれをPCの方にインストールしておきます。現時点では無料です。これを使えば自分の好きなレイアウトで各種コントローラを配置することができます。面倒であればファイルの中にLayoutというものがあり、この中にテンプレートが各種あるのでそれをひな型に加工するほうが早いです。

今回作ってみた操作画面は車両のリモコン用なので前後進と旋回のスライダーが二つというシンプルなものです。

これを、スマホのTouchOSCに同期させておきます。

スマホのTouchOSCを開けば、Layoutの中に上記の操作画面の名前がありますので、これを選択すれば上記の画面が現れます。
つぎにスマホでの設定です。操作画面右上の●をタッチするとSetting画面に変わりますので、画面のOSCをタッチするとOSC画面がひらきます。

ここでHOST側のIPアドレス、送受信のPORTアドレスなどを設定し元画面に戻ってDONEをタッチすればスマホ側の設定は終わりです。

これでロボット車両のリモコンが出来るようになっているはずです。操作している動画はYouTubeに投稿してあります。

スケッチを掲載しておきます。

#include "ESP8266WiFi.h"
#include "WiFiUDP.h"
#include "OSCMessage.h"
#include "Wire.h"

//WiFiの定義
IPAddress myIP(192, 168, 4, 1);
IPAddress HOSTIP (192, 168, 4, 2);
const char *ssid = "OLDMAKERS";
const char *password = "12345678";
int localPort = 8000;
WiFiUDP Udp;

//定数の定義
float Turn_Speed = 0;
float Run_Speed = 0;
float LOutput,ROutput;
float Lrpm,Rrpm;

//モータードライバの配線
int AN1 = 12;//右PHASE
int AN2 = 13;//右ENABLE
int BN1 = 4;//左PHASE
int BN2 = 5;//左ENABLE

void setup() {
  // ESP8266のanalogWrite()の引数の範囲の初期値は[0-1023]。
  // 通常のArduinoのanalogWrite()の引数の範囲と同じ[0-255]に変更する。
  analogWriteRange(255);
  
  //WiFi接続
  WiFi.softAP(ssid, password);
  IPAddress myIP = WiFi.softAPIP();
  Udp.begin(localPort);
  Serial.begin(115200);
  int tries = 0;
  while (WiFi.status() != WL_CONNECTED) {
   delay(500);
    tries++;
    if (tries > 30) { //WiFi接続を30回繰り返してダメなら停止
      break;
    }
  }
  Wire.begin();

  //各ポートを出力に設定
  pinMode(AN1, OUTPUT);
  pinMode(AN2, OUTPUT);
  pinMode(BN1, OUTPUT);
  pinMode(BN2, OUTPUT);
}

void loop() {
  OSCMsgReceive();
  SpeedControl();
 }

void SpeedControl() {
  if (LOutput > 0) {
    digitalWrite(BN1, HIGH);
  }
  else if (LOutput < 0) {
    digitalWrite(BN1, LOW);
  }
  else {
    digitalWrite(BN1, LOW);
  }
  if (ROutput > 0) {
    digitalWrite(AN1, HIGH);
  }
  else if (ROutput < 0) {
    digitalWrite(AN1, LOW);
  }
  else {
    digitalWrite(AN1, LOW);
  }
  LOutput =Run_Speed + Turn_Speed ;
  ROutput =Run_Speed - Turn_Speed ;
  //LOutput,ROutputが正すなわち前進状態の時
  //右旋回してROutputが負となれば右車輪は後進、
  //左車輪は前進となり信地旋回状態となる
  
  Lrpm = min(255, abs(LOutput) );
  Rrpm = min(255, abs(ROutput) );
  //モータへの入力は絶対値をとり、かつ255を越えないようにする
  analogWrite(BN2, Lrpm);
  analogWrite(AN2, Rrpm); 
  Serial.print("Lrpm = ");
  Serial.print(Lrpm);
  Serial.print(" Rrpm = ");
  Serial.println(Rrpm);
 }

 void OSCMsgReceive() {
  OSCMessage msgIN;
  int size;
  if ((size = Udp.parsePacket()) > 0) {
    while (size--)
      msgIN.fill(Udp.read());
    if (!msgIN.hasError()) {
       msgIN.route("/micro_BR/fader1",fader1);//旋回
       msgIN.route("/micro_BR/fader2",fader2);//前後進
    }
  }
}

//前後進速度を設定
 void fader2(OSCMessage &msg, int addrOffset) { 
  int value2 = msg.getFloat(0);
  delayMicroseconds(10);
  if (value2 >= 145) {
    Run_Speed = map(value2, 145, 255, 0, 255);
  }
  else if (value2 <= 110) {
    Run_Speed = map(value2, 110, 0, 0, -255);
  }
   else {
    Run_Speed = 0;
  }
}

//旋回速度を設定
 void fader1(OSCMessage &msg, int addrOffset ){ 
  int value1 = msg.getFloat(0);
  delayMicroseconds(10);
  if (value1 >= 145) {
    Turn_Speed = map(value1, 145, 255, 0, 255); 
    }
  else if (value1 <= 110) {
    Turn_Speed = map(value1, 110, 0, 0, -255); 
    }
  else {
    Turn_Speed = 0;
  }
}

シェアする

フォローする