I/O LED (Part 4)

Part 123456

Here is a new version of the sensing LED. The sensing LED is turned on almost all the time, with very short periods of time during which it is biased as a photo LED. The measuring time is so short that it is almost impossible to observe the flickering effect. Approaching a source of intense light will turn the sensing LED off!

This amazing process is perfomed using the following code

/*
	SensingLED as per:
	MITSUBISHI ELECTRIC RESEARCH LABORATORIES:
	Very Low-Cost Sensing and Communication	Using Bidirectional LEDs
	by Paul Dietz, William Yerazunis, Darren Leigh
	TR2003-35 July 2003	

	The LED will be turned on when the ambiant light is lower than a trigger point
	and turned on under light exposure
	ATmega328 powered Arduinos only
	Copyright (C) 2012 Didier Longueville

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#define CATHODE_PIN PINB0 /* Connect the cathode of the sensing LED to the specified pin */
#define ANODE_PIN PINB1 /* Connect the anode of the sensing LED to the specified pin */
uint16_t triggerPoint = 2000; /* This depends on the LED properties */
uint16_t interval = 1000; /* Measurement interval */
uint32_t nextDataAcq, now;
/* LED status */
#define LED_STS_OFF_ALL_LOW 0
#define LED_STS_OFF_ALL_HIGH 1
#define LED_STS_FORWARD 2
#define LED_STS_REVERSE 3
/* Register masks */
uint8_t cathodeMask = (1 << CATHODE_PIN);
uint8_t anodeMask = (1 << ANODE_PIN);
uint8_t cathodeAndAnodeMask = (cathodeMask | anodeMask);

void setup()
{  
	/* Initialize serial comm port */
	Serial.begin(115200); 
	/* Set output ports */
	BlinkCtrlLED(3);
	delay(1000);
};

void loop() 
{
	/* Pause until next data acquisition */
	do {
		now = millis();
	} while(now < nextDataAcq);
	nextDataAcq = (now + interval);
	/**/
	if (Darkness() >= triggerPoint) {
		PhotoLEDCtrl(LED_STS_FORWARD); /* Turn LED on */
	} else {
		PhotoLEDCtrl(LED_STS_OFF_ALL_LOW); /* Turn LED off */
	}
};

void BlinkCtrlLED(uint8_t cycles) 
/* Blink control led */
{
	for (uint8_t i = 0; i < cycles; i++)	{
		PhotoLEDCtrl(LED_STS_FORWARD);
		delay(200);
		PhotoLEDCtrl(LED_STS_OFF_ALL_LOW);
		delay(200);
	}
};

uint16_t Darkness(void) 
/* Compute the "amount" of darkness */
{
	uint32_t start;
	uint16_t elapsedTime = 0;
	/* Bias LED in reverse mode */
	PhotoLEDCtrl(LED_STS_REVERSE);
	/* Give a litlle time for setting voltage */
	delayMicroseconds(10);
	/* Set Cathode pin in input mode */
	DDRB &= ~cathodeMask;
	/* Set Cathode pin in high Z mode */
	PORTB &= ~cathodeMask;
	/* Measuring cycle */
	start = micros();
	/* Wait for the cathode pin to reach the low level */
	while ((cathodeMask & PINB) && (elapsedTime < triggerPoint)) {
		elapsedTime = (micros() - start);
	};
	/* Print elapsed time */
	// Serial.print((millis() / 1000.0), 1);
	// Serial.print(";");
	// Serial.print(elapsedTime, DEC);
	// Serial.println();
	/* End print */
	return(elapsedTime);
};

void PhotoLEDCtrl(uint8_t state) 
/* Control LED state */
{
	/* Set port direction */
	DDRB |= (cathodeAndAnodeMask);
	switch(state) {
	case LED_STS_OFF_ALL_LOW:
		/* Turn LED off: no biasing */
		PORTB &= ~(cathodeAndAnodeMask); /* Anode and Cathode to Ground */
		break;		
	case LED_STS_OFF_ALL_HIGH:
		/* Turn LED off: no biasing */
		PORTB |= (cathodeAndAnodeMask); /* Anode and Cathode to VCC */
		break;		
	case LED_STS_FORWARD:
		/* forward polarity */
		PORTB |= anodeMask; /* Anode to VCC */
		PORTB &= ~cathodeMask; /* Cathode to Ground */
		break;
	case LED_STS_REVERSE:
		/* reverse polarity */
		PORTB &= ~anodeMask; /* Anode to Ground */
		PORTB |= cathodeMask; /* Cathode to VCC */
		break;
	}
};

 Next post on same subject

 

Leave a Reply

You must be logged in to post a comment.