In this instructable, I will explain how to use I2C on the Pi, with the examples of the CMPS03 compass module and SRF08 Ultrasonic range, using python. I will explain right through installing the OS, to ensure that the dependencies and everything is installed.I2C is a communication bus designed by Philips, for chips to communicate with each other on a PCB.
It is commonly used, however, for connecting sensors, such as the two examples later in this instructable and port expanders, because you can have multiple devices on the same two pins. The next thing to do is add the I2C module to the kernel.
Run the command sudo nano /etc/modules.You should see the following file: # /etc/modules: kernel modules to load at boot time.## This file contains the names of kernel modules that should be loaded# at boot time, one per line. Lines beginning with '#' are ignored.# Parameters can be specified after the module name.snd-bcm2835This should have the line i2c-dev added to the end.Final file: # /etc/modules: kernel modules to load at boot time.## This file contains the names of kernel modules that should be loaded# at boot time, one per line. Lines beginning with '#' are ignored.# Parameters can be specified after the module name.snd-bcm2835i2c-dev. There are a few packages that will need installing to use I2C. The first command to run is sudo apt-get install i2c-tools. If this fails, try running sudo apt-get update and try again, else run crying to your nearest nerd. The other package needed can be installed by running sudo apt-get install python-smbus.To configure the software, we will add the Pi user to the I2C access group, by running the command sudo adduser pi i2c.Now run sudo reboot to reboot, and test the new software.To test the software, run the command i2cdetect -y 0 to see if there is anything connected.
On my setup, it returned this output, because there was nothing connected: 0 1 2 3 4 5 6 7 8 9 a b c d e f00: -10: -20: -30: -40: -50: -60: -70: -. We now have everything ready to start using I2C!To use the CMPS03 compass module, connect the power to V+ and 0V, from the Pi. I used the 5V line, which they recommend not doing because it might damage your pi, It worked for me, and has caused now damage, but I am not responsible if your's fries.Then, connect the SDA and SCL lines to the Pi SDA and SCL, and you are ready to roll. The wiring diagram is shown at you have connected it, run the command 'i2cdetect -y 0'. In my case, this returned: 0 1 2 3 4 5 6 7 8 9 a b c d e f00: -10: -20: -30: -40: -50: -60: 60 -70: -This shows that the module is on address 0x60. You then need the following python file: import smbusimport timebus = smbus.SMBus(0)address = 0x60def bearing255:bear = bus.readbytedata(address, 1)return beardef bearing3599:bear1 = bus.readbytedata(address, 2)bear2 = bus.readbytedata(address, 3)bear = (bear1. The second example is the SRF08 range sensor, with built in light sensor.Wire it in in exactly the same way as before, with power, SDA and SCL connected to the Pi.
I found that this sensor would not work off 3.3V, but again, I bear no responsibility for you putting 5V through your Pi pins. You can even leave the compass module in as well, because I2C can handle multiple devices on one line. The wiring diagram can be seen here:.Run i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f00: -10: -20: -30: -40: -50: -60: 60 -70: 70 -Note that I have left the compass module connected.You will then need the following python file. It is more complex, becuase you have to write a command to the sensor to get it to begin reading.
Import smbusimport timebus = smbus.SMBus(0)address = 0x70#SRF08 REQUIRES 5Vdef write(value):bus.writebytedata(address, 0, value)return -1def lightlevel:light = bus.readbytedata(address, 1)return lightdef range:range1 = bus.readbytedata(address, 2)range2 = bus.readbytedata(address, 3)range3 = (range1. Do you have access to an oscilloscope?
I've always had a lot more luck understanding what's going on when I can see what they're sending back and fourth. I have some experience with both PICs and the Raspberry Pi, but I've noticed that the PIC freaks out a bit more readily than a Raspberry Pi with i2c. Make sure that the speeds are set up accordingly (although this shouldn't be a problem with i2c).
Start Programming Python With Raspberry Pi
Another thing is, you could just transmit things over GPIO pins on your own. What are you trying to do?
I2c may not be the only thing that can accomplish the goal you want.
.For the first part of this we will be using a single push button. Normally the top two pins and bottom two pins are not connected, but when pressing the button a connection is formed, allowing current to flow.
We will put a 330 Ohm resistor in-line with the switch to protect the GPIO ping from recieving too much current.I have used GPIO4 for this example, but any GPIO pin not otherwise in use will work fine, just update the pin number in later code samples. Important: Never connect GPIO pins to the 5V power supplyThe two 5V supply pins on the breakout board are very useful for powering complex chips and sensors, but you must take care to never accidentally use them to directly interface with the GPIO pins. The GPIO system is only designed to handle 3.3V signals and anything higher will most likely damage your Raspberry Pi.
Remember that you must run your interpreter as root (ex. Sudo ipython).First we need to configure the GPIO pins so that the Raspberry Pi knows that they are inputs: import RPi.GPIO as GPIOGPIO.setmode(GPIO.BCM)GPIO.setup(4, GPIO.IN, pullupdown=GPIO.PUDDOWN)The pullupdown argument controls the state of the internal pull-up/down resistors. Looking back at the circuit diagram above you can see that when the button is not pushed, the GPIO pin is effecitvely not connected to anything.
This is referred to as 'floating', and it means that the voltage there can be unpredictable. A pull-down adds an additional resistor between the pin and ground, or put simply forces the voltage when the button is not pressed to be 0.With the pin configured we can now do a simple read of the button: print GPIO.input(4)This should output False if the button is released and True if the button is pressed. Try it a few times each way to make sure you wiring and configuration is correct. While directly checking the state of the button is nice, often we want to take action at the moment the button is pressed. To do this we will use the edge edection mode of our RPi.GPIO library: GPIO.addeventdetect(4, GPIO.RISING)def mycallback:print 'PUSHED!' GPIO.addeventcallback(4, mycallback)Internally this starts a background thread that watches for state transitions, in this case we have specifically asked to only be notified of transitions from False to True (or more specifically, from 0 to 3.3V on the pin).
Raspberry Pi Python Install
While the use of this background thread is suffcient for most simple applications, complex asynchronous applications may want to use something like Twisted.As you press and release button you may see some instances where PUSHED! Is printed more than once during a single press, or possible printed while you are releasing the button. This is because our simple circuit is very 'noisy' in the moments during a press or release. This kind of multiple-triggering is referred to as 'bounce' and the process of removing it is 'debouncing' the input. Several strategies exist to debounce inputs ranging from simple software solution to complex hardware augmentations. For the purposes of the rest of this guide we will ignore this artifact, however as you build more complex things you will most likely want to look into debouncing solutions.
Raspberry Pi Python Gpio
Look at the diagram above to connect an LED and another 330 Ohm resistor to another GPIO pin. As before we use the resistor to limit the current through the GPIO pin, thus protecting the Raspberry Pi from dangerous over-draw. Unlike other components we have used before, LEDs only work when power is flowing in the correct direction, so make sure the flatter side of the LED is connected to the resistor (or more importantly, that the flatter edge must be towards the direction connected to ground).Once you have the LED connected, we can control it from Python: GPIO.setup(25, GPIO.OUT, initial=GPIO.LOW)GPIO.output(25, GPIO.HIGH)This should light up the LED. Now we have both an input and output that we can control from Python, so lets wrap it all up: import RPi.GPIO as GPIOGPIO.setmode(GPIO.BCM)GPIO.setup(4, GPIO.IN, pullupdown=GPIO.PUDDOWN)GPIO.setup(25, GPIO.OUT, initial=GPIO.LOW)GPIO.addeventdetect(4, GPIO.BOTH)def mycallback:GPIO.output(25, GPIO.input(4))GPIO.addeventcallback(4, mycallback)Now when you press the button, the LED will turn on. A simple application but the same technique can be easily applied to anything from a REST API to the lights in your home!