Thursday, February 13, 2014

315MHz / 433MHz RF - Part 1

A few months ago, I was scratching an itch and digging into the reliability of high frequency radio transmissions in a home environment, a practical example being 'how far away from the garage will my garage door opener reliably work?'. All of this was really a precursor to understanding what kind of throughput could you get out of a adhoc network of 433MHz transmitters scattered around the home. But we're getting ahead of the story (and about 8 blog posts of content...).


RF CONTROLLED SOCKETS

To bootstrap some experiments with 315/433MHz transmissions, I picked up a cheap set of 3x wireless remote controlled sockets from Amazon (http://goo.gl/bgNX6s) to see what people were buying in volume (and writing great reviews about).

Taking apart the transmitter and the 3 socket receivers, it clear to see why these are so inexpensive to buy. The transmitter is using a very simple chip that simply sends out hard coded messages depending on which of the multiple buttons is pressed. Circuit wise, each button simply connects 12v from the battery to the chip (via current limiting resister) and when a button is pressed, the chip wakes up from some ultra low power mode and transmits an RF message. The RF transmitter itself is a separate component, supplied current directly from the battery via a 2907A transistor (itself driven by the chip).


There is actually a great write up of a very similar chip here, schematic example shown below.



So how does it perform? Pretty well as it happens. From anywhere in my home I could turn a light on and off and walking down the street, I was also able to control them from over 70m away (although they were less reliable at this point).

It was very obvious from using these sockets however that as the distance from the socket increased, so did the length of time needed to hold down the button before the socket would respond. The most obvious hypothesis is that the transmitter just keeps sending a command as long as the key is held down and that the likelihood of a single command being correctly received by the socket diminishes as the distance between the transmitter the the receiver increases.

UNIFORM TESTING

To give a little more uniformity to the results (and because I like hacking things), I put together a quick PCB that contained a bunch of transistors that I could use to drive each of the individual buttons from a Raspberry Pi. Well, this experiment was one reason - I was also about the head to the UK for Christmas and wanted to automate a method of turning on my Christmas lights whilst I was away. So yeah, lets make a PCB.



I was super impressed with +James Neal and OSHPark for the turn around time, having seen up to a month from other vendors that outsource to China. PCBs look pretty sweet as well!



The board contains an I2C GPIO expander (16 IO pins) and a couple of ICs containing 7x darlington pairs each in each. I used DIP parts as I already had the I2C expander in my box of bits and thought I could reuse the board for general purpose expansion in the future. Schematic is over on github with the Eagle files / BOM. You can also order these PCBs over at OSHPark website, here.

I wired a small loom from the button through hole legs on the back of the board (+ GND and 12v) so I could emulate pressing the buttons via a transistor. Note, its a high side load, but I am using a NPN to switch the 12v to the input pin of the remote receiver.



Wiring this up to a Raspberry Pi looks like this:


Poor quality picture due to taking it in the middle of the night after a few beers (I was leaving the next day for the UK).

OBLIGATORY PYTHON APP

The code to control these sockets at specific times can be found over on github. Hold time for each button was fixed at .3 seconds for reliability, although 25ms actually worked in reality.

When I got back, I reversed engineering the protocol for these sockets (spoiler, it was OOK / ASK) and implemented this directly using a 315MHz RF transmitter. Then a made some very interesting graphs of the protocols reliability, but that is a write-up for another time.

Wednesday, February 12, 2014

Colored Logcat on Android

A fast hack done many moons ago to get logcat running over adb in color on an Android device. Posted for prosperity.


COLOR LOGCAT

Many moons ago, +Jeff Sharkey posted a python script to colour (or even color) in the output according to error severity etc...

And it was good.





PYTHON 2.6

At some point when hacking away for some project or other, I cross compiled python to ARM v5 (at the time, the default ARM architecture for Android) and statically linked it against gcc, I assume so it could run on a busybox based initramfs (but it was a long time ago and I was in China at the time drunk on jetlag). I fell across the code again and decided to see if it runs on my latest Android phone.

Poking at the code, it seems I stripped a lot of support libraries from the 2.7 release (the .py files) so it would take up less disk space (originally it was installed on the system disk of a development device). However, these files are pretty quick to restore if required from the python distribution.

Python was super handy when scripting power management tests i.e. grabbing the contents of /proc/stat and comparing against the behavior of the CPU governor.


CLOGCAT

Here is the code that you can extract / push to an Android device and experience the joy of color logcat over a serial cable. I quickly butchered it so it runs from /data instead of the system disk.
cd <extracted directory>
adb push clogcat-rev3 /data/local/tmp
adb shell
cd /data/local/tmp
./setup_clogcat.sh
./clogcat.sh <normal logcat parameters>

I recall in the past installing an Android terminal emulator APK and running clogcat from a shell, more to see what it did performance wise than anything. It was pretty sweet even on 2009 era SoCs (the good old days!).


RETROSPECTIVE

I suspect that adding in a little color to logcat would have been achieved much quicker by editing the src to the logcat app and inserting code that sends terminal colors commands in between the various log prints.

#define RED_ON "\033[0;31m"
#define RED_OFF WHITE_ON

#define YELLOW_ON "\033[0;33m"
#define YELLOW_OFF WHITE_ON

printf( RED_ON "All the errors!\n", RED_OFF );