Lots of stuff and my random thoughts

Welcome to Andy Brown's personal website - thebmwz3.co.uk
Thursday, April 24 2014

Arduino - Cheap wifi connectivity

General
Building a cheap ethernet connection for my Arduino. I needed to relay data from my Arduino back to my home server. The location
makes wired prohibitive, but I also don't have CAT5 cabled to the location I had the Arduino in. I then looked at the various
shields available, the Ethernet shield wasn't too expensive at around £20, but this would mean wiring, and the location in the kitchen
was particularly difficult to get wiring to.
 
I then looked at wifi shields, these came in at around £85 and way too expensive for just a little hobby project, the in-between options
of using Zigbee interfaces, which is a slightly cheaper option, but I was concerned about the distance and complexity of setting
this up with my server.
 
I therefore started posting to mailing lists and trying to find a way of doing a wifi-bridge cheap, or USB over wifi. All I needed was
to get the usb/serial data out from my Arduino to my server so that I could graph it, monitor it, etc.
A kind chap on an ISP mailing list brought forward the TP-Link TL-WR703N suggesting that this device can be flashed with OpenWRT
and then act as a wifi bridge. This sounded interesting, and you can get them on eBay for less than £15 inc delivery. This was sounding
good.
 
The TP-Link TL-WR703N has 3 physical ports (RJ45, USB host and power (via a micro-usb port)). It also has integrated WIFI. So my
idea was to connect the wifi up to my house wifi, then use the USB port to monitor the serial output from Arduino. Ideal!
 
The TL-WR703N arrived, all in its chinese writing and unfortunately its chinese web admin interface. Luckily for me, the OpenWRT
site for this device was very detailed and told me exactly what to click to upload OpenWRT.
Then OpenWRT site at http://wiki.openwrt.org/toh/tp-link/tl-wr703n Had all the details to flash it, very simple and quick.
Once flashed with OpenWRT a little more tweaking was needed. I've generally not done much with OpenWRT in the past, I stick to DDWRT
which has a nice web-gui, so OpenWRT involved SSH'ing to the unit and setting the rules correctly for what I wanted.
 
I did a bit of reading on the OpenWRT recipies site on what I needed which was to be a client on a mixed WPA2-Personal AES 
encrypted wifi with MAC protection.
The basic method is follow the outline of a MASQUERADE CLIENT on OpenWRT and adjust accordingly. So my /etc/config/network looked like:
 
config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'
 
config interface 'lan'
option ifname 'eth0'
option type 'bridge'
option proto 'static'
option ipaddr '192.168.1.1'
option netmask '255.255.255.0'
 
config interface 'wan'
option ifname 'wlan0'
option proto 'dhcp'
 
(Note that I left LAN on the 192.168.1.1 setup, this meant that if the WAN or dhcp failed I can plug into it and still admin the thing)
 
/etc/config/wireless was a bit more tricky:
 
config wifi-device 'radio0'
option type 'mac80211'
option channel '1'
option macaddr '8c:21:0a:d8:7b:57'
option hwmode '11ng'
option htmode 'HT20'
list ht_capab 'SHORT-GI-20'
list ht_capab 'SHORT-GI-40'
list ht_capab 'RX-STBC1'
list ht_capab 'DSSS_CCK-40'
 
config wifi-iface
option device 'radio0'
option mode 'sta'
option ssid 'MYSSID'
option encryption 'psk2+ccmp'
option key 'MYPSKPASSWORD'
 
To find these settings you issue 'iwlist scan' and look for your SSID and the other settings. So in my case I set the channel of 1.
The encryption of psk2+ccmp (This refers to wpa2 with AES encryption). After doing that you can then do 'ifup wan' and 'wifi' which
should then get things working. Except in my case it didn't. I checked, I had the MAC address in my wifi router, all looked fine but it
wouldn't join the WIFI. The settings in OpenWRT are a little hazy so I assumed this was the problem and spent a while here, but in the end
I found turning MAC protection off temporarily on my DDWRT allowed it to connect, enabled it, saved and it all works each time now,
so unsure if I hit a bug in my DDWRT on my wifi access point or something, but for future, debugging with MAC protection turned off
is a lot easier!
 
Now I had it connected I needed to get info from the Arduino over the USB port. I plugged it in hoping for the /dev/ttyACM0 to be
created, but no luck. I got the USB insert message:
[   10.020000] usb 1-1: new full-speed USB device number 2 using ehci-platform
So it looks like the kernel driver doesn't exist.
Luckily the OpenWRT group have a packaging system that includes a lot of drivers and add-ons, so using the package management to install:
 
opkg update
opkg install kmod-usb-acm
 
Reboot, and when I plugin the arduino, success, I see:
[   10.020000] usb 1-1: new full-speed USB device number 2 using ehci-platform
[   10.160000] usbcore: registered new interface driver cdc_acm
[   10.160000] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[   10.210000] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
 
And the /dev/ttyACM0 is there. Last trick is how to get a couple of lines of data from the serial connection and SSH/SCP it up
to my server. This proved a little tricky, as first of all getting just a couple of lines of data from a constantly flowing serial
terminal, then the scp function itself.
 
To get just a couple of lines of serial I firstly tried the stty trick "stty -F /dev/ttyACM0 9600 -echo -onlcr time 50 min 0" and then
cat /dev/ttyACM0 which will read data for a specific amount of time. This was very unreliable and often hung the /dev/ACM0 interface.
So I looked to alternatives. I then tried a constant/background "cat /dev/ttyACM0 > /tmp/serial.log", periodically from cron reading
it and zero'ing it. Problem here was the filesize growing and causing the device to hang due to the limited ram on the device. Also when
/dev/null'ing the /tmp/serial.log the cat then failed and a kill/hup to the cat caused the ACM0 to hang again! So no good there.
Finally I tried "head -n 12 /dev/ttyACM0 > /tmp/arduino.log" So this output the last 12 lines from the serial console to a file.
(Overwriting the file each time keeps it low filesize). Then I can parse this for the info I need, and then scp it over. Except scp
doesn't exist as the ssh is just dropbear! So again to opkg and install the ssh client tools so I get the scp binary. Generate an
id_rsa key and then I can scp my output over: "scp -i /etc/dropbear/id_rsa /tmp/arduino.log root@192.168.xx.xx:/tmp"
Success! I can now parse this with my graphing tools.
 
Enjoy, and thank you to the TP-Link TL-WR703N for a cheap and nifty solution! (PS: Got any direct questions? See me on twitter: www.twitter.com/andyb2000 )

Trackback

Trackback URL for this entry: http://www.thebmwz3.co.uk/trackback.php?id=20120611144749730

Here's what others have to say about 'Arduino - Cheap wifi connectivity':

Linkduino from Blog J.Schweiss
Linkduino [read more]
Tracked on Sunday, January 19 2014

Arduino - Cheap wifi connectivity | 6 comments | Create New Account
The following comments are owned by whomever posted them. This site is not responsible for what they say.
Arduino - Cheap wifi connectivity
Authored by: steftech on Wednesday, June 13 2012

Hello,

I've also tryed to read serial output from my arduino using WR703N from a C program. But I'm experiencing problem every day, ttyACM0 hang, I need to disconnect/reconnect arduino to get it work .Did you experience that with your last solution ? 

To send message to database I use a couple of program I've wrote, client/server style . You can have n arduino communicating to 1 server and n clients compiling data as you want (with plugins).

 I've tried to add links to code, but Spam detector don't like them ...

Arduino - Cheap wifi connectivity
Authored by: Admin on Wednesday, June 13 2012

 Hi Steftech,

I did have that problem at first, whenever I used the constant CAT or constantly kept the serial port open after a while (I didn't time it) it just stopped receiving data and exactly as you said either had to plug/unplug (rmmod and insmod it back didn't cut it), but switching to just occasionally grabbing the output when I needed it seemed to solve this, maybe you can switch to this in your code and just grab the data periodically and open the serial at that point, then close it back again for the sleep/loop?

 

---
Andy Brown
Arduino - Cheap wifi connectivity
Authored by: steftech on Wednesday, June 13 2012

Thank for your reply,  I will try this, there is 30s delay beetween arduino sending data, so no problem for closing/opening port beetween two of those.

If not I think about rebooting WR703N from cron ... but it's ugly ...

 

 

Arduino - Cheap wifi connectivity
Authored by: steftech on Saturday, June 16 2012

What if the power from WR703N isn't stable ?

I've added to arduino a power source (a 6V), and it's still running with no problem for 12h (it's a bit short to conclude)

Is that the solution ? Future will tell us ^^

Arduino - Cheap wifi connectivity
Authored by: steftech on Thursday, June 21 2012

Just to say that the adding of a power source don't change anything :(. No stability added.

I will try your idea of closing/opening ttyACM another time.

Arduino - Cheap wifi connectivity
Authored by: Anonymous on Monday, July 30 2012

Thanks for great instructions about secure WiFi. I am also a fan of WR7803N and wrote an instructable:
How-to-set-up-OpenWRT-on-a-pocket-router-WR703N

With Arduino I experience that serial connection crashes in ca one day, if data are sent once per second, for example, when sending DS18B20 sensor data.
If I send data every 50 ms, like from electricity meter sensor, then connection does not crash.

Connection does not crash, if reset is issued every time a new line is read, but then Arduino can not be used for counting. (To disable reset I usually conect Arduino reset to 3.3V)

I have made some work around  to improve reliability. First word in the sent line is a key word,  for example, "databegin".
When line is received and contains this word then information is usually reliable, if not then repeat reading. I did not bother implementing checksum.
I save line to file in /tmp.

Arduino also sends in every line seconds from its' start.  Every 5 min the file containing last Arduino line is checked. And if the seconds are the
same as 5 min ago, it means connection has crashed and script  issues command reboot. As it does not happen often, I think rebooting is fine.

Last year I did checking reverse way: if Arduino did not receive a command in 10 min, it activated relay removing power from router.