Maxbotix Controller Copyright 2007, Gerald Duprey Overview: The MaxBotix ultrasonic ranging sensor (http://www.maxbotix.com) is an amazing sensor that makes it very easy to determine distance from 6 to 255 inches. While easy to interface (you can hook it right up to a serial port), it does send a continuous stream of readings, even when nothing is changing. This can be a bit of a burden on whatever hardware is listening to it. Further, if you need multiple sensors in close proximity and leave them all on, they will start to interfere with each other. The front end is designed to connect between one (or more) maxbotix sensor and the computer. It will constantly read the sensor(s) and can be configured to send a report when a sensor detects movement. If connected to multiple sensors, it polls each one, shutting the others off to prevent them from interefering with each other. As a result, a single serial port can accept readings for multiple sensors and receive data to process only when something "interesting" happens (which is usually a lot less overhead than continously reading/re-reading the sensors and checking for a change. Each sensor can be configured to one of 5 reporting modes or be disabled. Sensor configurations are stored in EEPROM, so once set, they do not need to be reconfigured again (though, of course, they can be). Unused sensor control lines can also be used as digital outputs or inputs. The state of those outputs can be controlled either via serial command or be tied to a sensor and reflect if that sensor is "in range" or not. This can be used to create standalone units (where a digital output turns someting on (or off) when a sensor finds an object in range) or just for controlling digital devices at the location where the board is installed via a single shared serial line. Inputs can be polled or set to send reports when they change and have optional debouncing support for connection to mechanical switches. Hardware: The controller is designed to be easy to build and use a minimum number of parts. Only 8 parts are needed for a single sensor controller, 11 parts for a 2 sensor controller, 12 parts for a 3 sensor controller, etc. For a single sensor front end, the parts consists of a PIC 16F88 or 16F87 controller, a MAX232 RS232 level shifting chip and 6 capacitors (4 for the RS232 charge pump of the MAX232, and the others as power filters for the MAX232 and PIC 16F87/88. For a 2 sensor front end, you need to add a diode to each each sensor (including the first) and a single "pull down" resistor, bringing the parts count to 11. For a 3 sensor front end, a single additional diode is added for a part count of 12 and so on. The controller is very forgiving of external conditions, so nearly any assembly technique will work (breadboard, perf/vero board or PCBs). The pin assignements on the PIC are: RA0-4, RA6-7, RB1, RB2-4 and RB6-7 are device select lines. The order listed here corrosponds to the sensor number (i.e. RA0 is sensor 0, RB1 is sensor #7, etc). The line should be hooked to the sensors RX connection. This is the case even if there is only a single sensor. RB0 is the input from the sensors, tied to the TX connection. If there is a single sensor, it can be directly wired to RB0. If there are multiple sensors, then each sensor has it's own diode to isolate them and there is a single 1k pulldown resistor. You can use this arrangement with a single sensor setup as well if needed. RA5 controls the baud rate from/to the computer. Low/0 is 19200 baud, High/1 is 9600. Baudrates are checked only when the chip powers up or reboots -- changes made after that are not picked up until the next reboot/power cycle. RB2 & 5 and the computer serial in and out and feed to a MAX232 to get the requires RS232 signal levels. Communications Protocol ----------------------- The comm protocol is a simple text based protocol that consists of a lead in character (a dollar sign), a number of hex characters (always a multiple of 2) and a line terminator (a CR -- ASCII 13). There may also be a LF after the CR, but any sending or receiving code should ignore anything before a $ and after a CR to be compatible. Sensors are addressed using hex numbers 00 (First sensor) through 0B (last sensor). All alpha characters MUST be in upper case. Data is send and received at either 9600 or 19200 board in 8 bits, 1 stop bit, no parity format. All commands sent to the controller will be confirmed with either a $F0 (command accepted) or $F1 (command rejected). The controller should wait to get a response code back before sending another command. As a safety, the controller should abandon that wait after some time (10 seconds is a goodly amount) in case something goes wrong. Commands: --------- $10SSFF[PP[HH]] Configure sensor line SS (00-0C) as a sensor or digital I/O with flags FF and optional parameters PP and HH For Sensor configuration: Bit 0-2 - Sensor Reporting Mode 000 - Disabled (not checked/reported/used) 001 - Polled 010 - Periodic 011 - Triggered 100 - Inclusive Range 101 - Exclusive Range (other values reserved) 3 - Must be 0 to configure a sensor 4 - Send Value Change Reports ($91) 5 - Send Range Change Reports ($92) 6 - Simplified Range Change Reporting ($92) 7 - Enable Anti-Jittering The number of bytes varies for each mode. For a polled or disabled mode, the entire command is 6 bytes. For triggered and periodic, it's 8 bytes and for exclusive or inclusive range, it's 10 bytes/characters. If Periodic, then PP is # of seconds between reports. If Triggered, then PP is # of inches change before a report is sent If Inclusive or Exclusive Range, then PP is the low end and HH is the high end. Inclusive/Exclusive mode is similar to triggered, but only reports changes when they occur within a range and sends a report when an object moves into range and then out of range. Movement outside the range is not reported (though you can still query/poll the sensor any time for a valid reading). Bit 4 controls whether value change reports ($91) are sent when a range reporting mode is active. If set, then all changes while an object is in range are sent. If clear, then changes are not sent (though you can still query the sensor). This applies only to periodic, triggered, inclusive and exclusive range and digital input (below) modes. Polled never sends anything automatically. Bit 5 controls whether range change reports ($92) are sent when an object moves into and out of the sensors range. If enabled, the report is only sent on the transition even from in or out of the range (once in the range, only value change events, if enabled, are allowed). If disabled, then you will not receive reports when objects move in and out of range. Bit 6 is similar to bit 5. When set, it enables simple range reporting mode. Instead of reporting the direction of the entry or exit from a range, it reports a single "in range" or "out of range" message. You loose some info, but you gain a very easy to match against message for HA systems that can handle only direct string matches. You should generally set either bit 5 ot 6 but not both when tracking range changes. NOTE: For all modes but polled and disabled, you must enable at least one of the above bits to receive any update messages. If the appropriate reporting bits are not set, you can stil query the sensor for it's current value. Bit 7 controls an internal "anti-jitter" filter for a sensor. In some cases, the sensor can occasionally report a odd, one-time and often wildly inaccurate reading. This can be caused by vaugeries in the sensors mechanics, temporary changes in the sensing environmment, thermals and just plan unexplainable phenominom (no, not implying ESP or the like). It does happen with these sensor from time to time. The Anti Jitter filter will suppress sending out reports of a new value until the same value has been read 3 times in a row. Once that happens, the value is reported (if reporting is enabled). Settings this can slow sensor response down to around 1/3rd a second to 1/2 a second (which is why it's an option). If you need immediate feedback (i.e. "fast" moving devices), then don't use this, but do have some sort of logic that can deal with getting a scenario like a 8 inch report, then a 30 inch report and then an 8 inch report again without freaking out. All sensors initially are defined as disabled. Sensor configuration is stored in EEPROM so it only has to be set once. NOTE: If the identified sensor was being used as an output or input, this command will overwrite the output settings and change it to being a sensor. For Digital I/O configuration: Bit 0-2 - Output mode 000 - Manual Output Mode 001 - Range Output Mode 010 - Pulse Output Mode 011 - 100 - Digital Input Mode 101 - 110 - 111 - 3 - Must be 1 to configure as Digital I/O For Outputs:: 4-5 - Output State control (meaning depends on mode) 00 - Tristate/Hi-Z output 01 - Low 10 - High 11 - Reserved 6-7 - Alternate Output State control (meaning depends on mode) 00 - Tristate/Hi-Z output 01 - Low 10 - High 11 - Reserved For Inputs:: Bit 4 - Send Value Change Reports ($91) 5 - 6 - 7 - Enable switch Debounce processing For manual outputs, bits 4 & 5 determine the state of the output pin at powerup or after any reboot. Bits 6 & 7 are ignored. The state of the output is changed only by receiving a $15 command. Note that changes to state are NOT stored in EEPROM. If there is a power fail or reboot, the default state specified in bits 4&5 are installed, regardless of the state of the output before the reboot/power cycle. For range outputs, bits 4&5 indicate the state of the output when the associated sensor does not detect anything in the target range and bits 6&7 define the state when there is something in the target range. PP defines the sensor to monitor. The PP sensor # should be valid, not the same as SS (i.e. you can define a reference to yourself) and should be a sensor (not an output, input or disabled). The command will still succeed if the sensor is currently an output but is a not a "range" sensor, but the output will take on the state of bits 4&5 and not change until the monitored sensor is set to a range based sensor. For pulse outputs, bits 4&5 define the state of the output when there is no change in the related sensor (i.e. idle state). Bits 6&7 are used to indicate the state the output should take when being pulsed to indicate a change in the related sensors value. PP defines the sensor to monitor. The PP sensor # should be valid, not the same as SS (i.e. you cannot define a reference to yourself) and should be a sensor (not an output, input or disabled). The command will still succeed if the sensor is currently an input, output or is disabled, but the output will take on the state of bits 4&5 and not change until the monitored sensor enabled as a sensor. NOTE: The pulse only occurs when the value for the sensor changes. For triggered sensors, that means the sensor reading changed by the minimum report amount for the sensor. For all other sensor reporting modes (which do not have a minimum change reporting amount), the change threashold is 1. NOTE: When an output is in Hi-Z mode, it will not be putting any current out on the line. However, the line is still electically connected to the controller internal circuitry. This means that you should not put any out of range voltages on that line (i.e. anything outside of 0-5 volts). Doing so will likely damage the controller. For a digital input, the state of the input is checked regularly (approx every 100us). If you want to receive reports when the value changes, be sure to set the auto-report option bit which will cause a $91 report any time the state of the input changes. If that auto-report bit is not set (or even if it is), you can still query the sensor manually (i.e. poll) for the current status of the pin. Returned values are 00 for an input that is LOW and 01 for an input that is HIGH. If the debounce bit is set, the input is assumed to be mechanical and a new state change isn't registered until the input stops changing for more than 10ms (i.e. after the switch stops bouncing). NOTE: If you manage to read a digital input in the very brief time after it's setup but before it has a chance to sample the pins, you will receive a value of FF indicating the current state of the digital input is unknown. This occurs for only a very brief period of time after a reboot or setting up a digital input line and is usually valid within 100us of the transition. While unusual, if you depend on this, you should handle the case of receiving an FF back and discarding the sample, considering only values of 00 and 01 as valid. $15SSFF Set the state of output SS. That sensor must be configured as an output and FF describes the new state. That state is not stored in EEPROM and if there is a reboot or power cycle, the initial/default value for that output is installed. If this command is issued for any non-output, the command will fail (return a $F1). Changes to non-manual outputs are subject to being overwritten by the outputs control mechanism (i.e. something comes into range, changes in sensor values, etc). FF flags are defined as follows: Bits 0&1 - State of output 00 - Tristate/Hi-Z output 01 - Low 10 - High 11 - Reserved 2-7 - reserved NOTE: When an output is in Hi-Z mode, it will not be putting any current out on the line. However, the line is still electically connected to the controller internal circuitry. This means that you should not put any out of range voltages on that line (i.e. anything outside of 0-5 volts). Doing so will likely damage the controller. $20SS Query Sensor SS for it's current value. Causes a $81 value report to be sent. This will always report the actual range, regardless of the "Simple Message Mode" bits. For outputs, the returned value will indicate the current state of the output (details in the $81 report). For inputs, it'll report the current state of the input (either 00 for LOW or 01 for HIGH). Note that if you query an input while it's in the process of debouncing a switch (assuming the debounce option is enabled), you will get the last VALID state which may not be the state the switch is in the process of changing too. Once the debounce cycle is complete, further reports will include the new state. $21SS Query sensor SS for it's configuration. Causes a $83 report. $22 Query Board Configuation. Causes a $80 reports $FF Reboot the board. All hardware is reset, all sensor configurations are re-read from EEPROM, the baudrate is checked on RA5 and changed (if needed), etc. The $FF will cause a $F0 to be immediatly returned. After the controller reboots, it will issue a $90 event report. If you initiate a reboot and get a $F0 back, you should refrain sending any commands until you see the $90 report, indicating the front end is up and running again. This can take up to 4 seconds in some cases (if the board was writing EEPROM when $FF was received, for example). Status Reports Status reports are sent as a result of request commands ($2x series commands). -------------- $80MMnnPPSSFF Current board configuration. MMnnPP are the current firmware version (MM: Major version, nn: minor version, PP: patch level). SS is the number of sensors (to allow for using larger and smaller chips to control less and more sensors). FF is controller status flags. Flags are defined as Bit Meaning 0 EEPROM invalid, factory defaults used 1-3 Reserved 4 Last restart was PowerUp 5 Last restart was a WatchDog reset 6 Last restart was a Brown Out reset 7 Last restart was manual (i.e. $FF) NOTE: The length of this report may change in future versions. The above will not change, but there may be additional items added to the end. $81SSVV Result of a $20 Query, returns the current value, VV for sensor SS NOTE: Disabled sensors will always report a value of 00 if queried. For outputs, the value returned is read as: Bit 0&1 00 - Tristate/Hi-Z 01 - Low 10 - High 11 - Reserved All remaining bits are reserved for future use. For inputs, the value returned is read as: Bit 0 - 0 if input is low, 1 if input is high All remaining bits are reserved for future use. NOTE: If you qoery an input (via $20) while the input is in a debouncing state (assuming the input has the debounce option), you will get the last stable state before the debouncing/change was found. The actual state of the input is not reported back until after the debounce period. Most of the time, this is excatly what you want if you have enable debouncing, but in certain very timing sensitive situation, it's important to know why your logic probe (for example) may show a different state than being reported. In most cases, debouncing is over within 10ms (it can take longer for very noisy switches). $83SSFF[PP[HH]] Current configuration for sensor SS with FF and optionally PP and HH having the same definition as they have in the $10 command. Event Reports Event reports are sent when something is actually changed (and that report is allowed) ------------- $90MMnnPPSSFF Same as the $80 report, but sent as a result of the board powering up or the board rebooting/reseting. After powerup, it is sent one second after the board powers up. NOTE: The length of this report may change in future versions. The above will not change, but there may be additional items added to the end. $91SSVV Sensor/input value changed report. Result of a change in a sensors value (for triggered/range sensors) or periodic time (for Periodic sensors). SS is the sensor, VV is the value. This report is only sent if value change reports are enabled for a sensor (triggered, timed or range mode with the values changed bit and the value in range) of for digital inputs with reporting enabled. NOTE: If the sensor is in range mode and has the bit set to send range change reports, upon transition into a range, the range change report will be sent first, then the current value. Keep in mind that depending on how fast an object is moving, the first value report when the object is in range may be several inches higher or lower than the range limits. NOTE: If bit 4 in the sensors configuration flags is 1 and the sensor is configured as an digital OUTPUT, there will be no $91 reports sent under any circumstances. NOTE: If bit 4 in a sensors configuration flags is 1 and the sensor is configured as a digital INPUT AND input state change reporting is enabled, the input will generate reports (see $81 for important notes on the effect of debouncing on inputs). $92SSRR Sensor range changed report. If enabled and if the sensor is in range mode, this report is sent whenever a range is entered or exited. If you also have value reporting enabled, upon entry into the valid range, this report will be sent first, then the actual value report. RR describes the type of range change. Changes are described as coming into range or going out of range and whether the entry/exit is from the high end or low end of the range. If the Simplified Range Change Reporting is disabled, RR will be one of: 00 - Transition out of range via the low range limit 01 - Transition out of range via the high range limit 10 - Transition into range via the low range limit 11 - Transition into range via the high range limit If the Simplified Range Change Reporting is enabled, RR will be one of: 00 - Transition out of range 10 - Transition into range If neither bits 5 or 6 of a sensors configuration flags are set, there will be no $92 reports sent under any circumstances. Also, if the sensor mode is not inclusive or exclusive range mode, no $92 reports will be sent for that sensor. NOTE: Digital I/O sensors never generate a $92 report. Command Confirmations Sent after every command sent to the controller --------------------- $F0 Sent to confirm last command was received, valid and completed. Note that for some commands, the command may generate responses before the command completes. So you may receive reports or triggers after a command is sent but before the $F0 or $F1 is returned. $F1 Sent to indicate the last command was invalid or encountered an error while executing (i.e. bad command code, invalid sensor #, invalid configuration command, etc). Last Updated: January 27, 2007