スマホでプラレールのスピードを制御する

スマホからの操作で、プラレールのスピードを制御してみたいと思います。
プラレールにモータードライバやM5Stack Basicをつなぎ、スマホからM5Stack Basicにアクセスすることで、プラレールのスピードを制御してみます。


モータードライバでプラレールのスピードを制御する

まずは、モータードライバを使ってプラレールのスピードを制御しようと思います。
モータードライバは、秋月電子通商で購入した「DRV8835(通販コード:K-09848)」を使用します。

このモータードライバは、入力端子にPWM信号を与えることでモーターの回転速度を変えることができます。今回、PWM信号の生成には「M5Stack Basic」を用います。

今回の回路図は以下のとおりです。

制御するモーターは1個だけなので、「AIN1とBIN1」「AIN2とBIN2」「AOUT1とBOUT1」「AOUT2とBOUT2」をそれぞれつなぎます。
今回、モーターは前進だけで良いので、「xIN2」はGNDにつなぎ、「xIN1」だけにPWM信号を与えます。M5Stack Basicでは「IO16」でPWM信号を出力し、それをモータードライバの「xIN1」につなぐことにします。
電源は、M5Stack Basicとモータードライバで共用するために、単四型Ni-MH電池4本(4.8V)を使います。

M5Stack Basic用のスケッチは以下のとおりです。

#include <M5Stack.h>

int PWM_VALUE = 0;

void setup() {
  M5.begin();
  // PWM出力用設定
  pinMode(16, OUTPUT);
  ledcSetup(0, 490, 8); // channel0, 490Hz, 8bit
  ledcAttachPin(16, 0); // io16, channel0
  // LCD表示用設定
  M5.Lcd.setTextSize(1);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextDatum(4);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.drawNumber(PWM_VALUE, 160, 120, 8);
}

void loop() {
  M5.update();
  if(M5.BtnA.wasPressed()) {
    PWM_VALUE = PWM_VALUE - 5;
    if(PWM_VALUE < 0) PWM_VALUE = 0;
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.drawNumber(PWM_VALUE, 160, 120, 8);
  }
  if(M5.BtnC.wasPressed()) {
    PWM_VALUE = PWM_VALUE + 5;
    if(PWM_VALUE > 255) PWM_VALUE = 255;
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.drawNumber(PWM_VALUE, 160, 120, 8);
  }
  ledcWrite(0, PWM_VALUE); // PWM出力
  delay(10);
}

ArduinoでPWM出力するには「analogWrite」という関数を使いますが、M5Stack Basicに搭載されている「ESP32」では「ledcXXX」という関数群でPWM信号を出力します。
Arduinoの「analogWrite」では、PWM信号の周波数は490Hz、出力する値は0〜255(8bit)とのことなので、M5Stack Basicでも同じ条件でPWM信号を出力できるように「ledcSetup」関数で設定します。
PWM値の初期値は「0」とし、Cボタンを押すたびにPWM値を「5」ずつ増やし、Aボタンを押すたびにPWM値を「5」ずつ減らします。設定された値のPWM信号を「IO16」から出力します。

プラレールとモータードライバ、M5Stack Basic、電池などを回路図のとおりにつなぎます。あわせてモータードライバの「xOUT1−xOUT2間」にテスターをつなぎ、モータードライバの出力電圧を観測することとします。

M5Stack BasicのCボタンを押してPWM値を上げていくと、「35〜40」程度の時にモーターがゆっくり回り始めます。このときのモータードライバ出力電圧は0.55V程度でした。
さらにPWM値を上げていくと、「55」のときにドライバ出力電圧が1.5〜1.6V程度になります。このプラレールは単二型乾電池1本で動かすタイプなので、これが通常使用時の電圧になります。
さらにPWM値を上げていくと、「110」の時に3V程度になりました。モーターはかなり勢いよく回ります。
プラレールのスピードを制御するからには、通常より速いスピードでも走らないとあまり楽しくなさそうです。プラレールに使われているモーターの型番がわからないのですが、このぐらいの電圧までは与えても大丈夫だろうと考え、PWM値は「0〜110」の範囲で使用することとします。

M5Stack BasicでつくったPWM信号をモータードライバに与えることで、プラレールのスピードを制御することができました。

スマホでM5Stack Basicを制御する

次に、M5Stack BasicのPWM値をスマホから制御できるようにしてみます。

M5Stack Basic用のスケッチを以下のように変更します。

#include <M5Stack.h>
#include <WiFi.h>

int PWM_VALUE = 0;

const char* ssid = "ESP32-AP";
const char* password = "12345678";

WiFiServer server(80);
String header = "";

void setup() {
  M5.begin();
  // Wi-Fi設定
  WiFi.softAP(ssid, password);
  IPAddress ip = WiFi.softAPIP();
  Serial.print("IP Address as Access Point: ");
  Serial.println(ip);  
  server.begin();
  // PWM出力用設定
  pinMode(16, OUTPUT);
  ledcSetup(0, 490, 8); // channel0, 490Hz, 8bit
  ledcAttachPin(16, 0); // io16, channel0
  ledcWrite(0, PWM_VALUE); // PWM出力
  // LCD表示用設定
  M5.Lcd.setTextSize(1);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextDatum(4);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.drawNumber(PWM_VALUE, 160, 120, 8);
}

void loop(){
  M5.update();
  WiFiClient client = server.available();
  if(client) {
    unsigned long currentTime = millis();
    Serial.println("New Client.");
    String currentLine = "";
    while (client.connected() && millis() - currentTime <= 2000) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        header += c;
        if (c == '\n') {
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            if (header.indexOf("GET /dn") >= 0) {
              PWM_VALUE = PWM_VALUE - 5;
              if(PWM_VALUE < 0) PWM_VALUE = 0;
              M5.Lcd.fillScreen(BLACK);
              M5.Lcd.drawNumber(PWM_VALUE, 160, 120, 8);
              ledcWrite(0, PWM_VALUE); // PWM出力
            } else if (header.indexOf("GET /up") >= 0) {
              PWM_VALUE = PWM_VALUE + 5;
              if(PWM_VALUE > 110) PWM_VALUE = 110;
              M5.Lcd.fillScreen(BLACK);
              M5.Lcd.drawNumber(PWM_VALUE, 160, 120, 8);
              ledcWrite(0, PWM_VALUE); // PWM出力
            }
            client.println("<!DOCTYPE html>");
            client.println("<html lang=\"ja\">");
            client.println("<head>");
            client.println("<meta charset=\"utf-8\">");
            client.println("<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">");
            client.println("<title>SPEED CONTROL</title>");
            client.println("<style>");
            client.println("html {");
            client.println("  font-family: sans-serif;");
            client.println("  text-align: center;");
            client.println("}");
            client.println("button {");
            client.println("  color: white;");
            client.println("  background-color: steelblue;");
            client.println("  font-weight: bold;");
            client.println("  border: none;");
            client.println("  padding: 16px 40px;");
            client.println("  font-size: 30px;");
            client.println("  width: 300px;");
            client.println("}");
            client.println("</style>");
            client.println("</head>");
            client.println("<body>");
            client.println("<h1>SPEED CONTROL</h1>");
            client.printf("<p>[SPEED] %d</p>\n", PWM_VALUE);
            client.println("<p><a href=\"/up\"><button>UP</button></a></p>");
            client.println("<p><a href=\"/dn\"><button>DOWN</button></a></p>");
            client.println("</body>");
            client.println("</html>");
            break;
          } else currentLine = "";
        } else if (c != '\r') currentLine += c;
      }
    }
    header = "";
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

スマホのWi-Fi接続先を「ESP32-AP」に変更します。パスワードは「12345678」です。
その上で、スマホのWebブラウザで「192.168.4.1」にアクセスすると、M5Stack BasicのPWM値を制御するための画面が表示されます。

「UP」ボタンをタップすると、スマホ画面、M5Stack BasicのLCD画面の両方に表示されているPWM値が「5」ずつ増えます。最大は「110」で、それ以上大きくはなりません。
「DOWN」ボタンをタップすると、PWM値が「5」ずつ減ります。

スマホからの操作で、M5Stack BasicのPWM値を変更することができました。

スマホでプラレールのスピードを制御する

最後に、これらを組み合わせて、スマホからの操作でプラレールのスピードを制御してみたいと思います。

先ほどと同様に、プラレールとM5Stack Basicなどをつなぎ、できあがったものをレールの上におきます。
スマホのWebブラウザでM5Stack Basicにアクセスし、先ほどと同じようにPWM値を変更してみます。

結果は以下のとおりです。

PWM値を上げていくと、「45」あたりでプラレールが動き始めました。
数値を上げていくとどんどんスピードが速くなり、「100」ではかなり高速に走っています。ちなみに「105」まで上げると速すぎて脱線してしまいました。
PWM値を下げていくと、だんだん遅くなり、「45」あたりで停止しました。

M5Stack Basicやモータードライバを組み合わせることで、スマホでプラレールのスピードを制御することができました。


なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。


ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。


このサイトで書いている、M5Stackシリーズ(M5Stack、M5StickCなど)に関するブログ記事を、「さとやまノート」という別のブログページに、あらためて整理してまとめました。

他のM5Stackシリーズの記事にも興味のある方は「さとやまノート」をご覧ください。