I/O LED (Part 6)

Part 12345, 6

Here is an amazingly simple and effective application that applies the photovoltaic properties of LEDs. Two identical extremly simple Arduino platforms are used. Each of them is fitted with a LED and a pushbuton. In idle mode, the LED is biased in photo sensing mode, waiting for potential signal. Each time the push button from an Arduino module is depressed a randomly generated byte value is sent by the related LED which is biased in light emitting mode.

Here is the schematics that is required to run this application, once again, it is plain simple

The communication protocol is a simplified serial type. Eight data bits (MSB first, LASB last) are lead by one start bit. Here is a copy of the byte sending function

void SendData(uint8_t sentData) 
{
	uint8_t bitMask = (1 << 7);
	uint32_t tickMark =  micros();
	/* Send start bit */
	PhotoLEDCtrl(LED_STS_FORWARD); /* LED on */		
	tickMark += bitDuration;
	while (micros() < tickMark);		
	/* Send bits MSB->LSB */
	for (uint8_t i = 0; i < 8; i++) {
		/* Switch LED */
		if (sentData & bitMask) { 
			PhotoLEDCtrl(LED_STS_FORWARD); /* LED on */		
		} else {
			PhotoLEDCtrl(LED_STS_REVERSE); /* LED off */
		}
		/* Update bit mask value */
		bitMask >>= 1;
		tickMark += bitDuration;		
		while (micros() < tickMark);		
	}
	/* Return to idle state */
	PhotoLEDCtrl(LED_STS_REVERSE);
};

And here is the receive function

uint8_t ReceiveData(void) 
{
	uint8_t readByte = 0x00;
	uint32_t tickMark = micros();
	/* Delay tick mark to half the bit duration for safety */
	tickMark += (bitDuration >> 1);
	/* Skip start bit */
	tickMark += bitDuration; 
	while (micros() < tickMark);	
	/* Read bits MSB->LSB */
	for (uint8_t i = 0; i < 8; i++) {
		readByte <<= 1; /* Shift previous bits */
		readByte |= PhotoLEDState(); /* Sum bit */
		/* Increment next tick mark */
		tickMark += bitDuration; 
		while (micros() < tickMark);
	}
	return(readByte);
};

The ReceivedData function is triggred as soon as the LED senses a lightening condition, as per this example of the loop function

void loop() 
{
	if (PushButtonState()) {
		/* Send data */
		uint8_t sentByte = random(0, 255);
		SendData(sentByte);
		Serial.print("Data out: ");	
		Serial.println(sentByte, DEC);	
	}
	if (PhotoLEDState()) {
		/* Receive data */
		uint8_t receivedByte  = ReceiveData();
		Serial.print("Data in: ");	
		Serial.println(receivedByte, DEC);	
		/* Acknowledge incoming data */
		PORTB |= CtrlLEDMask;
		delay(200);
		PORTB &= ~CtrlLEDMask;
	}
};

Some more useful function’s code …

uint8_t PushButtonState(void)
{
	uint8_t result = 0x00;
	if (~PIND & PushButtonMask) {
		while(~PIND & PushButtonMask);
		result = 0x01;
	}
	return(result);
};

and…

void PhotoLEDCtrl(uint8_t state)
/* Control LED state */
{
	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 Ground */
		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;
	}
};

and last not least …

uint8_t PhotoLEDState(void) 
/* Compute the light power */
{
	uint8_t result = 0x01;
	/* 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;
	uint32_t stop = (micros() + triggerLevel);
	while (micros() < stop);
	/* Check charge state */
	if (cathodeMask & PINB) {
		result = 0x00;
	}
	/* Returned sate */
	return(result);
};

Starting from there, it is easy to imagine all sorts of communication devices that use a simple LED, including interactive applications. Advanced users will add stop bit and parity check in order to insure safe data transmission. Enjoy!

Leave a Reply

You must be logged in to post a comment.