Using an Arduino with an I2C‑MaxSonar
Table of Contents
- Why use an I2C library?
- Installing the I2C Library
- Loading the I2C‑MaxSonar Code
- How the I2C‑MaxSonar Code Works
- Download the Files
Why use a library?
Use a library because the default Arduino Wire() library does not support changes in bus speed or feature proper clock stretching support. This makes the default library only marginally functional with an I2C‑MaxSonar because the I2C‑MaxSonar currently only supports bus speeds up to 50kHz (without clock stretching) or 400kHz (with clock stretching). Neither of these combinations is available without taking more direct control. Thankfully, Peter Fleury and Bernhard Nebel were able to write an I2C library that uses a bit‑bang approach and has a nifty set of user-defined parameters for greater flexibility in our interface. You can find the library here: https://github.com/felias-fogg/SoftI2CMaster. I am grateful for their work, as it means I did not have to write my own library.Installing the I2C Library
Go to: https://github.com/felias-fogg/SoftI2CMaster and download the I2C library. Install the new library filesLoading the I2C‑MaxSonar Code
First, copy the I2C‑MaxSonar code here into your Arduino Sketch software. Save the code to your working directory. The default location for Windows is %UserProfile%/My Documents/Arduino, but this may vary and you can generally use whatever is most comfortable for you. Load the Arduino Code Connect the Arduino to your PC and to the I2C-MaxSonar Sensor. For wiring diagrams, please reference your datasheet here NOTE: The code defaults to using the SDA and SCL outputs of the Arduino. Edit the corresponding #define statements if you want to use something else. Compile and upload the code. Start the Arduino Serial Monitor. You should now have the I2C code running and reading the connected sensor. Please note that the I2C‑MaxSonar Arduino code defaults to running 3 different code examples.1. Address Polling Example (runs once) – The code will poll all of the available I2C addresses and look for connected I2C‑MaxSonar sensors. The rest of the code assumes that the I2C‑MaxSonar is located at its default address of 224.
2. Change Address Example (runs once) – The code will take a range reading at the default address of 224, change the sensor address to a new address of 222, take a range reading at the new address, then change back to the default address.
3. Read the Sensor Example (runs continuously) – The code will take a range reading from a connected I2C‑MaxSonar at the default address of 224 and output the range information that it received.
How the I2C‑MaxSonar Code Works
I have included 3 functions (one for each command the sensor can do) and 3 different code examples (one for each type of activity a typical user will have to do). I do not go into every detail in this article. (You should read the code notes for that.) I have provided a brief description of what I did at each point. These functions are included so you can easily talk to the I2C‑MaxSonar sensors. If you have other devices on the I2C bus, make the proper modifications to the code to run your other devices as needed. The included functions and their related information are as follows:A. start_sensor(addr)
Description: Uses the I2C library to start a sensor at the given address. You must start the sensor 100ms before requesting a range from it if you want the most recent information.
Parameters: addr: an even byte value corresponding to the 8-bit address of the sensor you want to command a range reading at. The default value for I2C‑MaxSonar sensors is 224.
Returns: errorlevel: defaults to FALSE (value of 0) when the communication is successfully completed. Set to TRUE (value of 1) if there was a communication error.
Note 1: Care should be taken to only operate one sensor at a time. Commanding more than one sensor to range at once may cause cross-talk (interference).
Note 2: addr is always an even value with the last bit being reserved for a Read/Write signal as defined by the I2C specification. Using an odd value will cause the address to automatically be rounded down to the next lowest even number when used.B. read_sensor(addr)
Description: Uses the I2C library to read a sensor at the given address.
Parameters: addr: an even byte value corresponding to the 8-bit address you are reading from. The default value for I2C‑MaxSonar sensors is 224.
Returns: range: an int value corresponding to the distance found by the sensor (for the current I2C‑MaxSonar sensors this is a value between 20cm and 765cm). A value of “0” represents that the sensor could not be read and that there was an error in communication.
Notes: The I2C‑MaxSonar sensors are configured to report the last range reading stored in memory. Because of this, read_sensor() is called after at least 100ms has elapsed after running the function start_sensor(). Readings can be taken faster if absolutely required, but this will limit the maximum range of the sensor. (See the datasheet here for more details.)
C. change_address(oldaddr,newaddr)
Description: Uses the I2C library to change the sensor address at oldaddr to newaddr.
Parameters: oldaddr: an even byte value corresponding to the 8-bit address of the sensor you want to update to a new address. The default value for the I2C‑MaxSonar sensors is 224.
newaddr: an even byte value corresponding to the new 8-bit address of the sensor. A value of "0" is considered invalid and will be ignored.Returns: errorlevel: defaults to FALSE (value of 0) when the communication is successfully completed. Set to TRUE (value of 1) if there was a communication error.
Note: For other devices operating on the I2C bus: It is recommended that you use addresses for the I2C‑MaxSonar that are below 240. This keeps the sensor away from the reserved address space.