Thursday, 31 July 2014

RF24 and ATtiny, now with added debugging!

Last time's throwaway comment about the potential to use plain-old Serial.print() instead of printf() for debugging RF24 on constrained platforms turned into an itch that had to be scratched. The latest versions of RF24 and RF24Network on the GitHub have a bunch of improvements:

  • RF24Debug (and RF24NetworkDebug) now extend the non-debugging classes,
  • Their constructors take a Print object which defaults to Serial,
  • Their implementations use plain-ol' Print.print() throughout,
  • An ATtiny example, tinypingpair, has been added.
You've seen it all before, but hey!
The upshot of all this is that simply replacing the declaration of RF24 by RF24Debug in your sketch causes all sorts of debugging to be written to the serial port, even on ATtiny!

A nice side-effect is that debugging can be directed at anything which implements the Print interface, for example, anything which extends Adafruit's GFX library, i.e., their LCD screens.

Note that tinypingpair with debugging now takes up 99% of the available space on my ATtiny development board (there would be slightly more room without a bootloader). In spite of that, this work remains useful, helping beginners get started with this nice combination of radio and microcontroller.

Update: I've just verified that debugging works on the Fraunchpad with the new scheme, pace the usual caveat about timeouts.

Tuesday, 29 July 2014

RF24 with MSP430 revisited

Well it's taken longer than expected, but today the RF24 and RF24Network libraries are finally ready for use with MSP430. (Get them from GitHub as usual.)

The main improvement is to switch from using the C++-preprocessor to conditionally-compile debugging printf() statements, to explicitly configuring a debugging class into the sketch. For an example of its use, see the revamped pingpair sketch.

The advantage of this is that it allows other approaches to debugging, such as blinking LEDs (on platforms without serial ports) or using plain old Serial.print() on platforms too constrained to support printf(), such as the ATtinys. A secondary advantage is that it makes the mainline code easier to read.
MSP430 (with jumpers set for Hardware UART)

Note that the MSP430 has a fairly restricted serial port itself, at least compared to what we're used to from Arduino. A long description can be found here, but suffice it to say that, as shipped, you have to change jumpers to see anything output by Serial.print() and what you get is limited to 9600 baud. This means that the very act of debugging can cause some of the examples to timeout, so caution is required!

Linux users are rewarded with an additional set of problems to deal with, as documented here. Follow the instructions from the section "Fix a Linux kernel bug..." to rebuild the relevant kernel driver. (Note that there are some existing patches floating around the network which no longer work because this driver has seen some updates recently --- my kernel is version 3.11).

Once the driver was patched, I found that the serial port is best accessed using minicom as root. (Furthermore the first attempt at an upload usually fails for me, although the second and subsequent ones succeed.)

Finally note that a quick smoke test showed these libraries working on the Fraunchpad and Stellarpad too, although serial port issues prevented me seeing any debugging info on these targets.

Monday, 9 June 2014

Starting with the LightBlue Bean

LightBlue Beans by PunchThrough

I have just received my LightBlue Beans. I ordered them before they were made, rather like Kickstarter (they used the dreadful word preorder). These boards are pretty neat, they have Bluetooth LE, motion sensors, temperature sensors and they are Arduino compatible with a few Arduino pins exposed and a small prototyping board to add extra functionality.

One nice thing about them is that they can be programmed wirelessly over BlueTooth, a great boon if you have one in your ceiling monitoring the mouse population up there!

Here they are in their boxes, along with a couple of developer's kits, resistors, leds, spare batteries etc.

My new goodies
Clearly labeled holes
It has a battery!

Installation on a Mac

Uh, oh! I do hope the devices themselves are better than the installation problems I've had. I have followed their instructions very carefully. Download Arduino 1.0.5 (not 1.5.x), move it into Applications. Download and install the Teensyduino software. Ok, that bit went well. Now all I have to do is download the LightBlue software installation package and I'm good to go. Great! No errors! Let's see, what's next?

"Choose the LightBlue Bean board" erm. What LightBlue Bean board? Nothing there! I deleted my Arduino and reinstalled many times, no go, the LightBlue Bean installation package simply did nothing, I just cannot see LightBlue Bean under the Arduino Board menu at all.

I checked out their web site and could see that quite a few people are complaining about similar problems. Someone from PunchThrough uploaded a zip file that was supposed help but that didn't work either, it was old software and was missing drivers.

So, I had a look inside the installation package. The first thing I saw, and didn't like, was that it expects to install software in /Application/Arduino.app (it still didn't work when I put my Arduino IDE there). It was also looking for specific versions of Teensyduino so maybe I didn't have the correct version but I had the only one I could download. Anyway, I didn't follow that through, I could see what had to be done (instructions lower down in this post) so I extracted the files from the package and installed them by hand.

Once I restarted the Arduino IDE everything finally worked.

Battery Woes

Well, almost everything!  I could only see a few of my eight boards and even then it was hard to connect to them.  I checked the battery on one and it was 2.7V, I checked a few others, well under 3V. Hmm, these batteries should be 3V, time to open the new ones that came with the boards and pop them in. This is a little worrying, these are new boards with (I imagine) new batteries in them but now they are run down; this does not bode well for future projects.

At least they are fairly easy to check using the BAT and GND holes

Feeding the Beans

Now the batteries are replaced I can see the beans. I have to connect to each one with a right mouse click but how do I know which is which?

Confusing display, it would be nice if they had the MAC address
All I have is signal strength and once they are connected, they are all called Bean.

So, which is which?
Once connected, the right-click gives me a few other options including Blink LED.


I tried that with one and a box lit up momentarily, it made me smile, nice design.

Here it is!
Ok, what else? Firmware upgrade. That is advised on the site so off we go, with new batteries I feel confident in upgrading the firmware. It takes a while, it is registering increments of 0.1%, I hate doing this, I always feel I am going to brick something.

Fingers Crossed!


Ok, firmware upgrade complete, time to get to work with them tomorrow!

Installing the LightBlue files by hand (Mac OS X only)

These instructions require you to use the terminal. If you haven't used it before take extra care typing in the commands, it is easy to make mistakes and you might move files to the wrong locations.

I am going to present the commands as a complete block that can be copied and pasted. You can do them one command at a time if you feel uncomfortable or want to see what is happening with each step. Notice that the last if statement covers several lines. Personally I prefer putting the commands in a file and executing them from there. However, I have tried copying and pasting them directly into a terminal and they worked fine.

Assuming that you have downloaded the installation package into Downloads and it is called LightBlueBean-MacLoader-1.0.0.pkg and your Arduino IDE is called Arduino in /Applications, you can finish your setup with the files using the following commands (adjust the first few lines as necessary, the .app after the Arduino name is hidden in the finder).

# Assume that the pkg file is in Downloads
cd ~/Downloads
IDE=/Applications/Arduino.app
PKG="./LightBlueBean-MacLoader-1.0.0.pkg"
TMP="/tmp/LBexpanded.$$"

# No need to change the following lines
echo "Checking directories and files"
if [ ! -e "$IDE" ]; then echo "$IDE not found"; exit 1; fi
if [ ! -e "$PKG" ]; then echo "$PKG not found"; exit 1; fi

# Open the package
echo "Unpacking the package"
pkgutil --expand "$PKG" "$TMP"

# Extract all the files
echo "Extracting files"
cd "$TMP/Arduino.pkg"
gunzip < Payload | cpio -i

# Now copy the files into place
echo "Copying files"
cd "./Applications/Arduino.app/Contents/Resources/"
tar cf - Java | (cd "$IDE/Contents/Resources" && tar xf -)

echo "Checking to see if the library was installed: "
LIB="/usr/local/lib/libBean OSX Library.a"
if [ -e "$LIB" ]; then 
    echo "yes, library ok"
else 
    echo "$LIB not found"
    cp "$TMP/Arduino.pkg/usr/local/lib/libBean OSX Library.a" /tmp
fi

# Tidy up
rm -r "$TMP"


If you get a message saying /usr/local/lib/libBean OSX Library.a not found then you will need to install this by hand because it requires administrator privileges. The following command will copy it over for you and it will ask for your password in order to be able to do it (note that this command is all on one line):

sudo cp "/tmp/libBean OSX Library.a" /usr/local/lib/.

Ok, now restart the Arduino IDE and you should see the correct board type and the LightBlue-Bean examples in the examples directory.


Saturday, 7 June 2014

RF24 with Energia and MSP430

Energia pinout on TI Launchpad
The MSP430 is a considerably easier target for RF24 than the ATtiny because it actually has its own SPI interface, see above.
// Set up nRF24L01 radio on SPI bus plus pins 8 & 9
RF24 radio(P2_1,P2_0);

// sets the role of this unit in hardware.  Connect to GND to be the 'pong' receiver
// Leave open to be the 'ping' transmitter
const int role_pin = P2_2;

Making the changes above to the pingpair sketch, allows a TI Launchpad to play an equal role in this proud application via Energia.

It's still early days for this project, this is really just a proof-of-concept. Things to be done include: porting RF24Network and reducing the library footprint, the pingpair sketch comes in at just over 8000 bytes (I think that unwanted parts of the stdio library are being included). Stay tuned!

Friday, 25 April 2014

Power Consumption

Initial news on the power consumption of a TinySensor just in! A sensor was configured to transmit every 5 seconds until its battery ran down; it managed 1205331 transmissions in just under 70 days on a Duracell AAA Plus. Therefore, if configured to transmit once per minute, it would have lasted for 2 years and 4 months.

This handy page informs us that a long-life AAA Alkaline battery contains about 5kJ of energy, therefore each transmission takes about 4mJ, which equals an average power consumption of 0.8mW. At an average voltage of 3v this requires a current of about 0.26mA. Ignoring consumption by the sensors and boost converter, and estimating current drawn by the radio and processor combined at 25mA, gives a duty-cycle of 1:100, meaning it's awake for 50ms.

Voltage over time looks like this, which seems typical for Alkaline batteries; it jumps around quite a bit at the end, and the interval between transmission times increases considerably.
During normal operation there is a bit of variation between successive readings, I'm not sure whether this is just due to thermal fluctuations or an artifact of the ATtiny's ADC.

The starting battery voltage was logged at an unsurprising 1.51v but the last reading received was an astonishing 0.28v! This shows the amazing ability of the step-up voltage converter to suck every last drop of juice out of a battery. Here we have zoomed in on the end of its life:
Each transmission carries a message-ID which should be monotone increasing, within the limits of its range. The next plot shows that the TinySensor worked perfectly (or at least didn't reboot) for most of its run (and also that the message-ID is 16-bits unsigned):

However, towards the end of the battery's life, this is certainly not the case:

Here we zoom in still further on the system's behaviour at the end of the battery's life:
It is clear that the system halts for increasingly long periods of time while the battery recovers, then it manages a few hundred transmissions before collapsing again. We can look at the time interval between messages on the same time axis as the plot above:
Noticing the change in the slope of the message ID line above, let's zoom in on the corresponding part of the inter-arrival time graph:
Note that this is the time at which the message was written to the database on the Raspberry Pi, so some variation must arise from the behaviour of the Linux kernel on that box, however it's not clear what to make of the rising trend in the graph from about 03:37 onwards. (The processor used its Watchdog timer to sleep; this is clocked using its own 128kHz RC-oscillator so perhaps the falling supply voltage is causing time to dilate!)

Update:

A little experiment with an ATtiny, a blinking LED and an almost-exhausted battery disproves the hypothesis that the watchdog timer is losing time: the blink-rate remained constant until the battery died. Furthermore a voltmeter attached to the battery confirmed that it fluctuated up and down by about 10mV during the sketch's blink cycle.

Update 2:

An important lesson from this kind of experimentation is to keep as many sources of time as possible. We've seen the inter-arrival time above, but what about the transmission time as seen by the sensor? Below is a plot of the inter-transmission time, as recorded by the millisecond timer on the ATtiny:
What is really interesting about this is that all of the noise in the inter-arrival times has vanished! As far as the ATtiny is concerned, there are only 4 distinct intervals between packets: 5s (as intended), 10.45s, 15.9s and 21.4s. My best guess for this is that the radio has only succeeded in transmitting one out of every two, three and four packets respectively. Lastly, the steadily rising inter-arrival time is most likely due to radio-level retransmissions, required due to diminishing transmission signal power.

Friday, 7 February 2014

The Next Level

The PCB and TinySensor assembled!
A mere three weeks after submitting the order, Seeed Studio returned my PCBs! The picture above shows one before assembly and the other after. The assembled one is mounted on half of a sick-of-beige case, also from Seeed Studio. This was needed because the PCB chosen was 0.8mm thick and flexes easily. (Perhaps a thicker PCB wouldn't have this problem.)

Assembling a PCB is much easier than stripboard mainly because of the smaller number of holes on offer for each part. Printing the component names helps too but not having them wouldn't have mattered so much, for this project anyway. The main thing to remember is to add the parts in increasing order of height.

The board worked first time! No embarrassing green wires needed! I attribute this to the fantastic job done by Eagle's autorouter. The only change I would make in retrospect is to ensure the capacitors were the right physical size: the parts chosen from Eagle's library had a smaller footprint than the ones eventually used. The Eagle files are here.


Quick-and-dirty graphs of humidity and light from the bathroom over the past 8 hours. (Note the spike at 9am when I was showering!)

Here's the bill-of-materials. Say €20 including headers, nuts-and-bolts, AAA battery, etc.
PartQty
ATtiny84 1 3.00
14-pin DIL 1 0.15
PCB 1 4.50
Sick-of-Beige Case 0.5 1.00
DHT22 1 3.50
NRF24L01+ 1 1.00
NCP1402 3v3 1 5.00
100nF 3 0.05
10k 2 0.05
4k7 1 0.02
Total 18.27

Thursday, 16 January 2014

Taking it to the Next Level

TinySensor Board Layout
Up till now we've just used Eagle to draw schematics and, in all honesty, it's not the world's greatest drawing tool. It only really comes into its own when used as it was intended, to assist the complete design process.

What follows is a summary of my experience using Eagle to lay out the TinySensor circuit, described previously, on a sub-credit-card-sized board and generate the files required to fabricate the board. (It's based on a reading of these two useful posts.)

So, once a circuit has been designed and prototyped on breadboard/stripboard, its schematic drawn and checked for errors (using the ERC tool in Eagle), board layout can begin. Unsurprisingly this involves Eagle's "Switch to Board" menu item. A new window appears with a jumble of interconnected footprints corresponding to the components chosen in the schematic view.

The board view is connected to the schematic so that any changes to the latter are reflected in the former. The first changes might be to replace some components by equivalents with different footprints, for instance (and Eagle provides a tool for just this purpose).

However the main action of this view is layout, routing and manufacture. Layout must be done manually, by dragging individual components out of the jumble and into the white rectangle, representing the board itself. At this stage, I chose the board above (it's from Dangerous Prototypes) and deleted the white rectangle. A good rule of thumb is to place the largest parts first, although you'll probably have a good idea of the desired relative positions of the parts, having prototyped it already on stripboard.

It's good practise to try manually routing the circuit, if only to be even more amazed at what a good job the autorouter does. The undo command is your friend here: I found it useful to try autorouting slightly different placements, undoing autorouting before moving components around.

Once satisfied with the placement, print the layout on paper! This provides an essential sanity check of component footprints: use a pin for the drill holes and attempt to fit your chosen parts. Better to discover they don't fit at this stage than when the boards come back from the fabricator!

The next step is to run a Design Rules' Check. This often requires a rules' file tailored to the fabrication process itself, in this case Seeed Studio's Fusion PCB Service. Download the rules' file, load it from the DRC dialog and run the check. This thread contains descriptions of some errors found at this point.

Finally, run the CAM Processor to generate the design files for manufacturing. (For Seeed Studio, this requires its own Gerber Generator, downloadable from the second step of the Fusion PCB workflow.)
At the CAM Processor dialog, load this file from File > Open > Job... and then hit Process Job. This will generate a bunch of files, of which Seeed requires 8:

% zip seeed.zip sensors.{GTL,GBL,GTS,GBS,GTO,GBO,TXT,GML}

A sanity-check widely recommended at this stage is to load up the layer-files above using a separate tool (e.g., gerbv) to see if there is a discrepancy between it and Eagle and correct it. Once this is done, upload the zip file, pay your money and wait!