RadioCommTest (vague) Instructions This archive contains code to test radio communications on the Mica Motes. It is actually a robot control application but has been slightly extended to do message request/reply cycles just about as fast as they can be done. Within the message code radio ACKs are implemented, as well as sequential access to both the radio and UART using the GenericComm component. In addition to the message code, there is code for using PWM outputs, binary inputs, and low-level ADC access. It's just about everything I know about the mica2 and micaz, and some parts may be edible. I make no representations as to suitability, paridigmatic TOS usage, or clarity of vision... The three directories in this archive should be copied into the tinyos-1.x/contrib/xbow/apps directory. They are: Mote -- A host side java command line driver for tests. Robot -- The re-Mote TOS program for mica2 or micaz. TOSBase -- Slightly modified for use of radio ACKs. They are compiled using j2sdk1.3.1_10 (so the host program should work for everyone), and tinyos-1.1.10Jan2005cvs-1 under Windows XP and cygwin. The mica2 versions are known to work under TOS v1.1.7 but the micaz does not, due to Framer.nc discrepancies (I think). Use: 1. Both the TOS projects contain binaries for mica2 and micaz. They use groupID 51 (0x33) and the default xbow radio settings for channels and power, set in MakeXbowlocal. They assume that the TOSBase is set to moteID 0, and the re-Motes are sequential starting at ID 1. You should be able to download "Robot" to a number of re-Motes using: make mica2 reinstall.1 make mica2 reinstall.2 ... And then down load "TOSBase" to the basestation mote with: make mica2 reinstall.0 You may use micaz instead of mica2 as you wish... You may also recompile using the standard techniques, but note that the TOSBase.nc and Robot.nc files should be modified to switch between mica2 and micaz...this is due to different files being used to enable ACKs... As loaded they are set for mica2. 2. The Mote directory contains a "run.sh" file which should execute the RadioCommTest program. Just execute this file in a cygwin bash window. It assumes that you have an appropriate Java JRE in your path, and the MOTECOM environment variable set to: "serial@COM1:mica2" or whatever your basestation port. (Note: use mica2 for both the 2's and the Z's !???) You should see something like this: serial@COM1:57600: resynchronising ?>> If you hit it will try to send a status request message. You should see the TOSBase LEDs flash as normal: TX(34) d=1 h=34 g=51 l=29 s=0 n=1 :: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 write ACK failed, retry NFG ?>> If you have one or more re-Motes turned on you may see replies: TX(34) d=1 h=34 g=51 l=29 s=0 n=6 :: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 write ACK failed, retry NFG d=0 h=10 g=51 l=29 s=1 n=6 :: rs=0 mt=0 tt=0 bm=0 bl=0 bc=0 a0=0 b0=0 a1=0 v1=0 td=0 ts=0 od=0 rs=88 na=6 nm=1 d=0 h=10 g=51 l=29 s=1 n=6 :: rs=0 mt=0 tt=0 bm=0 bl=0 bc=0 a0=0 b0=0 a1=0 v1=0 td=0 ts=0 od=0 rs=88 na=7 nm=0 ?>> The "write ACK failed" message means that the message send did not receive an ACK and so a retry was attempted. The "retry NFG" means that the retry didn't get an ACK either. In the above it can be seen that the failed ACKs are meaningless because we got a two replies, one for each request... If you type a '?' you will see a terse command list: ?>> ? SPACE--delimiters!! -- get status Command movetime turntime mspd tspd... DestAddrs [...] (-1 for bcast) Halt Run delay logtype time Status statbits txstrength Quit All of the above will (may) be explained later in this document. Note that the Mote/classes directory contains two jar files: rct.jar -- The RadioCommTest application files. tinytools.jar -- The TOS tools/java/net classes. There is one small change to the tools files. Packetizer.java has final ACK_TIMEOUT changed to a public in order to facilitate ACK testing. Otherwise you can use the standard tools if you get into modifying and recompiling... There is also a Makefile that will build the application classes and rct.jar should you wish to go that route. The project was developed under Eclipse, so there are a couple tracking files that may be useful if you want to load the whole thing up. 3. A (perhaps) clearer description of the testing methodology and components can be found at the site containing this archive: http://www.etantdonnes.com/Motes/ RadioCommTest Host Program usage: RadioCommTest [output-file] where: output-file is an optional logfile for the Run command The RadioCommTest program sends three types of messages to re-Mote devices and prints any replies that are received. All messages are the full TOSMsg length with 29 byte data payloads. The message structs are in Robot/RoboMsg.h and the Java equivalents (hand done, not MIG generated) are in Mote/src/com/etantdonnes/tinyos/robo: RoboMessage.java -- base class. RoboStartReq.java -- robot command message. RoboStatReq.java -- status request message (we use this...) RoboStopReq.java -- robot halt message. RoboStatMsg.java -- status reply message (we use this...) RoboStatMsg's are sent in reply to all command requests. Since the actual use of the system is for robot motion control, status replies to RoboStartReq's will be delayed by the amount of time needed to execute the motion. For communication testing we only use the RoboStatReq and expect to get a RoboStatMsg forthwith. When started, the RadioCommTest uses the MOTECOM environment variable to attach to the appropriate serial port and basestation and then does the standard synchronization cycle. This is done in the TOS tools/java/net/tinyos/packet/Packetizer.java file and it's cohorts. Once cranked up RadioCommTest sends a '?>> ' prompt to the shell window. Any of the commands shown above may be entered at that time. Only the first letter of the command is significant and case is ignored. Arguments may follow the command and are always space delimited (commas don't work). Commands: -- get status This sends a status request to the first re-Mote in the DestAddrs list. Typically you should see: TX(34) d=1 h=34 g=51 l=29 s=0 n=1 :: 0 0 0 0 .... where: TX(34) -- Transmit 34 bytes total. d=1 -- Destination mote Id (from destAddrs list). h=34 -- Handle ID (message type) 34=statReq, 10=statReply. g=51 -- Group ID (set in MakeLocal and in RoboMessage.java). l=29 -- Payload data length in bytes. s=0 -- Source mote Id, 0=TOSBase. n=1 -- Message serial number (will increment on each request). 0 0 0 0 .... -- byte dump of message payload. Status Reply messages will be printed to the shell window: d=0 h=10 g=51 l=29 s=1 n=1 :: rs=0 mt=0 tt=0 bm=0 bl=0 bc=0 a0=0 b0=0 a1=0 v1=0 td=0 ts=0 od=0 rs=88 na=6 nm=1 where: d, h, g, l, s, n -- the same as the command fields. Note that the dest and src mote Id's should be reversed. The rest up to 2nd "rs" are robot status which can be reverse engineered from the header and class files... rs=88 -- The received message RSSI value at the re-Mote. na=6 -- Number of missing message ACKs on the last cycle. nm=1 -- Message sequence number difference from last message. The last two are described in more detail under the Run command. Command movetime turntime mspd tspd... This sends an actual motion command to the Robot. Again you can reverse engineer the thing via the headers and classes if you are interested... DestAddrs [...] (-1 for bcast) This sets a list of destination mote Ids that will be used in the Run test. The first value will also be used for regular status requests. If the first value is -1, a BroadCast message will be sent. See Run command for more details. Halt Sends a RoboStopReq message to the Robot. Should get an immediate status reply. Run delay logtype time This does a status request message loop. This is the real comm test. The arguments are: delay -- Milliseconds to wait between request sends. logtype -- Type of output log to keep, see below. time -- Number of seconds to run loop test. The "delay" time is a throttle on message sending and turns out to be quite significant. From experiment with mica2's it seems that about 50ms is required between the end of a statReq and the beginning of the next, or else statReplies are lost with disturbing frequency. The "logtype" switches between the standard status message dump as shown above and an accumulator log that is more relevant to the Run test. A value of 0 will use the standard status request/reply dump and anything else will use the accumulator log. The accumulator log looks like: dev ts sn wr msg !ack rssi na nm 1 0 57 51 81 1 92 34 1 1 200 59 50 60 1 88 35 1 1 101 58 50 Drop 1 xxx Where each line represents one message request/reply cycle. The lines will normally be in message order except when a message is dropped. The fields are tab delimited and are: dev -- Re-Mote Id. ts -- Timestamp (ms) when request began sending. sn -- Serial number of message. wr -- Write time in ms. msg -- Full message cycle time in ms (start to reply finish). !ack -- 1=not ACKed by re-Mote. rssi -- Re-Mote received signal strength. na -- Replies not ACKed at re-Mote. nm -- Difference in sequence number between received messages. Note that when a message is dropped the full msg time is "Drop", and the !ack field can indicate whether it was received or not (missing ACKs turn out to be much higher than expected so this is not a good indicator). Dropped messages are 'garbage collected' a couple seconds after they are expected, so the log is out of order. Also the "nm" field can be used to determine if a request was not received at the re-Mote when the value is >1 (for single device tests, caveats apply and are supposedly handled in the Run accumulation logging). When the test run completes a summary line is printed for each device, and then a total for all, the total has dev=0: dev msec msgs m/s !ack %!ack drop %drop minWR avgWR maxWR \ ACM 1 902 10 11.09 10 100.00 1 33.00 50 50 51 minMS avgMS maxMS avgRSSI noack % nomsg % \ 60 74 81 86 3 100.00 0 0.00 devs bcast delay state txstr 1 false 50 2 255 where: dev -- Re-Mote Id. msec -- Length of test in ms. msgs -- Total messages sent. m/s -- Messages per second. !ack -- Total missing ACKs from re-Mote. %!ack -- Missing ACKs percent of total msgs. drop -- Total messages dropped (no reply received). %drop -- Dropped messages percent of total msgs. minWR -- Minimum write time (all in ms). avgWR -- Average write time. maxWR -- Maximum write time. minMS -- Minimum message time, only successful msgs (all in ms). avgMS -- Average message time. maxMS -- Maximum message time. avgRSSI -- Average re-Mote received signal strength. noack -- Missing ACKs at re-Mote. % -- Percent of replies missing ACKs. nomsg -- Number of request messages not received at re-Mote. (Calculated from sequence number differences.) % -- Percent of missed requests. devs -- Number of re-Mote devices used in test. bcast -- true if request messages sent in BroadCast mode. delay -- Request throttle delay. state -- Message statbits state, see Status below. txstr -- Request transmit strength (not impl, always max). The Run test sequence can be in two different modes depending on the DestAddrs setting. If the first destAddr is -1 then a BroadCast request message will be sent, and a reply expected from each specified re-Mote. This is done by setting DestAddrs as such: d -1 1 2 3 [...] The first -1 specifies Bcast, and the following numbers are the re-Mote Ids that are expected to participate in the test. There can be up to 10 (arbitrarily set in LogMessageTest.java) re-Motes, and their Ids must be between 1 and 10 (I was lazy in implementing the accumulators). In this case one status request will be sent every write+"delay" period, and all re-Motes will try to reply. Any replies that are outstanding after a couple seconds are assumed to be dropped messages and logged accordingly. The second mode is a Round-Robin test where each re-Mote is addressed individually in sequence. This is done by setting DestAddrs as such: d 1 2 3 [...] Now a status request will be sent to re-Mote Id=1 and after a pause of the "delay" length a request will be sent to re-Mote Id=2, USW... Missing replies will be logged as dropped as above. The Bcast test causes all the re-Motes to attempt to reply at the same time and allows some evaluation of the CSMA behavior while competing for airtime. The Round-Robin test gives a good estimate of how many well-behaved messages can be handled in a system. Note about ACKs...they don't work very well, and the re-Mote "noack" counters are very reliable either, so don't put too much faith in it. Fixes for such are welcome... Status statbits txstrength Like the bare this sends a status request message to the first re-Mote in the DestAddrs list (or Bcast if so set). But it allows the setting of some global parameters...actually one because txstrength is not implemented (or not tested really). statbits -- Sets the response mode: 0 -- Normal. 1 -- Shut off ACK sends at re-Mote. It should shut off ACKs at the TOSBase too, but I just recompile... 2 -- Shut off Robot retry mechanisms. The Normal mode is my attempt to make messaging more reliable. On the host side, if a ACK is not received for a send, the request is resent once. A resend is also done on the re-Mote side if a reply does not receive an ACK. Setting statbits=1 disables the ACKing at the re-Mote so it doesn't ask for a an ACK. Setting statbits=2 shuts off the resends, but still sends ACKs to messages. Setting statbits=3 shuts off everything so it's just one-request,one-reply,no-ACK. This is a kludge to avoid having to reload all the re-Motes to do no-retry tests. The Run command always uses statbits=2 so there are not retry attempts, but you can shutoff ACKS during Run by using "Status 3" before starting the Run. Quit Stangely enough does exactly what it says.