micro

I’ve been doing quite a bit of PCB design these days, here is a version of my controller board, the ‘microwidget’. It’s quite compact. I have not had any made yet but I thought it came out really sort of, well, neat. Like art kinda.

All total I have about five or six small circuits for doing control networks- specifically for large scale model trains. DCC input and output, servo control, DC brushed motor control, reversing relays- all via Industrial strength Xbee Network wireless.

I’m also thinking of making an apt-get debian package to install JMRI on a RPi 2 and gitlab for my code. Hmm.

I think I need a Kickstarter 🙂

newboards

I have a lot less time to work on my projects than I used to so here is another sort of work in progress post.

I have the new widget boards and will be assembling several soon. I am missing a part, an SMD 140 ohm resistor for the power LED. It’s ordered.

Along with that order is all the parts I will need to intercept the DCC stream with my control widget and then either process it internally (moving servos, motor controllers, outputs, etc) or send it out to other Xbee wireless nodes. Something fun to do anyhow.

I should have a MRC Prodigy Express DCC controller soon. I will put it to use with my N scale trains but the main focus will be intercepting the DCC signals and sending them out via wireless XBee as mentioned above.

Also, if you notice, there is the Raspberry Pi 2 there beside Mr Foreman, I’ve got that up and running, very nice board. Really sweet.

Hmm. Also making progress on the CNC styrene cutting, I have large parts of the depot finished, I’ll post some pics soon.

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;


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.

cover11

I’ve released the source and executables for my Master/Slaves Wixel Software. This uses one Wixel as a master plugged into your Raspberry Pi USB to control up to 64 slave Wixels via 2.4Ghz wireless. Each slave can control 6 R/C type servos and monitor 3 analog inputs. I’ve also included a Python class for the Raspberry Pi, some HTML5 javascript and graphics for the user interface and instructions for running your Pi as a web server.

More info on it is here: http://servowidget.com

dash9

Not much new, I have gotten the Xbees to communicate in API mode. The only subsystem left to develop is the servo driver. Turns out I’m going to have to roll my own incarnation using timer 1. But that’s actually good, I don’t like depending on ‘libraries’ from third parties which often have deep dependency lists.

I’m also doing another pass on the RaspberryPi/Wixel/HTML5/Websockets project with the idea of releasing it open source or at least a collection of source code that mostly works. I hope to include the Master/Slave Wixel protocol thing I’ve had laying around for a while too.

Some very sad news too, Aristocraft Trains, who make one of the locomotives I really really want (pic above), is going out of business. Perhaps I can pick up a NS Dash9 before they go completely extinct but damn, that messes up some of my plans. Oh well. Shit happens.

txhack

I’ve taken an old airplane radio and hacked it down to train size. Channel 1 is now a pot for speed and the two push buttons alternate a servo ‘position’ on channel 2. Not enough I know but this is just a quick prototype.

The tray has my Android tablet where I’m running an html5 page talking to a tornado instance on the server. The page takes finger presses and sends them via tornado back to the server. It turns them into servo movements out ‘in the field’ via Wixel wireless and Python to change the turnouts. Whew. Long path there but it works quite well.