#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;

// MQTT Broker
//设置MQTT 地址,订阅名称,连接用户名,密码,端口
const char *mqtt_broker = "网址";
const char *topic = "esp8266/led";
const char *mqtt_username = "用户名";
const char *mqtt_password = "密码";
const int mqtt_port = 1883;

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

void setup() {
    //设置板载LED管脚为输出模式
    pinMode(LED_BUILTIN, OUTPUT);
    // Set software serial baud to 9600;
    //设置软件串口波特率为9600;
    Serial.begin(9600);
    servoThumb.attach(16);//大拇指D0
    servoIndex.attach(0);//食指D3
    servoMiddle.attach(2);//中指D4
    servoRing.attach(12);//无名指D6
    servoPinky.attach(13);//尾指D7
  
   // 建立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 callback(char *topic, byte *payload, unsigned int length) {
    Serial.print("Message arrived in topic: ");
    Serial.println(topic);
    Serial.print("Message:");
    String message;
    for (int i = 0; i < length; i++) {
        message = message + (char) payload[i];  // convert *byte to string
    }
 
    Serial.println(message);
    if (message == "on") { digitalWrite(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() {
    client.loop();
}

已经解决,自动配网,并连接到mqtt,通过mqtt发送字符串,各舵机转动角度。

遇到的问题:

1,开发板开始选择的是Generic ESP8266 Module ,没有选择 LOLIN WeMos D1 时

'D0' was not declared in this scope 我管脚写的是D0,说未声明。

2,
message是一个数字的字符串,我想对其中的数字进行对比
if (message[0] == 1)
我直接这样写,没反映,但我如果message[0]=="1",又会报错

最后解决办法是:message[0] == '1',使用的是单引号;

原因:c中单引号引用的是

在c中,

  1. 单引号括起来的单个字符代表整数,双引号括起来的字符代表字符指针;
  2. C 编译器接受字符和字符串的比较但无任何意义,允许字符串对字符变量赋值,只能得到错误。

3,当各舵机对象管脚设置为D0,D3,D4.D6.D7时,只有D6,D7发送有反映,其它3个管脚无反映,设置为对应8266芯片自带IPOS管脚时,各管脚都能反映,暂时不知道是开发板对应管脚不一致所造成,还是程序没保存搅错,有时间重新检查 一下,

3,原来arduino的转动角度,现在感觉反了,例如大拇指程序写的是当接收到数字1时,转到80度,拇指会伸直,但拇指是往回转,当接收到数字0时,应该转到0度,这时拇指向外伸直,伸直角度很小。

待解决,先把角度全部转到0度,重新锁紧各手指头的拉线,试试发送角度字符串,转为数字直接让舵机转动,得到正常角度。

解决:重新写了一段单手指头角度旋转代码分别测试握紧时旋转的角度,得到大拇指旋转120度 ,其它4指旋转150度

2022.02.24新问题

1.WiFiManager有个回调函数setApCallBack,可以在转到连接wifi前操作,相法是调用中断,快闪led提醒需要连接wifi进行操作

2.当连接wifi后,登陆不成功mqtt,led慢闪

3.成功mqtt,led长亮

请输入图片描述

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