利用 Arduino Mega 2560+WiFi R3 中的 ESP8266





5.00/5 (5投票s)
通过一种巧妙的配置板的方法来加速您的设备
引言
最近,我在这里 发布了一篇关于 Arduino Mega 2560+WiFi R3 入门的简短文章。在那篇文章中,我暗示了板载 WiFi 拥有自己的 CPU,并且该 CPU 的功能比 Arduino 板上的主 ATMega2560 CPU 强大得多。事实上,它非常强大,即使在处理 TCP/IP 堆栈时,仍有足够的处理周期来超越 Mega。
在本文中,我旨在向您展示如何利用更强大的 CPU,并将 I/O 任务委托给功能较弱的 CPU。
此项目包含 Arduino IDE 项目的 .ino 文件,用于 ESP8266 演示代码和 ATMega2560 演示代码。两者都必须上传到开发板,因为它们协同工作。该项目还包含一个 C# 实用程序,用于将 HTML 文件转换为 C 风格字符串。这有助于编辑 Web 服务器代码。
概念化这个混乱的局面
计划
在这块特定的 Arduino 板上,有两个 CPU。在典型配置中,8 位 ATMega2560 CPU 以 16MHz 运行,作为主 CPU。它通过串行 UART 与 ESP8266 通信,ESP8266 包含其自己的 32 位 Tensilica XDS 106Micro,运行频率为 80 MHz。显然,后者在各个方面都优于前者。如果我们在此 CPU 上运行代码,理论上其执行速度将比在另一个 CPU 上快。
将 106Micro CPU 用作主处理器的主要限制是,它唯一的 I/O 是一个串行 UART,以及对 WiFi 和 TCP/IP 堆栈的访问。这意味着它与另一个 CPU 以及 Arduino 板其余部分通信的唯一方式是通过单个串行连接。
现在,如果您的应用程序进行大量的 WiFi 和 CPU 计算,但对于与板上所有其他 I/O 进行通信,最高可承受 115200 波特率,那么这种配置将非常适合您。
主要缺点是您需要编写额外的代码,并且现在需要刷新 ESP8266 和主 Arduino。
另一个缺点是您的代码会变得更复杂。
在这里,ESP8266 负责处理所有互联网事务以及任何需要发生的主计算,如果需要访问其他 I/O,则必须通过其硬件串行连接与 ATMega2560 通信。ATMega2560 再将串行数据用于读取或操作它控制的所有 I/O,并在必要时向 106Micro CPU 报告。
高级系统也可以让 ATMega2560 进行一些协处理,特别是如果需要处理大量 I/O。
这使得编码变得复杂,因为这意味着您必须创建一个串行协议来在两个 CPU 之间进行双向通信。
另一方面,这意味着您 8 位 16MHz 的 CPU 只负责 I/O,而您的 32 位 80MHz 的 CPU 现在可以执行更繁重的工作。
设置 Arduino IDE
为了实现这一目标,我们必须将 Arduino IDE 设置为使用此配置。首先要做的是通过转到 **文件 | 首选项...** 来添加 ESP8266“开发板管理器”,然后找到“附加开发板管理器 URL”并逐字添加 URL http://arduino.esp8266.com/stable/package_esp8266com_index.json。如果其中已经有其他 URL,可以用逗号分隔它们。
这将在 **工具** 菜单下添加一些内容,但这还无关紧要——我们稍后会讲到。
如何处理编码 - 开发周期
开发周期由于需要根据您正在编码的 CPU 来翻转 DIP 开关而变得有些复杂。最好先设计您的串行协议,然后编写可能更简单的 ATMega2560 端代码,然后再处理 106Micro 端。您能做的任何限制双向操作的事情都有帮助,因为它减少了您需要玩 DIP 开关的次数。
针对 ATMega2560 部分进行编码(部署配置)
(这也是设备部署时使用的配置。)
- 确保您的 DIP 开关设置如下:1-4 为 ON,5-8 为 OFF。
- 确保 TXD0/TXD3 开关设置为 TXD3
- 确保在 Arduino IDE 的 **工具 | 开发板:** 下显示“Arduino Mega 或 Mega 2560”,在 **工具 | 处理器:** 下显示“ATmega2560 (AT Mega)”
- 仔细检查以上设置!
在您的草图中,主处理器通过 Serial3
连接到此处理器。USB COM 端口是 Serial
。
您需要从 Serial3
读取和写入数据,根据您已经设计好的协议设置 I/O 引脚或路由到 Serial
,甚至可能包括 Serial1
和 Serial2
。您 *已经* 设计好您的协议了,对吗?
这是此处理器的工作,除非您还有协处理任务。
请注意,在上述状态下上传代码时,开发板将重置并自动运行新代码。以这种方式进行编码应该您很熟悉。
针对 XDS 106Micro 进行编码
- 确保您的 DIP 开关设置如下:1-4 和 8 为 OFF,5-7 为 ON。
- 确保在 Arduino IDE 的 **工具 | 开发板:** 下显示“Generic ESP8266 Module”
- 确保 **工具 | 闪存大小:** 设置为“4 MB (FS: 2MB OTA:~1019KB)”
- 仔细检查它!
代码可以上传到 XDS 106Micro,但在该模式下不会运行。有两种方法可以运行代码。要么将其切换回前面列出的部署配置,要么将 DIP 开关设置如下:1-4 和 7-8 为 OFF,5-6 为 ON。这将把 USB COM 端口直接桥接到 XDS 106Micro 的 UART,这对于从中获取调试输出很有用。
显然,针对此 CPU 进行编码会稍微复杂一些,因为您必须翻转 DIP 开关才能使其运行。不幸的是,这只是设计的一部分。
测试整个系统(两个 CPU 同时工作)的唯一方法是将其置于部署配置。
编写这个混乱的程序
CPU 之间的通信
您首先需要做的就是开发一个协议,以便在 ATmega2560 和 XDS 106Micro 之间以 115200 波特率通过串行进行通信。
让我们考虑一个场景,我们想从 XDS 106Micro 处理器读取或写入 I/O 引脚。我们会这样做:
Serial.write(op_write); // op_read or op_write
Serial.write(pin);
Serial.write(value);
然后,如果操作码是 op_read
Serial.write(op_read);
Serial.write(pin);
while(!Serial.available());
byte value = (byte)Serial.read();
您还需要为其他操作添加更多的操作码,但它们是什么取决于您做什么。上面的例子只是一个示例,并且可能比您在实际应用程序中使用的要低级别,是逐个引脚操作。
上面使用的是 Serial
,因为那段代码是为 XDS 106Micro 处理器及其单个串行端口编写的。
在另一端——ATmega2560 端,我们将使用 Serial3
作为此链路的另一端,因为它们是硬连线连接的。
另一个主要的问题是使用 ESP8266 的 WiFi 功能。幸运的是, there's the ESP8266WiFi library,它专门设计用于我们这种情况,即我们在 ESP8266 的 CPU 本身上运行。它非常易于使用,入门信息 在这里。
主 ESP8266
在此项目中,有一个简单的 Web 服务器,设计运行在 ESP8266 上。它允许您读取板上的 3 个引脚,并通过一系列复选框设置或清除 LED 灯。
我厚颜无耻地从 **文件 | 示例** 下的一个内置示例中复制代码,并为演示目的进行了修改。
Web 服务器将在 http://esp8266.local 上广播,如果您的网络支持 mDNS(组播 DNS),否则 IP 地址将通过 COM 端口报告。
基本上,它所做的就是连接到给定的网络(通过 SSID),然后设置 Web 服务器和组播域(如果您的网络支持),以便为您提供一个表单。该表单显示 Arduino 板上的引脚以及主 LED。您可以设置 LED,但无法读取它。您可以读取其他引脚,但它们无法写入——至少默认情况下是这样。您可以编辑代码轻松更改这一点。
这是主处理程序代码的略微缩减版
void handleRoot() {
// if the form parameters are specified
// set them high, otherwise set them low
// note we do this for all pins, not just
// the LED. That's okay, it just doesn't
// actually do anything for those pins
String sza = server.arg("Pin1");
if(0!=sza && 0!=sza[0])
writePin(2,HIGH);
else
writePin(2,LOW);
sza = server.arg("Pin2");
if(0!=sza && 0!=sza[0])
writePin(3,HIGH);
else
writePin(3,LOW);
sza = server.arg("Pin3");
if(0!=sza && 0!=sza[0])
writePin(4,HIGH);
else
writePin(4,LOW);
sza = server.arg("PinLED");
if(0!=sza && 0!=sza[0])
writePin(13,HIGH);
else
writePin(13,LOW);
char sz[1024];
sz[0]=0;
// prepare the checked=\"checked\"
// attribute for the relevant
// checkboxes
char su[] = "";
char sc[] = " checked=\"checked\"";
char* s1=(0!=readPin(2))?sc:su;
char* s2=(0!=readPin(3))?sc:su;
char* s3=(0!=readPin(4))?sc:su;
char* s4=(0!=readPin(13))?sc:su;
// omitted part of the string
// below for display
// don't copy/paste this code!
sprintf(sz,"<!DOCTYPE html>\r\n\r\n<html...",s1,s2,s3,s4);
server.send(200, "text/html", sz);
}
通信协议
我们的协议简单方便。它将 ESP8266 的所有串行数据转发到 ATMega2560。当 ATMega2560 CPU 接收到数据时,它会将其转发到主串行端口。例外情况是,如果它接收到值为 254 或 255 的字节。如果接收到前者,则表示要读取引脚的代码。紧随其后的是一个包含引脚 ID 的字节。如果接收到 255,则表示要写入引脚的信号。随后的字节包括一个字节用于引脚 ID,下一个字节用于值。这种读写操作基本上与前面两个图所示的代码相同。它仅适用于数字引脚,没有办法从服务器设置引脚方向,也无法使用此实现处理模拟引脚或其他串行 UART。您需要为这些情况创建更复杂的解决方案。
以下是 ESP8266 Web 服务器代码用于向从设备发送 I/O 命令的两个方法
int readPin(int pin) {
Serial.write((byte)254);
Serial.write((byte)pin);
while(0==Serial.available());
int ret = Serial.read();
return ret;
}
int writePin(int pin,int value) {
Serial.write((byte)255);
Serial.write((byte)pin);
Serial.write((byte)value);
}
这些方法很简单。反之亦然,在后面的从设备代码中有所体现,我们将在接下来介绍。
从设备 ATMega2560
此 CPU 仅负责转发串行输出或设置和获取数字 I/O 引脚值。此代码仅执行此操作。与之前一样,它转发除字节 254 或 255 之外的所有内容,这些字节是用于读取和写入引脚的转义符。这是代码
void setup() {
// initialize the serial ports
Serial.begin(115200);
Serial3.begin(115200);
}
void loop() {
int pin;
// wait for data
while(0==Serial3.available());
// get the next byte
int b = (byte)Serial3.read();
if(254==b) { // read
// wait for data
while(0==Serial3.available());
// read the pin id
pin = Serial3.read();
// read the pin
int val = digitalRead(pin);
// write the result back to the other CPU
Serial3.write((byte)(0==val?0:1));
} else if(255==b) { // write
// wait for data
while(0==Serial3.available());
// read the pin id
pin = Serial3.read();
// wait for data
while(0==Serial3.available());
// read the value to set
int val = Serial3.read();
// set the pin
digitalWrite(pin,0!=val?HIGH:LOW);
} else // simply forward
Serial.write((byte)b);
return;
}
关注点
现在您可以获得的强大的 ESP32 板,其出现很大程度上归功于爱好者对 ESP8266 的黑客行为,包括上述项目。虽然这里使用的开发板和这项技术有些过时,但它们将帮助您获得有关这些设备编码的背景知识。
历史
- 2020 年 11 月 2 日 - 首次提交