ESP8266通过MQTT协议远程控制ESP8266

ESP8266按键手柄远程控制ESP8266远程遥控车(小黄车版本)
ESP8266通过MQTT协议远程控制ESP8266
ESP8266按键手柄代码

MQTT服务器我搭建的是EMQ的,腾讯云或者阿里云都可以,我有教程,需要的CSDN留言你的信息,我会联系你

按键手柄以及接收板PCB也将在CSDN进行发布!!主页查看

整套程序亲测可靠,人头担保,我用过!B站发过视频

B站视频:飞宇智控4G远程遥控车 里面按键手柄的同款
现不再销售,特此开源!

安装一下库

PubSubClient     Arduino IDE安装
WiFiManager     百度太极创客官网下载处下载
ESP8266 3.0以上        Arduino IDE安装

下面是ESP8266做的按键手柄

#include <PubSubClient.h> //MQTT_TEST
#include <Ticker.h>

#include <WiFiManager.h>  // 引用WiFi管理员库
#include <EEPROM.h>     //使用EEPROM保存数据
#include <String.h>
#ifdef ESP8266                  // 若晶片类型是ESP8266
#include <ESP8266WiFi.h> 
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>   // ESP8266网站服务器库
ESP8266WebServer server(80);    // 建立网站服务器
#elif defined(ESP32)            // 若晶片类型是ESP32
#include "WiFi.h"
#include <ESPmDNS.h>
#include <WebServer.h>    // ESP32网站服务器库
WebServer server(80);           // 建立网站服务器
#endif
/********************** 参数设置 *****************/
char publishTopic[] = "fff123" ;
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
//const char* mqttServer = "mqtt-cn-i7m2omxjh0b.mqtt.aliyuncs.com";
const char* mqttServer = "114.132.158.66";//ip地址
// MQTT服务端连接用户名密码
//const char* mqttUserName = "Signature|LTAI5t7qtbYjGYBcpci2mjs9|mqtt-cn-i7m2omxjh0b";
//const char* mqttPassword = "AyjfUDaezp72ZxChHnYKAT4npwc=";

#define BUTTON_forward 4
#define BUTTON_RIGHT 12
#define BUTTON_BACK 5
#define BUTTON_LEFT 14
#define BUTTON_accelerate 13
#define BUTTON_decelerate 2
#define BUTTON_oil 16

byte forward_flag = 0;
byte back_flag = 0;
byte right_flag = 0;
byte left_flag =0;
byte accelerate_flag =0;
byte decelerate_flag =0;
byte oil_flag =0;

byte forward_foward = 0;
byte back_back = 0;
byte right_right = 0;
byte left_left = 0;
byte accelerate_accelerate =0;
byte decelerate_decelerate =0;
byte oil_oil =0;

byte pwm_ac_flag=0;
byte pwm_de_flag=0;
 
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/

Ticker ticker;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

int count;    // Ticker计数用变量

#define AP_SSID "宇宙飞船遥控器" // 自定义的ESP设备AP名称
#define AP_PWD "12345678" // 自定义的AP密码
#define TRIGGER_PIN 0 // 启用「Wi-Fi设置入口」的按键引脚
unsigned int timeout = 180; // 设置入口的超时秒数
unsigned int startTime = millis(); // 记录设置入口的启动时间
bool portalRunning = false; // 设置入口是否执行中,默认为「否」


WiFiManager wifiManager;  // 建立WiFiManager对象


bool shouldSaveConfig = false;  //是否保存数据的标志位
//回调函数,用于通知我们需要保存配置
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

/********************** 开始编程存储器部分 *****************/
#define EEPROM_SALT 12664   //用于校验读取的数据是否有效
typedef struct
{
  int   salt = EEPROM_SALT;
  char Secret_Key[15]  = "";
}WMSettings;//结构体, 用于保存秘钥数据

WMSettings blynk;   

//EEPROM读取函数
void eeprom_read()
{
  EEPROM.begin(3000);
  EEPROM.get(2500, blynk);
  EEPROM.end();
  
  Serial.print("从EEPROM读取到的秘钥为:");
  Serial.println(blynk.Secret_Key);
}

//EEPROM存储函数
void eeprom_saveconfig()
{
  EEPROM.begin(3000);
  EEPROM.put(2500, blynk);
  EEPROM.commit();
  EEPROM.end();
}


/********************** WIFI管理员参数配置以及重置函数 *****************/
WiFiManagerParameter custom_Secret_Key("KEY", "秘钥", blynk.Secret_Key, 15);

//用于重置WIFI设置以及秘钥
void doWiFiManager() 
{ // 执行WiFi管理员的工作
  if (portalRunning) 
  { // 若「设置入口」执行中…
    wifiManager.process(); // 处理「设置入口」的用户端连接请求
    // 如果「设置入口」已启用超过预设时间(180秒)…
    if ((millis() - startTime) > (timeout * 1000)) 
    {
      Serial.println("「Wi-Fi设置入口」操作超时…");
      portalRunning = false; // 设成「非执行中」
      if(strlen(custom_Secret_Key.getValue()) == 12)//简单判断填写的秘钥是否有效
      {
        strcpy(blynk.Secret_Key, custom_Secret_Key.getValue());
        Serial.print("写入EEPROM的秘钥为:");
        Serial.println(blynk.Secret_Key);
        eeprom_saveconfig();
      }
      wifiManager.stopConfigPortal(); // 停止「设置入口」
      Serial.println("正重启您的设备");
      delay(1000);
      ESP.restart();//重新启动ESP设备
//      Blinker.begin(blynk.Secret_Key, WiFi.SSID().c_str(), WiFi.psk().c_str());
//      Blinker.attachData(dataRead);
//      Button1.attach(button1_callback);
     }
    }
    
    // 若启用「设置入口」的接脚被按一下
    // 而且portalRunning的数值不为true…
    if (digitalRead(TRIGGER_PIN) == LOW && (!portalRunning)) 
    {
      Serial.println("按钮被按下了,启动设置入口。");
      wifiManager.setConfigPortalBlocking(false); // 设成「非搁置」模式
      wifiManager.startConfigPortal(AP_SSID, AP_PWD); // 启用Wi-Fi AP
  
      portalRunning = true; // 设成「设置入口」执行中
      startTime = millis(); // 纪录目前的时间
    }
}

void setup() {
    pinMode(BUTTON_forward, INPUT);
    digitalWrite(BUTTON_forward, HIGH);
    pinMode(BUTTON_RIGHT, INPUT);
    digitalWrite(BUTTON_RIGHT, HIGH);
    pinMode(BUTTON_BACK, INPUT);
    digitalWrite(BUTTON_BACK, HIGH);
    pinMode(BUTTON_LEFT, INPUT);
    digitalWrite(BUTTON_LEFT, HIGH);
     pinMode(BUTTON_accelerate, INPUT);
    digitalWrite(BUTTON_accelerate, HIGH);
    pinMode(BUTTON_decelerate, INPUT);
    digitalWrite(BUTTON_decelerate, HIGH);
    pinMode(BUTTON_oil, INPUT);
    digitalWrite(BUTTON_oil, HIGH);

 
    pinMode(TRIGGER_PIN, INPUT_PULLUP);   //配置触发重置函数的引脚//配置触发重置函数的引脚
    
    Serial.begin(115200);     

    WiFi.mode(WIFI_STA);  //Wi-Fi设置成STA模式;预设模式为STA+AP
    /****************************************************************/
    delay(500);
    eeprom_read();  //读取EEPROM中的秘钥数据
    //判断EEPROM中读取的秘钥数据是否被污染
    if (blynk.salt != EEPROM_SALT)
    {
      Serial.println("读取到 EEPROM 中无效的设置,已尝试使用默认值");
      WMSettings defaults;
      blynk = defaults;
    }
  
    
    wifiManager.addParameter(&custom_Secret_Key); //在WiFi管理员界面添加秘钥参数
    wifiManager.setSaveConfigCallback(saveConfigCallback);
    
    /********************** 只用于测试 *****************/
    //重置设置——进行测试
//    wifiManager.resetSettings();
    //设置信号的最小质量,这样它就忽略了在这个质量下的 AP
    //默认为 8%
//    wifiManager.setMinimumSignalQuality(30);
    //设置连接的超时时间
//    wifiManager.setConnectTimeout(CONNECT_TIMEOUT);
//    wifiManager.setTimeout(AP_TIMEOUT);
  
    //然后进入一个阻塞循环,等待配置
    if (!wifiManager.autoConnect(AP_SSID,AP_PWD)) 
    {
      Serial.println("未能连接或者超时");
      Serial.println("正重启您的设备");
      delay(1000);
      ESP.restart();
    }

    //到这里表示你已经连接上WiFi
    Serial.println("已经连接上WiFi:)");

    //简单判断秘钥是否有效
    if(strlen(custom_Secret_Key.getValue()) == 12)
    {
      strcpy(blynk.Secret_Key, custom_Secret_Key.getValue());
      Serial.print("秘钥为:");
      Serial.println(blynk.Secret_Key);
      eeprom_saveconfig();
    }//至此,结束数据保存

  
    // 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称
//    wifiManager.autoConnect("AutoConnectAP");
    
    // 如果希望该WiFi添加密码,可以使用以下语句:
    // wifiManager.autoConnect("AutoConnectAP", "12345678");
    // 以上语句中的12345678是连接AutoConnectAP的密码
    // WiFi连接成功后将通过串口监视器输出连接成功信息 
    Serial.println(""); 
    Serial.print("ESP8266 Connected to ");
    Serial.println(WiFi.SSID());              // 串口打印当前连接的WIFI名称
    Serial.print("IP address:\t");
    Serial.println(WiFi.localIP());           // 串口打印当前连接的WIFI的IP
    Serial.printf("password: %s\n", WiFi.psk().c_str());// 串口打印当前连接的WIFI密码 

     // 设置MQTT服务器和端口号
    mqttClient.setServer(mqttServer, 1883);
  
    // 连接MQTT服务器
    connectMQTTServer();
  
    // Ticker定时对象
    ticker.attach(1, tickerCount); 

}

void loop() {
    doWiFiManager();
    if(!portalRunning)
    { if (mqttClient.connected())
  { // 如果开发板成功连接服务器
    // 每隔3秒钟发布一次信息
      pubMQTTmsg();   
    // 保持心跳
    mqttClient.loop();
  } else 
   {                  // 如果开发板未能成功连接服务器
    connectMQTTServer();    // 则尝试连接服务器
   }}

}
void tickerCount(){
  count++;
}

void connectMQTTServer(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "esp8266-" + WiFi.macAddress();

  // 连接MQTT服务器
//  if (mqttClient.connect(clientId.c_str(),mqttUserName,mqttPassword)) { 
  if (mqttClient.connect(clientId.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address: ");
    Serial.println(mqttServer);
    Serial.println("ClientId:");
    Serial.println(clientId);
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }   
}

// 发布信息
void pubMQTTmsg(){
  byte fac = 0;
  byte bac = 0;
  byte lac = 0;
  byte rac = 0;
  byte fde = 0;
  byte bde = 0;
  byte lde = 0;
  byte rde = 0;
  
if(digitalRead(BUTTON_accelerate) == LOW && pwm_ac_flag == 0){
  pwm_ac_flag = 1;
  if(digitalRead(BUTTON_forward) == LOW){mqttClient.publish(publishTopic, "fd_ac");fac=1;}
  if(digitalRead(BUTTON_BACK) == LOW){mqttClient.publish(publishTopic, "bk_ac");bac=1;}
  if(digitalRead(BUTTON_LEFT)== LOW){mqttClient.publish(publishTopic, "left_ac");lac=1;}
  if(digitalRead(BUTTON_RIGHT) == LOW){mqttClient.publish(publishTopic, "right_ac");rac=1;}
  if(fac==0&&bac==0&&lac==0&&rac==0){mqttClient.publish(publishTopic, "ac");}
}
else if(digitalRead(BUTTON_accelerate) == HIGH){pwm_ac_flag = 0;fac=0;bac=0;lac=0;rac=0;}


if(digitalRead(BUTTON_decelerate) == LOW && pwm_de_flag == 0){
  pwm_de_flag = 1;
  if(digitalRead(BUTTON_forward) == LOW){mqttClient.publish(publishTopic, "fd_de");fde=1;}
  if(digitalRead(BUTTON_BACK) == LOW){mqttClient.publish(publishTopic, "bk_de");bde=1;}
  if(digitalRead(BUTTON_LEFT)== LOW){mqttClient.publish(publishTopic, "left_de");lde=1;}
  if(digitalRead(BUTTON_RIGHT) == LOW){mqttClient.publish(publishTopic, "bk_de");rde=1;}
  if(fde==0&&bde==0&&lde==0&&rde==0){mqttClient.publish(publishTopic, "de");}
}
else if(digitalRead(BUTTON_decelerate) == HIGH){pwm_de_flag = 0;fde=0;bde=0;lde=0;rde=0;}


if(digitalRead(BUTTON_oil) == LOW &&  oil_oil == 0) {
   mqttClient.publish(publishTopic, "oil");
   oil_flag = 0;
   oil_oil = 1;
    Serial.println("油门");
 }
else if(digitalRead(BUTTON_oil) == HIGH && oil_flag==0)
{
  mqttClient.publish(publishTopic, "oil_");
   oil_flag = 1;
   oil_oil = 0;
}

if(digitalRead(BUTTON_forward) == LOW &&  forward_foward == 0 && fac==0&&fde==0 ) {
   mqttClient.publish(publishTopic, "fd");
   forward_flag = 0;
   forward_foward = 1;
    Serial.println("前进");
 }
else if(digitalRead(BUTTON_forward) == HIGH && forward_flag==0)
{
  mqttClient.publish(publishTopic, "fd_");
   forward_flag = 1;
   forward_foward = 0;
}

if(digitalRead(BUTTON_BACK) == LOW && back_back == 0 && bac==0&&bde==0 ) {
   mqttClient.publish(publishTopic, "bk");
   back_flag = 0;
   back_back = 1;
   Serial.println("后退");
 }
else if(digitalRead(BUTTON_BACK) == HIGH && back_flag==0)
{
  mqttClient.publish(publishTopic, "bk_");
   back_flag = 1;
   back_back = 0;
}

if(digitalRead(BUTTON_LEFT) == LOW && left_left==0 && lac==0&&lde==0 ) {
   mqttClient.publish(publishTopic, "left");
   left_flag = 0;
   left_left = 1;
   Serial.println("左转");
 }
else if(digitalRead(BUTTON_LEFT) == HIGH && left_flag==0)
{
  mqttClient.publish(publishTopic, "left_");
  left_flag = 1;
  left_left = 0;
}
 
if(digitalRead(BUTTON_RIGHT) == LOW && right_right==0 && rac==0&&lde==0 ) {
   mqttClient.publish(publishTopic, "right");
   right_flag = 0;
   right_right = 1;
   Serial.println("右转");
 }
else if(digitalRead(BUTTON_RIGHT) == HIGH && right_flag==0)
{
  mqttClient.publish(publishTopic, "right_");
  right_flag = 1;
  right_right = 0;
}
}

下面是车子接收端的代码,配合L298N驱动接线进玩具车轮子上

#include <PubSubClient.h>

#include <WiFiManager.h>  // 引用WiFi管理员库
#include <EEPROM.h>     //使用EEPROM保存数据
#include <String.h>
#ifdef ESP8266                  // 若晶片类型是ESP8266
#include <ESP8266WiFi.h> 
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>   // ESP8266网站服务器库
ESP8266WebServer server(80);    // 建立网站服务器
#elif defined(ESP32)            // 若晶片类型是ESP32
#include "WiFi.h"
#include <ESPmDNS.h>
#include <WebServer.h>    // ESP32网站服务器库
WebServer server(80);           // 建立网站服务器
#endif
/********************** 参数设置 *****************/
//const char* mqttServer = "mqtt-cn-i7m2omxjh0b.mqtt.aliyuncs.com";
const char* mqttServer = "114.132.158.66";
#define AP_SSID "智控物联—小车" // 自定义的ESP设备AP名称
#define AP_PWD "12345678" // 自定义的AP密码
#define TRIGGER_PIN 0 // 启用「Wi-Fi设置入口」的按键引脚

#define fd_bk1 12
#define fd_bk2 14
#define lt_rt1 5
#define lt_rt2 4

unsigned int timeout = 180; // 设置入口的超时秒数
unsigned int startTime = millis(); // 记录设置入口的启动时间
bool portalRunning = false; // 设置入口是否执行中,默认为「否」
// MQTT服务端连接用户名密码
//const char* mqttUserName = "Signature|LTAI5t9XAHpNLn4LUaEKETez|mqtt-cn-i7m2omxjh0b";
//const char* mqttPassword = "0uNk+aVm2W7guPrEfo6iSr6tBow=";



WiFiManager wifiManager;  // 建立WiFiManager对象
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

bool shouldSaveConfig = false;  //是否保存数据的标志位
//回调函数,用于通知我们需要保存配置
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

int pwm = 100;
int pwm_temp = 0;
byte flag = 0;
byte fd_flag = 1;
byte bk_flag = 2;
byte left_flag = 3;
byte right_flag = 4;
/********************** 开始编程存储器部分 *****************/
#define EEPROM_SALT 12664   //用于校验读取的数据是否有效
typedef struct
{
  int   salt = EEPROM_SALT;
  char Secret_Key[15]  = "";
}WMSettings;//结构体, 用于保存秘钥数据

WMSettings blynk;   

//EEPROM读取函数
void eeprom_read()
{
  EEPROM.begin(3000);
  EEPROM.get(2500, blynk);
  EEPROM.end();
  
  Serial.print("从EEPROM读取到的秘钥为:");
  Serial.println(blynk.Secret_Key);
}

//EEPROM存储函数
void eeprom_saveconfig()
{
  EEPROM.begin(3000);
  EEPROM.put(2500, blynk);
  EEPROM.commit();
  EEPROM.end();
}

/********************** 点灯Blinker的配置部分 *****************/

/********************** WIFI管理员参数配置以及重置函数 *****************/
WiFiManagerParameter custom_Secret_Key("KEY", "秘钥", blynk.Secret_Key, 15);

//用于重置WIFI设置以及秘钥
void doWiFiManager() 
{ // 执行WiFi管理员的工作
  if (portalRunning) 
  { // 若「设置入口」执行中…
    wifiManager.process(); // 处理「设置入口」的用户端连接请求
    // 如果「设置入口」已启用超过预设时间(180秒)…
    if ((millis() - startTime) > (timeout * 1000)) 
    {
      Serial.println("「Wi-Fi设置入口」操作超时…");
      portalRunning = false; // 设成「非执行中」
      if(strlen(custom_Secret_Key.getValue()) == 12)//简单判断填写的秘钥是否有效
      {
        strcpy(blynk.Secret_Key, custom_Secret_Key.getValue());
        Serial.print("写入EEPROM的秘钥为:");
        Serial.println(blynk.Secret_Key);
        eeprom_saveconfig();
      }
      wifiManager.stopConfigPortal(); // 停止「设置入口」
      Serial.println("正重启您的设备");
      delay(1000);
      ESP.restart();//重新启动ESP设备
//      Blinker.begin(blynk.Secret_Key, WiFi.SSID().c_str(), WiFi.psk().c_str());
//      Blinker.attachData(dataRead);
//      Button1.attach(button1_callback);
     }
    }
    
    // 若启用「设置入口」的接脚被按一下
    // 而且portalRunning的数值不为true…
    if (digitalRead(TRIGGER_PIN) == LOW && (!portalRunning)) 
    {
      Serial.println("按钮被按下了,启动设置入口。");
      wifiManager.setConfigPortalBlocking(false); // 设成「非搁置」模式
      wifiManager.startConfigPortal(AP_SSID, AP_PWD); // 启用Wi-Fi AP
  
      portalRunning = true; // 设成「设置入口」执行中
      startTime = millis(); // 纪录目前的时间
    }
}

void setup() {

    pinMode(fd_bk1, OUTPUT);//
    pinMode(fd_bk2, OUTPUT);//
    pinMode(lt_rt1, OUTPUT);//
    pinMode(lt_rt2, OUTPUT);//
    digitalWrite(fd_bk1, 0);
    digitalWrite(fd_bk2, 0);
    digitalWrite(lt_rt1, 0);
    digitalWrite(lt_rt2, 0);
//    pinMode(LED_BUILTIN, OUTPUT);     // 设置板上LED引脚为输出模式
//    digitalWrite(LED_BUILTIN, HIGH);  // 启动后关闭板上LED
    WiFi.mode(WIFI_STA);  //Wi-Fi设置成STA模式;预设模式为STA+AP
    Serial.begin(115200);       
    /****************************************************************/
    delay(500);
    pinMode(TRIGGER_PIN, INPUT_PULLUP);   //配置触发重置函数的引脚
    eeprom_read();  //读取EEPROM中的秘钥数据
    //判断EEPROM中读取的秘钥数据是否被污染
    if (blynk.salt != EEPROM_SALT)
    {
      Serial.println("读取到 EEPROM 中无效的设置,已尝试使用默认值");
      WMSettings defaults;
      blynk = defaults;
    }
  
    
    wifiManager.addParameter(&custom_Secret_Key); //在WiFi管理员界面添加秘钥参数
    wifiManager.setSaveConfigCallback(saveConfigCallback);
    
    /********************** 只用于测试 *****************/
    //重置设置——进行测试
//    wifiManager.resetSettings();
    //设置信号的最小质量,这样它就忽略了在这个质量下的 AP
    //默认为 8%
//    wifiManager.setMinimumSignalQuality(30);
    //设置连接的超时时间
//    wifiManager.setConnectTimeout(CONNECT_TIMEOUT);
//    wifiManager.setTimeout(AP_TIMEOUT);
  
    //然后进入一个阻塞循环,等待配置
    if (!wifiManager.autoConnect(AP_SSID,AP_PWD)) 
    {
      Serial.println("未能连接或者超时");
      Serial.println("正重启您的设备");
      delay(1000);
      ESP.restart();
    }

    //到这里表示你已经连接上WiFi
    Serial.println("已经连接上WiFi:)");

    //简单判断秘钥是否有效
    if(strlen(custom_Secret_Key.getValue()) == 12)
    {
      strcpy(blynk.Secret_Key, custom_Secret_Key.getValue());
      Serial.print("秘钥为:");
      Serial.println(blynk.Secret_Key);
      eeprom_saveconfig();
    }//至此,结束数据保存

  
    // 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称
//    wifiManager.autoConnect("AutoConnectAP");
    
    // 如果希望该WiFi添加密码,可以使用以下语句:
    // wifiManager.autoConnect("AutoConnectAP", "12345678");
    // 以上语句中的12345678是连接AutoConnectAP的密码
    // WiFi连接成功后将通过串口监视器输出连接成功信息 
    Serial.println(""); 
    Serial.print("ESP8266 Connected to ");
    Serial.println(WiFi.SSID());              // 串口打印当前连接的WIFI名称
    Serial.print("IP address:\t");
    Serial.println(WiFi.localIP());           // 串口打印当前连接的WIFI的IP
    Serial.printf("password: %s\n", WiFi.psk().c_str());// 串口打印当前连接的WIFI密码 

      // 设置MQTT服务器和端口号
    mqttClient.setServer(mqttServer, 1883);
      // 设置MQTT订阅回调函数
    mqttClient.setCallback(receiveCallback);
 
    // 连接MQTT服务器
    connectMQTTserver();

}

void loop() {
    doWiFiManager();
    if(!portalRunning){if (mqttClient.connected()) { // 如果开发板成功连接服务器
    mqttClient.loop();          // 处理信息以及心跳
  } else {                      // 如果开发板未能成功连接服务器
    connectMQTTserver();        // 则尝试连接服务器
  }}
}

// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
 String clientId = "esp8266-" + WiFi.macAddress();
 
  // 连接MQTT服务器
//  if (mqttClient.connect(clientId.c_str(),mqttUserName,mqttPassword)) { 
  if (mqttClient.connect(clientId.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address:");
    Serial.println(mqttServer);
    Serial.println("ClientId: ");
    Serial.println(clientId);
    subscribeTopic(); // 订阅指定主题
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }   
}
 
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
  char recode[20]={0};
  Serial.print("Message Received [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
     Serial.println(length);
    Serial.print((char)payload[i]);
    recode[i] = payload[i];
  }
//  Serial.println("");
//  Serial.print("Message Length(Bytes) ");
//  Serial.println(length);
// 
//  if ((char)payload[0] == '1') {     // 如果收到的信息以“1”为开始
//    digitalWrite(BUILTIN_LED, LOW);  // 则点亮LED。
//    Serial.println("接收到1");
//  } 

  if( !strcmp(recode,"ac") || !strcmp(recode,"fd_ac")|| !strcmp(recode,"bk_ac")|| !strcmp(recode,"left_ac")||!strcmp(recode,"right_ac") && pwm<1000){                           
    if(pwm<250){ pwm += 10; } //每按一下加速键,加速50,可调
     Serial.println("加速__");
  } 
  if( !strcmp(recode,"de") || !strcmp(recode,"fd_de")|| !strcmp(recode,"bk_de")|| !strcmp(recode,"left_de")||!strcmp(recode,"bk_de") && pwm>0){                           
     if(pwm>0){pwm -= 10; }  //每按一下加速键,减速50,可调
     Serial.println("减速__");
  } 
  if( !strcmp(recode,"oil")){       //按下油门键后全速往前                    
    digitalWrite(fd_bk1, 0);
    digitalWrite(fd_bk2, 1);
    Serial.println("油门");
  } else if(!strcmp(recode,"oil_")){ //油门键松手后停止 
    digitalWrite(fd_bk1, 0);
    digitalWrite(fd_bk2, 0);
   }

  if( !strcmp(recode,"fd")||!strcmp(recode,"fd_ac")|| !strcmp(recode,"fd_de")){   //按下前进键,按当前速度往前开                        
    digitalWrite(fd_bk1, 0);
    analogWrite(fd_bk2, pwm);
//   Serial.println("前进");
  } else if(!strcmp(recode,"fd_")){ //前进键松手,小车停止
    digitalWrite(fd_bk1, 0);
    digitalWrite(fd_bk2, 0);
//    Serial.println("停止前进");
   }
   
  if( !strcmp(recode,"bk")|| !strcmp(recode,"bk_ac")|| !strcmp(recode,"bk_de")){  //按下后退键,按当前速度往后退
    analogWrite(fd_bk1, pwm);
    digitalWrite(fd_bk2, 0);                      
// Serial.println("后退");
}else if(!strcmp(recode,"bk_")){ //松手后停止后退
    digitalWrite(fd_bk1, 0);
    digitalWrite(fd_bk2, 0);
//    Serial.println("停止后退");
   }
   
  if( !strcmp(recode,"left")|| !strcmp(recode,"left_ac")|| !strcmp(recode,"left_de")){  //按下左转键,按当前速度左转
    analogWrite(lt_rt1, 150);
    digitalWrite(lt_rt2, 0);                       
// Serial.println("左转");
}else if(!strcmp(recode,"left_")){ //松手后停止
    digitalWrite(lt_rt1, 0);
    digitalWrite(lt_rt2, 0);   
//    Serial.println("停止左转");
   }
   
  if( !strcmp(recode,"right")||!strcmp(recode,"right_ac")||!strcmp(recode,"bk_de")){ //按下有右转键,按当前速度右转
    digitalWrite(lt_rt1, 0);
    analogWrite(lt_rt2, 150);                             
// Serial.println("右转");
}else if(!strcmp(recode,"right_")){//松手后停止
    digitalWrite(lt_rt1, 0);
    digitalWrite(lt_rt2, 0); 
//    Serial.println("停止右转");
   }

}
 
// 订阅指定主题
void subscribeTopic(){
 
  // 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。
  // 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
  String topicString = "fff123" ;
  char subTopic[topicString.length() + 1];  
  strcpy(subTopic, topicString.c_str());
  
  // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  if(mqttClient.subscribe(subTopic)){
    Serial.println("Subscrib Topic:");
    Serial.println(subTopic);
  } else {
    Serial.print("Subscribe Fail...");
  }  
}
 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打工人阿秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值