上一篇文章怎么给arduinoIDE添加ESP8266开发板,添加以后8266模块的操作就和普通的arduino用法大相径庭了,这几天突发奇想,用两块ESP8266-01模块给arduino开发板下载程序,其实我这样想的原因是,假如我想做一些作品,而这些模块全部安装在外壳里,实在不好拆外壳,如果可以用WIFI模块来刷固件,那就省去拆机的时间了。
所以我整体的思路是:USB转TTL模块☞ESP8266 ))))WIFI )))WIFI )))WIFI ESP8266☞arduino开发板(或者串口屏之类的)。
再给8266模块下载程序之前,先做一些准备工作,先来看看引脚图:
由引脚图可知,如果上电时,GPIO0为低电平,才会进入下载模式,那么为了方便,我焊了个轻触开关在上面,同时,现在可用的IO口只有GPIO2了,焊接一个LED作为指示吧,我用GPIO2输出低电平来复位arduino。网络上某些文章说这个引脚接550k电阻到arduino的RESET脚,那是因为没有其他芯片对这个引脚上拉才可以,否则,应该用三极管来下拉。还有就是CHPD引脚必须为高电平。
接下来就是给这两个模块下载程序了,我用的是这配套的下载器
一块WIFI模块做AP,另一块工作在标准模式,下面是主机和从机的程序:
主机:
#include
#include
IPAddress RemoteIP(192, 168, 4, 2);
unsigned int localUDPPort = 9999; // local port to listen on
unsigned int sendUDPPort = 8888; // send port to listen on
byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
WiFiUDP Udp;
void setup() {
delay(2000);
Serial.begin(115200);
WiFi.mode(WIFI_AP); //设置工作模式为AP
WiFi.softAP("WIFI_Serial", "12345678");//设置wifi名称和密码
Udp.begin(localUDPPort);//udp 接收
Serial.print("AP Name:WIFI_Serial");
Serial.println("Password:12345678");
Serial.flush();
delay(5000);
}
void loop() {
//串口收到数据时转发到UDP
if (Serial.available() > 0){
delay(2);
Udp.beginPacket(RemoteIP, sendUDPPort);//to wifi
while (Serial.available() > 0) {
Udp.write(Serial.read());
}
Udp.endPacket();
}
//UDP收到数据时转发到串口
int packetSize = Udp.parsePacket();
if (packetSize) {
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
Serial.write(packetBuffer,packetSize);
}
}
从机:
#include
#include
IPAddress RemoteIP(192, 168, 4, 1);
unsigned int localUDPPort = 8888; // local port to listen on
unsigned int sendUDPPort = 9999; // send port to listen on
byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
WiFiUDP Udp;
void setup() {
delay(2000);
Serial.begin(115200);
WiFi.mode(WIFI_STA);// 标准模式
WiFi.begin("WIFI_Serial", "12345678");
Udp.begin(localUDPPort);//udp 接收
Serial.flush();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println("WIFI_Serial");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
pinMode(2, OUTPUT);
digitalWrite(2,HIGH);
}
void loop() {
if (Serial.available() > 0){
Udp.beginPacket(RemoteIP, sendUDPPort);//to wifi
delay(2);
while (Serial.available() > 0) {
Udp.write(Serial.read());
}
Udp.endPacket();
}
int packetSize = Udp.parsePacket();
if (packetSize) {
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
if(packetBuffer[0] == 0x30 && packetBuffer[1] == 0x20)//重点
{
digitalWrite(2,LOW);//复位arduino
delay(5);
digitalWrite(2,HIGH);
delay(200); //必须等这么久
}
Serial.write(packetBuffer,packetSize);
}
}
其实上面两个代码就可以玩无线串口传输了(包括无线MIDI传输,只要把波特率改为31250就好了),
而 if(packetBuffer[0] == 0x30 && packetBuffer[1] == 0x20)
{
digitalWrite(2,LOW);
delay(5);
digitalWrite(2,HIGH);
delay(200);
}
这几句是为了复位arduino,因为正常情况下,下载到开发板的过程是上位机会发送两个字节0x30 0x20 ,然后arduino会回复 0x14 0x10 ………………
然后他们会聊很多东西,最后才开始传输固件。而复位arduino是在收到0x30 0x20之前的规定时间内干的,意味着复位以后规定时间内收到0x30 0x20时arduino才会回复0x14 0x10,超过时间是没有回复的。
关于ESP8266模块的下载方法:
可能是arduino IDE不能在下载那一瞬间reset这个模块的原因,在下载时需要特别注意,先把下载器连上电脑,在arduino IDE上点“下载”了以后,开始编译,在显示“上传”那一瞬间,按住轻触开关插入模块才能成功,时机的把握很重要。如果可以,尽量买配套的一键下载功能的下载器吧
请不要理解错噢,我就是在arduinoIDE下给ESP8266下载程序的。
主从机程序下载好以后,接下来就是硬件连接了,从机接arduino,主机还是插在下载器上。
关于硬件连接:reset用了2N3906这根PNP三极管,当8266的GPIO2为低电平时,他就把arduino的reset脚往GND撸。为什么不直接连接,因为8266是3.3v的,对于arduino这种5V系统来说3.3V是低电平了,意味着arduino将一直处于reset状态。
主机: 从机:
最后,总结一下,不知道为什么测试这两个模块作为无线串口传输时,并没有发现数据丢失的现象,但是用来作无线下载的时候,有30%的几率会下载错误,我也不打算去深入研究了,如果哪个高手知道原因,欢迎评论。