Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

software based AMBIENT light detection

Status
Not open for further replies.

fantabulous68

Junior Member level 2
Joined
Aug 15, 2007
Messages
22
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,591
ambient light detector

/*generating 40KHz low duty cycle pulses which will drive an Infrared transmitter. When an object is
infront of the infrared transmitter then the receiver IC will detect the object and an LED will GLOW.

i want the project to be immune to ambient light such as a desk lamp.
1)when i shine light on the transmitter i want the led to be off.
2)when there is no object infront of the transmitter i want the led to be off.
3)when there is an object infront of the transmitter i want the led to glow.

i programmed the pic16f690 and put it in my circuit. this is what happens:
1)LED pulses continuously when no object in front of it.
2)when object infront of transmitter it stops glowing
3)when shine light on transmitter the LED pulses very fast


hardware connections:
LED connected to RC3
output of receiver connected to RC2
micro generates pulses at RA2

here is my code:

*/

#include <pic.h>
#include "pic.h"
#include "math.h"
#include <stdio.h>
#include <stdlib.h>
#include "delay.h"

void Transmit40(void);

bit ir1,ir2; / 2 different outputs of sensor during On & Off pulse
unsigned char ir; // stores final result


void Transmit40(void)
{


int t=0;
int cnt=0;

while(cnt<20) //Tx 10 IR pulses/burst
{ if (t==0)
{
PORTA=PORTA^0x04; //send IR, Toggles RA2
DelayUs(5);
ir1=RC2; // IR bit1= RC2
cnt++;
t=1;

}
else if (t==1)
{

PORTA=PORTA^0x04; //stop IR, Toggles RA2, RA2 is source of low duty cycle pulses
DelayUs(20);
ir2=RC2; // O/P IR bit2= O/P pin of receiver IC
cnt++;
t=0;
}


if ((ir1 == 1)&(ir2 == 0)) //Obstacle detected
{
ir = 1;
}


else
{
ir = 0; // The way is clear in front of the sensor
}


RC3=ir; // led connected to RC3, LED indicates detection

}
}

void main(void)
{
ANSEL=0; // Set inputs to digital
TRISC=0x04; //making pin RC2 input. output of detector IC connected to RC2
while (1)

Transmit40();

}


/*
the hardware part of my circuit works. i initially used a 555timer to generate pulses and the hardware worked.
all im doin now is using a microcontroller to generate pulses instead of a 555timer. so the problem lies in the software.

please do assist me to correct my code. it is for a project Im a beginner with the pic*/
 

software base light

I don't understand the ambient light point. It's suppressed by all remote control receiver ICs by design.
 

reflective sensor ummune ambient light

fantabulous68 said:
/*generating 40KHz low duty cycle pulses which will drive an Infrared transmitter. When an object is
infront of the infrared transmitter then the receiver IC will detect the object and an LED will GLOW.

i want the project to be immune to ambient light such as a desk lamp.
1)when i shine light on the transmitter i want the led to be off.
2)when there is no object infront of the transmitter i want the led to be off.
3)when there is an object infront of the transmitter i want the led to glow.

i programmed the pic16f690 and put it in my circuit. this is what happens:
1)LED pulses continuously when no object in front of it.
2)when object infront of transmitter it stops glowing
3)when shine light on transmitter the LED pulses very fast


hardware connections:
LED connected to RC3
output of receiver connected to RC2
micro generates pulses at RA2

here is my code:

*/

#include <pic.h>
#include "pic.h"
#include "math.h"
#include <stdio.h>
#include <stdlib.h>
#include "delay.h"

void Transmit40(void);

bit ir1,ir2; / 2 different outputs of sensor during On & Off pulse
unsigned char ir; // stores final result


void Transmit40(void)
{


int t=0;
int cnt=0;

while(cnt<20) //Tx 10 IR pulses/burst
{ if (t==0)
{
PORTA=PORTA^0x04; //send IR, Toggles RA2
DelayUs(5);
ir1=RC2; // IR bit1= RC2
cnt++;
t=1;

}
else if (t==1)
{

PORTA=PORTA^0x04; //stop IR, Toggles RA2, RA2 is source of low duty cycle pulses
DelayUs(20);
ir2=RC2; // O/P IR bit2= O/P pin of receiver IC
cnt++;
t=0;
}


if ((ir1 == 1)&(ir2 == 0)) //Obstacle detected
{
ir = 1;
}


else
{
ir = 0; // The way is clear in front of the sensor
}


RC3=ir; // led connected to RC3, LED indicates detection

}
}

void main(void)
{
ANSEL=0; // Set inputs to digital
TRISC=0x04; //making pin RC2 input. output of detector IC connected to RC2
while (1)

Transmit40();

}


/*
the hardware part of my circuit works. i initially used a 555timer to generate pulses and the hardware worked.
all im doin now is using a microcontroller to generate pulses instead of a 555timer. so the problem lies in the software.

please do assist me to correct my code. it is for a project Im a beginner with the pic*/

This sounds seriously cool! Nice idea. It would be nice if we can implement this kind of code to control lighting in houses, etc...

Regards,
Lamber
https://www.lyco.co.uk
 

light travels in1us in centimeters

What kind of IR sensor are you using? Most remote control types have built in filtering at around 38KHz specifically to exclude ambient lighting effects. In your code, you toggle the IR LED at two different speeds, at least one of them will not pass through a normal IR sensor unit.

Without knowing the clock speed you are using it is impossible to judge the instruction speed and it will be a significant part of the loop time. Quite possibly, your light pulses are simply the wrong lengths or not consistent enough.

A better method is to use a PIC timer register to generate interrupts at a fixed rate rather than using software loops.

Depending on which device you are using, a slow PWM signal may also be an option. You could maintain a constant pulse frequency but change its length by adjusting the mark/space ratio.

Brian.
 

im, using a TSOP48,
output is active low, digital output

Added after 1 minutes:

What do you guys think about this method for calculating the distance?
Any simpler method?im using a timer to determine the interval between transmitted and received signals

Code:
//////////////////////CALCULATING DISTANCE///////////////////////

void enable_interrupt(void)
//This function is basically designed to set the specific bits of the timer and capture registers
{
	CCP1CON=0x05; //bits 3-0 of the capture control register are set to 0101.
				  //This mode is to capture every rising edge of the pulse being
				  //transmitted and then received 
	TMR1IF = 0;   //The interrupt flag bit of the PIR1 register is cleared before
				  //enabling the interrupt.
	CCP1IF = 0;   //Before a capture is made, the Interrupt Request Flag bit
				  //CCP1IF of the PIR1 register is cleared.
	CCP1IE = 1;   //The capture interrupt enable bit is set to enable the interrupt
	TMR1IE = 1;

//An interrupt will occur immediately provided that the GIE and PEIE bits of the INTCON
//register are set.
	PEIE = 1;	  
	 GIE = 1;	 
}

void interrupt ISR(void)
{
 if (TMR1IF)  //if there is an overflow
 {		
  TMR1IF = 0; //and the flag is then cleared
  TMR1_OF++;	
 }
 
 if (CCP1IF) //if there is a capture
 {
   CCP1IF = 0; //Zero Capture flag
   if (Cap_1st) //allow only 1 capture to be taken
     {
       	Cap_1st=0;    		 //Cap_1st is cleared as if another value is captured before the previous value is read
					  		 //then the 
  	 	t_capL=CCPR1L; 	    //lower byte of the capture register
       	t_capH=CCPR1H; 		//higher byte of the capture register
        capture_status=1;	//signal that a capture occured is enabled.
     }
 }
}

void calc_distance(void)
{
	long sample=0;
	i=1; j=0;
	 
	Cap_1st = 1;
	capture_status=0;    //signal that a capture occured is disabled
	TMR1ON = 0;         //stop timer
	//tH=TMR1H; tL=TMR1L;
	tH=0; tL=0; t_capL=0; t_capH=0;  //initialise capture
	TMR1_OF=0;
	
    	Transmit40khz();
	DelayUs(100);

	enable_interrupt();  //Interrupt is enabled to capture time when the rising edge occurs
	TMR1ON = 1; 		// start timer 1

 //when timer 1 starts, the enable_interrupt function will be called to 
//capture the time from the 40kHz signal once the first rising edge of the transmitted
//pulse occurs
	
//A continuous loop is run such that when the signal to state that a capture has occurred
// is 0, then the 40 kHz will be transmitted and received when sending out 10 pulses. 
//Once this condition is satisfied, the global interrupt enable bit will be cleared to 
//prevent the interrupt from occurring when an interruption is in progress. 
//The timer is then stopped by disabling TMR1ON and TMR1IE. 

	while((capture_status==0)&&(TMR1_OF<1));
	GIE = 0; //disable global interrupt
	TMR1ON = 0;  //stop timer 1
  	TMR1IE = 0;   // disable timer 1 interrupts on overflow//

//Another condition arises such that if the signal to state that a capture has occurred
// is then enabled, then the sample time is calculated and stored in an array. The sample
// time is calculated via the difference between high byte of the capture time and the high
// byte of Timer1 added to the low byte of the capture time and the low byte of Timer1. 
//The index is incremented. This then deduces the end of the function to get the samples.
//However, if the index is less than 20, then the function will continue.

    if (capture_status==1)
		{
		 sample = ((t_capH)*0x100)+(t_capL);
		 i = 2;
			GIE=0;   //Global interrupt is disabled to avoid another interrupt from occurring while
					// an interrupt is taking place
			t_capH = 0;
			t_capL = 0;
			
		}

	if (i==1)
		distance = 0;


//if and only if a capture is made will the process of distance calculation continue.
	if (i==2)
	{
		time = sample * 1e-6; //since each count takes 1us to complete, this value is multiplied
							  //to the sample time.
	

		//Distance is calculated via multiplying the time and distance light travels
		//light travels 300m in 1 us.This result is divided by 2

		//as speed travels twice the measured distance.

		distance=(time*30000)/2; 

		//liquidLEVEL=heightOFtank-distance im still working on this part
	}
	return; 
}
////////////////////END CALCULATING DISTANCE//////////////////////

Added after 3 minutes:

1. OSCCON|=0x60; //set fosc to 4Mhz

2. I want to use a 50cm deep tank

It is a continuous level detetector.

3. the calculation of distance is in centimeters
 

My gut feeling is this will never work.

The TSOP includes a bandpass filter which alone will delay the signal more than the time you are measuring, add the need for >10 cycles for the output to change state and I think you are already going to be wildly inaccurate it measuring anything at all.

Now look at your time measurement. The PIC clocks at 4MHz with an internal timer increment of 1uS, this equates to 300m in itself. This is 600 times more distance than the longest distance you want to measure. You are not going to be able to measure fast enough intervals to make it accurate.

Also look at your math, I appreciate you have not yet added the final calculation but the interval you are measuring is already divided by 1,000,000 then multiplied by 15,000 so you will lose significant accuracy in rounding and truncation errors.

There are ways to achieve what you want but modulated IR pulses and a slow processor are not the route to take. You might get away with using ultrasonics where the time of flight is longer because the wave is slower to travel or you could try reflective measurement where the angle of a light beams reflection is measured.

Brian.
 

Im using the hardware circuit from this link:

Quote:
**broken link removed**

Added after 1 minutes:

i want to determine the distance from the time interval between pulses.
Just imagine you dropping a stone into a deep hole and waiting for the sound of the stone hitting the floor.
The shorter the time between the point of release of the stone and the sound of it hitting the floor, the shorter
the distance the stone travelled.

The is how i want to program the circuit to operate.



Basically the sequence for programming should be as follows:

Set timer to ZERO!
Send signal to transmitting IR diode
Start timer
If your receiving IR diode(active low) - indicating it received the signal the STOP timer.

Work out the distance from halving the time and using that speed formula : distance = speed * time.


if i cant get the timer to work properly maybe i try this approach... its a little crude
but should give me some results in any case...

using an arbitrary variable say T (being an integer)

Set T = ZERO.
Send signal to transmitting diode.

If your receiving IR Diode is still low (meaning no signal received as yet)
increase T by 1

The above loop will continue to run until the receiving IR Diode goes HIGH.

Now you will have an unknown positive value in T which is not associated in any equation.
But if you plot out the value of T versus the distance you set the diodes at, then you can work out the equation
for distance - straight line equation

y = mx + c

m = (y2-y1)/(x2-x1)
(x1,y1) and (x2,y2) being co-ordinates with x representing distance and y representing the various values of T.

^
| /
T| /
| /
| /
| / this is a straight line
| /
|/
|----------------------------- >
0

your two co-ordinates (x1,y1) and (x2,y2) are for the shortest and furthest distance of measurement.
So when setting the shortest distance - use a ruler and obstruct the IR diodes approximately 5cm away.
Your distance is known cos you measured it right But you will get a T value for this distance.

Now set the furthest distance (50cm) - use the ruler, obstruct again at 50cm away and get that T value.
Plot a graph and work out the equation of T versus distance.

But this is if i cannot get the timer function to work but the procedure is the same in any case.
 

I understand the principle you are describing. It is called "time of flight" measurement because it calculates distance from departure (of the signal) to arrival (of the reflection) based on how long it was in transit.

Your problem isn't the theory, it is just the incredibly short interval you are trying to measure. Quoting your figure of 300m per uS, and assuming you wanted to measure accurate to 1cm, your timer has to count at about 30GHz, not the 1MHz you are proposing. If you need better accuracy, the frequency needs to be even higher.

If you can find a PIC capable of clocking at 120GHz I would like one, in fact I think everyone would like one!

Looking at the problem from another angle, in the minimum possible time it takes to switch from transmit to receive, the beam would already have traveled 300m.

Its like using a calendar to time how long it takes to boil an egg.

Brian.
 

thanks for your opinion. I undastand what you saying now.
 

Re: ambient light detector

thanks for your information, it would helps for me.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top