概述
一 设置WIFI 串口模块:
首先,要准备两个Wifi串口透传模块(比如ESP-01S),设置让它俩处在同一AP,然后设置它们的固定IP,不要用DHCP。接下来,将二者设置为串口透传模式,建立双向UDP连接,这样,二者之间就成了WIFI双向透传模式。(所有设置均要用XXX_DEF这类)
二 硬件连接:
选择其中一个串口透传模块A用来与Uno连接,模块的TX对Uno的RX,模块的RX对Uno的TX,模块的GND和3.3V可以连接UNO的对应接口,也可以由外部电源供电。
另一个串口透传模块B通过与USB-TTL模块连接后,成为PC的COM输出端。具体连接就是透传模块的RX和TX与USB-TTL模块的TX和RX交叉连接,电源同样可以使用USB-TTL的GND和3.3V或者外部供电。(这里其实也可以用带串口芯片CH340或者cp2102的开发板替代,更加紧凑,少用了一个转接模块)
三 软件部分:
我测试了Arduino的几种RESET方式,发现纯软件方式很难触发reboot,只有由Uno的RESETpin接口触发或者直接按Reset按钮(按按钮这种方式完全不考虑)。其它方式多多少少都跟jump 0 差不多,相当于将板子的客户程序重新运行一遍,但是不会调用bootloader。而上传程序需要bootloader运行后才会执行。(如果您有直接软件触发bootloader的方法,欢迎分享)
这样一来,就只有使用连线的方法,用GPIO的pin去控制Uno的RESETpin的电平(时序是低电平+高电平)。
Arduino端程序如下
//#include <avr/wdt.h>
String comdata = "";//缓存字符串
int ledL = 13;
int RSPin = 2;
int flag = 1;
void(* resetFunc) (void) = 0; //declare reset function @ address 0
void setup() {
pinMode(ledL, OUTPUT);
Serial.begin(115200);//打开串口波特率115200
//pinMode(RSPin, OUTPUT); //不能在这里预先操作,否则循环reset
//digitalWrite(RSPin, HIGH);
}
void loop() {
if (flag == 1) { //闪灯表示程序开始运行
Splash(10, 500, 50);
flag = 0;
}
if (Serial.available() > 0) {//判读是否串口有数据
String comdata = "";//缓存清零
while (Serial.available() > 0) {//循环串口是否有数据
comdata += char(Serial.read());//叠加数据到comdata
delay(2);//延时等待响应
}
if (comdata.length() > 0) {//如果comdata有数据
//Serial.println(comdata);//打印comdata数据
if (comdata == String("SERIAL_RESET")) {
//resetFunc(); //call reset, but cannot invoke hardware reboot(no bootloader)
//wdt_enable(WDTO_15MS); //this also only call a non-bootloader reset
pinMode(RSPin, OUTPUT);
digitalWrite(RSPin, LOW);
delay(10);
digitalWrite(RSPin, HIGH);
}
}
}
}
void Splash(int rept, int onTime, int interval) //闪耀pin13的联动灯
{
int interv = interval < 0 ? 10 : interval;
for (int i = 0; i < rept; i++)
{
digitalWrite(ledL, HIGH);
delay(interv);
digitalWrite(ledL, LOW);
delay(interv);
}
delay(interv);
}
在IDE里面,编译这个文件,然后导出二进制文件。
写一个python脚本,通过发送指定字符串到com口触发reset。
import serial
import sys
Port = sys.argv[1]
print('Using com port:%s' %Port)
baudrate = 115200 # 设置波特率
timeout = 0
ser = serial.Serial(Port, baudrate,
parity=serial.PARITY_NONE,
bytesize=serial.EIGHTBITS,
stopbits=serial.STOPBITS_ONE, # number of stopbits
timeout=None, # set a timeout value, None for waiting forever
xonxoff=0, # enable software flow control
rtscts=0, # enable RTS/CTS flow control
interCharTimeout=None # Inter-character timeout, None to disable
)
if ser.isOpen():
print("open success")
else:
print("open failed")
#try:
ser.write('SERIAL_RESET'.encode('utf-8'))
ser.flush()
ser.close()
print('RESET signal has been sent succefully!')
# except:
# if ser != None:
# ser.close()
接下来,要解决的是串口命令发送与上传指令的时序问题。
python3 ./reset.py '/dev/tty.SLAB_USBtoUART'&avrdude -C/Users/user/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -carduino -P/dev/tty.SLAB_USBtoUART -b115200 -D -Uflash:w:/Users/user/Documents/Arduino/ArduinoPrjs/SerialReset/SerialReset.ino.standard.hex
注意:上面是等同于两个命令并行运行,连接符不能用;,否则不能成功,用&才行(第一个命令进入后台然后马上执行第二个),甚至可以颠倒这两个命令的顺序(颠倒顺序后似乎成功率会下降)
主要实现和建立的机制:WIFI双向透传;通过串口自动上传(更新)Arduino程序无需再人工干预。
如果你有RS232的无线透传模块,应该可以直接用Arduino IDE 或者avrdude上传,但我没有试过。RS232支持了DTR 和 RTS信号,这两个就是IDE直连时可以让板子重启的信号线。实际连接时还更麻烦些,因为需要占用板子的USB接口,且还需要先连一个USB转RS232来连接板子与RS232无线透传模块,逻辑上相当于多做了一次必要无用功,因为USB进入到板子里面最后又会被转换成RS232信号。
最后
以上就是俊秀期待为你收集整理的通过WIFI双向透传串口向Arduino Uno 无线上传(更新)程序的全部内容,希望文章能够帮你解决通过WIFI双向透传串口向Arduino Uno 无线上传(更新)程序所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复