我是靠谱客的博主 俊秀期待,最近开发中收集的这篇文章主要介绍通过WIFI双向透传串口向Arduino Uno 无线上传(更新)程序,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一 设置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 无线上传(更新)程序所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部