在车间部署了十几个网络版的温湿度采集器(基于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”。如图所示:
(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指令。详见的代码见附件。
8、附件下载