Raspberry Pi
MaxBotix sensors have 2 output types that can be easily interfaced with a Raspberry Pi. The Serial output is the preferred method, allowing sensors equipped with a TTL output to easily interface with a UART on the Raspberry Pi. Additionally, I2C sensors can also be interfaced with a Raspberry Pi, but that requires a little more configuration on the Pi side. We will use a Raspberry Pi 3 Model B+ in these examples, but it should be very similiar on any Raspberry Pi SBC.
Most MaxBotix Inc. sensors include a serial output. That output comes in one of two varieties: RS-232 and TTL. Raspberry Pi (and most microcontrollers/Single Board Computers) communicate using TTL by default. RS-232 is useful because this is the protocol that standard serial ports on computers use. The difference between these two protocols is the polarity of the data. In TTL the data is idle HIGH, while in RS-232 the data is idle LOW. Some sensors come equipped with an RS-232 output and some with a TTL output. For use with an Raspberry Pi, the TTL outputs are much more convenient. In this example we will use an MB7388 as it is representative of most TTL sensors.
Three pins are needed to operate a sensor with this output: Power, Ground, and TX. The other 4 pins can be left not connected.
While TTL parts are prefered for use with Raspberry Pi due to the simplicity, it is possible to use an RS-232 part with an Raspberry Pi. If this is desired, you could invert the RS-232 serial data externally to the Raspberry Pi.
More information on TTL Vs. RS-232I2C is a common protocol for connecting sensors and other peripheral devices to controllers. Its primary advantage over other interfaces is that it allows multiple devices to share a bus, thereby dramatically reducing the number of pins and wires needed to operate several devices. MaxBotix offers a product line of I2C sensors which can be easily integrated with most I2C hosts.
The Raspberry Pi has a known hardware limitation that prevents it from reliably making use of clock-stretching. MaxBotix sensors require either a lower I2C Clock speed (such as 50KHz) or clock-stretching. Therefore to use a MaxBotix I2C sensor with a Raspberry Pi, the clock speed must be lowered to 50KHz. see below for more details.
Four pins are needed to operate a sensor with this output: Power, Ground, SCL, and SDA. The other 3 pins can be left not connected. Optionally, pin 2 can be used to detect the end of a ranging cycle, and Pin 1 can be used to make a sensor temporarily reset it's I2C address.
MaxBotix I2C sensors ship with a default address of 0x70 in 7-bit representation (or 0xE0 in 8-bit reprentation). This address can be changed using the change address command (0xAA followed by 0xA5.) and will be preserved through power cycles. If Pin 1 is pulled low during power up, then the address will default to 0x70 for the current power cycle (but will return to the memorized address on the next power cycle.)
There are different ways to represent an I2C address. I2C Addresses are 7 bits long, and are placed in the top 7 bits of the address byte. The 0th bit is used to indicate if this transaction will be a read or a write from the device. Sometimes addresses are represented by ignoring the 0th bit (7-Bit addressing) and other times they are represented by including the 0th bit. In terms of hardware these two systems are equivalent, but different software/languages will refer to this differently. The SMBus library used in this Raspberry Pi example uses 7-Bit addressing.
The Raspberry Pi has integrated 1.8K Pull-up resistors, so we will not need to include them in our wiring. multiple sensors can be connected to the I2C at once. This can be accomplished by individually setting the addresses of each device with only a single device connected to the bus, and then attaching them all to the same bus. Because I2C is a multi-drop bus you can connect all the I2C devices to the same pins on the Raspberry Pi. As long as each I2C device has a unique address, they will all be able to communicate.
I2C requires pull up resistors on both the SDA and SCL lines to operate correctly. I2C devices are Open-Drain which means that they can only pull a line to ground, and cannot pull a line up to Vcc. If a device wants to indicate a 1, it will release the line and allow the pull-up resistors to pull the line back to Vcc. This allows multiple devices to operate on the bus without risk of damaging IO pins or drawing excessive current.
In order to prepare to run the example code, we must change the clock speed of the Raspberry Pi's I2C bus. This can be done as follows:
1) Edit the file /boot/config.txt (One option is to open a terminal and run "sudo nano /boot/config.txt")
2) Add this line to the end of the config file "dtparam=i2c1_baudrate=50000"
3) Save the file (press ctrl-O followed by ctrl-X if using Nano)
Below is Python example code showing how to communicate with a MaxBotix I2C sensor using a Raspberry Pi.
It is often useful to operate multiple sensors within one system. MaxBotix sensors are designed to allow this to be as easy as possible, but there are some things to keep in mind when doing so. Acoustic noise transmitted by one sensor can be picked up by another sensor and misinterpretted as a target.
This image shows an example of how sound can travel through the air and reach another sensor. This will often result in undesirable behaviour.
Due to small differences in timing between the sensors, this echo can return at any point during the ranging cycle of the second sensor and can cause
the sensor to report ranges to targets that don't even exist. There are a few different ways to approach a resolution for this problem.
1) Some sensors are more resilent to this kind of interference than others. The HR line of sensors (Such as 1043, 7388, etc.) include a built in filtering algorithm that can
differentiate between a real target and an echo from interference such as this one.
2) Additionally, all MaxBotix sensors include a method of individually triggering
sensors to take a range reading. Using that method, you can command each sensor to perform a range reading one at a time with a period of time between. This way
there is no chance for interference.
3) Depending on the application is often possible to plan sensor mounting locations such that there is no potential for cross talk between them.
This cross talk can also be helpful in some situations. Some users have built advanded systems that involve processing Analog Envelope signals from multiple
sensors, where one sensor is setup as a transmitter and others as receive-only sensors. This can allow for improved performance in short range detection (similiar
to our Dual-transducer line), the ability to triangulate targets, the use of ultrasonic sensors as beam-break devices and so on.
The MaxBotix TankSensor line of products includes a series of commands that can be sent to the sensor using a UART. These commands can configure settings on the sensor, and allow for debug information to be received from the sensor. Additionally, the sensor includes the capability to memorize the acoustic environment in front of the sensor to improve close range target detection.
Three pins are needed to operate a sensor with serial input and output: Power, Ground, RX, and TX. The other 3 pins can be left not connected.
The commands come in the form of single ASCII characters. The sensor cannot receive commands while it is actively ranging, or while it is stopped (because Pin 4 is held low). Rather, there is a 10 Millisecond window after every ranging cycle where the sensor stops to receive commands. This 10 Millisecond window starts immediately after the final character of range data is output (Carriage Return). If the sensor receives the command outside of this window, it will be ignored. Therefore timing is extremely critical.
Sending commands using a USB-to-Serial converter can be extremely difficult, because the USB bus and driver software often introduce extra latency to the serial connection, potentially greater than the 10mS window. Integrated UARTs often do not include this latency. If a USB-to-Serial connection is required, we have found that USB-to-Serial converters made by FTDI can be made to operate successfully. By default they have 16mS of latency applied to outgoing connections, but this can be changed using their FTD2XX driver which has wrappers for several languages, including Python.
TankSensors can operate in either TTL or RS-232. By default the sensors operate with TTL serial data, but if Pin 2 is pulled low during powerup, the sensor will operate in RS-232 instead.
More information on TTL Vs. RS-232