加入星計劃,您可以享受以下權益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 1 OTA原理簡介
    • 2 Arduino IDE環(huán)境搭建
    • 3 編寫OTA測試代碼
    • 4 OTA升級測試
  • 相關推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

Arduino應用開發(fā)——OTA(通過網(wǎng)絡升級)

10/28 08:14
1873
閱讀需 14 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

什么是OTA

百度百科:空中下載技術(Over-the-Air Technology; OTA),是通過移動通信的空中接口實現(xiàn)對移動終端設備及SIM卡數(shù)據(jù)進行遠程管理的技術。經(jīng)過公網(wǎng)多年的應用與發(fā)展,已十分成熟,網(wǎng)絡運營商通過OTA技術實現(xiàn)SIM卡遠程管理,還能提供移動化的新業(yè)務下載功能。

實際上,現(xiàn)在我們所說的OTA比百度百科的定義還要更廣泛,OTA的形式已經(jīng)不再局限于手機和SIM卡,只要涉及到遠程下載升級程序的方式我們都可以稱之為OTA。例如通過4G,5G,WiFI,藍牙無線通訊進行下載升級的可以稱為OTA,通過U盤,RS485串行接口進行升級的也可以稱之為OTA。

OTA的作用?

OTA的意義在于它在一定程度上突破了距離的限制,在沒有下載器沒有電腦不用到現(xiàn)場不用拆開設備等情況下完成固件的燒錄,極大的方便了產(chǎn)品的升級和維護,降低售后成本。

1 OTA原理簡介

在使用OTA時我們一般會把內(nèi)存分成三個部分:BootLoader,APP,Download(OTA)。

分區(qū) 作用
BootLoader 存放引導程序
APP 存放用戶程序,也就是我們自己寫的代碼
Download(OTA) 存放要升級的程序固件,也就是新版本的代碼

OTA原理簡單介紹:

不管是在什么平臺,不管用的是什么MCU,要使用OTA都離不開BootLoader,BootLoader是一個統(tǒng)稱,它其實只是一段引導程序,在MCU啟動的時候會先運行這段代碼,判斷是否需要升級,如果不需要升級就跳轉到APP分區(qū)運行用戶代碼,如果需要升級則跳轉到Download分區(qū)進行固件解壓解碼等操作并且把該固件拷貝覆蓋到APP分區(qū),從而實現(xiàn)OTA。

怎么在Arduino下搭建OTA?

在明白了OTA升級原理之后我們再來看看Arduino下搭建OTA需要哪些東西,首先,APP部分用戶程序我們肯定是有的,Download分區(qū)的固件其實也是我們的新版本的APP程序,這兩部分都沒什么問題,關鍵在于BootLoader,這個是必須要搞的,而且還要根據(jù)自己的實際情況來使用,不同的升級方式,不同的MCU,不同的內(nèi)存地址等等都會有區(qū)別。我這里介紹是是一種比較簡單的方式,直接利用Arduino IDE現(xiàn)有的框架和開源源碼,通過TCP/IP協(xié)議來傳輸固件,從而實現(xiàn)OTA的功能,但是這種方式會有些局限性,具體有哪些局限性我放到最后再講。

2 Arduino IDE環(huán)境搭建

這個我具體就不說了,根據(jù)你自己用的MCU安裝好相應的庫就行了,既然你都開始研究OTA了應該不會連環(huán)境都沒搭好吧。如果有不懂的同學可以看下我之前發(fā)布的博客。

esp8266開發(fā)入門教程(基于Arduino)——環(huán)境安裝

ESP32 Arduino開發(fā)環(huán)境搭建

使用VS code搭建Arduino IDE環(huán)境

3 編寫OTA測試代碼

我這里以ESP8266和ESP32為例編寫測試代碼,其他的MCU基本也是一致的,舉一反三即可。

硬件配置如下:

模塊 型號 說明
ESP8266 ESP-12F 這是安信可的一款模組,內(nèi)部主要是用樂鑫的ESP8266EX再加上一個片外FLASH組成,開發(fā)板型號是NodeMCU-12F(CH340版本)
ESP32 ESP-WROOM-32 MCU是樂鑫的一款芯片,開發(fā)板型號ESP32 DEVKITV1

具體的硬件參數(shù)和電路原理圖這里就不發(fā)出來了,不同廠家做的開發(fā)板引腳可能會有點差別。

示例代碼如下:
提示1:ESP8266和ESP32的庫是不同的,但是基本用法是類似的,我這個示例代碼做了ESP8266和ESP32的兼容,可以通用。
提示2:WIFI賬號和密碼要根據(jù)自己修改,代碼中的定義僅供參考。
提示3:PC端和設備端要在同一個局域網(wǎng)下。不懂什么是局域網(wǎng)的同學直接把兩個設備都連到同一個WIFI即可。

#ifdef ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#else
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#endif

#define APP_VERSION "1.0.0"        // app version

#ifndef STASSID
#define STASSID "test"             // wifi user
#define STAPSK  "123456789"        // wifi password
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

void setup() {
    Serial.begin(115200);
    Serial.printf("nAPP version: %srn", APP_VERSION);
    Serial.println("Booting");
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (WiFi.waitForConnectResult() != WL_CONNECTED) 
    {
        Serial.println("Connection Failed! Rebooting...");
        delay(5000);
        ESP.restart();
    }

    ArduinoOTA.onStart([]() {
        String type;
        if (ArduinoOTA.getCommand() == U_FLASH) {
            type = "sketch";
        }
        else { // U_FS
            type = "filesystem";
        }

        // NOTE: if updating FS this would be the place to unmount FS using FS.end()
        Serial.println("Start updating " + type);
    });

    ArduinoOTA.onEnd([]() {
        Serial.println("nEnd");
    });

    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("Progress: %u%%r", (progress / (total / 100)));
    });

    ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) {
            Serial.println("Auth Failed");
        }
        else if (error == OTA_BEGIN_ERROR) {
            Serial.println("Begin Failed");
        }
        else if (error == OTA_CONNECT_ERROR) {
            Serial.println("Connect Failed");
        }
        else if (error == OTA_RECEIVE_ERROR) {
            Serial.println("Receive Failed");
        }
        else if (error == OTA_END_ERROR) {
            Serial.println("End Failed");
        }
    });
    ArduinoOTA.begin();
    Serial.println("Ready");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
}

void loop() {
    ArduinoOTA.handle();
}

4 OTA升級測試

因為ESP8266和ESP32的測試結果是一樣的,這里就沒必要全部展示了,只貼一下ESP32的運行情況給你們做個參考。

先把代碼燒錄進去,通過串口打印的數(shù)據(jù),可以看到我們在代碼里面寫的用戶版本號以及wifi連接成功后的IP地址。

#define APP_VERSION "1.0.0"        // app version

Serial.printf("nAPP version: %srn", APP_VERSION);

在這里插入圖片描述

然后打開Arduino IDE,在 工具 -> 端口 一欄可以看到多出了一個網(wǎng)絡端口,這個IP就是我們ESP32的網(wǎng)絡IP地址。

提示:如果沒有出現(xiàn)該端口,要么是設備沒有連上網(wǎng)絡,要么是PC和設備不在同一個局域網(wǎng)。

在這里插入圖片描述

選擇這個新的端口之后,我們就可以通過TCP/IP網(wǎng)絡協(xié)議燒錄程序。

我這里修改一下版本號,然后重新燒錄一遍。在Arduino IDE這里可以看到燒錄的日志跟之前串口燒錄不一樣了,顯示的是IP地址和下載進度條。(注:esp8266沒有顯示IP地址,只有進度條,不過不影響使用)

在這里插入圖片描述
同樣的通過串口也能看到升級時運行的情況,Progress顯示的是OTA的升級進度,后面的百分比在升級過程中是會動的,從0%到100%。固件下載完成后設備會自動重啟,不需要手動進入下載模式。

注:這個顯示的結果跟串口助手也有一點關系,我這里用的是Xshell,如果用其它普通串口助手的話,Progress是會打印很多出很多個的,不過并不影響正常使用,如果不需要顯示這個進度,可以在代碼里面注釋掉。

在這里插入圖片描述

結束語

好了,關于Arduino OTA的編程和使用方法就講到這里,其實這只是其中一種OTA的方式,而且有些局限性,因為PC端和MCU之間是通過局域網(wǎng)進行連接和傳輸固件的,在實際使用中,不可能所有設備和電腦都在同一網(wǎng)絡下,這樣的話就沒辦法做到遠程OTA了。最好的辦法還是通過一個公網(wǎng)IP或者服務器來連接設備,設備可以通過http進行固件的下載,這樣的話只要設備能連上網(wǎng)絡,連上服務器,就可以實現(xiàn)真正意義上的遠程OTA。

時間關系我這里就講這么多,后續(xù)有時間的話我會考慮再介紹一下其他方式的OTA。

想了解更多Arduino的內(nèi)容,可以關注一下博主,后續(xù)我還會繼續(xù)分享更多的經(jīng)驗給大家。還有什么問題的話,歡迎在評論區(qū)留言。如果這篇文章能夠幫到你,就…你懂得。

相關推薦

電子產(chǎn)業(yè)圖譜