Another simple real world measurement that can be performed with the Raspberry Pi B+ is to make measurements of the physical world around you. As several have shown before, you can get digital sensors to determine temperature, humidity, distance, motion, and a host of other things. But sometimes you may not have a digital sensor, or your budget doesn't allow for it. The lack of an Analog to Digital converter built into the Raspberry Pi would seem to be a hindrance, but that is not entirely true. You can use a few inexpensive discrete components and approximate analog values by combining an analog sensor, like a photocell, or an analog temperature sensor, or any other sensor that changes resistance based on external stimuli, with a capacitor of fixed value. This creates an RC circuit. Where R means resistor and C means capacitor. According to wikipedia (and probably every electronics textbook in the world) :
"The simplest RC circuit is a capacitor and a resistor in series. When a circuit consists of only a charged capacitor and a resistor, the capacitor will discharge its stored energy through the resistor. The voltage across the capacitor, which is time dependent, can be found by using Kirchoff's current law, where the current charging the capacitor must equal the current through the resistor."
What does all that mean to us? The key in the above is that the voltage across the capacitor is time dependent. That means we can measure it. There is a threshold in digital circuits where a signal is recognized as a High (logic 1) or a Low (logic 0). We often dismiss this by saying "A high is 3.3v or 5v and a Low is 0v." This is not necessarily true, what about the voltages in between. Sure, 0 volts is a LOW, but what about 0.5 volts? It's not a HIGH. So until it reaches a certain voltage logically we will treat it as a logic 0, once it exceeds the threshold, the device will register the level as a HIGH and we will treat it as a logic 1. This threshold on the Raspberry Pi seems to be around 1.4 volts. Back to the fact that we can measure this time, since the current charging the capacitor must equal the current through the resistor, and our resistor value is changing due to external stimulus, the time to charge and discharge the capacitor will also change, and that is what we will measure.
In this example we will use a photocell and a capacitor together in series. A photocell is simply a device that changes resistance based on ambient light. The brighter the light, the lower the resistance, the dimmer the light, the higher the resistance. Very simple.
The way we will take advantage of all of the above information is:
1) We will start by driving our sensing pin on the B+ to low, this will give us a known starting point of 0 volts
2) We will change the sensing pin to an input
3) We will count in a loop until the capacitor charges to a level recognized as a logic level 1 on the input pin (approximately 1.4 volts)
4) We will print the value and do it again
What we expect to see is that as the amount of light is decreased, the time it take to charge the capacitor will be longer, so the counted output from our loop will be higher, if we increase the brightness of the light, the resistance will decrease, causing the capacitor to charge more quickly, giving us a lower number from our count. This is sensitive enough to be done by simply waving your hand over the photocell, or you can place a finger over the sensor to simulate total darkness. Bear in mind, this is not an exact measurement, but it is good enough to tell if there is a light on in a room, or if the sun is up, but that is the extent of it. If we were to use an analog temperature sensor instead of a photocell we would probably need to calibrate the outputs to known good values.
On to the code and the circuit, first things first, you need the python GPIO libraries, these can be installed as follows:
sudo apt-get update sudo apt-get install python-dev sudo apt-get install python-rpi.gpio
If you are not sure whether those things are installed just run them, it will either download the latest version or tell you that you have the latest version already installed. It may prompt you to answer 'Y' to confirm the installations.
Next you can wire up the circuit. Make sure the Raspberry Pi is off and no power is applied. Even with simple circuits you can make mistakes, so double check your connections. The components needed are:
1) A breadboard
2) A 1 uF Capacitor
3) A photocell
4) The B+
5) Some jumper wires.
We are only going to use 3 pins from the B+, Pin 1 3.3 volts, Pin 6 Ground, and Pin 11 one of the GPIO pins.
Follow the diagram below to make your connections:
I straddled the capacitor from the light blue rail on the left side to the first pin on row 10 of the breadboard, if using an electrolytic capacitor like I did (looks like a small soda can with legs) make sure that the - side (will be clearly marked) is inserted into the ground row (- bus) and not in row 10. I then took my photocell and straddled the channel down the middle of the board on row 10. I connected a jumper from the red row on the right side of the board (+ bus) to row 10 on the right side of the channel down the middle of the board. I connected a green jumper from a hole on row 10 on the left side of the channel in between the capacitor and the photocell and connected that to pin 11 of the Rasberry Pi. I then connected pin 1 of the B+ to the +bus on the right side of the board and Pin 6 of the B+ to the -bus on the left side of the board.
That's it!!! Easy peazy, George and Wheezy.
Now on to the code:
#!/usr/bin/python import time import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) def RCtime (RCpin): reading = 0 GPIO.setup(RCpin, GPIO.OUT) GPIO.output(RCpin, GPIO.LOW) time.sleep(0.1) GPIO.setup(RCpin, GPIO.IN) while (GPIO.input(RCpin) == GPIO.LOW): reading += 1 return reading while True: print RCtime(11)
The code above was shamelessly lifted from adafruit. I made a few small modifications, but the basic code came from there.
I've included it as an attachment, so you can download it.
Once the code has been downloaded to your B+, open a command window and go to the directory where the file is stored and type:
chmod 755 RCTime.py
This will change the permissions on the file to allow it to be executed. This is only necessary one time, after you download it. To run the program, from the directory where the program was downloaded type:
The sudo is necessary because you need to be super user to access the GPIO pins, and the ./ just tells the shell that the file is in the current directory.
you should expect to see an ouput as follows:
You can stop the execution of the program by typing Ctrl-C (hitting the Ctrl key and the c key at the same time) this will generate a keyboard interrupt to stop the program.
The above output was generated in a room lit by sunlight with the blinds partially drawn. The highest values were read when I cupped my hand over the sensor. Play around with it, run it in a dark room, then turn the lights on, see how the values change.
Below is a picture of the actual setup. Looks a lot like the fritzing diagram :-)
Now I have to give credit where credit is due. I didn't invent this technique. I discovered it in an adafruit tutorial. Being one to never believe anything I read, I had to prove it to myself and write a blog on it giving it my own spin.
This is a very interesting method of measuring analog values with the Raspberry Pi that I would have never thought of, but it uses basic electronic principles and works pretty well for rough measurement, with a little more work and some calibration with other more precise measurement tools you could probably convert the time values read to fairly consistent values that equate to the real world. BTW, although I used a B+ for this, any of the Raspberry Pi family would probably work just as well.
I hope you have enjoyed it.