## Exercise 7 - Automatic Night Lamp

An automatic night lamp is basically a lamp that will automatically turn on when it sense darkness in the environment. In this example, we will be using a photoresistor to demonstrate how to convert the ambient level into a lamp’s brightness.

A photoresistor or photocell or a light dependent resistor (LDR) is a component that has a variable resistance with the light intensity that falls upon it. The brighter the light is, the lower the resistance will be. The photoresistor is commonly used to turn on a light and also used to control the shutter speed on a camera.

In the circuit below, a voltage divider is formed by a 10K resistor and the photoresistor. When light shines on the photoresistor, the resistance of the photoresistor become lower, thus the voltage drop across the photoresistor will be lower. When the photoresistor is being covered and away from light, the resistance of the photresistor will become higher and caused the voltage drop across it to be higher. By knowing the voltage drop across the photoresistor, we can obtain the relative light level value converted from the voltage read across the photoresistor.

x3
x1
x1
x1
x1
1. Connect the 10K resistor to 5V and 30A.
2. Connect the photoresistor to 30E and 30F.
3. Connect the 220Ω resistor to PIN9 and 32J.
4. Connect the anode (longer pin) of the LED to 32I and the other pin to 33I.
5. Connect a jumper to GND and 30J.
6. Connect a jumper to GND and 33J.
7. Connect a jumper to A0 and 30C.

### Write and Upload the Automatic Night Lamp Sketch

In order to execute the sketch for this exercise, launch Arduino IDE then

Click File -> New.

A new sketch editing window will appear. Copy the whole block of code below and paste it into the new sketch window, overwriting the empty `setup()` and `loop()` that was pre-created. Ensure that the board selected is Arduino Uno and the right COM port is chosen according to “Board Selection” chapter.

``````int brightness;
int lightLevel;
int ambient=120;
int totalDark=240;

void setup() {
pinMode(9, OUTPUT);
pinMode(A0, INPUT);
Serial.begin(9600);
}

void loop() {
brightness = map(lightLevel, ambient, totalDark, 0, 255);
if (brightness<0) brightness=0;
analogWrite(9, brightness);

Serial.print("Light Level=");
Serial.print(lightLevel);
Serial.print(", ");
Serial.print("Brightness=");
Serial.println(brightness);
}
``````

Click Upload, and the Arduino IDE will prompt you to Save sketch folder as. Enter `Excercise_7` into the filename field and click save. Once saved, the Arduino IDE will start to compile the sketch. After the compilation is completed, the Arduino IDE will start to upload the compiled sketch into the STEMTera™ Breadboard. During this stage both yellow LEDs on the STEMTera™ Breadboard will start blinking indicating the Arduino IDE is uploading the sketch to the STEMTera™ Breadboard.

### Calibrating the Automatic Night Lamp

When we first execute the sketch, the STEMTera™ Breadboard does not know the ambient light level, but this ambient light level is important because we need to tell the STEMTera™ Breadboard the ambient light so that it will be able to turn the brightness of the LED according to the ambient lighting.

In order to find out the current ambient light level measured by the photoresistor, we need to open the serial monitor window.

When the status bar of the Arduino IDE shows `Done uploading`, click serial monitor. A new serial monitor windows will be displayed. The serial monitor is a way for the STEMTera™ Breadboard to communicate with the computer to send or receive data, most commonly the debugging messages.

On this windows, we can see a continuous stream of messages is being displayed. In this messages, we are interested in the `Light Level` and `Brightness`.

Place the STEMTera™ Breadboard at a place where you would like it to read the ambient light level from. Without anything blocking light to the photoresistor, write down the value of `Light Level` from the serial monitor. This value is the digital value of the corresponding voltage dropped on the photoresistor (see explanation below for details). Add about 10 to this value, for example, if the value is 115, then add 10 to become 125. Switch back to the Arduino IDE and edit the following line of code

`int ambient=120;`

change it to the value we have just calculated

`int ambient=125;`

Now take a dark cloth or use your palm to cover the photoresistor, you will notice the `Light Level` value on the serial monitor changing to a larger value as you place the cover over the photoresistor. While maintaining the cover over the photoresistor, write down the `Light Level` value. This should be a larger value than the previous value. Switch back to the Arduino IDE and edit the following line of code

`int totaldark=240;`

if the value is 260, then change that line to

`int totaldark=260;`

By changing these two lines of code, we are telling the STEMTera™ Breadboard the ambient light and the total darkness light level in your environment.

Move you palm over and then away from the photoresistor, you will see the brightness of the LED changing as you move your palm over the photoresistor.

### Understanding the Automatic Night Lamp Sketch

We first declare two integer variables to store the brightness and light level as below

``````int brightness;
int lightLevel;
``````

Variable `lightLevel` is use to store the current light level and variable `brightness` is for storing the brightness of the LED. Another two variables are `ambient` and `totalDark` that were already explained in the calibration section.

In the `setup()` section PIN9 is setup as `OUTPUT` and `A0` as `INPUT`. In this exercise we will introduce a debugging or data transfer feature of the STEMTera™ Breadboard, the `Serial` object.

`Serial.begin(9600);`

The line of code tells the STEMTera™ Breadboard to initialize its serial port to 9600 baud rate and start using it. Baud rate is the rate at which data is transferred between serial devices. Serial devices need to set the same baud rate to talk to each other.

In the `loop()` function we first call

`lightLevel = analogRead(A0);`

to read the analogue value from pin A0 and then store into the variable `lightLevel`. Because the value of the light level (125 to 260 from our previous calibration) is different to the `analogueWrite()` function’s 0 to 255 PWM value, we need to have them converted into a relative value that is corresponding to each other. By using the `map()` function

`brightness = map(lightLevel, ambient, totalDark, 0, 255);`

we are converting the ambient value 120 to PWM value of 0, to the max range of ambient value or 260 to a PWM value of 255. The `map()` function then return the converted value and stored into the variable `brightness`.

Because the ambient light is not always consistent, the `map()` function might sometimes return a negative value which is not a valid value for brightness when using `analogWrite()` function, we need to perform a conditional check using

`if (brightness<0) brightness=0;`

This means, if the `brightness` variable has a value that is less than zero, store zero to the variable `brightness`. By doing this, we can ensure that the variable `brightness` will not have a negative value.

The following codes instruct the STEMTera™ Breadboard to print out the variables message via the serial monitor window.

``````Serial.print("Light Level=");
Serial.print(lightLevel);
Serial.print(", ");
Serial.print("Brightness=");
Serial.println(brightness);
``````

When executed in a loop, the current ambient light level is continuously being converted into a relative brightness value and thus making the LED automatically controlled by the ambient light.

CHALLENGE! Connect another LED to the circuit and add codes into the currect sketch to do the reverse of the current LED’s behavior.