The protocol is used over serial (RS-232) or similar connections.
The basic element of the protocol is the
message can go in one of two possible directions.
In this document we refer to direction in the terms of who
is sending the message - with two possible sources:
Each message is a single line of text, ending with '\n' (0x0A, newline) character.
Allowed are only ASCII printable characters. Actually used are only the characters explicitly mentioned in any part of this specification.
Each message consists of fields. Each field is delimited by single space ' ' (0x20, space) character. Fields are numbered from 0 (zero). Numbers in fields are in decimal notation unless specified otherwise.
There are mandatory and optional fields.
Mandatory fields are:
|0||MId||2|| “Unique” decimal (00-99) identifier, used in replies. Identifier MUST change by 1 every command from SW.
-1 - invalid id received
-2 - special id for alerts
|1||Type||1||Specific type or command, must be uppercase letter.|
All other fields are optional. They could be mandatory for specific message type (see below).
|C||00 C||00 C M:-99:99 M:0:99 S:0:10||Capabilities|
|M||00 M #1 #2 [#3 #4 …]||00 M OK||Run motor #1 at speed #2, motor #3 at #4 …|
|S||00 S #1||00 S #1 #2||Get sensor #1 value, the value is #2|
|A||—||-2 A #1 [#2 …]||Alert number #1, further fields depend on implementation|
|E||00 E #1 [0/1]||00 E #1 0/1||Query or enable/disable (1 or 0) some feature|
|V||00 V #1 [#2]||00 V #1 #2||Get/set configuration variable|
|W||00 W #1 [#2]||00 W #1 #2||Get/set steering wheel angle - or similar thing|
|R||—||00 R [#1]||Resend line 00, reason in #1|
|I||00 I||00 I OK||Reinitialize uC|
The capabilities message returns a number of fields. Each field has a device type which should correspond to device command (M for motor, S for sensor…) and allowed scale, grouped by : character . For binary devices (triggers, lights) it doesn't report scale. Optionally for sensors it may contain “alert” paramteter, which when exceeded emits Alert message. For sensors where high value needs attention (ie. raw IR sensors) use the value as is, for sensors where low walue needs attention (rangefinder) use negative.
Returned fields order does matter. All devices of given type are given a number according to where they appeared in the capabilities reply. Each device type has its own numbering starting from 0 (zero).
Known capabilities specifications:
|M:#1:#2[:name[:comment]]||Motor, can drive at speeds from #1 to #2. #1<=0 #2>=0|
|S:#1:#2:[#3[,#4…]][:“name”[:“comment”]]||Sensor, returns values from #1 to #2, #2>#1, has configuration variables #3, #4…|
|A[:name[:comment]]||Generated alert, just to know how many are there|
|E[:name[:comment]]||Feature that can be enabled/disabled, just to know how many are there|
|V:#1:#2[:name[:comment]]||Configuration value that can be set with minimum and maximum values, #2>#1|
|W:#1:#2[:name[:comment]]||Steering wheel with minimum and maximum values, #2>#1|
|SW:||00 C||Hi, who's there?|
|uC:||00 C M:-99:99 M:-99:99 S:0:10:0:“Proximity”:“0 - alert level” A|| Hi,
two motors running -99 to 99
one sensor that detects 0 to 10 with configuration variable 0
One alert possible
|SW:||01 V 0 10||Set alert level on sensor 0 to 10|
|uC:||01 V 0 10||Ok, we did it.|
|SW:||02 M 0 50 1 -50||Start spinning|
|uC:||02 M OK||We started.|
|—||—||Sleep for some time|
|SW:||03 M 0 0 1 0||Stop spinning|
|uC:||03 M OK||We stopped.|
|SW:||04 M 0 50 1 50||Drive forward|
|uC:||04 M OK||We're driving.|
|—||—||Sleep for some time|
|uC:||-2 A 0||Alert 0: Interpreted as something on sensor 0|
|SW:||05 S 0||What is the value of your sensor 0?|
|uC:||05 S 0 10||Sensor reports 10, the highest value (say it means there's an obstacle)|
|SW:||06 M 0 0 1 0||Stop driving.|
|uC:||06 M OK||We stopped.|
Current example implementation as a “library” for Arduino development can be found at http://repo.joe.cz/brmbot/annotate/head%3A/brmdriver/brmprotocol.h. Feel free to suggest improvements.
This document specifies BRM protocol version 1.