当前位置:   article > 正文

ESP8266 OTA(无线远程升级)热更新

esp8266 ota

ESP8266或者ESP32 有一个问题,就是在上传程序在开发板中里面的程序联网IP是固定;
1、如果你的MQTT服务器换 ip、端口、域名等情况那么开发板将无法连接MQTT服务。
在这里插入图片描述
2、如果业务需求有变更需要在开发板原有的基础增加一些功能,而这些开发板已经上线部署在各的自动售卖机,那如果按照传统方法,是不是要跑遍每个智能物联网设备,拿根数据线连接电脑重新上传烧录程序???
所以这时候就需要进行OTA热更新,类似于手机自动更新系统功能,自动获取版本,并且下载安装包在主板里,然后系统升级成功。

具体步骤流程
1、需要把 编译后更新包,挂在服务器上,目的是能够下载
比如我把下面的代码热更新到开发板里

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <MD5Builder.h>

// GPIO 5 D1
#define LED 5
#define JDQ D0  //继电器

// WiFi
const char *ssid = "yang1";          // Enter your WiFi name
const char *password = "872332847";  // Enter WiFi password

// MQTT Broker
const char *mqtt_broker = "172.20.10.2";
const char *topic = "esp8266";
const char *mqtt_username = "admin";
const char *mqtt_password = "admints";
const int mqtt_port = 1883;

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  // Set software serial baud to 115200;
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(JDQ, OUTPUT);
  digitalWrite(JDQ, HIGH);
  // connecting to a WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
  Serial.println("Connected to the WiFi network");
  //connecting to a mqtt broker
  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(1000);
    }
  }
  // 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.print(message);

  // 解析JSON数据
  DynamicJsonDocument jsondoc(1024);
  deserializeJson(jsondoc, message);
  JsonObject obj = jsondoc.as<JsonObject>();
  String type = obj["type"];
  String value = obj["msg"];
  //LED
  if (type == "LED") {
    if (value == "ON") {
      digitalWrite(LED, LOW);
      digitalWrite(LED_BUILTIN, LOW);
    }
    if (value == "OFF") {
      digitalWrite(LED, HIGH);
      digitalWrite(LED_BUILTIN, HIGH);
    }
  }
  //继电器
  if (type == "JDQ") {
    if (value == "ON") {
      digitalWrite(JDQ, LOW);
    }
    if (value == "OFF") {
      digitalWrite(JDQ, HIGH);
    }
  }
  //digitalWrite(LED, LOW);

  /*
  if (value == "on") {
    digitalWrite(LED, LOW);
    digitalWrite(LED_BUILTIN, LOW);
  }  // LED on
  if (value == "off") {
    digitalWrite(LED, HIGH);
    digitalWrite(LED_BUILTIN, HIGH);
  }  // LED off
  */

  Serial.println();
  Serial.println("-----------------------");
}

void loop() {
  client.loop();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

把以上代码编译成二进制文件
在这里插入图片描述在这里插入图片描述在这里插入图片描述以上编译成二进制文件,接下来我们挂在服务器上面,能够下载就行
下面以最简单的方式,方便演示直接挂在iis 默认文件下面
在这里插入图片描述在这里插入图片描述看一下是否能下载
在这里插入图片描述

2、需要使用 #include <ESP8266httpUpdate.h> 热更新库
3、上传程序
String upUrl = "http://172.20.10.2/ad/sketch.bin"; //更新包地址 也就是刚刚部署在iis上面的bin文件

#include <ESP8266WiFi.h>
#include <ESP8266httpUpdate.h>

/******需要修改的地方****************/

#define wifi_name       "yang1"       //WIFI名称,区分大小写,不要写错
#define wifi_password   "872332847"   //WIFI密码
                                      //固件链接,在巴法云控制台复制、粘贴到这里即可
String upUrl = "http://172.20.10.2/ad/sketch.bin";  //更新包地址

/**********************************/

/*
 * 主函数
 */

void setup() {
  Serial.begin(115200);                     //波特率115200
  WiFi.begin(wifi_name, wifi_password);     //连接wifi
  while (WiFi.status() != WL_CONNECTED) {   //等待连接wifi
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
  updateBin();                              //开始升级
}

/**
 * 循环函数
 */
void loop() {

}

//当升级开始时,打印日志
void update_started() {
  Serial.println("CALLBACK:  HTTP update process started");
}

//当升级结束时,打印日志
void update_finished() {
  Serial.println("CALLBACK:  HTTP update process finished");
}

//当升级中,打印日志
void update_progress(int cur, int total) {
  Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\n", cur, total);
}

//当升级失败时,打印日志
void update_error(int err) {
  Serial.printf("CALLBACK:  HTTP update fatal error code %d\n", err);
}

/**
 * 固件升级函数
 * 在需要升级的地方,加上这个函数即可,例如setup中加的updateBin(); 
 * 原理:通过http请求获取远程固件,实现升级
 */
void updateBin(){
  Serial.println("start update");    
  WiFiClient UpdateClient;
  
  ESPhttpUpdate.onStart(update_started);//当升级开始时
  ESPhttpUpdate.onEnd(update_finished); //当升级结束时
  ESPhttpUpdate.onProgress(update_progress); //当升级中
  ESPhttpUpdate.onError(update_error); //当升级失败时
  
   
  t_httpUpdate_return ret = ESPhttpUpdate.update(UpdateClient, upUrl);
  Serial.println(ret);
  Serial.println("测试2");  
  switch(ret) {
    case HTTP_UPDATE_FAILED:      //当升级失败
        Serial.println("[update] Update failed.");
        break;
    case HTTP_UPDATE_NO_UPDATES:  //当无升级
        Serial.println("[update] Update no Update.");
        break;
    case HTTP_UPDATE_OK:         //当升级成功
        Serial.println("[update] Update ok.");
        break;
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

连接开发板上传程序
在这里插入图片描述这时候开发板上面的程序就会自动更新到我们刚刚部署编译成二进制bin文件

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/600646
推荐阅读
相关标签
  

闽ICP备14008679号