您现在的位置是:网站首页> 硬件

Arduino通用研发信息收集

  • 硬件
  • 2024-10-05
  • 898人已阅读
摘要

Arduino通用研发信息收集

Arduino烧写软件程序

Mqtt 客户端多主题订阅

Arduino的IO口驱动力不够解决办法

LVGL Arduino界面开发库



Arduino烧写软件程序

用命令行给Arduino烧写软件程序
arduino远程刷新(烧录)固件

使用Arduino开发ESP32:固件更新演示

Arduino 一次性烧录引导程序和用户程序的方法

USB-ISP烧写器

Arduino编译bootloader(示例代码)

Mega2560(Arduino)Bootloader烧录指南

Arduino Mega2560 作为烧录器烧写Mega2560的bootloader(试成功的)

ESP32烧录Arduino生成的bin文件

用Arduino UNO板子烧写Arduino 2560板子脚对应

#define PIN_MOSI        51    //mega2560的51脚对应UNO的MOSI 11

#define PIN_MISO        50   //mega2560的50脚对应UNO的MISO 12

#define PIN_SCK         52   //mega2560的52脚对应UNO的SCK 13


也就是UNO 10脚对应 2560 RESET

也就是UNO 11 对应 2560的51

也就是UNO 12对应 2560的50

也就是UNO 13 对应 2560的52


Arduino烧录程序如何保护知识产权



用命令行给Arduino烧写软件程序

有挺多工具软件可以完成脱离Arduino IDE烧录Hex二进制文件的工作,他们大多是通过GUI前端在后台调用avrdude程序。大多数情况下,他们可以很好的工作,但是要么是不跨平台,只能用于Windows(这类工具Windows版本的比较多,也有些是python编写的,但是又打包为exe文件运行,也是只支持Windows),要么就是工具本身有些限制。


我实验了用命令行的方式来烧写Hex文件,这样的话,只要系统内安装有Arduino IDE,甚至是只要安装了avrdude程序,就可以方便的烧写Hex文件,而且可以跨平台,无论Windows,macOS,或者是Linux(树莓派?)都可以工作。


首先,我的系统里安装了Arduino IDE v1.8.9。 目前,这个版本是最新版。


确定Arduino IDE编译好的Hex文件的位置

在File菜单的Preferences里面,打开preferences.txt文件,在更改之前,关闭Arduino IDE。

新建一个文件夹C:\Users\zz\Documents\Arduino\hex (zz是我的Windows登录用户名)

在preferences.txt文件里加入如下一行, 并保存

build.path=C:\Users\zz\Documents\Arduino\hex

对于macOS的话

build.path=/Users/zz/Documents/Arduino/hex

打开Arduino IDE,并打开Blink示例程序,Ctrl-R编译后,会在新建的文件夹中看到编译好的Blink.ino.hex文件

C:\Users\zz\Documents\Arduino\hex>dir

 驱动器 C 中的卷没有标签。

 卷的序列号是 1234-5678


 C:\Users\zz\Documents\Arduino\hex 的目录


2019/06/08  14:28    <DIR>          .

2019/06/08  14:28    <DIR>          ..

2019/06/08  14:28                13 Blink.ino.eep

2019/06/08  14:28            13,920 Blink.ino.elf

2019/06/08  14:28             2,640 Blink.ino.hex

2019/06/08  14:28             4,000 Blink.ino.with_bootloader.hex

2019/06/08  14:28               968 build.options.json

2019/06/08  14:28    <DIR>          core

2019/06/08  14:28               397 includes.cache

2019/06/08  14:28    <DIR>          libraries

2019/06/08  14:28    <DIR>          preproc

2019/06/08  14:28    <DIR>          sketch

               6 个文件         21,938 字节

               6 个目录 31,183,998,976 可用字节

尝试用Arduino IDE下载程序,并观察编译和烧写过程

在Arduino IDE中的preferences设置对话框中show verbose output during: 选中compilation和upload,保存设置

打开Blink示例程序,连接Arduino Uno并Ctrl-U(Upload)

然后在主界面的信息提示区域,会打印输出编译和烧写过程。输出内容很多,最关键的是avrdude的命令行

C:\arduino-1.8.9\hardware\tools\avr/bin/avrdude -CC:\arduino-1.8.9\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM3 -b115200 -D -Uflash:w:C:\Users\zz\Documents\Arduino\hex/Blink.ino.hex:i

我也尝试了Arduino Micro (更换不同的板子后,需要注意Arduino IDE的board和Port的设定变更),命令行是这样的:

C:\arduino-1.8.9\hardware\tools\avr/bin/avrdude -CC:\arduino-1.8.9\hardware\tools\avr/etc/avrdude.conf -v -patmega32u4 -cavr109 -PCOM4 -b57600 -D -Uflash:w:C:\Users\zz\Documents\Arduino\hex/Blink.ino.hex:i

可以清楚的看到Arduino IDE调用avrdude烧写hex文件,以及相关命令行参数

在macOS系统下,我看到的是

/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -carduino -P/dev/cu.usbmodem141301 -b115200 -D -Uflash:w:/Users/zz/Documents/Arduino/hex/Blink.ino.hex:i 

avrdude的参数

-C 制定配置文件的位置.

对于Windows系统的例子

-CC:\arduino-1.8.9\hardware\tools\avr/etc/avrdude.conf

对于macOS系统的例子

-C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf

-v 打印详细的提示信息.

-p 必须项. 指定AVR零件号.

对于Arduino Uno

-patmega328p

对于Arduino Micro

-patmega32u4

-c 指定编程器的类型.

对于Arduino Uno

-carduino

对于Arduino Micro

-cavr109

-P 指定连接的串口.

对于Windows系统的例子

-PCOM3

对于macOS系统的例子

-P/dev/cu.usbmodem141301

-b 指定RS-232串口波特率.

对于Arduino Uno

-b115200

对于Arduino Micro

-b57600

-D 禁止自动擦除闪存空间

-U :r|w|v:[:format]

指定存储类型,操作方式,hex文件名以及文件类型.

对于Windows系统的例子

-Uflash:w:C:\Users\zz\Documents\Arduino\hex/Blink.ino.hex:i

对于macOS系统的例子

-Uflash:w:/Users/zz/Documents/Arduino/hex/Blink.ino.hex:i

命令行烧写hex文件

这样我们就可以用命令行很便捷的烧写hex文件到Arduino里了


Windows

Uno


C:\arduino-1.8.9\hardware\tools\avr\bin\avrdude -CC:\arduino-1.8.9\hardware\tools\avr\etc\avrdude.conf -v -patmega328p -carduino -PCOM3 -b115200 -D -Uflash:w:C:\Users\zz\Documents\Arduino\hex\Blink.ino.hex:i

Micro


C:\arduino-1.8.9\hardware\tools\avr\bin\avrdude -CC:\arduino-1.8.9\hardware\tools\avr\etc\avrdude.conf -v -patmega32u4 -cavr109 -PCOM4 -b57600 -D -Uflash:w:C:\Users\zz\Documents\Arduino\hex\Blink.ino.hex:i

macOS

Uno


/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -carduino -P/dev/cu.usbmodem141301 -b115200 -D -Uflash:w:/Users/zz/Documents/Arduino/hex/Blink.ino.hex:i 

Micro


/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -patmega32u4 -cavr109 -P/dev/cu.usbmodem141401 -b57600 -D -Uflash:w:/Users/zz/Documents/Arduino/hex/Blink.ino.hex:i 

注意

对于32u4芯片的Arduino板子,必须在烧写前先按一下板子上的Reset按钮,等1-3秒再执行烧写命令

如果有新的芯片类型或者不同板子的Arduino及其兼容版,只要能先尝试用Arduino IDE编译后烧写,得到烧写相关的命令行信息,就可以手动的用命令行烧写

总结

命令行烧写hex文件比用IDE打开源文件烧写要快捷很多

用于烧写的命令行可以在其他程序(比如Python)中调用,非常方便用于二次开发



arduino远程刷新(烧录)固件

在车间部署了十几个网络版的温湿度采集器(基于arduino的),这些采集器分布在不同的地方,现在要更新一下上面的固件。最笨的方法是一个一个地取下来,插到电脑的USB接口上进行固件更新,这样做显然很麻烦。能不能直接通过网络(以太网)进行固件的更新呢?


    我查了一下资料,发现网上只有通过蓝牙更新的固件的,但是没有以太网的。低功耗的商用的蓝牙,其传输距离只有10米,且那个方法必须在板上进行手动复位。我研究了一下,发现了通过以太网刷新固件的方法,现跟大家分享一下。


 


1、原理:


(1)通过串口转wifi模块发送一个指令,让arduino复位。


(2)然后开始传送编译好的二进制文件,arduino在重启的时候,会将这个文件写入到flash中。avr固件的烧录原理请见:http://news.eeworld.com.cn/mcu/2013/0608/article_13291.html


 


2、硬件:


Arduino uno + 串口转wifi模块。


线路连接:2号IO口串联一个550k电阻接到reset上。


 


我所用的Wifi模块是在这家店买的:


http://item.taobao.com/item.htm?spm=a1z09.2.9.41.0CxtvI&id=36815717425&_u=blmt59h45fc


 


3、所需要工具软件:


  (1)avrdude。版本013.9.18,在附件的bin文件夹下。这个程序可用来将编译好的二进制文件刷写(烧录)到arduino中,它需要用到串口。


  (2)VSPM虚拟串口服务器,下载地地址:http://www.kinghwawin.com/DownloadShow.asp?ID=40。


    这个软件的作用是将TCP服务器虚拟成本地的串口,用于跟avrdude配合使用,即提供一个串口给avrdude使用。下载完毕之后,请按默认路径安装。启动该程序,然后新建一个虚拟串口,将串口号设置为“COM256”。如图所示:

1.jpg

(3)TCP/UDP调试工具。此工具的作用是给远端的arduino控制器发送复位指令。


4、arduino代码

void setup()


{


    Serial.begin(115200);


    pinMode(2,OUTPUT);


    digitalWrite(2, HIGH);   // switch off


}


 


void loop()


{


   if (Serial.available() > 0)


   {


       char val;


       val = Serial.read();     // read serial data


       if(val == 'r')


       {


          digitalWrite(2, LOW);    // 将reset管脚的电平拉低50ms,起到复位的作用


           delay(50);


          digitalWrite(2, HIGH); // 


      } 


  }


}


 


注:arduino中必须有以上的这些代码才能被远程刷新。请将这些代码嵌入到你的arduion中,然后用usb线刷新到arduino中。


 


5、在arduino编辑器中找到编译好的固件(.hex文件)


    默认情况下,arduino会在后台将源码进行编译成二进制文件,然后下载到arduino控制器中,这个过程不会有提示。


    可以通过一些方法来显示编译烧录的过程,并且提取hex文件,详细方法见链接:http://see.sl088.com/wiki/Arduino_%E6%8F%90%E5%8F%96hex


    这个步骤完成之后,我们手头上就有了一个后缀名为hex的二进制文件。


    附件中的bin文件夹下,有一个名为的Blink.cpp.hex文件,它是官方提供的例子编译之后的二进制文件,可以拿这个来做测试。


 


6、手工烧录


     手工烧录是直接使用avrdude来进行烧录。avrdude是一个控制台程序,需要在命令行下进行操作。


    (1)cd进附件中的bin文件夹下。


    (2)使用TCP/UDP调试工具连接到TCP服务器,发送指令r,将arduino复位。


    (3)马上执行以下命令:avrdude.exe avrdude.conf -v -v -v -v -patmega328p -carduino -P\.COM256 -b115200 -D -Uflash:w:Blink.cpp.hex:i


     至于为什么知道是这个命令,我是通过分析arduino编辑器的编译及下载输出得出的,以下是arduino的编译下载时的输出(过程),请注意第43行。



7、自动烧录


我用C#写了一个工具,将上面的手工操作给封装起来。功能包括启动VSPM虚拟串口服务器,复位远端的arduino uno,执行avrdude指令。详见的代码见附件。



使用Arduino开发ESP32:固件更新演示

经过SD卡更新固件

从SD卡进行固件升级算是最简单的了,将固件重命名为 update.bin(不是必须的,只要代码中读取的文件名能匹配上就行) ,而后复制到SD卡中,而后按照下文方式链接SD卡:

《使用Arduino开发ESP32(13):SD卡的使用》

完成电路链接后就可使用下面代码测试了:web


#include <SD_MMC.h>

#include <Update.h> // 引用相关库


void setup()

{

    Serial.begin(115200);

    Serial.println();


    if (!SD_MMC.begin()) //挂载SD卡

    {

        Serial.println("存储卡挂载失败");

        return;

    }


    File updateBin = SD_MMC.open("/update.bin"); // 读取update.bin文件

    if (!updateBin)

    {

        Serial.println("读取update.bin失败");

        return;

    }

    if (updateBin.isDirectory())

    {

        Serial.println("update.bin是一个文件夹");

        updateBin.close();

        return;

    }


    size_t updateSize = updateBin.size(); // 获取固件大小

    if (updateSize <= 0)

    {

        Serial.println("文件为空");

        return;

    }

    Serial.println("固件大小为" + String(updateSize) + "字节");


    Serial.println("开始固件升级");


    if (!Update.begin(updateSize)) // 开始固件升级,检查空可用间大小,若是正在升级或空间不够则返回false

    {

        Serial.println("升级不可用");

        return;

    }


    size_t written = Update.writeStream(updateBin); // 将数据写入到OTA区域 // 使用writeStream方法的话前面Update.begin()必须填写要更新的固件大小

    Serial.println("写入" + String(written) + "字节到OTA区域");


    if (!Update.end()) // 完成数据写入,设置在系统重启后自动将OTA区域固件移动到Sketch区域

    {

        Serial.println("升级失败 Error #: " + String(Update.getError()));

        return;

    }


    updateBin.close(); // 关闭update.bin文件

    //SD_MMC.remove("/update.bin"); // 移除update.bin文件


    Serial.println("升级操做完成,模块将在5秒后重启以完成固件升级");

    delay(5000); 

    ESP.restart(); // 重启设备

}


void loop()

{

}

上面演示中代码看着蛮多行,大可能是都是文件读取、检测的代码,真正固件更新的操做就 Update.begin() 、 Update.writeStream() 、 Update.end() 这几步。服务器


经过网页更新固件

经过网页更新也不复杂,和上面经过SD卡升级须要涉及SD卡使用相关内容同样,经过网页更新须要涉及网页和服务器相关内容,能够参考下面文章:

《使用Arduino开发ESP32(09):WebServer使用演示与说明》

使用下面代码能够测试经过网页进行更新固件的操做:网络


#include <WiFi.h>

#include <WebServer.h>

#include <Update.h> // 引用相关库


const char *ssid = "********";

const char *password = "********";


WebServer server(80);


// 如下为网页文件

String indexhtml = String("") +

                   "<!DOCTYPE html>\n" +

                   "<head>\n" +

                   " <meta charset=\"UTF-8\">\n" +

                   " <title>Update Test</title>\n" +

                   "</head>\n" +

                   "<body>\n" +

                   " <form method=\'POST\' action=\'/update\' enctype=\'multipart/form-data\'>\n" +

                   " <input type=\'file\' name=\'firmware\'>\n" +

                   " <input type=\'submit\'>\n" +

                   " </form>\n" +

                   "</body>\n";


bool shouldreboot = false; // 重启标志,固件升级操做完成后设置该标志准备重启设备


void handleResponse() //回调函数

{

    server.sendHeader("Connection", "close");

    server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");

}


void handleFileupload() //回调函数

{

    HTTPUpload &upload = server.upload();   // 文件上传对象

    if (upload.status == UPLOAD_FILE_START) // 文件上传开始

    {

        Serial.printf("开始上传文件: %s\n", upload.filename.c_str());

        if (!Update.begin()) // 开始固件升级,检查空可用间大小,若是正在升级或空间不够则返回false

        {

            Update.printError(Serial);

        }

    }

    else if (upload.status == UPLOAD_FILE_WRITE) // 文件读写中

    {

        if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) // 将文件数据写入到OTA区域

        {

            Update.printError(Serial);

        }

    }

    else if (upload.status == UPLOAD_FILE_END) // 文件上传完成

    {

        Serial.println("写入" + String(upload.totalSize) + "字节到OTA区域");

        if (!Update.end(true)) // 完成数据写入,设置在系统重启后自动将OTA区域固件移动到Sketch区域 // Update.begin不指定大小时这里设置true

        {

            Update.printError(Serial);

        }

        Serial.println("升级操做完成,模块将在5秒后重启以完成固件升级");

        shouldreboot = true;

    }

    else

    {

        Serial.printf("固件上传失败: status=%d\n", upload.status);

    }

}


void setup()

{

    Serial.begin(115200);

    Serial.println();


    WiFi.mode(WIFI_STA);

    WiFi.setSleep(false);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED)

    {

        delay(500);

        Serial.print(".");

    }

    Serial.println("Connected");

    Serial.print("IP Address:");

    Serial.println(WiFi.localIP());


    server.on("/", HTTP_GET, []() {

        server.sendHeader("Connection", "close");

        server.send(200, "text/html", indexhtml); // 发送网页

    });


    server.on("/update", HTTP_POST, handleResponse, handleFileupload); // 绑定回调函数


    server.begin(); //启动服务器


    Serial.println("Web server started");

}


void loop()

{

    server.handleClient(); //处理来自客户端的请求


    if (shouldreboot)

    {

        delay(5000);

        ESP.restart(); // 重启设备

    }

}


上面演示中代码看着也蛮多行,大可能是都是网页文本、回调函数、网络链接等代码,真正固件更新的操做就 Update.begin() 、 Update.write() 、 Update.end() 这几步。和上一个例子不一样的是这里使用Update.begin()时未指定需求空间的大小,因此在后面Update.end()中指定了true参数。


ESP32烧录Arduino生成的bin文件

前言

Arduino有着丰富的第三方库,因此开发起来非常的方便快捷,但是在实际的生产中,我们不可能使用Arduino IDE来进行固件的烧录,因为使用Arduino IDE烧录效率很低,而且要先帮工厂把环境搭建好,更重要的是烧录时必须要打开源代码,这可能会导致工厂泄露机密。因此,最好的方案还是将代码转成通用的bin文件烧录。

废话不多说,马上开始讲解。


1 Arduino生成bin文件

关于Arduino的环境搭建,库安装这些我就不介绍了,都走到量产这一步了不会有人还不知道吧。

1.png

打开Arduino IDE,打开 项目 -> 导出已编译的二进制文件,等待编译完成即可在工程目录下生成相应的bin文件。


编译成功后生成的bin文件:

2.png


2 bin文件烧录

2.1 下载烧录工具

烧录bin文件的时候我们需要用到乐鑫的flash烧录工具。

工具可以在乐鑫官网下载:

https://www.espressif.com/zh-hans/support/download/other-tools

3.png


2.2 集齐MCU需要烧录的固件

用Arduino IDE烧录ESP8266、ESP32、ESP32-S2或者其他ESP系列的MCU时给我们的感觉是它仅仅烧录了自己编写的代码以及底层支持库。但实际上除了这些,还包含了启动文件,bootloader,sdk等。

因此,如果我们只烧录Arduino生成的bin文件是无法正常运行的。我们还需要找到另外几个文件。

这几个文件都在你安装的开发板库里面。比如你用的ESP32,那就是在esp32库。


我这里以ESP32-S2为例讲解,其他ESP系列的MCU也是一样的。


首先我们要打开库文件对应的文件夹。

这个路径可以在Arduino IDE的首选项里面看到。点击一下这个路径就可以弹出文件窗口。

4.png

5.png

在packages文件夹可以看到所有已安装的开发板库。比如我这里安装了esp32和esp8266的库。

6.png

进入相应的库,找到partitions和sdk这两个文件夹。

7.png

提示:我这个是esp32 v2.0.1版本的库,其他MCU或者其他版本的库文件框架可能会有区别,但是大体上应该都是类似的。


1)第1个文件:boot_app0

在partitions文件夹里面。

8.png

2)第2个文件:bootloader

在sdk文件夹里面。

特别说明一下:目前esp32是有3个MCU的sdk的,选择自己要用的即可。我这里用的是esp32-s2。

9.png

提示:dio、dout、qio和qout是spi的模式,40m和80m是flash的频率,比较常用的是dio和40m。当然,如果对性能有更高的要求可以选80m,在SPI作为主机时可以达到80MHz,但相应的对硬件的抗干扰能力也有更高的要求。


3)第3个文件:app

这个是你实际的应用代码,也就是用Arduino IDE生成的bin文件。


4)第4个文件:default

和第1个文件一样,也是在partitions文件夹里面。

10.png


2.3 烧录固件

打开乐鑫的烧录工具,选择对应的芯片和烧录方式。

提示:ESP32-S2除了串口以外,还可以通过USB下载。


11.png

依次添加烧录文件,并填写相应的烧录地址,配置好相应的模式。

我这里还是以ESP32-S2为例。

12.png

获取烧录文件地址的方法:这几个地址可以在Arduino IDE烧录时输出的日志中找到。

13.png


连接好硬件设备,并且进入下载模式。

进入下载模块的方法:按住boot键,然后再按reset键,最后松开boot键。或者按住boot键之后再上电。只要保证MCU启动时,boot脚是低电平即可。

14.png


通过串口打印的信息可以确定是否已进入下载模式。

进入下载模式时可以看到以下信息:

15.png


在烧录工具上选择好对应的com口,配置好波特率(波特率越大,下载速度越快)。

提示:ESP32-S2除了串口以外,还可以通过USB下载,要先进入下载模式才能检测到USB对应的com口,或者之前运行的代码有把USB配置成虚拟串口也可以看到对应的com口。


点击START开始烧录。

提示:烧录固件之前可以先全部擦除一遍。如果点击开始烧录之后才发觉MCU没有进入烧录模式,也可以在这里进入,进入之后马上就会开始烧录了。


16.png

等待下载完成后重启一下即可。


结束语

好了,关于Arduino生成bin文件及烧录方法的介绍就到这里。本文只列举了ESP32-S2的情况,ESP8266和ESP32我也试过,也是一样的,大家举一反三即可。如果这篇文章对你有帮助,可以点赞收藏,如果还有什么问题,欢迎在评论区留言或者私信给我。





Mqtt 客户端多主题订阅


前言: mqtt 的主题一个层级的概念. 我们订阅多个主题就需要用到这个技术点

功能是在主题中引入层次。层次又分主题层级分隔符,多层通配符和单层通配符

需要注意的一点是: 这些层级不能用在发布消息的 Publish 接口中


层级分类

主题层级分隔符: /

多层通配符: #

单层通配符: +

主题层级分隔符

"/" 被用来分割主题树的每一层,并给主题空间提供分等级的结构。当两个通配符在一个主题中出现的时候,主题层次分隔符的使用是很重要的。


// 主题Topic1: 分了三层

/test/child/aaa

// 主题Topic2: 分了四层

/test/child/aaa2/bbb2

多层通配符

多层通配符"#"是一个匹配主题中任意层次数的通配符。我们用案例说明


案例1

订阅主题: /test/child/#

我们将收到这些主题发送来的消息:


/test/child 

/test/child/aaa

/test/child/ccc

/test/child/aaa/bbb

/test/child/aaa/bbb/ddd

多层通配符可以理解为大于等于0的层次。

多层通配符只可以确定当前层或者下一层


常见错误 和正确表示案例


#   // Success, 会接收到不以 / 开头的所有主题

/#  // Success

/test/#/child   // Error, #必须是最后一个字符

/test/#           // Success

/test/child#    //Error  无效的通配符

/test/child/#   // Success

单层通配符

单层通配符 "+" 只匹配主题的一层


案例1

订阅主题: /test/child/+

我们将收到这些主题发送来的消息:

注意:接收不到 /test/child 主题发送的消息


/test/child/aaa

/test/child/bbb

/test/child/ccc

常见错误 和正确表示案例


+  //Success

/+  // Success

/test/+/child   // Success, 

/test/+           // Success

/test/child+    //Error  无效的通配符

/test/child/+   // Success

主题语法和用法

当你建立一个应用,设计主题树的时候应该考虑以下的主题名字的语法和语义:


主题至少有一个字符长。

主题名字是大小写敏感的。比如说,ACCOUNTS和Accounts是两个不同的主题。

主题名字可以包含空格。比如,Accounts payable是一个有效的主题。

以/开头会产生一个不同的主题。比如说,/finnace与finance不同。/finance匹配"+/+"和/+,但不匹配+

不要在任何主题中包含null(Unicode \x0000)字符。

以下的原则应用于主题树的建造和内容


在主题树中,长度被限制于64k内但是在这以内没有限制层级的数目 。

可以有任意数目的根节点;也就是说,可以有任意数目的主题树



Arduino的IO口驱动力不够解决办法

使用Arduino驱动模块

当Arduino的IO输出口驱动力不够时,有几种常见的解决方案:


使用晶体管或MOSFET作为开关:

可以使用NPN晶体管(如2N2222)或N沟道MOSFET(如IRLZ44N)来控制更大的电流。

Arduino的IO口用来控制晶体管或MOSFET的开关,而实际的大电流则通过这些器件来控制。


使用继电器:

继电器可以控制更大的电流和电压。

使用Arduino控制继电器的线圈,继电器的触点则用来控制大功率设备。


使用专用驱动器IC:

例如ULN2003(用于控制多个小功率设备)或L298N(用于控制电机)。

这些IC专门设计用于驱动大电流负载。


使用运算放大器:

运算放大器可以用来放大Arduino的输出信号。

这对于需要精确电压控制的模拟设备特别有用。


电平转换器:

如果需要不同电压级别的信号,可以使用电平转换器IC。


使用外部电源:

对于大功率设备,使用单独的电源供电,而Arduino仅用于控制信号。



LVGL Arduino界面开发库

LVGL(Light and Versatile Graphics Library)是一个免费的开源图形库,提供了创建嵌入式GUI所需的一切。它具有高度的可定制性和低内存占用,非常适合资源受限的嵌入式系统。lv_arduino 是 LVGL 在 Arduino 平台上的移植版本,使得 Arduino 用户可以轻松地在他们的项目中集成图形界面。

项目快速启动

安装步骤

下载并安装 Arduino IDE:确保你已经安装了最新版本的 Arduino IDE。

安装 LVGL 库:

打开 Arduino IDE。

进入 工具 -> 库管理。

搜索 lvgl 并安装 lv_arduino 库。

示例代码

以下是一个简单的示例代码,展示如何在 Arduino 上使用 LVGL 创建一个基本的界面:


#include <lvgl.h>

#include <TFT_eSPI.h>

 

TFT_eSPI tft = TFT_eSPI();

 

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {

  uint32_t w = (area->x2 - area->x1 + 1);

  uint32_t h = (area->y2 - area->y1 + 1);

 

  tft.startWrite();

  tft.setAddrWindow(area->x1, area->y1, w, h);

  tft.pushColors((uint16_t *)&color_p->full, w * h, true);

  tft.endWrite();

 

  lv_disp_flush_ready(disp);

}

 

void setup() {

  lv_init();

  tft.begin();

  tft.setRotation(1);

 

  static lv_disp_buf_t disp_buf;

  static lv_color_t buf[LV_HOR_RES_MAX * 10];

  lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

 

  lv_disp_drv_t disp_drv;

  lv_disp_drv_init(&disp_drv);

  disp_drv.flush_cb = my_disp_flush;

  disp_drv.buffer = &disp_buf;

  lv_disp_drv_register(&disp_drv);

 

  lv_obj_t *label = lv_label_create(lv_scr_act(), NULL);

  lv_label_set_text(label, "Hello, LVGL!");

  lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);

}

 

void loop() {

  lv_task_handler();

  delay(5);

}














Top