AVR Tutorial – Experiment 9

Experiment 9

Automatic Porch Light

Objective – Use the LDR and estimate a threshold for the LDR value and use that to turn the RGB LED on, to simulate an ‘automatic porch light’.

Pre-Requisites – Arduino Nano (ATmega328P-PU), Mini USB cable, 12V DC Adapter, Software Setup (as described in introduction)

Theory – LDR is light dependent resistor, the change in light intensity falling on the LDR leads to the change in resistance of LDR. The change in resistance will lead to change in voltage which can then be read using the ADC module. Based on observation a set reading can be used to act as threshold for turning on a given combination of LEDs. Hence, whenever the light intensity reaches a certain value, the corresponding LEDs will be turned ON.

Connections/Schematic

Connections :-
Nano <–> MV1

D10(PB2) <–> red led
D11(PB3) <–> green led
D12(PB4) <–> blue led
A0 <–> LDR

Code

/*Connections:
 *D10(PB2)-red led
 *D11(PB3)-green led
 *D12(PB4)-blue led
 *LDR – A0
 */

#include <avr/io.h>

uint16_t adc_value;            //Variable used to store the value read from the ADC
uint8_t i=0;                    //Variable for the for() loop

void adc_init(void);         //Function to initialize/configure the ADC
uint16_t read_adc(uint8_t channel);    //Function to read an arbitrary analogic channel/pin

int main(void){

DDRB|= _BV(DDB2);        //D10(PB2) as red led
DDRB|= _BV(DDB3);        //D11(PB3) as green led
DDRB|= _BV(DDB4);        //D12(PB4) as blue led

adc_init();        //Setup the ADC

for(;;){        //Our infinite loop
 for(i=0; i<1; i++){

 adc_value = read_adc(i);        //Read one ADC channel

if((adc_value<15)&&(adc_value>0))
{
PORTB|= _BV(PORTB2);
PORTB&= _BV(PORTB3);
PORTB&= _BV(PORTB4);
}
if((adc_value>15)&&(adc_value<75))
{
PORTB&= _BV(PORTB4);
PORTB&= _BV(PORTB2);
PORTB|= _BV(PORTB3);
}

if(adc_value>75)
{
PORTB|= _BV(PORTB4);
PORTB&= _BV(PORTB2);
PORTB&= _BV(PORTB3);
}
}
}

return 0;
}

void adc_init(void){
 ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));    //16Mhz/128 = 125Khz the ADC reference clock
 ADMUX |= (1<<REFS0);                //Voltage reference from Avcc (5v)
 ADCSRA |= (1<<ADEN);                //Turn on ADC
 ADCSRA |= (1<<ADSC);                //Do an initial conversion because this one is the slowest
                                              //and to ensure that everything is up and running
}

uint16_t read_adc(uint8_t channel){
 ADMUX &= 0xF0;                    //Clear the older channel that was read
 ADMUX |= channel;                //Defines the new ADC channel to be read
 ADCSRA |= (1<<ADSC);                //Starts a new conversion
 while(ADCSRA & (1<<ADSC));            //Wait until the conversion is done
 return ADCW;                    //Returns the ADC value of the chosen channel
}