一个APRS气象站,基于Arduino
得到这个构想,从0开始写代码,同时和BA5AG讨论,查原版书。收获不小!
目前项目代码已经公开,参见文章底部的链接。
APRS是业余无线电的自动分组报告系统(Automatic Packet Reporting System)。HAM(业余无线电爱好者)们可以使用它,互相分享自己的信息,包括但不限于位置、天气、守候频率等等。APRS主要使用两种方式进行数据的传输:RF(射频)和Internet。RF方式下,数据包由电台发送,传输距离较短,需要使用数字中继或网关增加传输范围。Internet方式下,数据包通过TCP/IP协议传输,由各地的APRS服务器收集,可以被全球的HAM看到。
本项目通过Arduino和Ethernet Shield连接Ethernet,
从传感器收集温湿度信息,再通过路由器等设备连接互联网,连接APRS服务器,上传气象信标,同时上传位置信息,其他用户将可以从APRS网站(比如aprs.fi)或客户端获得数据,达到信息共享的目的。
以上是设备的原型,已经可以进行一些基本的功能。
去年寒假快结束的时候,BA5AG提出了这个构想,并建议合作实施,开发出一个让HAM方便的使用APRS的小设备。一开始分析难点,如下
- 读取并确认服务器回传的信息
- 读取温度信息
- 设备无需值守长期稳定地工作
了解通过TCP/IP上传数据包的过程后,大概3月初,我先写出了测试的代码。测试后发现连接上就有问题。于是查看了Ethernet库的函数使用示例,解决了问题。
接下来处理登陆的问题。一开始打算使用类似
char c = client.read()
if (c == “Verified”)
的结构,但发现client.read一次只读一个字节,只好继续想,找个简单的方法解决这个问题。偶然看到Arduino Cookbook上出现一个”client.find”的函数,查找关于这个函数的资料,没有任何内容,于是抱着试试看的态度,结果居然可以做到,在这里也向各位介绍”client.find”这个函数。
BA5AG给我提供了几个DHT21传感器(感谢),如下图
再加上配套的库,读取温湿度只需插三根线,写一行代码,非常方便!Arduino的方便之处在于,你要用时,总有人已经做好了对应的库。读取的数据可以存在不同种类的变量中,比如int和float,来达到输出整数或小数的功能。本项目中限于APRS数据包的格式,输出整数。
处理完登录服务器后,要发送数据包。APRS数据包有明确的格式。费尽周折,下载了APRS的协议手册,总算找到了明确的格式。APRS的气象信标里,没有的数据全部留为0。
以上代码搞定后上电试验,发现信标无法按一定间隔连续发送,于是换一种思路,每一次发完后断开与APRS服务器的连接。解决问题。
接着,准备连续工作6天以测试稳定性,但第三天时,设备停止工作,后来发现是电源坏了。此外还发现温度的输出有问题。于是再修改。BA5AG也开始优化代码。这里写一种强制转换变量类型的格式
(int)(1.8*t+32)
上面一行可以把1.8t+32的结果转换为整数。
加入了DHCP自动配置功能,并且恢复了串口的反馈(方便调试)。另外,BA5AG添加了更可靠的登陆、发送机制,并且把各个功能写成函数,进行模块化,为以后功能的添加提供方便。另外还加入了DHT传感器的检测。
五一过后,BA5AG提供给我了一个BMP085气压传感器,希望能加入气压功能。BMP085是一个集气压与温度校准于一体的传感器,通过I2C总线传输数据。我在Ladyada上找到了相应的库文件,实在是很方便。沿用前面的格式,我写了一个函数,功能是读取和发送气压数据。现在该功能一切正常。
APRS允许台站添加注释。我看了APRS协议手册,发现注释(comments)只要直接加在信标的内容后面就可以了。现在我给它加的是”APRSWXStation ver2.1”。
BA5AG提出了一个设想,加入串口的配置工具和一个滑动平均机制。”滑动平均”是我从来没有接触过的一个东西。简单说来,它是一种滤波的机制,间隔t连续取样,每次需要输出的时候输出的是最后n个值的平均值。这样可以起到一个滤去波动的功能。我尝试了一下,现在还是有问题的,输出无缘无故变成0。
现在学习越来越忙了。。项目被迫暂停。
我们已经开放该项目的源代码,位置是在BA5AG的博客。http://ba5ag.blog.163.com/blog/static/21050107020128513458245/
另外有关于我们这个项目的一小段介绍,也在那里,是在文章的最后一段。http://ba5ag.blog.163.com/blog/static/21050107020127142177676/