008 TEST READ OF A PHOTORESISTOR
January 25, 2011 (See also
Companion Blog )
[
Go BACK to Table of Contents] [
Next Experiment ] [
Last Experiment ]
008 TEST SERIAL READ OF A PHOTOSENSOR
This experiment accepts the premise that all sensing devices in common usage operate on a varying voltage (as opposed to current). I accept for now that at time some other signal may be used, but experiment 007 above consistently failed to measure any changes that I could measure except in voltage.
I propose to test in two phases here. The first is a simple circuit that confirms a photoresistor can vary the brightness of an LED. I have found contradictory accounts of whether the photoresistor drops or climbs in resistance as the light gets brighter, hence we put it to the test once and for all. The inherent fault with this experiment is that I have to shine a light on the photoresistor and at the same time keep the LED in the relative dark to see it operate. I’d like to substitute a buzzer, but I don’t have one.
If the first stage is successful, I will then devise or pirate code to determine the best way to have the Arduino IDE serial monitor display the changing values, intending to find a way to permanently record those values.
Theory:
Any change in the amount of light falling on the photoresistor should cause the voltage through the LED to change, varying the brightness. Note the inclusion of R1 in the circuit (any resistance will do, I used 4700Ω). That is my insurance policy against burning out yet another LED. Hint: use your yellow LEDs for testing as they have practically no use in the real world and so what if they burn up? For convenience, I used a 9V power supply where 5V would have worked fine.
Practice:
Phase One:
Instant success on Phase One. The photoresistor definitely allows more voltage to pass as brighter light falls on it. In an effect I do not yet understand, the resistance across the photoresistor shows no change, and even less intuitive is that the voltage across the photoresistor pins drops as the source light gets brighter. Hold that thought for later.
The effect is instant and the photoresistor is very sensitive. I tested two photoresistors, a big one and a small one. The big one had to be completely encased in darkness before the LED went out. The small one easily turned it off in partial shade.
Phase Two:
The only change in the circuit is that analog read code is connected to this circuit between the photoresistor and the LED, see diagram. The code should detect and read the varying voltage (or other signal) just before it reaches the LED. Here I met with failure. I adapted code for reading potentiometer values and the code has been triple checked. Either I am missing something or testing the wrong thing.
Read the code below, where I even used an old programming “You are here” message to confirm at least part of the code is working. I even divided the variable value by 5 to ensure the read isn’t out of range and still nothing. The test works the same even when the test lead is removed from the breadboard. For some unknown reason, my apparatus failed to read the sensor values from the photoresistor.
Conclusion:
I realize afterward that Phase One could have been performed by attaching the multimeter probes directly to the photoresistor. When I did that, the resistance changed from 120,000Ω in darkness (enough to turn the LED completely off) to 1,400Ω under a very bright flashlight. But then, I would have missed that inverse voltage effect discovered here, wouldn’t I? You might want to be careful that the analog pins are numbered in the opposite direction than the digital pins. Ahem.
Later, this code and various similar sketches has been checked and double-checked, I am up against some other problem than the code. All the code tested contains a common command to read the analog values from the variable resistor (analogRead(Input);). The values displayed on the serial monitor are nonsense, but in each case it is the same nonsense. This read command, or something to do with it, is the hurdle. Not shown here is how I separated the input and output circuits onto two breadboards to isolate the steps and still got the same results.
UPDATED March 26, 2011
I’ve found a partial answer to the failure of my measurements. The sensitivity of the photoresistor is determined by the size of the resistance in the circuit, as the circuit behaves like a voltage divider. All of the resistors I tried had too large a value to cause significant changes in the readings. I watched a video from element14.com where a guy named Blum manages to talk for 15 minutes about the changing values picked up by the Arduino without actually saying what those values represent.
They represent neither volts, nor amps, but a reading based on samples of the changing voltage. (This range is called the “resolution” so you will confuse it with photographs and a half dozen other meanings.) For those that have to ask or didn’t know enough to ask, element 14 is silicon and you are probably reading the wrong blog as well.
I was a little unclear on the concept that the photoresistor was analog and could only be read by an analog pin. This completely trounces my chances of getting into Yale. However, the experiment is now a success. Here is the updated schematic. I am beginning to notice the commonalities in sensor reading circuits and have decided to read up on voltage dividers. See how the A0 pin is “tapped” into the circuit to read the voltage between the sensor and the fixed resistor?
New conclusion:
This is a lesson I learned the hard way. Once working, the circuit actually performed better than some of the lessons and diagrams I had learned from. For instance, the readings taken were between 330 and 830, a range of 500 on a scale of 0 – 1023 (known as a ten-bit reading). Also, I confirmed the photoresistor drops in resistance as the light gets brighter, but causes the reading to get higher indicating it is measuring voltage rather than resistance.
I tested further by changing the size of LED, which made a significant difference, the larger the LED the less brightly it shone. In this circuit, the Arduino is not controlling the LED brightness, rather the LED is wired onto the breadboard. Thus, I did not test the LED by using pulse width modulation (PWM), for that see experiment 017.
However, I did test the map command. This is the Arduino language command that takes the analog input range 0 to 1023 and changes it to the digital range 0 to 255. This portion, involving only code changes, worked perfectly the first time. I also tested the constrain command with indifferent results. I toyed with several arrangements, the biggest change is swapping out the positions of the fixed resistor and photoresistors which resulted in totally different sensor readings. I did not follow up.
Update April 25, 2012
After a year of further studies and coding with the Arduino, I came back to this experiment as the first useful "robotic" scenario, although I did not realize it as such until much later. I'll explain. If you look at the bigger picture of what is going on here, you'll see better than I did that there is a continuous loop of information occurring. And that is where the Arduino shines for robotics applications.
There is an analog sensor, in this case the photoresistor. It senses its environment in "10-bit" pieces. That means it takes a reading of between zero and 1023 (two to the tenth power, ten-bit). It sends this to an analog pin of the Arduino, which sends it to the programming in the chip for processing.
This processing takes the 10-bit analog data and changes it to 8-bit digital data, that is, a value between 0 and 255. The Arduino is constantly taking this changing data and sending values to the output pins. The output device, in this case the LED, varies in brightness according to the digital information received.
That, folks, is essentially the way the Arduino does things. Analog input, digital output. It seems redundant, even over-complicated, until you realize that the digital part can be made far more elaborate and control an infinite number of other actions that would be daunting to try any other way.
I thought to point out this perspective learned after months of tough going. It makes you almost angry that somebody didn't just explain it that way in the first place. But, that's how breakthroughs are made. Your thinking gets channelized by the learning process and stays there until you know enough about it to take another looke at what's really happening. It may change, but right now, all my complicated robot programming, when you get down to it, follows the same cycle described here.
Here is two versions of the code, I have no idea why it is so small and light-colored, those are more quirks of blogspot. If you really need to view it, highlight it or print it. It seems designed to display the reading (technically, the 8-bit output value) on the Arduino serial monitor. You should examine this effect, as it forms the basis of PWM (Pulse Width Modulation), which you will find is one of the more interesting things that Arduino can do.
PWM
In fact, PWM is so important, I'm going to try to describe it. Work with me, this isn't easy. PWM is the process turning a voltage on and off so rapidly that it simulates a smaller voltage. I used the following example. If I could turn the kitchen light switch on and off fast enough, I could fool your eye into thinking the light was dimmer. Use your imagination, but equally important, notice that the voltage (110) and the frequency (60Hz) does not change. Only the amount of time the light is off or on changes, and your eye, which is analog, interprets this as varying brightness. This is called POV (Persistence Of Vision), but that is a separate topic also much used on the Arduino.
That's how the Arduino fakes an analog signal on a digital pin. It writes and ANALOG value to a DIGITAL pin, varying the amount of time the voltage is on or off. It uses a value between 0 and 255 to get the results. For instance, a value of 127 (=255/2) means the voltage is on for 50% of the time. Since Arduino digital voltages are 0V and 5V, the effect is 2.5V at the digital pin. Any brightness can be chosen between 0 and 255, try it and see.
For those who must know, the Arduino is sending square wave (not smooth sine waves) to the pin at 500 Hz, fast enough to fool even your digital multimeter. The full 5V is present when it is on, but it is only on part of the time. This PWM effect is another robotics fundamental that you will eventually have to understand completely. For now, it is enough to be aware that it works, and it is very precise. PWM "controls" the voltage much better than any analog dimmer switch ever built.
How accurate is PWM? Well, it got me started with microcontrollers, that's how impressed I was. On December 1, 2010, I saw a demo of a toy electric train that was so realistic, I was floored. None of those jerky starts caused by rheostats. You can see the same video, called the
Dawson Train on youTube. I didn't have a clue what was happening at the time, nor how relevant it was, you decide for yourself. The bottom line? Learn your PWM.
/* January 25, 2011.
* Experimental Serial Read & Display.
* THIS CODE DOES NOT WORK, IT IS LEFT HERE AS A DISPLAY
* OF AN INITIAL ATTEMPT THAT FAILED. Can you spot the errors?
*/
/* The idea is to get a sensor, in this case a photoresistor
* to send a stream of data to the IDE and see how it displays
* under varying light conditions.
*/
// Assign variables
int Input = 0; // Assign input to analog pin 0
float vValue; // Allow decimal readings
// End assign variables.
////////////////////////////////////////////////////////////
//Begin Main Program
void setup()
{
Serial.begin(9600); // Turn on Serial Connection
}
void loop()
{
vValue = analogRead(Input); // Read the analog pin
vValue = vValue / 5; // Step it down to 0-255
Serial.println("You are here."); // Debug
Serial.println(vValue); // Print to Serial monitor
delay (1000); // Slow everything down
}
// End Main Program
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Key entered by da Bassguy January 26, 2011
// Adapted from several sources to read a sensor value.
// This version does not work.
// ///////////////////////////////////////////////////////
SECOND VERSION (the successful version)
// Experiment 008 - Photosensor Transistor Controlled Motor
// Today is March 17, 2011
// This sketch corresponds to Minutes 008 blog
/* Adapted from several sources, this experiment is
* designed to test the values read by the Arduino
* analogRead statement and display them on the
* Arduino serial monitor. Also, the input value
* is to be converted from 10 bit to 8 bit to match
* the range needed for PWM output. PWM is not tested
* in this circuit.
*/
////////////////////////////////////////////////
//Begin Initialization & Variables
int PhotoResistorRead = 0; //The photocell pin (Input)
int vPhotoCell; //Storage for photocell value
// Note that the Arudino does not have to declare that
// analog pins are input, that is the default for analog pins
//End Initialization & Variables
/////////////////////////////////////////////////
/////////////////////////////////////////////////
// Begin Main Program
/////////////////////////////////////////////////
void setup()
{
analogReference(DEFAULT); //Ensures we are reading 0 to 5 volts
Serial.begin(9600); //Enable serial monitor read
}
//-----------------------------------------------------------------------
void loop()
{
vPhotoCell = analogRead(PhotoResistorRead); //Read the photocell
vPhotoCell = constrain(vPhotoCell, 300, 800); // Keeps values in range
vPhotoCell = map (vPhotoCell, 330, 830, 0, 255); // convert to 8 bit
Serial.println(vPhotoCell); //Display the value on serial monitor
delay(500); //Slow things down
}
//-----------------------------------------------------------------------
////////////////////////////////////////////////////
// END MAIN PROGRAM
////////////////////////////////////////////////////
// Key entered by Anton da Bassguy 2011
// Verified March 26, 2011.
// Tested OK March 27, 2011
// Corresponds to meeting minutes project 008
// Schematic 008 - Read a photoresistor
// Reviewed March 28, 2011
////////////////////////////////////////////////////
Go BACK to Table of Contents