Return to the archive index

Re: Mobile Sensorium [was Re: Time for Serious GPS Application]

From: Doug Sutherland <>
Date: Fri, 5 Jan 2001 18:29:43 -0800

Following is a very detailed description of my microcontroller
based device multiplexing/interfacing system. Warning: it is 
a very long message and may be sleep inducing :)

Earlier this week I was describing my microcontroller based 
device multiplexing system. One of the comments (by Eric) was 
that it seemed to be quite a heterogeneous collection of parts. 
>From a hardware (processor) perpective it is, but from a software 
(protocol) perspective it is very homogeneous and is actually 
quite simple. I thought I'd share some more details on what I 
have done so far, and plans for enhancement. I thought that some
of you might find this interesting, and also figure that I might
get some interesting and useful feedback.

First, some background history. I have always wanted to have the 
abilty to interface many non-standard input/output peripherals
and multiple sensors and/or data acquisition devices to my 
wearable. My earlier approaches to this were centralized (as 
per Eric's comment) running on the pentium CPU, connected to 
many serial ports. In an earlier design, I specifically looked
for a carrier board with four buffered serial ports for this
reason (to attach many devices). I used the Cell Computing 
Mighty Mite (CardPC carrier) because it had 4 serial ports. But 
I discovered quicky that even 4 ports were not enough. The ports 
were quickly used up by the twiddler, GPS receiver, ricochet 
modem, and serial LCD display. I wanted the abilty to interface 
all of these devices plus many more (primarily sensors). I 
looked into adding more serial ports via a multi-port PC/104 
card, but it was too big, bulky, and expensive. I also tried 
expanding the number of serial ports with PCMCIA serial cards, 
this worked but also had some disadvantages. I did not want to 
use up a PCMCIA slot just for RS232, in fact I wanted to 
eliminate PCMCIA altogether to save weight and bulk on my core 
CPU enclosure. I thought about separating a PC/104 perpheral 
card (either a multi-port serial card or dual PCMCIA module) 
via PC/104 cables, thus "flattening out" and distributing the 
hardware on my body, but the necessary cabling is way too 
bulky (since there are 104 wires between the modules and 
connectors are bulky). 

Prior to using the Advantech PCM-5822, I had a system based on 
CardPC. It started with two modules, a Mighty Mite carrier 
board and dual PCMCIA PC/104 module. This was not bad from a 
weight/bulk perspective but had no audio. In order to provide 
audio support I added a PC/104 Crystal/MM audio card, but that 
made the overall system way too big. I then replaced the Mighty 
Mite carrier board with a new carrier board with dual PCMCIA 
slots onboard. This was an improvement since it eliminated the 
PC/104 PCMCIA module, but it was bigger (longer and wider) than 
the Mighty Mite carrier (and the board is now obsolete). I was 
still not happy having a whole PC/104 module for audio. At the 
time I could not find any PCMCIA or USB audio devices, so I 
moved to the Advantech PCM-5822 with audio onboard. This was 
very desireable for weight/footprint since it gave me (almost) 
everything I needed in a single 4 x 6 inch module. The challenge 
was that I only had two RS232 serial ports. Two good things 
happened at the same time: twiddler moved to PS/2 and ricochet
moved to USB, therefore it was possible to get by with only
two serial ports for GPS and serial LCD display. But this left 
me with no free ports for adding sensors or other devices. I 
could of course go back to adding a multi-port serial card 
and/or dual PCMCIA module, but I don't want to do that for 
four reasons: it's too expensive, it's too big, it's too power
hungry, and it's overkill (I don't need anywhere near 115.2k 
baud, most of the devices I want to interface only require a 
measly 9600 baud. I therefore decided to use microcontrollers 
to multiplex multiple devices on a single RS233 serial port. 
This has proved to be an interesting and powerful distributed 
approach. Here are some details on the design.

My first goal was to connect a microcontroller to one of the
serial ports and connect a GPS receiver, LCD display, and IR 
decoder (for infrared remote control). This was actually
surprsingly easy to do since all three are devices that use
simple serial communications. The first design simply took any 
data from the host (CPU) and sent it to the LCD display, and 
took data from both the GPS and IR decoder and sent them to 
the CPU (with some simple protocol codes to distinguish data 
types). Although this was simple it proved to be quite powerful. 
I recently added more devices including temperature, humidity, 
and barometer sensors, a bank of A/D converters, and an LED
bar graph display. All of these devices are connected to a 
single RS232 port and sharing the low band width (19200 baud) 
connection with the CPU. One small microcontroller acts as a 
router, routing requests to the appropriate peripheral pins 
and passing data between the devices and the CPU. To get an 
idea on the complexty of multiplexing these various devices, 
here is an overview of the devices and their protocols:

1) The SGX-120L text/graphics LCD from Scott Edwards 
   Electronics is already an RS232 serial device. It connects 
   at 9600/8N1 and has its own set of control odes. It requires 
   only one pin on microcontroller (receive data). Any text 
   sent along this channel will display on the LCD, and there 
   are a set of control codes (CTL-letter) and escape codes 
   (ESC-letter-number) to control features like backlight, 
   cursor positioning, and graphics commands. The LCD display 
   required RS232 level data, so I added a MAX232 level 
   converter between the microcontroller and display.
   http://www.seetron.com/sgx120_1.htm

2) The Motorola Oncore GPS receiver is an OEM module that 
   aleady has data transmit and receive serial ports for TTL 
   connection to a microcontroller. These are directly wired 
   to general purpose pins on the BX24. The GPS receiver can 
   operate in NMEA protocol format or in Motorola binary
   format. There is also an ASCII string command, which is 
   the simplest protocol, and this is what I am using. To 
   get a GPS reading, all you need to do is open up a 
   9600/8N1 serial connection and send a command (@@eq) 
   along with checksums per the motorola format specs. You 
   get back a simple ASCII string containing the most 
   important GPS data (position, time, date, etc).
   http://www.motorola.com/ies/GPS/products/prodgt.html

3) The Radio Shack 276-137B IR Detector Module is very easy 
   to interface. It connects to one of the general purpose 
   pins on the microcontroller and is a simple serial device 
   operating at 893 baud, 8N1. To read data all you do is 
   open the port and listen. The IR decoder sends codes each 
   time a button is pressed on the IR remote control, and 
   there is a unique code for each button on the remote.
   http://www.hometownvariety.com/credcarunrem.html 

4) To add sensors for humidity and barometer, I used a kit 
   from www.phanderson.com called the serial weather kit.
   The kit includes a pre-programmed PIC microcontroller 
   already set up to interface weather sensors. It is 
   possible to interface wind speed and rain guage devices, 
   but these are not practical for wearables, so I am using 
   the kit for just humidity and barometer data. All I had 
   to do was assemble the electronics and connect my BX24
   microcontroller to the IO pins on the pre-programmed 
   PIC. To get a reading I simply open a 9600/8N1 serial 
   connection and send any character. The PIC returns an 
   ASCII string containing the sensor readings.
   http://www.phanderson.com/weather/index.html

5) To add sensors for multiple temperatures, a bank of 
   12-bit A/D converters, and an LED bar graph driver, I 
   used another kit from www.phanderson.com. Like the serial 
   weather kit, it includes a pre-programmed PIC. This kit 
   can address up to 256 DS1820 temperature sensors (along a 
   single twisted pair) but I am only using seven of these. 
   The A/D ports are set up with filter capacitors and 
   resistors and are terminated with screw terminals on the 
   wearable for easy dynamic attachment of a varety of 
   sensors. The general purpose ouputs of this kit drive the 
   LED bar graph in my case, but they could also be used to 
   drive relays or could be read as general purpose logic 
   level inputs. Interfacing the PIC is easy, it's just a 
   9600/8N1 serial connection. To get readings you send 
   text with a simple protocol of text commands. 
   http://www.phanderson.com/t64.html

If you look at the protocols for all of these devices, you 
can see that although the technologies are diverse, they all 
operate on simple serial connections, most at 9600/8N1, and 
all operate on simple ASCII based data and commands. This 
makes it easy to interface them all to a microcontroller and 
ultimately to applications running on the CPU. Here is a 
diagram showing how my components are laid out physically.
It shows the pin connections for all devices connected to 
a single BX24 microcontroller attached to the CPU. 

                      Pentium CPU      Rx <----- pin 1  
                      RS232 Port       Tx -----> pin 2

                      Motorola GPS     Rx <----- pin 11
                      Receiver         Tx -----> pin 12 

Text/Graphics <------ Max232 Level     Rx <----- pin 5 
LCD Display           Converter

                      IR Decoder       Tx -----> pin 13

Pressure Sensor <---> PIC Weather      Rx <----- pin 8 
Humidity Sensor <---> Microcontroller  Tx -----> pin 9

Temp Sensors    <---> PIC Sensor       Rx <----- pin 6  
A/D Converters  <---> Microcontroller  Tx -----> pin 7    
LED Bar Graph   <----

Once these various devices are phyically connected, the 
challenge becomes one of software protocols. Communication
with any given device is easy, simply open a serial port on 
the desired pin(s) and request data. For example, to get a 
GPS reading, the BX24 configures its COM3 port to pins 11 
and 12 at 9600/8N1 and sends a command out pin 11, then the 
GPS send the data on pin 12. Programming for any single 
device is easy, but managing all of them is a bit more 
challenging. In order to simplify the communications, I 
designed a simple protocol of control codes to identify 
requests coming from the CPU. The protocol consists of an 
escape character (ASCII 27) followed by a CTL-letter 
combination specifying the device, and in some cases an 
additional parameter. The codes look like this:

ESC CTL-D [Data]           - send command to LCD display
ESC CTL-L [DevceID][State] - send command to LED display
ESC CTL-T [DeviceD]        - request temperature reading
ESC CTL-A [DeviceID]       - request ADC reading   
ESC CTL-G                  - request GPS reading
ESC CTL-H                  - request Humidity reading
ESC CTL-B                  - request Barometer reading

Establishing this command protocol made programming easy on 
both the microcontroller and CPU. The BX24 just sits there 
and watches for incoming data from the CPU on the RS232 
serial port (pin 2). It reads the data one byte at a time 
and checks if the byte is an escape character (ASCII 27) 
indicating a command (not data) from the CPU. When escape 
is detected it reads the following byte to determine which 
function is being requested (for example hexadecimal 7 is 
CTL-G which indicates a GPS request). When the control code 
is read, the BX24 opens a serial port on the appropriate
pin, and leaves it that way until another escape code is 
detected. All subsequent data will then route through the
BX24 to the selected device. For example, if the CPU sends 
ESC CTL-D, the BX24 microcontroller sets up pin 5 as the 
ouput port, and all subsequent data from the CPU routes to 
the LCD display. If later the CPU sends CTL-G the port is 
configured for pins 11 and 12. The control codes for the 
specific device are programmed on the CPU (not the BX24
microcontroller), and the microcontroller simply acts as 
a router. The BX24 also uses these same ESC CTL-# codes
to wrap data, so the CPU knows what kind of data is being 
received on the serial port. For example if the received 
data begins with ESC CTL-G the CPU knows it is GPS data 
and invokes the proper data parsing routine. Aside from 
managing connections and inserting control codes in return 
data, the BX24 also formats all return data to be comma 
delimited in the same way. This makes it very easy for the 
CPU to identify (by ESC CTL code) and parse (by comma 
delimiters) incoming data into variables.  

Establishing these "handshaking" or "routing" codes was 
only half the battle in multiplexing. The codes are simple 
enough that they can be manually keyed in a serial terminal 
like minicom or hyperterminal (which is good from a generic 
protocol perspective). But the next challenge is one of 
timing, priorities, and coordination. Some of the devices 
are polled (sensors and GPS) while others receive commands 
(LED and LCD displays). These are easy to manage, but 
interrupt devices (like the IR decoder or a keypad) need 
special attention. In the case of commands coming from the 
CPU, the task is easy, just watch for the ESC CTL-# code
combination and open the appropriate port. The problem is 
that only two serial ports can be open at the same time on 
the BX24 microcontroller, and one of them is always 
connected to the host CPU. This means that only ONE of 
the attached devices can operate at a time. My approach 
therefore is to follow these simple rules.

 - When no requests are coming from the CPU, always 
   default to watching the IR decoder port for interrupts 
   from the user. When IR data is detected, block all 
   other requests until the received IR data is sent to 
   the CPU.

 - Always watch for commands from the host CPU, but only 
   keep the serial ports connected to peripherals long
   enough to process the command, then default back
   to watching for IR data.

On the host side of things I created Java interfaces to all 
of these devices. This makes it very easy for any application 
(local or remote) to access the functions and data. I created
two Java applications to manage these connections, one is a 
device proxy server wich receives commands and sends them to 
devices, and the other is a proxy listener which receives 
data from devices and passes them to an application. Here 
are a couple of examples of the Java interfaces:

  TextDisplay.writeln("hello world from LCD display")

  The Proxy Server opens a serial output connection to the 
  BX24, sends the ESC CTL-D code, and then sends the text 
  down the port. The BX24 receives the control code, opens 
  up pin 5 as output, sends the text to the display, times 
  out, closes the LCD port, and defaults back to watching 
  for IR data on pin 13.

  GpsRecever.getPosition()

  The Proxy Server opens a serial output connection to the 
  BX24, sends the ESC CTL-G code, and sends the GPS command 
  down the port. The BX24 receives the control code, opens 
  up pin 11 as output and pin 12 as input, and sends the 
  GPS command to the receiver. The GPS receiver sends the 
  data back on pin 12, and the BX24 passes the data to the
  CPU, times out, closes the GPS port, and defaults back 
  to watching for IR data on pin 13. On the host CPU, the
  proxy listener receives the ESC CTL-G code indicating 
  GPS data, parses the data into variables, and passes 
  the data on to te requesting application. 

Now that I have completed this basic framework for device
multiplexing, I am planning to do some more enhancements
to make a better, cleaner interface. The goals are to 
separate processing based on communication connection 
types (polled/interrupt/process), reduce the amount of 
data sent across the host communication port, and allow
for better prioritizing of tasks. On the microcontroller
side of things, I plan to create separate tasks for 
each of the following:

  - Interrupt Devices - This currently includes only the
    IR remote control, but will soon also include a small
    matrix keypad a couple of buttons/switches, perhaps
    eventually small potentiometers or joysticks. These
    devices are being separated from the others because
    they are interrupt devices that must take priority
    over all others when in use. Also, whenever the other 
    devices are passive, the system must watch for 
    interrupts from these devices. By placing them in a 
    separate multitasked subroutine I can control the 
    priority of CPU cycles that they receive, and also 
    can give them exclusive access to all CPU cycles 
    when in operation. Data from these interrupt style
    devices are passed on to the proxy listener which
    in turn can pass events to applications. The Java 
    approach allows any application (local or remote)
    to subscribe to listening to any device.  

  - Process Devices - These currently include the LCD and 
    LED displays, but could also include other outputs 
    like audible signals or relay control. Requests are 
    managed through the device proxy server on the CPU, 
    and devices are connected by the BX24 microcontroller 
    on demand. Timeouts are set up so that as soon as any 
    given command is processed, the system returns contol 
    immediately to the interrupt devices. On the CPU side
    all of these services are remote interfaces, allowing  
    any process (local or remote) to invoke them.

  - Polled Sensors - The current approach is to have the 
    CPU (not microcontroller) make requests for sensor 
    data. This works fine, but tends to make the overall
    system harder to program, and introduces a lot of 
    serious timing/coordination problems for both the
    interrupt and process devices. I am therefore making 
    a choice to have the BX24 automatically cycle through
    all sensors repeatedly and send them to the CPU. This
    reduces overhead (band width) of incoming commands and 
    makes the prioritizing of CPU cycles much easier.
    Whenever both the interrupt and process devices are 
    passive (no current activity), the BX24 will poll the 
    GPS, ADC, Temp, Humidity, and Barometer sensors and 
    send them to the proxy listener automatically. New 
    commands will allow programs to start and stop the 
    polling and to select the polling frequency. One very 
    nice benefit is that the proxy listener on the CPU 
    always has the most recent data from all of the sensors, 
    allowing very fast acquisition from any local or remote 
    application, without affecting the interrupt and 
    process devices.

On the CPU side of things, I could have a single proxy 
server app manage both requests and responses, but I am 
intentionally separating these. The proxy device server 
is only an invoker, and the listener only receives data. 
Both are remote servers allowing control/monitoring by 
any process (local or remote) on the internet. The proxy
listener in particular will be interesting, since it will 
allow multiple processes to register to be notified of 
any given event, or even a threshold of sensor data. 
For example a remote app could respond to my GPS coords
exceeding specified bounds or call a doctor if my body
temp goes above or below acceptable olerances. The same 
kind of abstraction of services will be done on my home 
and vehicle systems, allowing some very powerful 
notifications/messaging among remote systems. The final 
challenge will be creating the framework that connects 
between my "proxied" devices and the applications that 
use them. I think I will try out the jAugment framework 
for this. My first target apps will be GPS logging and 
mapping, time/location stamping of sensor data, and 
remote monitoring and notificaitons.

This comment is targeted to Marcus Wolschon, the author 
of the jAugment framework, who is seeking testers for
his wearable system. My low level device architecture 
would make a very good testbed for jAugment. I suggest 
that we try to set up the same device framework on your 
system (I can help you do  that quickly), then we can 
work together on the creating of a wearable application 
framework for all of these devices.  One of the really 
cool things is that we could demonstrate powerful 
remote interactions between our wearables from across 
the world (or at least from across the pond). For 
example you should be able to read my sensors and 
display on your text LCD and vice versa. If we work 
together we can iron out the bugs/features in both 
jAugment and my device interfacing/multiplexing code, 
create useful apps for everyone else, and test the 
whole system for general public release. Let me know 
if this sounds interesting to you.     

If anyone else has any questions, feedback, or suggestions
relative to this muxing and interfacing, by all means fire 
away. If you are interested in adding some of all of these 
features to your wearable, stay tuned, I will be making a 
cookbook including schematics, build tips, source code, 
and applications for all of this. 

  -- Java Jacket's Doug Sutherland       

------------------------------------------------------------
  Grow your own Wearables: http://wearables.los-gatos.net
 What I'd like is to have you call me and my jacket answers
------------------------------------------------------------

--
Subscription/unsubscription/info requests: send e-mail with subject of
"subscribe", "unsubscribe", or "info" to 
Wear-Hard Mailing List Archive (searchable): http://wearables.blu.org
please, Please, *PLEASE* don't subscribe through a forward/false domain

+Previous Message in Thread | Next Message in Thread

From Wear-Hard Mailing list Archive (WH)
Maintained by R. Paul McCarty

Archive created with babymail