Tuesday, January 4, 2011

AudioStreamer - CeltStreamer

I must admit that chosing the Edimax 6104 router wasn't the easiest path to OpenWRT hacking, but it was very rewarding in terms of the learning curve. After some minor tweaking I decided to dig deeper into the wonders of Embedded micro-architectures. One of the uses of the Openwrt system was to be able to distribute audio without the hassle of audio cables. But what about capturing and broadcasting audio directly from my router or similar machine ?

So a new project was born : audiostreamer

Objective : find the smallest, cheapest machine to capture 22Khz audio and broadcast it to a corresponding receiver. Budget : 50 €

After reading some forums, I stumbled on the Bifferboard (S3282@150Mhz, 8MB ROM, 32MB RAM).
It has sufficient space for all my programming needs and measures only 68x28x21 mm ! That's tiny !

  • Bifferboard : 35 GBP
  • Housing : 5 GBP
  • USB Soundcard : 1.8 GBP

Streaming PCM from and to the device didn't pose any major difficulty :
[Streaming] arecord -D plughw:0,0 -r 48000 -c 2 -f S16_LE | nc 192.168.2.10 6666
[Receiving] nc 192.168.2.9 6666 | aplay -D plughw:0,0

Playing some MP3 audio worked too, using mpc and mpd, combined with a shoutcast-server on my desktop.

The next hurdle was to produce compressed audio in order to minimize bandwidth use ...

  • LAME : failed (lack of FPU on the S3282)
  • IVORBIS (Fixed Point version of Vorbis) : failed

Then I did some research and found another Fixed Point codec .... CELT - Constrained Energy Lapped Transform.

After some fiddling with the 'tools' sources, I managed to compile the celtencoder and celtdecoder.
They work fine ... but they don't seem to be compatible with the aplay / arecord PCM netcatting.
The result is a working encoding/decoding environment, but unfortunately not realtime !

Nicely tucked away in the GIT-repository, I found the celtclient demo and tried to implement it.
I stripped out the streaming part and reduced the main loop to the following activities :



do { alsa_read(pcm1) ; celt_encode(pcm1,celt) ; celt_decode(celt,pcm2) ; alsa_write(pcm2) } loop

Massive overruns and underruns in the ALSA part ....

My Bifferboard running at approximately 50 BogoMips could only handle following testcase @ 8Khz, mono:
do { alsa_read(pcm) ; celt_encode(pcm,celt) ; alsa_write(pcm) } loop

In order to estimate the needed processing power for celt_encode@22Khz I ported the sources to my Edimax environment.
The Adm5120 runs at approx 170BogoMips and should at least on paper provide 3x more processing power.

After implementing the ALSA-sound subsystem I couldn't get the USB Audio to play a standard WAV-file without being completely choppy and slowed down.
Turns out the USB-host on the ADM5120 isn't completely following the USB specifications and is lacking Isochronuous transfer mode.

I'm left no other solution than to get myself a different board to test on. I'm not sure if I would strip down one of the latest routers (TP-LINK 1043 - Atheros AR9132@400Mhz - 266 BogoMips) or maybe look at one of the Marvel boards.

Tuesday, December 7, 2010

REST interface

So, what have I been doing in the meanwhile ?
I wasn't too happy with the granularity of the Pachube solution and the lack of data access made me look for a better solution.
So I started with setting up a couple of tables on my MySQL webserver. Added a REST interface to it and implemented the corresponding code to my datalogger on my Edimax OpenWRT machine.

Finally I implemented the pGraph library from SourceForge and provided some basic graphs for daily use :
  • Solar Production
  • Solar Efficiency
  • Solar Production Today vs Yesterday
  • Power Consumption (last 24h)
  • Power Consumption (Day/Night per day)
  • Solar Production vs Power Consumption

Thursday, June 24, 2010

Patching The World

I'm too lazy to setup my own MySQL database on my webserver, so I looked at my other options and I stumbled upon Pachube.The idea to be able to upload data to a central repository, view the data, connect to it and if needed download the data, looked very tempting.

After setting up an account on Pachube, I downloaded the Pachulib OpenWRT library and installed it on my machine. It's basically allowing a manual feed using CSV data to your Pachulib account.

I decided to aggregate information into my SolarPower feed every 60s and I upload :
  • Instantaneous Power : last Power measured in Wh
  • Average Power (60s) : average Power over last 60s in Wh
  • Total Power : Total Power production since dawn in kWh
  • Efficiency : W/Wp efficiency in %
I'm quite happy with the results. I can access my data remotely without setting up my own hosting and share data to everybody interested; The only downside is the archiving in 15 minutes granularity. I sometimes need a more precise tracking of production.

Tuesday, June 22, 2010

Solar Tweet

I was reading Jannich Brendle's article  about how to setup a Twitter client on a  OpenWRT machine, but it appears Twitter is going to disable basic authentication by the end of June, making the whole experience just a shortterm experiment.

No panic, a blogger called Lostman was so friendly to provide a script to perform the oAuth authorisation routine on OpenWRT.  In my particular setup I had to install curl, iconv and openssl-utils to get things working on the Kamikaze 08.09.02 r188801 machine. And oh, I had to activate the curl-http option instead of the wget. I first wanted to test it on my Ubuntu machine but the OpenWRT won't run on a different machine. I couldn't figure out where the commands or options differ between the two machine, so be warned : don't run this script on the host machine. Just run it on your target machine !

And tada! A few manual tweets from my machine and then I automated by calling the script through a 'system' call in my logger.

Monday, June 21, 2010

Kamikaze or Backfire ?

After a lot of reading I decided to give Kamikaze a go on the Infineon ADM5120P machine. With only 2MB NOR Flash, there's not enough room to run a decent set of tools without having to use swap-space, hurting performance quite a lot. So, after installing my Ubuntu virtual machine, and setting up the Kamikaze 8.09.02 SDK environment, I modified the kernel configuration in order to mount a USB-drive as rootfs. I know, I know, I'll lose one valuable USB port and I'll have to use an thumbdrive on the outside of my router, but I don't care. I'm happy to be able to remove the USB-drive from the router and to mount it on my Ubuntu-box !

Anyhow, after having run the 'make kernel_menuconfig" and the 'make menuconfig', I was able to flash the router with my own base-kernel image and after mounting the USB-rootfs, I was able to install more packages like the GPIO-modules. It took me a while to figure out which versions to download and to compile. So never mix old sources or packages with more recent ones. Also beware for the precompiled packages in the Openwrt repository, if you're using a non-standard router like the ADM5120P-based Edimax or Sweex or Omnima boards, you're out of luck cause none of the images will work on your board, an neither of the corresponding packages will load.

After verifying the correct loading of GPIO, GPIO_proxy and GPIO_Leds package we're all set !

Oh yes, the ntp-package was usefull to keep the machine correctly in sync with my ISP's timeserver. And adding the dns-servers in the resolv.conf file allowed correct resolution of internet addresses. :-)

Sunday, June 20, 2010

Edimax BR-6104-KP as Solar Logger

I finally decided to start monitoring my Solar installation. From a 'Green' perspective, it doesn't make sense to install PV-panels on the roof, trying to save some energy and then spend ridiculous amounts of money on 'gadgets' like a monitoring console. After looking into some professional hard & software, I finally bought myself a low-cost router.

At a clearance sale, I picked up an Edimax BR-6104-KP router at 29€. It's not a perfect machine, but with 2 USB ports, 5x 10/100 Mb Ethernet,1 serial port, 2MB Flash and 16MB RAM and lots of GPIO to interface to my projects, price/quality is unbeatable.

First thing I did after buying this router, was to strip it from its housing, prepare the serialport for flashing my own firmware and connect some input to the GPIO.