Table of Contents

Photoresistor

Necessary knowledge: [HW] Sensors Module, [HW] User Interface Module, [ELC] Voltage Divider, [AVR] Analog-to-digital Converter, [LIB] Analog to Digital Converter, [LIB] Graphic LCD, [PRT] IDE Eclipse

Theory

A photoresistor
Electrical symbol for a photoresistor

A photoresistor is a sensor which electrical resistance is altered depending on the light intensity falling on it. The more intense is the light the more free carriers are formed and therefore the lower gets the resistance of the element. Two exterior metal contacts of the photoresistor are reaching through the ceramic base material to the light sensitive membrane, which determines the electrical resistance properties with its geometry and material properties. Since photo sensitive material itself has high resistance, with narrow, curvy track between the electrodes, low total resistance at average light intensity is gained. Similarly to the human eye, the photoresistor is sensitive at certain range of wavelengths and needs to be considered when selecting a photo element, otherwise it may not react to the light source used in the application. Following is simplified list of wavelengths of visible light segmented by colours:

Colour Range of wavelength (nm)
Purple 400 – 450
Blue 450 – 500
Green 500 – 570
Yellow 570 – 590
Orange 590 – 610
Red 610 – 700

A range of working temperature is set for photoresistor. Wishing the sensor to work at different temperatures, precising conversions must be executed, because the resisting properties of the sensors are depending on the temperature of the ambient.

For characterizing light intensiveness physical concept called light intensity (E) is used, this shows the quantity of light reaching any given surface. Measuring unit is lux (lx), where 1 lux represents, the even flow of light 1 lumen, falling on a surface of 1m2. Hardly ever in reality falls light (living area) on a surface evenly and therefore light intensity is reached generally as a average number. Below are few examples of light intensity:

 
Values of light intensity for comparison:

Environment Intensity of light (lx)
Full moon 0,1
Dusk 1
Auditorium 10
Class room 30
Sunset or sunrise 400
Operating room (hospital) 500 - 1000
Direct sun light 10000

Practice

The Sensor module in the HomeLab is equipped with VT935G photoresistor. One pin of the photoresistor is connected to +5 V power supply and second pin to the channel 1 (pin PF1) of the analogue-digital converter. Between this pin and the ground 10 kΩ resistor is also connected, which forms a voltage divider with the photoresistor. Since the electrical resistance of the photoresistor is decreasing as the light intensity falling on it grows, the measured voltage on the pin of the microcontroller grows as light intensity grows. It is worth to take into account that the photoresistor used in the HomeLab reacts most on orange and yellow light.

The sensor VT935G is not meant to be a specific measuring device. It is meant to be more a device to specify overall lighting conditions – is there a lighted lamp in the room or not. In this case one has to just measure the resistance of the sensor in the half dark room, note it in the program and compare measured values – is it lighter or darker.

The exercise here is a little bit more complex as the light intensity is measured also in lux. For doing this, exists an approximate formula and floating-point variables. In the C-language are floating-point variables float- and double-type variables, which can be used to present fractions. Their flaw is high demand of resources. Computers have special hardware to calculate floating-point variables, in the 8-bit AVR microcontroller calculations are executed in software which demands a lot of memory and time. If the flaws are not critical, the floating-point variables are worth using.

Relationship between resistance (R) of VT935G and intensity of light (E)

There is an approximate formula showing the relationship between the intensity of light and electrical resistance in the sensor datasheet. As seen on the graph (on the right), with using logarithm scale, the resistance and intensity of light are almost in linear relationship and form a in-line formula, because following conversion applies:

log(a/b) = log(a) - log(b)

The relation is characterised by the ascent of the factor γ (ascend of the line), which is 0,9 on VT935G sensor. We have also data on one of the points on that line: resistance 18.5 kΩ (RA) at 10 lx intensity of light (EA). Hence we have the coordinates of one point as well as the ascent of the line and for calculating any other point, we only need one coordinate. Meaning, if sensors' resistance (RB) is measured, it is possible to calculate from the equation of line, the intensity of light EB) that falls on the sensor. Finding EB from the equation of line:

log(EB) = log(RA/RB) / γ + log(EA)

EB = 10log(RA/RB) / γ + log(EA)

This gives the formula for calculating the intensity of light when the resistance is known. The resistance can not be measured directly with microcontroller. For this the photoresistor is in the voltage divider. The output voltage of this voltage divider is converted to a specific variable by the analogue-digital converter (ADC). To find the resistance, the output voltage (U2) of the voltage divider must be calculated first, using the ADC value, also comparison voltage (Uref) of the converter must be taken into account: The formula is following:

U2 = Uref * (ADC / 1024)

From the formula for voltage divider(check the chapter on voltage divider) the resistance of the upper photoresistor (R1) can be found:

R1 = (R2 * U1) / U2 - R2

In the following calculation of voltage and resistance, the known factors are replaced with numbers and indexes have been removed:

U = 5 * (ADC / 1024)

R = (10 * 5) / U - 10

For finding the intensity of light, simplifying conversions can be done:

E = 10log(18.5/R) / 0.9 + 1 = 10log(18.5/R) * 10/9 * 101 =

= 10log18.5*10/9 - logR*10/9 * 10 = (10log18.5*10/9 / 10logR*10/9) * 10 =

= (18.510/9 / R10/9) * 10 = 18.510/9 * 10 * R-10/9

By calculating the constant in front of the variable of the field R, the expression remains follows:

E = 255,84 * R-10/9

These formulas help only if the photoresistor on the module of sensors of the HomeLab is used. If circuit is used equipped with different components, respective variables need to be changed. Next, source code of the example program is presented, which measures and calculates using ADC and displays the intensity of light on the LCD. But before compiling the program, the settings for using floating-point variables must be written in the project. How to do that is explained in the chapter of installing the software.

In the example program variables of voltage, resistance and intensity are defined using type double of floating-point variables. The variables which should be used as floating-point variables must always contain a decimal point (it can be also just 0, because then the compiler understands it correctly). When using sprintf for converting floating-point variable to text, “%f” format must be used, this may be enhanced using integers and decimal places. For example: “%3.2”, which displays always 3 integers and 2 decimal places.

 

#include <stdio.h>
#include <math.h>
#include <homelab/module/lcd_gfx.h>
#include <homelab/adc.h>
#include <homelab/delay.h>
 
// Main program
int main(void)
{
	char text[16];
	unsigned short adc_value;
	double voltage, resistance, illuminance;
 
	// Initializing the LCD
	lcd_gfx_init();
 
	// Clearing the LCD.
	lcd_gfx_clear();
 
	//Cursor on the position x=3, y=1
	lcd_gfx_goto_char_xy(3, 1);
 
	// Name of the program
	lcd_gfx_write_string("Luxmeter");
 
	// Setting the ADC
	adc_init(ADC_REF_AVCC, ADC_PRESCALE_8);
 
	// Endless loop.
	while (true)
	{
		// Reading the average value of the photoresistor
		adc_value = adc_get_average_value(1, 10);
 
		// Calculating the voltage in the input of the ADC
		voltage = 5.0 * ((double)adc_value / 1024.0);
 
		// Calculating the resistance of the photoresistor 
 
		// in the voltage divider
		resistance = (10.0 * 5.0) / voltage - 10.0;
 
		// Calculating the intensity of light in lux
		illuminance = 255.84 * pow(resistance, -10/9);
 
		// Converting the intensity of light to text
		sprintf(text, "%0.1f lux   ", illuminance);
 
		// Displaying it on the LCD
		lcd_gfx_goto_char_xy(3, 3);
		lcd_gfx_write_string(text);
 
		// Delay 500 ms
		sw_delay_ms(500);
	}
}