User Tools

Site Tools


oak:tutorials:photocell

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Last revision Both sides next revision
oak:tutorials:photocell [2016/03/20 19:04]
jwhendy created
oak:tutorials:photocell [2016/03/22 21:53]
jwhendy
Line 1: Line 1:
-In this lesson, we will connect a photoresistor to our Oak. There some great background information and an Arduino tutorial on [[https://​learn.adafruit.com/​photocells|Adafruit]],​ so please do take a look there for further learning. In essence ​a photoresistor ​is simply a potentiometer where light is acting to turn the knob. When there is a lot of light, the resistance drops; with low light, the resistance is higher.+===== Oak: using photocell (photoresistor) =====
  
-==== Requirements ====+[[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell.png|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell.png?​400}}]]
  
-This tutorial ​will use the following (in addition ​to an Oak):+In this lesson, we will connect a photoresistor ​to the Oak. A photoresistor is like a potentiometer (a variable resistorexcept light is acting instead of a knob. When there is a lot of light, the resistance drops; with low light, the resistance is higher. Using this property, we can send a voltage through a photoresistor,​ measure the resistance via a change in voltage, and obtain a value for how much light is shining on the photoresistor.
  
-  * a breadboard +===== Components =====
-  * a photoresistor +
-  * jumper wires +
-  * a 10k resistor +
-  * a USB UART converter, [[http://​digistump.com/​wiki/​oak/​tutorials/​serial_through_arduino|serial-capable Arduino]], or familiarity with [[http://​digistump.com/​wiki/​oak/​tutorials/​particle-variable|Particle.variable()]]+
  
-==== Connecting the circuit ====+^ Part       ^ Quantity ​         ^Identification^ 
 +| Oak with soldered headers |1| | 
 +| Breadboard|1| | 
 +|Photocell|1| | 
 +|Jumper wires|7| | 
 +|Resistor, 10k ohm|1|Black-Brown-Orange| 
 +|3.3V USB UART or an Arduino*|1 | |
  
-Here is the wiring ​connection we'll use:+**Note:** if using an Arduino to read serial, you will need to follow the instructions at the tutorial on [[http://​digistump.com/​wiki/​oak/​tutorials/​serial_through_arduino|serial with an Arduino]]. In contrast, you don't need //either// of these components if you learn how to use ''​Particle.variable()''​ as described in [[http://​digistump.com/​wiki/​oak/​tutorials/​particle-variable|this tutorial]]. 
 + 
 +===== Concepts ===== 
 + 
 +=== Voltage divider === 
 + 
 +In the circuit we create below, electricity will flow from the Oak's ''​Vcc''​ pin into one leg of the photocell. When electricity leaves the photocell, it will see two paths: one to pin '''​A0'',​ and the other to ground through the 10k resistor. This creates what is known as a voltage divider, which is very helpful for measuring small changes in voltage. There'​s a great writeup of //why// this is required on the Electronics StackExchange Q&A site [[http://​electronics.stackexchange.com/​questions/​70009/​why-use-a-pull-down-resistor-with-a-ldr-and-microcontroller|here]]. An Adafruit [[https://​learn.adafruit.com/​photocells|tutorial]] also features a discussion on adjusting the resistor value to target different ranges of measurement in the section on [[https://​learn.adafruit.com/​photocells/​using-a-photocell|using a photoresistor]]. 
 + 
 +The short version is that a voltage divider creates a ratio in the voltages in each path based on their individual resistances. The voltage going to ''​A0''​ can be found as follows: 
 + 
 +<​code>​ 
 +A0 voltage = 3.3V (Vcc) * 10k / (10k + photocell_resistance) 
 +</​code>​ 
 + 
 +The ratio of the resistor going to ground divided by //total// resistance tells us how much will be measured at A0. If the photocell resistance is small, there will be very little difference between ''​Vcc''​ and ''​A0''​ with a direct ​connection. By using the ratio produced by a voltage divider, the ''​A0''​ voltage will vary a lot more as the resistance of the photocell changes. 
 + 
 +=== ADC === 
 + 
 +An analog sensor is one that produces a change in electrical properties in response to changes in the thing being measured. This is in contrast to digital sensors which use a communication protocol to report out an actual number. A photocell is an analog sensor in that it's resistance changes in response to light. We do not obtain a direct number from the photocell; instead, ​we need to measure the electricity going through it and convert //that// to a number of some form. 
 + 
 +An Analog to Digital Converter (ADC) does this for us. It will read in a voltage and compare it to a reference voltage (''​Aref''​),​ which serves as the maximum value it //could// read. The measured voltage is then converted into a number ranging from 0 (measured voltage = 0) to maximum (measured voltage = reference voltage), which depends on the microcontroller. The Arduino, for example, converts 0 - ''​Aref''​ into 0-255. The Oak, converts to a range of 0-1023. 
 + 
 +=== analogRead() === 
 + 
 +The ''​analogRead()''​ function is how we access the ADC. When we call ''​analogRead(A0)'',​ we are telling the Oak to convert the voltage it measures at ''​A0''​ into a number between 0-1023 depending on how big it is. By using the ''​delay()''​ function, we can adjust how often these readings are taken. We can also use an ''​if()''​ statement to do something else based on the 0-1023 value. 
 + 
 +=== the if() statement === 
 + 
 +For the second portion of this tutorial, the code will use an ''​if()''​ statement. This is one of the fundamental ways to control the Oak's behavior. The format is: 
 + 
 +<​code>​ 
 +if( some condition ) { do this; } 
 +</​code>​ 
 + 
 +In our case, the condition we're checking for is whether or not the ''​A0''​ light reading is above or below 250. If it's above 250, we do nothing. If it's below 250, we turn on the on-board LED. To compare the actual statements above to the actual code below, here are the lines. Can you see how they work? 
 + 
 +<​code>​ 
 +if(light < 250) { digitalWrite(1,​ HIGH); } 
 + 
 +if(light >= 250) {digitalWrite(1,​ LOW); } 
 +</​code>​ 
 + 
 +===== Circuit ===== 
 + 
 +To connect the photocell, we will use the following circuit:
  
 [[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell.png|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell.png?​500}}]] [[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell.png|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell.png?​500}}]]
  
-If you prefer ​real life example, here is the setup:+To complete the circuit, follow these steps: 
 + 
 +  * Insert the photocell legs into two different rows 
 +  * Connect the 10k resistor from one photocell leg (either is fine) to new row with a jumper wire 
 +  * Connect pin A0 of the Oak to the same row containing //both// leads from the resistor and photocell 
 +  * Connect a ground pin of the Oak to the free lead on the resistor 
 +  * Connect a Vcc pin on the Oak to the free lead of the photocell 
 + 
 +For reference, here is the setup above in real life:
  
 [[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-wiring.jpg|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-wiring.jpg?​400}}]] [[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-wiring.jpg|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-wiring.jpg?​400}}]]
  
-We connect one leg of the photocell ​directly to ''​Vcc''​and the other leg to two different "​outlets:"​ one to analog pin, ''​A0'',​ and the other to ground through the 10k resistor. This creates what is known as a voltage divider, which is required for measuring small changes in voltage. There'​s a helpful writeup of //why// this is required on the Electronics StackExchange Q&A site [[http://electronics.stackexchange.com/questions/70009/​why-use-a-pull-down-resistor-with-a-ldr-and-microcontroller|here]]. The Adafruit tutorial also features a discussion on adjusting the resistor value used to target different ranges of measurement in the section on [[https://learn.adafruit.com/photocells/using-a-photocell|using ​a photoresistor]].+If you wish to read the photocell ​output via serialplease take this time to follow ​the instructions ​as described ​[[https://github.com/digistump/OakRestore|here for a UART]] and [[http://digistump.com/wiki/oak/​tutorials/​serial_through_arduino|here when using an Arduino]].
  
-==== The code ==== 
  
-For an introduction to these sensors, we'll read the light value to get a handle on the expected ranges that will be encountered,​ and then pick a cutoff value at which point to turn on the built-in LED.+===== Code: reading ​the photocell =====
  
-Reading ​the photocell ​is straightforward:+We will begin by simply reading the value produced by the photocell ​signal to ''​A0''​:
  
 <​code>​ <​code>​
Line 37: Line 90:
 void setup() void setup()
 {                ​ {                ​
- 
-  // use the on-board LED to illuminate when the button is pressed 
-  pinMode(1, OUTPUT); 
-  pinMode(1, LOW); 
   ​   ​
   // initialize the analog pin as an input   // initialize the analog pin as an input
   pinMode(A0, INPUT);   pinMode(A0, INPUT);
  
 +  // start serial communication and create a variable for particle.io access
   Serial.begin(9600);​   Serial.begin(9600);​
 +  Particle.variable("​light",​ light);
  
 } }
Line 60: Line 111:
   Serial.println(light);​   Serial.println(light);​
  
-  // a short delay as we don't need readings ​every millisecond+  // a short delay as we don't need extremely fast readings
   delay(250);   delay(250);
  
Line 66: Line 117:
 </​code>​ </​code>​
  
-The code above assumes you will use a USB UART or Arduino to read the data via serialhowever you are free to access ​it through ​the [[http://​digistump.com/​wiki/​oak/​tutorials/​particle-variable|Particle.variable()]] if you prefer. Using serial, ​the output will look like this as you cover and uncover the sensor:+This code reads ''​A0'',​ stores ​the number it obtain in the variable called ''​light''​sends it ot the computer via serial, and then pauses for 0.25 seconds. ​
  
-<​code>​+Using serial, the output will look like this as you cover and uncover the sensor:
  
 +<​code>​
 764 764
 737 737
Line 90: Line 142:
 </​code>​ </​code>​
  
-Based on these readings, pick a value you want to consider "dark enough;"​ I'll use 250If we add some code to our sketch, we can automatically turn on the on-board LED when the sensor is in low light. This is just the modified ''​loop()'' ​section; include everything else from above in the full sketch.+If you are using ''​Particle.variable()''​, you would issue a call like this, substituting your device ID and access token in their appropriate locations:
  
 <​code>​ <​code>​
 +curl https://​api.particle.io/​v1/​devices/​id_here/​light?​access_token=token_here
 +</​code>​
 +
 +The result will look like this, where the value in "​result"​ is the output of ''​A0''​
 +
 +<​code>​
 +{
 +  "​cmd":​ "​VarReturn",​
 +  "​name":​ "​button",​
 +  "​result":​ 529,
 +  "​coreInfo":​ {
 +    "​last_app":​ "",​
 +    "​last_heard":​ "​2016-03-19T20:​51:​30.817Z",​
 +    "​connected":​ true,
 +    "​last_handshake_at":​ "​2016-03-19T20:​32:​30.268Z",​
 +    "​deviceID":​ "​12345678",​
 +    "​product_id":​ 82
 +}
 +</​code>​
 +
 +=== Code: turning on an LED when it's dark ===
 +
 +Now, we'll use these values to turn on and off the on-board LED at pin 1 based on how light or dark it is. Based on your readings, pick value 50-100 higher than your lowest reading. For the sensor above, 250 was chosen. If we add some code to our sketch, we can automatically turn on the on-board LED when the sensor is in low light. To do this, we add the LED functionality from the [[http://​digistump.com/​wiki/​oak/​tutorials/​blink|blink tutorial]] and use an ''​if()''​ statement:
 +
 +<​code>​
 +// variable to store our reading
 +int light;
 +
 +void setup()
 +{                ​
 +
 +  // enable the on-board LED as an output
 +  pinMode(1, OUTPUT);
 +  ​
 +  // initialize the analog pin as an input
 +  pinMode(A0, INPUT);
 +
 +
 +  // start serial communication and create a variable for particle.io access
 +  Serial.begin(9600);​
 +  Particle.variable("​light",​ light);
 +
 +}
 +
 +
 // the loop() routine runs over and over again // the loop() routine runs over and over again
 void loop() void loop()
Line 107: Line 204:
   if(light >= 250) {digitalWrite(1,​ LOW); }   if(light >= 250) {digitalWrite(1,​ LOW); }
   ​   ​
-  // a short delay as we don't need readings every millisecond+  // a short delay
   delay(250);   delay(250);
  
Line 113: Line 210:
 </​code>​ </​code>​
  
-Adjust the cutoff values as desired; with this code added, we get a nice effect like this (you may need to click and open in a separate tab to see the animation):+Adjust the cutoff values as desired; with this code added, we get a nice effect like this:
  
 [[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-turn-on.gif|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-turn-on.gif?​500}}]] [[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-turn-on.gif|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-turn-on.gif?​500}}]]
  
 +===== Conclusion =====
 +
 +Congratulations! You just connected to an analog sensor and read the values! Sensors are a crucial component to many projects, so this is an invaluable skill that will serve you well. For a next step, perhaps you could try connecting a different analog sensor? There are many Arduino tutorials for other types of sensors, such as Adafruit'​s on using the [[https://​learn.adafruit.com/​tmp36-temperature-sensor/​overview|TMP36 temperature sensor]].
  
-So, what could you use this forThat's up to you, but you now have a new sensor in your toolbox for future ​projects. Here's some [perhaps silly] ideas to get you going:+Or perhaps ​you can think up some projects that might include a photocellNow that you have this sensor in your toolbox for future ​project, here's some [perhaps silly] ideas to get you going:
  
   * an automated night light   * an automated night light
oak/tutorials/photocell.txt · Last modified: 2016/03/22 22:00 by jwhendy