极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 55403|回复: 19

再谈Arduino和DDWRT直接交互

[复制链接]
发表于 2012-12-4 01:55:38 | 显示全部楼层 |阅读模式
本帖最后由 cosailer 于 2012-12-4 19:03 编辑

这两天在做一个已经做烂的在线的温度发布系统。就是Arduino采集数据,然后发布到网页上去。很多的方案都是使用以太网的shield连路由,但是我没有shield,所以参考了国内外一些网站,最终做成了现在的这个方案。

简单来说,就是Arduino通过串口直接将数据传给路由器,路由器端运行一个小程序再把数据传给网页服务器。

下面解释几个问题:

1,路由器怎么选?
一般选择能运行开源固件的openWRT或DDWRT的路由,当然,本身要有(或者能引出)串口或者USB接口。我选的是DDWRT,觉得更方便,原因后面再详细说。

2,Arduino跟路由串口怎么连?
一般有2种吧。第一种是直接TTL对TTL,这个最好搞定,但是你要把路由器的TTL事先引出来,还有一个问题就是一般这种带登录的TTL在由启动的时候会输出大量启动记录,如果你打算控制Arduino的话要小心了,自定义通讯协议的时候要能避开这些信息,防止误触发。

第二种是借助一个TTL转USB的适配器,通过路由的USB口连接,很多Arduino都自带TTL转USB芯片,没有的话另外找一个。这种稍微麻烦一点,因为不是所有的适配器都行,要先选好驱动再找适配器。不过现在openWRT和DDWRT两个驱动都挺全的,问题也不大。

3,路由端怎么运行自制小程序?
这个是我想说的重点。一般想编译路由器程序要在PC上面搭建交叉编译环境。然后编译完成以后再拷贝回路由器测试。我选择DDWRT的原因是DD可以装GCC,直接在路由器上编译C程序,软件包是:buildroot_4.1.1-13_mipsel.ipk (39MB),目前GCC版本是4.1.1。编译了之后就可以直接运行了,很方便。openWRT我没有找到可以直接装的GCC。当然编译的话只适合编译小程序,大程序还得用PC。

4,小程序怎么把数据传给网页服务器?
方法应该很多吧。我暂时只想到2种。第一种是小程序把读到的数据写到文件里面,然后网页服务器直接读取文件。如果要这样弄,最好把文件放到 /tmp下吧。因为对于DDWRT来说/tmp在RAM里,频繁读写文件不伤Flash。

第二种是通过socket来发布,网页服务器那边用JS,JSP,PHP来读相应端口,从而获取数据。


然后说一说我的方案:

我的Arduino MEGA(兼容版,TTL转USB用的是FT232BM芯片)。上面连了2个传感器,一个是GL5528光敏电阻,还有一个是DHT11温湿度传感器(代码参考Arduino.cn)。

我的路由器是Asus WL-500G Premium v2,运行lighttpd和PHP。Arduino直接插到路由USB接口。路由器上运行程序sensor,接收从Arduino传过来的数据帧,帧格式定义都在附件的代码里面,代码写的很烂,看看差不多就行了。然后sensor把数据写到/tmp/sensorData.txt文件里(这里我把数据以字符串的形式写到文件里了,本来想直接按照相应数据类型存储的,但是在PHP处理字节流的方面遇到点问题),PHP直接读取这个文件再显示到网页上。小程序的编译命令是:gcc sensor.c -static -s -o sensor。我的路由每天早上4:30重启,所以把小程序加到自动启动列表里面了。

最后是网页的截图,因为PHP没学好,不会画图像,之后还可以直接绘制气温图。



结束以后可以通过DDNS发布到外网去,这样不管在哪里都可以看到温度了。如果不方便DDNS的话可以用Yeelink。
欢迎交流经验。




更新2:对于把传感器信息信息送到网页这点,我还有2个方法要补充一下,第一个就是5楼讲的方法,直接用cat直接打印,优点是不不要编译小程序了,但是这样做对数据做处理要全部交给网页服务器,如果数据一多,比如显示一个礼拜的平均温度,处理起来会不会麻烦?。如果自己写小程序,完全可以每天算好平均温度什么的。如果想法再多一点,还可以跟路由本地的mysql交互(DDWRT可以装mysql)。

第二个方法其实是我最先用的方法,就是用PHP直接读取路由端的串口,代码如下:
[pre lang="PHP" line="1"]<?php
ini_set('display_errors', 'On');

//exec("mode /dev/usb/tts/0: BAUD=9600 PARITY=N data=8 stop=1 xon=off"); //调波特率,如果是默认的9600可以不要

$fp = fopen("/dev/usb/tts/0", "r");

$read = fread($fp, 1000);
echo $read."</br>";

fclose($fp);

?>[/code]

我遇到的问题就是貌似只能读字符串形式的字节数据,如果是数据帧形式的字节数据,不知道怎么提取各个数据。希望有高人相助。然后这个缺点也是不能处理数据,但是这种方法对于单次查询Arduino串口非常方便。

更新1:之前Arduino的代码发错了,现在改好了


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2012-12-4 08:48:44 | 显示全部楼层
不错的方案,买了DB120才50不到,比wifi模块便宜多了(就是体积巨大),下次刷一个DDWRT
回复 支持 反对

使用道具 举报

发表于 2012-12-4 13:03:12 | 显示全部楼层
这个题目永远做不烂的啊,呵呵,方法越来越多层出不穷啊
回复 支持 反对

使用道具 举报

发表于 2012-12-4 13:32:23 | 显示全部楼层
强大{:soso_e113:}
回复 支持 反对

使用道具 举报

发表于 2012-12-4 14:49:59 | 显示全部楼层
不错。我在树莓派下也是采用了类似的方案。Arduino自带的usb2ttl 或者额外的ttl。
不过我是用的系统自带的Shell写的。
可以直接用  cat 查询语句.txt>/dev/ttyUSB0 | cat /dev/ttyUSB0 > /home/a/a.txt
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-12-4 16:39:30 | 显示全部楼层
Damn_intuition 发表于 2012-12-4 14:49
不错。我在树莓派下也是采用了类似的方案。Arduino自带的usb2ttl 或者额外的ttl。
不过我是用的系统自带的 ...

这个主意好,以后单次查询就用这个了
回复 支持 反对

使用道具 举报

发表于 2012-12-4 17:53:33 | 显示全部楼层
能具体写下路由端怎么做么
回复 支持 反对

使用道具 举报

发表于 2012-12-4 23:48:49 | 显示全部楼层
楼主,我用的方案是openwrt+arduino,路由器用的是703n, 直接用arduino自带的usb线连到703n的USB口上面,用usb转串口的方式进行通信。
程序方案使用c写串口程序,测试了能读写,但是读取的数据比较乱,没写好....不知道楼主有没有例子。
c写完以后,用mips-gcc进行交叉编译,然后和arduino通信。
具体的刷机器方法和usb通信部分的信息可以看看我的blog:
stevenyanzhi.blog.163.com

里面我自己按照网上别人的教程编译了个703N带arduino的usb驱动的固件。刷进去以后直接703N路由器能够识别arduino的驱动。我的是arduino uno。
回复 支持 反对

使用道具 举报

发表于 2012-12-4 23:53:11 | 显示全部楼层
蓝色布鲁斯 发表于 2012-12-4 23:48
楼主,我用的方案是openwrt+arduino,路由器用的是703n, 直接用arduino自带的usb线连到703n的USB口上面,用 ...

试试lua 脚本。会有惊喜的
回复 支持 反对

使用道具 举报

发表于 2012-12-4 23:55:47 | 显示全部楼层
更新一下,找了下具体的链接:
703N的固件,带arduino驱动:
http://stevenyanzhi.blog.163.com ... 932012929101910473/

还有就是我测试的linux下面的c 串口编程以及wifi连接路由器以后,PC通过java和路由器进行通信:
http://stevenyanzhi.blog.163.com ... 249320129291146781/

另外里面也有raspberry pi和arduino通信的例子,RPI上面装了arduino的usb转串口驱动就能用。估计linux都能这么搞。

我是用来想弄wifi小车的,但是串口通信部分有问题,能读写,但是数据有点乱,还没研究明白,弄的小车卡在一半....
我的方案是PC<->703N<->arduino,其中pc用java socket,703n用c,arduino用串口。

楼主要有串口通信的例子程序是否可以给一个参考咯~~
回复 支持 反对

使用道具 举报

发表于 2012-12-31 16:24:29 | 显示全部楼层
有时间试试发布温度数据到Yeelink上面。
http://www.yeelink.net/explore
这个做的人不少,方法也是层出不穷啊
回复 支持 反对

使用道具 举报

发表于 2013-1-6 13:51:40 | 显示全部楼层
我使用OpenWRT+Lua+Arduino。OpenWRT自带了Lua,不用安装php,适合不足够记忆体的无线路由器。

以下的实例展示Lua可以读取,也可以写入
http://ediy.com.my/index.php/pro ... ter-home-automation
回复 支持 反对

使用道具 举报

发表于 2013-1-6 21:55:05 | 显示全部楼层
本帖最后由 gaoshine 于 2013-1-6 21:57 编辑

另一种思路供大家参考:采用成熟的工具ser2net,避免在&#160;OpenWrt编程
OpenWrt与Arduino的USB直接通信方法有2:  ttl-ttl,还有usb-》usb。我喜欢第二种。


为了让数据更友好可爱,把它转成端口。串口转端口ser2net2.7-2
—-接着就是连接了

现在arduino写段测试代码:

const int ledPin=13;

int inVal=0;

void setup(void)

{

pinMode(ledPin,OUTPUT);

Serial.begin(9600);

}

void loop(void)

{

if (Serial.available() >; 0) {

// get incoming byte:

inVal = Serial.read();

Serial.flush();

Serial.println(inVal);

if (inVal == ’1′)

digitalWrite(ledPin,HIGH);

else if(inVal == ’0′)

digitalWrite(ledPin,LOW);

}

}

代码写的不简洁,不熟悉呗。基本意思是串口得到0就灭灯(板子上自带的一个灯),1就开灯。

接着在openwrt的tty里

ser2net -C “3001:raw:600:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS”

绑定端口进去,如果结束端口呢(我用的killall ser2net),netstat -an查看端口,ps查看进程。大概就这些啦。

然后回到来开始控制啦,telnet 192.168.1.1 3001,里面是你的路由器ip,然后就可以在终端里控制亮和灭了。

—灭灯,因为在终端里输了0


—开灯,因为在终端里输了1



回复 支持 反对

使用道具 举报

发表于 2013-1-7 19:51:46 | 显示全部楼层
gaoshine 发表于 2013-1-6 21:55
另一种思路供大家参考:采用成熟的工具ser2net,避免在伀瀀攀渀圀爀琀编程
OpenWrt与Arduino的USB直接通信 ...

usb-》usb是指什么呢?还是usb-》Serial?
ser2net我也使用过,好像不能使用Javascript来读取。请问你会解决吗?

这是我使用ser2net和socat来控制Arduino的网页
http://ediy.com.my/index.php/blo ... -tl-wr1043nd-router

Google中文翻译
http://translate.google.com/tran ... -tl-wr1043nd-router
回复 支持 反对

使用道具 举报

发表于 2013-1-8 17:46:08 | 显示全部楼层
smching 发表于 2013-1-7 19:51
usb-》usb是指什么呢?还是usb-》Serial?
ser2net我也使用过,好像不能使用Javascript来读取。请问你会 ...

usb ->usb 就是 Arduino的USB口插到路由器的USB口上。
ser2net可以简单理解成路由器把和Arduino的Serial通讯透传成TCP的协议。
也就是您可以通过网络访问路由器IP的端口变成和Arduino的Serial通讯。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-26 17:13 , Processed in 0.060927 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表