Maker Pro
Maker Pro

light automatic on off using pic 16f870

i want to make an automatic on off switch using pic and relay with light sensor (as in attachment) connected to adc channel 0 of pic 16f870 and relay connected to pin 0 of port c via darlington pair ic.
i have code for temperature sensor. can it be used in this project by modifying it.

unsigned char myvalue;
void main()
{
adcon0=0x85;
adcon1=0x01;
trisa=0xff;
trisc=0x00;
while(1)
{
myvalue=adc_read(0)>>2;
portc=myvalue;
delay_ms(1000);
}
}
 

Attachments

  • images.jpg
    images.jpg
    3.1 KB · Views: 156
Last edited:
I don't see any attachment., but yes you can always modify the code unless there is a copyright issue involved.

what is the output from the light sensor (current/voltage)? you need to set a certain ADC value for comparison for the relay to switch on and off inside your while loop.

thanks,
S!d
 
i think i forgot to attach image but now i have attached it in main post.i have set voltage across ldr to be 2.56v so that with change in voltage adc output changes linearly.
how to convert the binary output of adc to decimal form to compare it with some cutoff value??
 

Harald Kapp

Moderator
Moderator
how to convert the binary output of adc to decimal form to compare it with some cutoff value??
You don't have to. In C you can compare the ADC output directly to the decimal equivalent:
Code:
	if (ADC_value > 512) /* 512 is the arbitrary threshold */
	{ /* do something */ }
	else
	{ /* do something else */ }
 

KrisBlueNZ

Sadly passed away in 2015
You are setting ADCON1 to 0x01. This sets the PCFG bits to 0001. If you do this, you must provide a positive reference voltage into RA3. If you're using VDD as the positive reference for the ADC, you should set the PCFG bits to 0000, i.e. ADCON1 = 0x00. The ADC will use VDD as its positive reference. RA bits 0, 1, 2, 3 and 5 will all be ADC inputs.

You should use hysteresis in your comparison, otherwise your control output will witter when the light level is around the threshold value. Google hysteresis for details.
 
@harald i will try this code, thanx
@krisbluenz i googled hysteresis but the codes are very complex for a beginner like me but i will try to sort it out. thanx
 
Last edited by a moderator:
finally i made it and its workingbut i still need to sort out the hysteresis

unsigned char myvalue;
void main()
org 0x10
{
adcon0=0x85;
adcon1=0x01;
trisa=0xff;
trisc=0x00;
while(1)
{
myvalue=adc_read(0)>>2; //to get 8bit o/p from 10 bit
if(myvalue < 80) //cutoff more the value(80) more is light
{
portc.f0=1;
}
else
{
portc.f0=0;
}
delay_ms(1000);
}
}
 
Last edited by a moderator:

KrisBlueNZ

Sadly passed away in 2015
Adding hysteresis is pretty easy.

Code:
#define HYSTERESIS 10   // Distance from centre to each threshold
#define CENTRE 80       // Centre value (half way between thresholds)

unsigned char adcvalue;

void main()
org 0x10
{
  adcon0 = 0x85;
  adcon1 = 0x01;        // ADC gets its reference voltage from RA3. See post #5.
  trisa = 0xFF;
  trisc = 0x00;

  while(1)
  {
    adcvalue = adc_read(0) >> 2; // to get 8bit o/p from 10 bit
    if (adcvalue < (CENTRE - HYSTERESIS)) //cutoff more than value (80) more is light
      portc.f0 = 1;     // If ambient light level is lower than low threshold, turn the light bulb ON
    if (adcvalue > (CENTRE + HYSTERESIS))
      portc.f0 = 0;     // If ambient light level is higher than high threshold, turn the light bulb OFF
                        // If ambient light level is between the thresholds, don't change the light bulb state.
    delay_ms(1000);
  }//while(1)
}//main
 
Top