Tuesday, May 20, 2014

Arrggh.

Infinite Loop: A situation where in searching for the answer to something your own blog is on the first page of Google results, which results in you reading your own posts, and then searching again… and so on.. and so on…

So to break the cycle I'm posting this here:

Enabling the third (but second external) I2C bus on the Beaglebone Black (and shouts out to the original poster, Fortune Datko):

http://datko.net/2013/11/03/bbb_i2c/

That won't quite work, though, at least on on mine.

The command line should be this (with a '9', not an '8'):

echo BB-I2C1 > /sys/devices/bone_capemgr.9/slots

And for kicks, test it out:

i2cdetect -r -y 2

That is all.

Sunday, May 18, 2014

New Beaglebone Black I/O Library

Up to this point I've been testing hwio with Go on the Beaglebone black, which is ok, and seems to work.

Then a couple of days ago I got Go Newsletter #23, which somehow led me to a link to EMBD, an alternative that sounded similar, so I thought it would be worth a look; the examples sure seem simple!

Installation - because this is in Go - is a breeze. Just 'go get' the package from github and all is well. It also plays totally nice with my cross-compile environment from Dave Cheney's post, so that's nifty. With the BBB on wireless I simply do a 'go-linux-arm build whatevs.go' on my Mac, and then scp the binary 'whatevs' to /home/root/go on the BBB for testing. Nice.

First up, the normal blink test. Making a random guess that the LED names were 'USR' and not 'LED', it seemed to blink an LED just fine. This is the simpleblinker.go sample, with edits:

// +build ignore
// Simple LED blinker, works OOTB on a RPi. However, it does not clean up
// after itself. So might leave the LED On. The RPi is not harmed though.
// Edit: Changed host to 'bbb' from 'rpi' and "USR1" instead of "LED0" in the sample
package main
import (
"time"
"github.com/kidoman/embd"
_ "github.com/kidoman/embd/host/bbb" // This loads the RPi bbb driver
)
func main() {
for {
embd.LEDToggle("USR1")
time.Sleep(250 * time.Millisecond)
}
}



Next up: World Domination!



Monday, May 12, 2014

BeagleWoe

I thought I'd be clever and write about how I set up a VirtualBox Angstrom image for a more native cross-compiling environment, especially for things like portaudio bindings for Go.

Somewhere along the way I decided I wanted (needed?) to flip to Ubuntu and just pull down the Angstrom environment as a target, and part of that needs 'bitbake', which apt-get couldn't find, so I had to pull down manually.

Guess what? Big surprise, I got errors, and the instructions are gone...

I find a lot of reference from others with similar install issues, and some sort of RTFM message and link to here -> http://www.angstrom-distribution.org/building-angstrom

Go ahead. Click on it. I'll wait; you'll be back pretty quick.

Ummm. Ya. That's a day of my life I'll never get back.

So I think I'll skip the native cross-compiler to get portaudio working, and stick with Dave Cheney's cross compile scripts which work quite well in OS X. I guess I can call os.exec in a goroutine for simple sound generation.

Another alternate route is to use the cross compile scripts from Ubuntu, where at least I can install ALSA and the portaudio packages, cross-compile for ARM, and move the binaries to the Beaglebone. Something like this -> https://code.google.com/p/portaudio-go/

Saturday, May 10, 2014

Field Test - Low Data Rate Transmission

We had a break in the bad weather today long enough to sneak in a test of the low data rate transmit / receive boxes.

Here is the container with the transmitter, Attiny84, battery, and a PCB with two NeoPixels on it. I added them back to the project and found with a shorter strip count I wasn't getting any weird memory behaviors.


It's showing red on the chassis status LED (because it's disconnected) and pulsing the transmitter status LED when a nom (3 bits) is being sent.

Here is a sequence of ever increasing distance, to 100 paces. These images were from the camera in my iPhone 4s and are un cropped, which might help you interpret the scale if you've seen images from the camera before. It's a fairly 'normal' view; not overly telephoto or wide-angle.




This was a decent enough test to give me confidence in 3D printing an enclosure for it.

At 100 paces the receiver would lose lock if my body was between it and the transmitter, but would lock on again if I turned to face it. In practical terms I couldn't really see any detail of the transmitter or it's status LED's at that range, so without onboard video I wouldn't drive the rover from that far away. The battery pack on the transmitter was putting out 4.8v no-load, which is a bit low but within a realistic limit, so this would be a typical maximum range I would expect for line-of-sight use.

The receiver was also in a simple plastic box; with a USB battery, Arduino, receiver, and LCD shield, pictured here:


One obvious thing I found was that I couldn't read the LCD when it was backlit with anything but white. It was red because the transmitter wasn't being updated via I2C, or plugged into the Vex receiver, so it was sending a 'I can't hear anyone' alarm to the receiver, which is one of the conditions that changes the receiver LCD color... I guess it need a NeoPixel status LED for better visibility.

With the Vex RC decoder also completed as part of the package I can go ahead with building up to the first remote controlled drives now... weather permitting!



Tuesday, May 6, 2014

A Closer Look - Low Data Rate Transmitter

Here is the progression from breadboard to protoboard of the transmitter I mentioned in the last post. There are a couple of minor differences in layout between the two, given the protoboard is half the size, but the only obvious change is that I opted for a 3 pin connector for the status LED, instead of soldering it in. This leaves the option open to use a  Neopixel in the future - but probably only one, as I had to really trim back the code to get this stable on the Atmel Attiny 84 micro controller.

I've also used the Adafruit Perma-Protoboard for this. Yes, it's probably a whole dollar more for a board this size, but it's worth it. The mask makes it really clean and easy to work with, the through-holes are plated and not too small, and it's rigid and thick enough that you know it's as good as permanent.

Although this transmitter / Vex RC decoder isn't really needed as part of the operational rover plan, it's a handy first step in field testing by enabling simple remote controlled drives. I should be able to provide a demo video of both halves of the transmit/receive pairs range performance in the next few days. Long range isn't a requirement, however I need to know what kinds of limits I should be working within when directly driving the rover.

The original breadboard with transmitter module. Note that it's configured for software uploads via an Arduino-as-ISP, so there are a good many wires not needed for normal use.


The 433 Mhz transmitter module. There are four data pins, power and ground on a six pin connector. (Link to the original part source)


The protoboard version. The six pin connector at upper right is for the transmitter. There is a four pin socket connector for the I2C bus on the rover, and 3 pin socket for the Neopixel, a 3 pin header for the Vex Receiver (and 10k pull-up resistor),  and a spare 3 pin connector to a PWM capable pin on the Attiny 84 that was unused. 

I also added a 16 Mhz resonator, although the original instability / timing problem it was meant to address was likely due to poor memory management on my part, not bad timing caused by the internal 8 Mhz oscillator. There is also a 0.1 uF capacitor across the power and ground pins to clean up the supply for the Attiny.


A view showing the transmitter in place. It's connected via the 6 pin socket. There is (just) enough clearance on the left side over the resonator, and space above the 14 pin socket for the Atmel chip. The 3 pin Neopixel connector appears partially obscured by the edge of the transmitter; in fact there is no overlap, although fitting a connector here will be snug. For use while driving, especially over rough terrain, the board will have to be secured with additional support; perhaps as part of a 3D printed enclosure.



It's not bad for an evenings tinkering. There are a couple of things I would do differently, but as a proto board it's not really important, and it's unlikely I'd bother to do a PCB version, as the data rate is so slow. For the time investment compared to performance I should have used Synapse wireless modules, and I still might, once I can demonstrate that it's worthwhile to pursue.


Sunday, May 4, 2014

3 Bits is a Nom, 3 Noms is a Byte and a Bit

Wanting a long range wireless transmission from the rover I had purchased a transmit / receive pair of 433 Mhz modules last year. After some tinkering I realized these were super-slow speed, intended for 4 channel radio control of simple on/off switches based on the PT2272 chips, not data transmission. So I put them aside.

In the last couple of weeks I've been getting the rover ready for first-drives via remote control, and wanted a better way get the LiPo battery status where I could see it, and without the final configuration of software or WiFi. I thought about those wireless modules again, and thought that if I really only had a few bits of data to move, it was probably ok to try them out.

I wired up the units to two Arduinos for testing. There are four data channels that are sent / received in parallel, labeled D0, D1, D2, and D3. If any of these are set logic-high, there is a transmission. I started writing some simple test code, and worked out a simple timing scheme to get stable data transfer.

The speeds are super slow; the data pins have to be held in a state to transmit for something like 350 ms to 400 ms, and then all held low for as long for the next transmission to be recognized as changed (and for the code to work right).

I also started thinking about a timing scheme to send two nibbles (a nibble is 4 bits, half a byte); that would allow me to send 8 bits instead of 4, and get a lot more status data off the rover... and possibly up to 2km, if the documentation is to be believed.

But then I started to see some weirdness when sending groups of two nibbles. I had it transmitting a byte value, just an incrementing number, and noticed that it wasn't sending the zero value. Then I noticed it wasn't sending any all-zero nibbles. Doh!

That was a forehead-slapping moment; of course they can't send all zero's! For their intended use sending a 'no buttons pressed' message doesn't make sense. So a '0000' means 'don't transmit anything'.

But I had gotten kind of attached to the idea of getting a byte worth of bits from the rover via wireless, and wondered if I could just set one of the bits, and transfer data in the other three.

And then instead of transmitting just two nibbles, 2x 4 bits, I could send 3x 3 bits.

So three bits became a 'nom', because it's just a bit (pun intended) smaller than a nibble.

For fun, I could then use the 9th bit as a flag on the first 8 bits; one use would be to differentiate between a status byte of 8 bit flags, or a data byte, of 8 normal bits.

Now... what to transmit? Here is the list:

// Defines for bit packed positions, bit 8 is local RX failure
#define STA_L    0x01    // 1 V Logic low volts warning
#define STA_D    0x02    // 2 V Drive low volts warning 
#define STA_T    0x04    // 3 Temperature warning
#define STA_P    0x08    // 4 Pose out of range (rocker-bogie)
#define STA_A    0x10    // 5 Accelerometer out of range (pitch/roll)
#define STA_C    0x20    // 6 Route/path calculation vapour-lock
#define STA_H    0x40    // 7 Haz detected

Notice that there are only 7 bits defined; these first 7 bits come from the rover itself. The 8th bit is locally created, because I decided that I'd package this up as an I2C slave (big surprise) and use it to transmit RF status, and also receive and decode the pulses from a Vex RC controller set.

That eighth bit is a flag that says 'I'm not getting a signal from the Vex Receiver', to inform the operator that the rover is out-of-range of the Vex transmitter.

I sat down with my standard I2C boiler plate, and managed to cobble together a module that decodes the Vex signal to I2C registers, pull status and data and send them interleaved, and then summarize it all for a Neopixel visual status. I eventually removed the Neopixel status LED, as I started to see some oddities that indicated I was running out of RAM.

On the receive end is a simple I2C 16x2 LCD, which displays the bits across the top line, and a text are across the bottom. Half displays 8 character extended messages, and the other half is a scroller that rotates the characters as they come in, adding received characters to the right position. At these slow speeds it's not hard to read.

The protocol also has some hidden goodness. Because the printable ASCII set only takes up a small portion of the byte space, it's also possible to get extended status info in single byte messages, not just the status summary. The trade-off here is speed; in 2 seconds I can get a 'quick' summary, but getting 8 bytes takes about 10 seconds.

And because it would be just too geeky-cool, I reserved the last 64 positions as start-of-extended-message markers to flag the start of up to 64 byte blocks of actual non-character, pure byte data. I can't really see transmitting an image this way, but maybe a thumbnail in a pinch...

But I'll probably add a better system for mid sized data; WiFi is ok for some things 'local', but it would still be fun to add a couple of more methods; one might be higher speed RF or Synapse network, another might be using a servo-steered pulsed laser - who knows?