I’m going down much the same road with my new widgets as I did with the Wixels- depending on the software loaded and the application, a Widget can be a client or controller. A client can be a locomotive, turnout or any other device that is controlled via servos or discrete outputs. The controler can be a hand-held interface and/or a computer. In my case this is my Raspberry Pi, configured as a web server/web sockets host.

To that end, I coded up a quick Xbee interface for the Raspberry Pi in python that works with the datagrams in my set of train/control widgets. It’s extremely minimalistic (of course) but allows you to send standard ‘AT’ commands to the Xbee and also send advanced API datapackets. This code assumes that you have an Xbee module configured with X-CTU. I’m using the Parallax Xbee USB board to do this. You will need to set the interface baud rate of the Xbee to 38400 baud and place the Xbee in API mode. Once configured, move the Parallax board to the Raspberry Pi and that’s it. Destination Xbee modules (configured as above) will receive this data (based on it’s destination address of course) and pass this out the serial port to the host. In this case, the host is (will be) my train widget boards. Once they are available that is, perhaps early March (I hope)

Anyhow, you can now control Train Widgets with the following code or adapt it to your own xbee design. XbeeTransmitDataFrame is the primary control interface. All servo, sound and sensor data uses this fixed length datagram. It’s compact and fast and offers 65K of possible command codes (I’ve implemented 3 so far).

xbeeSendDataQuery is used to do a standard ‘AT’ command using the API mode. For example, you can pass ‘M’ and ‘Y’ to this method and it will return the 16 bit node address of the Xbee. Any of the other AT commands can be used as well but you will have to get the data using serial.read() and know where in the packet the return value and how long it is.

xbeeTransmitDataFrame is used to send the 16 byte packets I’ve made up for my implementation. You can see how these are constructed from the C structures below.


import serial

class xbeeController:
    def __init__(self):
        usbPort = '/dev/ttyUSB0'
        self.sp = serial.Serial(usbPort, 38400)

    def xbeeReturnResult(self, datalength):
        return(self.sp.read(datalength))

    def xbeeDataQuery(self, cmdh, cmdl):
        frame = []
        c0 = ord(cmdl)
        c1 = ord(cmdh)
        frame.append(0x7e)	# header
	frame.append(0)	        # our data is always fixed size
	frame.append(4)         # this is all data except header, length and checksum
	frame.append(0x08)      # AT COMMAND - send Query to Xbee module
	frame.append(0x52)	# frame ID for ack- 0 = disable
	frame.append(c1)	# Command high character
	frame.append(c0)	# low character
	frame.append(0)	        # zero checksum location

	cks = 0;
	for i in range(3,7):	# compute checksum
	    cks = cks + frame[i]

	i = (255-cks) & 0x00ff
	frame[7] = i	        # and put it in the message

	for i in range(0,8):	# send it out the serial port to the xbee
            self.sp.write(chr(frame[i]))
	
    def xbeeTransmitDataFrame(self, dest, data):
        frame = []
        frame.append(0x7e)	# header
	frame.append(0)	        # our data is always fixed size
	frame.append(21)        # this is all data except header, length and checksum
	frame.append(0x01)      # TRANSMIT REQUEST - send Query to Xbee module
	frame.append(0)	        # frame ID for ack- 0 = disable
	frame.append( (dest>>8) & 0x00ff) # Destination address
	frame.append( (dest & 0xff))
        frame.append(0)         # disable ack for fastest transmission

        for i in data:          # move data to transmit buffer
            frame.append(i)
        frame.append(0)         # checksum position

	cks = 0;
	for i in range(3,25):	# compute checksum
	   cks += frame[i]

	i = (255-cks) & 0x00ff
        frame[24] = i

	for i in range(0,25):	# send it out the serial port to the xbee
            self.sp.write(chr(frame[i]))


This is the xbee header information that is in the Widgets. This defines the three control packets I’m sending with the Xbee. These are the 16 bit fixed length packets that ride in the transport area of the above datagram. By keeping them small, I’m getting a 7ms packet transmit time which is very fast.


#define CONTROLLER   0x0000				// XbeeCTRLPacket{}
#define RFIDCOMMAND  0x0010				// XbeeRFIDPacket{}
#define SOUNDCOMMAND 0x0011				// XbeeSOUNDPacket{}
	
typedef struct
{
	uint16_t destinationAddress;		// Xbee destination address for this client
	uint16_t sourceAddress;				// This node's address
	uint16_t commandID;					// 16 bit command ID
	uint16_t Sound0;					// 16 Bits of Sound Triggers
	uint16_t Sound1;
	uint16_t Sound2;
	uint16_t Sound3;
	uint16_t Sound4;
} XbeeSOUNDPacket;
	

typedef struct
{
	uint16_t destinationAddress;		// Xbee destination address for this client
	uint16_t sourceAddress;				// This node's address
	uint16_t commandID;					// 16 bit command ID
	uint16_t RFID0;						// 12 bytes of ascii RFID info
	uint16_t RFID1;
	uint16_t RFID2;
	uint16_t RFID3;
	uint16_t misc1;
} XbeeRFIDPacket;

typedef struct
{
	uint16_t destinationAddress;		// Xbee destination address for this client
	uint16_t sourceAddress;				// This node's address
	uint16_t commandID;					// 16 bit command ID
	uint16_t Servo0;					// Servo 0
	uint16_t Servo1;
	uint16_t Servo2;
	uint16_t Discrete;
	uint16_t misc1;
} XbeeCTRLPacket;


widgetsm

This is the prototype control widget. I originally called them ‘train widgets’ but that is a bit limiting as they should be able to control pretty much any surface vehicle. I wouldn’t use them for flying devices however as the range is only about 300 feet- fine for earthbound machines but a bit too limited for anything that flies.

Nevertheless, since my primary purpose is controlling G scale model trains, this will do nicely. As you can see from the photo, these are very simple devices. An Xbee series 1 and an Atmel Attiny 1634 micro controller. I also have a suite of software modules written to control or monitor each of the functions mentioned in the diagram, plus do all the Xbee network message passing.

Each widget can control servos, motor controllers, discrete outputs (lights etc), a sound card with 8 channels of up to 1000 sounds, an RFID reader (for position sensing) and a configurable set of I/O pins for inputs (speedometer, current sensor, etc) or SSI/SPI to expand the I/O.

The Xbee allows bi-directional radio communications using the 802.15.4 protocol, so any node can communicate with any other node in real time. One Xbee in a hand-held configuration can control multiple locomotives, turnouts and animatronics, while a computer can also control and/or monitor the same (or other) locomotives or devices.

Anyhow, I’m working on a whole series of designs based on this, I have ordered the first set of PCBs, they should be here in a couple of weeks. After that I’ll be designing PCBs for the handheld, working on the sound card (I have a new one, see this link for more info) and expanding the software modules.

Well, after much debugging and trouble shooting I still cannot get either of my Android Interface prototypes to work. I have tickets open with the support guys but so far they have not been much help. This is rather disappointing but perhaps it’s a good thing. Time to move on. I have all of my control and sound s/w and h/w working, now I need to concentrate putting it into widget form with some custom PCB designs. I have the client widget designed, next are the hand held PCBs which will entail a display board and a keyboard circuit. The computer interface is covered, a parallax Xbee to USB board will be used for that, I just have to get the python drivers together and interface it into my websockets design.

I plan on releasing all of this as a series of several components, or widgets as I like to call them. The first will be the client widget. This will be for installation in a locomotive, turnout or animatronic device. It will interface to servos, motor controllers, my sound board, discrete outputs (ex lights). I will also provide inputs for various things like current sensors and feature an RFID reader port (for position sensing).

The second will be a couple of small PCBs, this will be the hand-held widget. I’ll also offer a resin cast/3D printed housing for this. And like the client widget, the s/w will be open source.

The third widget is the mp3 sound player. This will require the client widget to function.

The last widget will require only s/w as it’s based on the parallax Xbee interface board. You will need one of these anyway to program the Xbees for each of the clients and the hand-held. It will then double as a computer control point for the raspberry pi.

I’ll link all this together with some of the software I’ve done for the Wixels, at least on the HTML5/websockets and server side.

The basic idea is two fold. You can drive your trains with the hand-held and control all client nodes with that (locomotive or whatever) AND/OR control them with the computer or some combination of the two. I’ll open source everything so you have something working right away, yet also have the ability to alter the code to whatever you need. I’ll keep the cost of the PCBs to the absolute minimum and offer them bare, as a kit, or populated and programmed. Stay tuned.

As we enter 2014, I thought I would post up a recap of what I’m working on. Primarily I’m developing a wireless method for controlling moving vehicles. In my particular case, this is Garden Scale (G) model train locomotives. However the principles and widgets I’m designing could be used to drive almost anything via real time wireless up to a distance of about 300 ft (100 meters).

The key difference between my method and say standard FHSS (or similar) 2.4Ghz Radio Control is that I am oriented toward a computer driven network, in my case, 802.15.4 as implemented with the Xbee Series 1 modules.

Why a computer network? Well, for one, it gives me fine control over the exact data I’m passing back and forth. Second, it’s bi-directional. The network is oriented as a single to many so any device can talk to any other device. Each Xbee module has a unique 16 bit ‘node address’. You just form a message, add the address of the node you want it to go to and send. The network takes care of getting it there.

This is quite powerful. You can be sending control data to your locomotive and then, as it passes over an RFID tag, it could send that position data back to the computer (or your hand-held, or another device, etc) in real time. Additionally, other data such as speed, current draw, etc could be returned from the locomotive as well. Just because this is a computer type network, it isn’t slow. I’m getting data packet transmission times in the 7ms range which is quite fast. (For reference, your average servo scan time is 20ms)

Anyhow this level of potential automation is, by electronic design standards, fairly simple. I have an Xbee and an Attiny 1634 Microcontroller as the main components of my ‘Train Widget’ and that’s pretty much it. Basically about $22 worth of electronics as the ‘brain’ of all of my devices.

mainWidget

This is a picture of the basic train widget. Xbee does the communications, the Attiny handles the processing and drives the servos and motor controller. It also sequences the mp3 players (2 stereo channels) so you can play sounds via commands sent over the network or by throttle control positions. The two cards are just to the left of the speaker which I’m driving with a generic LM386 amplifier chip and some caps from Radio Shack.

widgetDetail

Above is a shot of the front end showing the coupler connected to a micro servo, the ‘back’ coupler servo sitting beside it and the RFID reader in the upper left. I have all of this working including the transmission of the RFID data to the hand-held.

handheldA

This is a picture of my stand alone ‘simple’ hand held throttle prototype. I also have all of this working, however only at a basic level of controlling one locomotive at a time, I don’t have any multiple unit code in there yet. I’m also thinking of going with a graphic display instead of this ASCII only one and also designing a ‘cradle’ or appliance of some sort so I can use my tablet as a user interface instead of a LCD. (See the post below this one)

couplerRF

Finally, this is a pic of my uncoupler device. One of these per car with the locomotive in charge of each one. The handheld would allow you to address the locomotive and then each car individually to uncouple anywhere. Each of these consist of one Attiny Microcontroller and a small 2.4Ghz transceiver. The locomotive has the ‘master’ transceiver and can talk to each car in the train that has a ‘slave’. The Attiny then controls the servo motor to move the coupler. This is clocking in at about $2 for the Attiny and $8 for the transceiver. Add $4 for a servo. Not super cheap but not too bad. $18 per car? I guess. Hmm, need batteries too…

xbeeTX

Phase B of a hand held transmitter takes shape. This is a rough approximation but I think it will serve as a master for an RTV mold to cast a resin model from. It still needs a bit of design work but this is the basic idea. Xbee transmitter, 1634 Attiny, Parallax Joystick and a Pololu USB/serial interface plugged into the tablets’ USB port. I had considered Bluetooth but it’s the first thing to get dropped on cheap tablets, whereas everyone has USB.

Originally, I had something similar that I had put standard R/C radio guts into, however there was no actual interface to the tablet except via wifi. This design, although in the early stages, will interface with the tablet for a user interface, plus transmit directly on the Xbee Network. The tablet will also do standard WiFi so I can interface to the server as well. With an additional Xbee node on the server, (which will be a Raspberry Pi), all sorts of control possibilities emerge, just requiring s/w. I’ve downloaded the Eclipse SDK for Android as well, I have limited app development experience, at least in the native Java, but it seems like an interesting challenge. I have done some Python development on Android and may end up doing that here too, not sure quite yet. What I would like is to run Chrome on this tablet as they have a serial port API. However, despite this being an Android tablet, I can’t get Chrome to install. Go figure.

P1030763

I refactored the software for both the master and client nodes over the last few days. I cleaned up some of the prototype code, added some basic structures to lay over the xbee transmit packets and moved things around just a bit. As far as functionality, I can now control three servos and send the RFID tag reading back to the master. If you look closely at the display you can see the raw hex code from a read in the lower left of the display. The ID20 from Sparkfun is a really nice reader, it catches the card passing by very quickly at about 40-50mm.

This also shows some experiments with the Kadee coupler controlled by a servo. Seems to work well, but this is on a bench test setup, not a real locomotive- but I’m optimistic. All I did was drill a very small hole in the ‘tab’ on the coupler. This is a standard Kadee 787 coupler meant for the Aristocraft RS-3. The actuator wire will be replaced by a chain or something more cosmetically pleasing.

The sound cards are the next step. Right now I’m feeding the power from the same bus as the servos so I get a bit of noise mixed into the amp output. I’ll clean that up later, for now all I hear is the servo when it moves, other than that it sounds fine, good enough to get the s/w working.

P1030760

I’m thinking of how to make the Kadee couplers automatic per car. It’s easy to add them to a locomotive, I’ve allocated two servo controls to my XBee wireless widget controller for that. The tougher part is how to make something that will do individual cars.

Here is what I’ve come up with. It clocks in at about $15 in electronics. Two sub-micro servos for $3, an attiny 1634 at $2 and a WRL-12031 wireless transceiver for $7. That’s $15 per car. Hmm. Still a bit on the high side but if you could have the locomotive be the master and then control each coupler on each car in the consist, you could do some nifty automated switching moves, eh?