arduniowifi

This is a nice board but a little mysterious to get working. Or at least like I want it to. But I’m getting there. The Xbee is just so much easier for what I want to do in terms of a high speed real time network without all the overhead of access points, tcp/ip and all that jazz. BUT, I’m hoping this chip will allow direct control of my widget (and all it’s connected servos and other devices) direct from a smartphone or tablet. It should also provide a gateway from the Xbee network to the 802.11 network without the raspberry Pi. We shall see. Nevertheless, I really enjoy playing with new gadgets like this so I’m having a blast.

terminal

I’ve come up with a very basic uart library for the widget called obviously enough, wiFlyUartLibrary. You can find it on the control widgets files page.

Here is a listing of the Ardunio code that turns the widget (with the help of the serial port on the USB programmer) into a local terminal for the WiFly Module:



#include <WiFlyUart.h>

WiFlyUart wifi;

void setup()
{
  wifi.Initialize();
  wifi.enableRX1IRQ();
  wifi.enableRX0IRQ();
  sei();
}

void loop()
{
  uint8_t data;
  
  data = wifi.getByte1();
  if (data != 0xff)
  {
    wifi.sendByte0(data);
  }
  
  data = wifi.getByte0();
  if (data != 0xff)
  {
    wifi.sendByte1(data);
  }

}


All the schematics and source code for this are on my controlwidgets.com page.


pygame

I also have been exploring a way to make apps for my Android Tablet. I’ve tried all sorts of development things like Eclipse and Android Studio and Xamarin and PhoneGap and all that and I really like, I prefer just because its simple and easy, is Python and PyGame for Android. Here are several links:

Here is the initial download for Pygame, I use Python 2.7 32 bit for this.
PyGame for Python

This is an add-on to allow you to develop android apps using Python and PyGame.
PyGame for Android Subset

There is also a library of widgets (sliders, dropdowns, buttons, etc) for PyGame called PGU that will also work on Android, IF you make a few changes to it:
Phils Game Utilities

And this link has the changes you will need to make to PGU so it works on Android:
PGU Modifications for Android


This is the python code to display one slider and send it via a socket to the Wifly module:



import pygame
from pgu import gui
import socket
from pygame.locals import *

# Import the android module. If we can't import it, set it to None - this
# lets us test it, and check to see if we want android-specific behavior.
try:
    import android
except ImportError:
    android = None

TIMEREVENT = pygame.USEREVENT
FPS = 30
screen = pygame.display.set_mode((800,480),SWSURFACE)

 # Map the back button to the escape key.
if android:
   android.init()
   android.map_key(android.KEYCODE_BACK, pygame.K_ESCAPE)

# set the timeout to 1 second, just in case it's not there
socket.setdefaulttimeout(0.25)

# open a connection to the AP in the locomotive
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    s.connect(('10.20.10.1',2000))
    print "connected to 10.20.10.1"
except:
    pass
        
class screenContainer(gui.Table):
    def __init__(self,**params):
        gui.Table.__init__(self,**params)

        fg = (255,255,255)
        self.tr()
        self.td(gui.Label("Speed: ",color=fg),align=1)
        e = gui.HSlider(100, 0, 500, size=20,width=700,height=80,name='speed')
        e.connect(gui.CHANGE, self.adjustSliderA, (0,e))
        self.td(e)
        self.sv = 0

    def adjustSliderA( self, value):
        (num, slider) = value
        self.sv = slider.value

    def SliderValueA( self ):
        return self.sv
        

app = gui.App()
sc = screenContainer()
c = gui.Container(width=200,height=180)
c.add(sc,0,0)
app.init(c)

pygame.time.set_timer(TIMEREVENT, 1000 / FPS)

##$$$
pygame.init()
 
done = False

while not done:

     for ev in pygame.event.get():
    
        if ev.type == TIMEREVENT:
            screen.fill((100,0,0))
            app.paint()
            pygame.display.flip()
            
        elif ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE:
            done = True
            break
        else:
            app.event(ev)
            v = str(sc.SliderValueA()) + "\r\n"
            s.send(v)

pygame.quit()


hhd-A
hhd-B

Here is my latest stand-alone hand-held-throttle design. It’s based on my control widget thing and I (finally) have it all working.

All the circuits and keyboard are mounted on a 3D printed faceplate with a 3D printed back enclosure. It still needs some structural work, screws to hold the face plate on and I need to mount the power switch too, not sure where that should go.

There is some hard-coded stuff in the handheld software but it does work quite well. I also have a slight design gotcha on my USB interface into this thing but I’ll get that solved soon.

pir-widget

I’m really enjoying my widget PCB design. Simple, cheap, easy bake oven for SOIC, program in C, add an Xbee for wireless real-time control, how cool is that? Here I have one hooked up to a parallax IR motion sensor. With a bit of C code it controls the servo based on the input from the motion sensor. Think railroad crossing signals- that crossing arm that comes dowm and blocks the traffic, right?

Anyhow, great fun and a good project to post over to controlwidgets.com

I’m looking at a $9 retail for board and components. Software will be free and open source. Of course :)

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.