#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <PubSubClient.h>
#include <Servo.h>

Servo servoThumb;//拇指
Servo servoIndex;//食指
Servo servoMiddle;//中指
Servo servoRing;//无名指
Servo servoPinky;//尾指
Servo servoWrist;//手腕

// MQTT Broker
//设置MQTT 地址,订阅名称,连接用户名,密码,端口
const char *mqtt_broker = "www.gxd****.com";
const char *topic = "esp8266/led";
const char *mqtt_username = "f****n";
const char *mqtt_password = "24******0";
const int mqtt_port = 1883;

//创建一个wificlient对象                                                     
WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
    ArduinoOTA.setHostname("ESP8266-ROBOTARM");
    ArduinoOTA.setPassword("12345678");//这个是第一次无线上传时需要输入的密码
    ArduinoOTA.begin();//启动OTA 
    //设置板载LED管脚为输出模式
    pinMode(LED_BUILTIN, OUTPUT);
    // Set software serial baud to 9600;
    //设置软件串口波特率为9600;
    Serial.begin(9600);
    servoThumb.attach(16);//大拇指D0,测试角度为120
    servoIndex.attach(0);//食指D3
    servoMiddle.attach(2);//中指D4
    servoRing.attach(14);//无名指D5
    servoPinky.attach(12);//尾指D6   150
    servoWrist.attach(15);//手腕D8
   // 建立WiFiManager对象
    WiFiManager wifiManager; 
    // 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称
    wifiManager.autoConnect("AutoConnectAP");
    // WiFi连接成功后将通过串口监视器输出连接成功信息 
    Serial.println(""); 
    Serial.print("ESP8266 Connected to ");
    Serial.println(WiFi.SSID());              // WiFi名称
    Serial.print("IP address:\t");
    Serial.println(WiFi.localIP());           // IP
    //connecting to a mqtt broker
    //连接MQTT服务器
    client.setServer(mqtt_broker, mqtt_port);
    client.setCallback(callback);
    while (!client.connected()) {
        String client_id = "esp8266-client-";
        client_id += String(WiFi.macAddress());
        Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
        if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("Public emqx mqtt broker connected");
        } else {
            Serial.print("failed with state ");
            Serial.print(client.state());
            delay(2000);
        }
    }
    // publish and subscribe
    client.publish(topic, "hello emqx");
    client.subscribe(topic);
}


void Hand(String message){
    if (message[1] == '1') { servoThumb.write(120);Serial.println("大拇指动作"); } else {servoThumb.write(0);Serial.println("大拇指没动作");}  // 判断大指拇
    if (message[2] == '1') { servoIndex.write(150); Serial.println("食指动作");} else {servoIndex.write(0);}  // 判断食指
    if (message[3] == '1') { servoMiddle.write(150);Serial.println("中指动作"); } else {servoMiddle.write(0);}  // 判断中指
    if (message[4] == '1') { servoRing.write(150);Serial.println("无名指动作");} else {servoRing.write(0);}  // 判断无名指
    if (message[5] == '1') { servoPinky.write(150);Serial.println("尾指动作");} else {servoPinky.write(0);}  // 判断尾指  
    if (message[6] == '1') { servoWrist.write(30);Serial.println("尾指动作");} else {servoWrist.write(0);}  // 判断手腕  
  }
void HandAngle(String message){//手转动角度,
    char flag = message[1];
    message = message.substring(2,4);
    unsigned int num = message.toInt();
    if (flag == '1') { servoThumb.write(num);Serial.println("大拇指动作"); }
    if (flag == '2') { servoIndex.write(num); Serial.println("食指动作");} 
    if (flag == '3') { servoMiddle.write(num);Serial.println("中指动作");} 
    if (flag == '4') { servoRing.write(num);Serial.println("无名指动作");} 
    if (flag == '5') { servoPinky.write(num);Serial.println("尾指动作");} 
    if (flag == '6') { servoWrist.write(num);Serial.println("手腕动作");}
    }
void callback(char *topic, byte *payload, unsigned int length) 
   {
    Serial.print("Message arrived in topic: ");
    Serial.println(topic);
    Serial.print("Message:");
    String message;
    int num;
    for (int i = 0;i < length; i++){
       message = message + (char)payload[i];
   
      }
    if (message[0] == '#'){HandAngle(message);}//输入#1150,第一位代表控制单个手指头,第二位代表所控制手指头,第三到五位代表角度
    if (message[0] == '$'){Hand(message);}//输入$加6位数字,0或者1,$111111,第一位代表控制整个手掌的手指,第二位到第六位分别控制手指头张开(1)还是握紧(0);
  
 /*判断接收数据指定手指动作
    Serial.println(message);
    if (message == "on") { digitalWrit e(LED_BUILTIN, LOW); }   // LED on
    if (message == "off") { digitalWrite(LED_BUILTIN, HIGH); } // LED off
  
    if (message[0] == '0') { servoThumb.write(80);Serial.println("大拇指动作"); } else {servoThumb.write(0);Serial.println("大拇指没动作");}  // 判断大指拇
    if (message[1] == '0') { servoIndex.write(90); Serial.println("食指动作");} else {servoIndex.write(0);}  // 判断食指
    if (message[2] == '0') { servoMiddle.write(100);Serial.println("中指动作"); } else {servoMiddle.write(0);}  // 判断中指
    if (message[3] == '0') { servoRing.write(80);Serial.println("无名指动作");} else {servoRing.write(0);}  // 判断无名指
    if (message[4] == '0') { servoPinky.write(75);Serial.println("尾指动作");} else {servoPinky.write(0);}  // 判断尾指
    Serial.println();
    Serial.println("-----------------------");
}
*/  
  
  }
void loop() {
    ArduinoOTA.handle();//循环检测是否有上传程序
    client.loop();
}

重新打印了底座,嗯,底座不就加长了电路板的支柱,方便底下螺丝不碰到电路板,结果更改跟打印,弄了一天多,

MQTT控制,自动配网还没有做外部提醒,根本不知道是否已经连接上,只能通过发指令测试,或者利用手指的动作来提醒?

另外 每次只能发送象$111111的指令,来控制一次的动作,下一步难道要做个小程序来简化指令的输入?小程序感觉好麻烦。

最后修改:2022 年 03 月 20 日
如果觉得我的文章对你有用,请随意赞赏