検索コード

ESP32 チュートリアル 30/55 - Adafruit IO サービスを使用した MQTT を通じてウェブ上でサーボを制御する | SunFounder の ESP32 IoT 学習キット

ESP32 チュートリアル 30/55 - Adafruit IO サービスを使用した MQTT を通じてウェブ上でサーボを制御する | SunFounder の ESP32 IoT 学習キット

このチュートリアルでは、ESP32マイクロコントローラーを使用して、ウェブ上でMQTTプロトコルを介してサーボモーターの位置を制御する方法を学びます。Adafruit IOサービスを活用することで、サーボを0°、90°、または180°のようなさまざまな角度にリモートで位置決めすることができます。このプロジェクトは、内蔵のWi-FiとBluetoothを含むESP32の能力を示しており、IoTアプリケーションにとって強力なツールとなっています。

ESP32-30_MQTT_diagram-0

このプロジェクトでは、Adafruit IOを使用してMQTTブローカーをセットアップし、サーボを制御するためのダッシュボードを作成し、ESP32をそれに接続します。サーボの位置はダッシュボードのスライダーを使用して調整可能であり、インターネット接続可能なデバイスからリアルタイムで制御できます(動画の5:30にて)。

ハードウェアの解説

このプロジェクトの主なコンポーネントには、ESP32マイクロコントローラーとサーボモーターが含まれています。ESP32はWi-FiとBluetooth機能を統合した多用途のマイクロコントローラーであり、IoTアプリケーションに最適です。ESP32は、MQTTプロトコルを使用してAdafruit IOサービスと通信します。これは軽量で効率的なメッセージ伝送手段としてインターネット上で利用されます。

サーボモーターは、角度位置を正確に制御できる回転アクチュエーターです。これは、その位置を指示するパルス幅変調(PWM)信号を受信することによって動作します。このプロジェクトでは、サーボをESP32のデジタルピンの1つに接続し、遠隔で角度を制御できるようにします。

データシートの詳細

メーカー 視差
部品番号 SG90
論理/IO電圧 3.3 V - 5 V
供給電圧 4.8 V - 6.0 V
出力電流(チャンネルごと) 1 A 最大
PWM周波数ガイダンス 50ヘルツ
入力ロジック閾値 0.3 V - 0.7 V
電圧降下 / RDS(on)/飽和度 0.2 V 最大
熱的限界 動作温度:-10°Cから60°C
パッケージ プラスチックケース
ノート / バリアント ミニサーボ、180°回転

  • サーボに適切な電圧供給を確保してください(4.8 V - 6.0 V)。
  • ESP32とサーボの間に共通のグラウンドを使用してください。
  • PWM信号を監視して、サーボの限界を超えないようにしてください。
  • 運転中に接続が切れるのを避けるため、サーボを安全に接続してください。
  • Adafruit MQTTライブラリを更新して互換性を確保してください。

MQTTダイアグラム

ESP32-30_MQTT_diagram-2
ESP32-30_MQTT_diagram
ESP32-28_dht温度センサーメイン

配線指示

ESP32-17-Sevo_motor-wiring

サーボモーターをESP32に配線するには、まずサーボのグラウンドワイヤーをESP32のグラウンドピンに接続します。次に、サーボの電源ワイヤー(通常は赤)をESP32の5Vピンに接続します。最後に、信号ワイヤー(多くの場合黄または白)をESP32のデジタルピン25に接続します。接続が緩まないように、しっかりと固定されていることを確認してください。

ESP32に電源を供給するためにバッテリーを使用している場合、バッテリーの電圧がESP32とサーボの両方に対して許容範囲内であることを確認してください。さらに、コードで使用されているピンの定義と配線が一致していることを再度確認し、問題を避けてください(動画の12:45で)。

コード例とウォークスルー

提供されたコードでは、まずESP32とMQTTに必要なライブラリを含めます。サーボオブジェクトを定義し、それが接続されているピンを指定します。const int servoPin = 25;デフォルトの角度も設定されています。const int defaultServoAngle = 90;ESP32が起動したときの初期位置になります。


Servo myServo;
const int servoPin = 25;
const int defaultServoAngle = 90;
int servoAngle = defaultServoAngle;

このスニペットは、ピン25のサーボを初期化し、そのデフォルト角度を90°に設定します。変数servoAngleMQTTブローカーから受信したメッセージに基づいて更新されます。

の中でsetup()機能では、Wi-Fiに接続し、MQTTクライアントを設定します。ここではAdafruit IOの資格情報が定義されており、ユーザー名とキーが含まれています:


#define AIO_USERNAME "robojax"
#define AIO_KEY "aio_xmIW58uNNsjJCSOqzZ9QoHyq29wu"

このセクションでは、Adafruit IO サービスへの接続を確立します。コードを実装する際には、これらの値を自分の Adafruit IO 認証情報に置き換えることを確認してください。

最後に、メインループはMQTTサーバーへの接続がアクティブのままであり、受信したメッセージを処理します。サーボの位置は受信した角度に基づいて更新されます:


mqtt.processPackets(500);
int pulseWidth = map(servoAngle, 0, 180, minPulseWidth, maxPulseWidth);
myServo.writeMicroseconds(pulseWidth);

このコードはサーボ角を対応するパルス幅にマッピングし、それをサーボモーターに送信します。processPackets()この機能により、ESP32は受信したMQTTメッセージを処理でき、サーボがAdafruit IOダッシュボードを介して送信されたコマンドに反応します。

デモンストレーション / 期待すること

すべてが設定されたら、作成したスライダーを使用してAdafruit IOダッシュボードからサーボを制御できるはずです。スライダーを動かすと、サーボはリアルタイムで角度を調整します。ESP32がWi-Fiに接続されており、MQTT接続が安定していることを確認してください。サーボが反応しない場合は、配線とサーボへの電源供給を確認してください(動画の :15)。

サーボの範囲制限に注意してください。0°から180°の範囲外の値を送信すると、予期しない動作をする可能性があります。このコードには、角度をこの範囲内に収めることでそのような事態を防ぐチェックが含まれています。

ビデオのタイムスタンプ

  • 00:00 スタート
  • 1:54 プロジェクト紹介
  • 2:52 MQTTのイントロダクション
  • 6:50 Adafruit IOの設定
  • 9:54 サーボの配線
  • 11:07 コードの説明
  • 18:59 ESP32ボードとCOMポートを選択中
  • 22:10 プロジェクトデモンストレーション

画像

ESP32-17-Sevo_motor-schematic
ESP32-17-Sevo_motor-schematic
ESP32-17-Sevo_motor-wiring
ESP32-17-Sevo_motor-wiring
ESP32-28_dht_temperature-sensor-main
ESP32-28_dht_temperature-sensor-main
ESP32-30_MQTT_diagram
ESP32-30_MQTT_diagram
ESP32-30_MQTT_diagram-0
ESP32-30_MQTT_diagram-0
ESP32-30_MQTT_diagram-2
ESP32-30_MQTT_diagram-2
831-ESP32 Tutorial 30/55- ESP32 to control Servo motor using MQTT service of Adafruit
言語: C++
/***********************************************************************
 This is Arduino sketch for ESP32 to control Servo motor using MQTT service of Adafruit
 www.Robojax.com
 Written By Ahamd Shamshiri
 on Feb 2nd, 2024
Watch video instruction for this code on YouTube https://youtu.be/T4DhWNg2Rb8
  Adafruit MQTT Library ESP32 Adafruit IO SSL/TLS example
  this code can be downloaded from  https://robojax.com/RJT671

  

/// ref: https://www.electronicwings.com/esp32/esp32-mqtt-client
*/
#include <ESP32Servo.h>

// Define the servo and the pin it is connected to
Servo myServo;
const int servoPin = 25;
const int defaultServoAngle = 90;
int servoAngle =defaultServoAngle;

// Define the minimum and maximum pulse widths for the servo
const int minPulseWidth = 500; // 0.5 ms
const int maxPulseWidth = 2500; // 2.5 ms




#include <WiFi.h>
#include "WiFiClientSecure.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

/************************* WiFi Access Point *********************************/


#define WLAN_SSID "Barqasaa"
#define WLAN_PASS "wan9&Jang~5"

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER "io.adafruit.com"

// Using port 8883 for MQTTS
#define AIO_SERVERPORT 8883

// Adafruit IO Account Configuration
// (to obtain these values, visit https://io.adafruit.com and click on Active Key)
// #define AIO_USERNAME "YOUR_ADAFRUIT_IO_USERNAME"
// #define AIO_KEY      "YOUR_ADAFRUIT_IO_KEY"

#define AIO_USERNAME "robojax"
#define AIO_KEY "aio_xmIW58uNNsjJCSOqzZ9QoHyq29wu"

/************ Global State (you don't need to change this!) ******************/

// WiFiFlientSecure for SSL/TLS support
WiFiClientSecure client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);


// io.adafruit.com root CA
const char* adafruitio_root_ca = \
      "-----BEGIN CERTIFICATE-----\n"
      "MIIEjTCCA3WgAwIBAgIQDQd4KhM/xvmlcpbhMf/ReTANBgkqhkiG9w0BAQsFADBh\n"
      "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
      "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n"
      "MjAeFw0xNzExMDIxMjIzMzdaFw0yNzExMDIxMjIzMzdaMGAxCzAJBgNVBAYTAlVT\n"
      "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
      "b20xHzAdBgNVBAMTFkdlb1RydXN0IFRMUyBSU0EgQ0EgRzEwggEiMA0GCSqGSIb3\n"
      "DQEBAQUAA4IBDwAwggEKAoIBAQC+F+jsvikKy/65LWEx/TMkCDIuWegh1Ngwvm4Q\n"
      "yISgP7oU5d79eoySG3vOhC3w/3jEMuipoH1fBtp7m0tTpsYbAhch4XA7rfuD6whU\n"
      "gajeErLVxoiWMPkC/DnUvbgi74BJmdBiuGHQSd7LwsuXpTEGG9fYXcbTVN5SATYq\n"
      "DfbexbYxTMwVJWoVb6lrBEgM3gBBqiiAiy800xu1Nq07JdCIQkBsNpFtZbIZhsDS\n"
      "fzlGWP4wEmBQ3O67c+ZXkFr2DcrXBEtHam80Gp2SNhou2U5U7UesDL/xgLK6/0d7\n"
      "6TnEVMSUVJkZ8VeZr+IUIlvoLrtjLbqugb0T3OYXW+CQU0kBAgMBAAGjggFAMIIB\n"
      "PDAdBgNVHQ4EFgQUlE/UXYvkpOKmgP792PkA76O+AlcwHwYDVR0jBBgwFoAUTiJU\n"
      "IBiV5uNu5g/6+rkS7QYXjzkwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsG\n"
      "AQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMDQGCCsGAQUFBwEB\n"
      "BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEIGA1Ud\n"
      "HwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEds\n"
      "b2JhbFJvb3RHMi5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEW\n"
      "HGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDQYJKoZIhvcNAQELBQADggEB\n"
      "AIIcBDqC6cWpyGUSXAjjAcYwsK4iiGF7KweG97i1RJz1kwZhRoo6orU1JtBYnjzB\n"
      "c4+/sXmnHJk3mlPyL1xuIAt9sMeC7+vreRIF5wFBC0MCN5sbHwhNN1JzKbifNeP5\n"
      "ozpZdQFmkCo+neBiKR6HqIA+LMTMCMMuv2khGGuPHmtDze4GmEGZtYLyF8EQpa5Y\n"
      "jPuV6k2Cr/N3XxFpT3hRpt/3usU/Zb9wfKPtWpoznZ4/44c1p9rzFcZYrWkj3A+7\n"
      "TNBJE0GmP2fhXhP1D/XVfIW/h0yCJGEiV9Glm/uGOa3DXHlmbAcxSyCRraG+ZBkA\n"
      "7h4SeM6Y8l/7MBRpPCz6l8Y=\n"
      "-----END CERTIFICATE-----\n";

/****************************** Feeds ***************************************/

// Setup a feed called 'test' for publishing and 'test2' for subscription.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Subscribe SERVO = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/servo-angle-1");


/*************************** Sketch Code ************************************/


void setup() {
    // Attach the servo to the specified pin and set its pulse width range
  myServo.attach(servoPin, minPulseWidth, maxPulseWidth);

  // Set the PWM frequency for the servo
  myServo.setPeriodHertz(50); // Standard 50Hz servo

  Serial.begin(115200);
  delay(10);

  Serial.println(F("Adafruit IO MQTTS (SSL/TLS) Example"));

  // Connect to WiFi access point.
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  delay(1000);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  delay(2000);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Set Adafruit IO's root CA
  client.setCACert(adafruitio_root_ca);

  // register callback for feed
  SERVO.setCallback(servoCallback);
  // Setup MQTT subscription for time feed.
  mqtt.subscribe(&SERVO);


}

// uint32_t x=0;


void loop() {

  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  Serial.print("Angle: ");
  Serial.println(servoAngle);

  // wait 0.5 seconds for subscription messages
  mqtt.processPackets(500);

  //from lesson 17
  int pulseWidth = map(servoAngle, 0, 180, minPulseWidth, maxPulseWidth);
  myServo.writeMicroseconds(pulseWidth);
  delay(15);
  // wait a couple seconds to avoid rate limit
  //delay(2000);
}

void servoCallback(char* message, uint16_t len) {
  char messageBuffer[40];
  snprintf(messageBuffer, sizeof(messageBuffer), "Servo status is :: %s, len :: %u", message, len);
  Serial.println(messageBuffer);
  Serial.println(message);
  String inString = message;//sotre the message to String
 
  servoAngle  =  inString.toInt();//convert the message to Integer
  if(servoAngle >180 || servoAngle < 0)
  {
    servoAngle =0;
  }

}




// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;
  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }
  Serial.print("Connecting to MQTT... ");
  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) {  // connect will return 0 for connected
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000);  // wait 5 seconds
    retries--;
    if (retries == 0) {
      // basically die and wait for WDT to reset me
      while (1)
        ;
    }
  }
  Serial.println("MQTT Connected!");
}

必要かもしれないもの

リソースと参考文献

ファイル📁

他のファイル