Driving IR LEDs using XMEGA128A1

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi friends,

I m new to XMEGA(using XMEGA128a1 with AVR Dragon debugger). As a simple starting test I would like to drive an IR LED circuit with 5 LEDs and series resistors.
In the data sheet it was mentioned that each pin can drive an output of 20mA, which will be sufficient for my test.

Input will be a pulse and I want to sense the rising edge. I had tried some code which didn't worked out. Can u guys pls help me with this. Its the first time I am using XMEGA.:roll:

Thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I had tried some code which didn't worked out. Can u guys pls help me with this.

Unless anyone here is psychic we're not going to get very far without actually seeing that code ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi clawson,

Thank you for your reply.
Here is the code that I have tried.

#include "compiler.h"
#include "preprocessor.h"
#include "board.h"
#include "ioport.h"
#include "conf_ioport_example.h"
#include "xplain.h"
#include "sysclk.h"
#include "avr_compiler.h"


int main(void)
{
	
	int8_t state = 0;
	int32_t i;
	int counter = 0 ;
	// Initialize the board.
	// The board-specific conf_board.h file contains the configuration of the board
	// initialization.
	
	sysclk_init();     ///System clock initialisation
	board_init();

	while (1)
	{		
   
////Sensing Rising Edge  on Port D 2nd pin	 
	if (ioport_pin_is_high(TRIGGER_PORTD_2))  
	{
ioport_set_pin_high(LED2_GPIO);  //Turn OFF LED 2	
		                 			
counter = counter++;  // increment counter value

		
		if(counter=31999)  		   
			{
                counter = 0;    ///Reset the counter
			
				}
	    			        
	 if(counter % 2 == 0)
		{	     
// for first 2 pulses output drives the LEDs ON  & for next two pulses off	     				   	  
	    					       ioport_set_pin_low(LED0_GPIO);  //Turn ON LED

				ioport_set_pin_high(TRIGGER_PORTA_2);  // OUTPUT pin A2 Drives LED circuit
			    	}
}

			
     else 
	 {
ioport_set_pin_high(LED0_GPIO);   //Turn OFF LED 0

ioport_set_pin_low(TRIGGER_PORTA_2); // LED circuit Switched off
				}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's only half a program. There are defines such as TRIGGER_PORTD_2 which are used but their definitions are not shown. And there's calls to functions such as sysclk_init(), board_init(), ioport_pin_is_high(), ioport_set_pin_high() for which the function bodies are not shown.

You do seem to be over complicating things - for a simple test to light an LED it should be a simple case of setting a direction register and an output port and nothing more. Don't try and run before you can walk.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

vitsux,

Can you please clarify the purpose and topology of your application?

1. You are driving 5 IR LEDs at 20 ma each from 5 separate port pins? Or, 5 IR LEDs in parallel from one GPIO with a total LED current of 20 ma?

2. How are the LEDs connected to the GPIO port pin(s)? E.g. Cathode to the pin with series resistor(s) to +3.3 VDC? Or, Anode to the pin? In other words are you sourcing or sinking the LED current thru the GPIO pin(s)?

3. The 20 ma rating you are referring to is an Absolute Maximum Rating. You will get less depending on whether you are sourcing or sinking the load current. See the graphs in the 128A1 Data Sheet Section 33.1 PAD CHARACTERISTICS for actual, achievable current values.

4. What is you hardware platform? E.g XPLAIN, Audrino, etc.

5. What, specifically, do you mean by "Input will be a pulse"? Do you mean a pulse applied on another GPIO input and you want to drive the IR LEDS ON for the duration of that pulse? Or, for some fixed time for each occurence of the "pulse"? Or, what?

6. Assumming these are the type of IR LEDs which are invisible to the naked eye, you may want ot hook up a 6th visible LED which mimics the behavior of the IR LEDs so you can see what's going on as you develop and debug your code.

7. Do you have an O-scope or logic probe?

Thanks,
Chuck

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thank u Chuck-Rowst for ur reply

1.I want to drive 5 IR LEDs in parallel from one GPIO with a total LED current of 20 mA..the LEDs I am using are SFH 4650.

2.I am sourcing the current from GPIO to the circuit.

3.Yeah. Its absolute maximum rating. But the LEDs are working if the current is something around 18mA.

4.Hardware platform is XPLAIN.

5.I am working with a camera, which outputs each frame as a pulse. The period of each pulse (each frame) is around 30ms. Pulse will be applied on another GPIO pin which will be input, and once if this pin senses the rising edge of pulse, the other (output) GPIO pin should be high and thus sourcing the IR LEDs.

6.Yes these are IR LEDs which are invisible to naked eye.

7.Yes I have an O.scope and a freq gen. Right now i am using these to test my code.

The purpose of this application is, I need the IR LEDs to be turned ON for the first two frames and turn OFF for the next two frames.

Thank u,
vitsux

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're using this LED?
http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=475-2569-1-ND

It has a maximum forward current of 100mA. Somehow I don't think 20mA is going to drive 5 of these things. That would only give you 4mA per LED!

Better to use the pin to drive a BJT that LED current.

Dan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am still not entiirely clear about your LED topology.

Does each LED have its own series resistor?

Are you expecting to get 4 Ma in each LED for a total of 20 ma? Or, 20 ma per LED? Did you actually measure 18 ma flowing thru the LEDs? Or where did you get that 18 ma figure?

The function you are trying to create seems pretty straightforward. What problem(s) are you experiencing?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What voltages do you have available to power the LEDs besides the Xmega's power supply?

As CR noted above, you can't put the leds in parallel with each other. they are not that carefully matched.

You can put a series resistor in series with each LED, and then connect the (LED & resistor) units in parallel.

You can stack them all in series, with one resistor, if you have a high enough voltage supply to work with.

I would switch them with a NFet these days.

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know the OP is using an XMega but this is basic to all MCUs.

There was an article in the February 2008 Nuts and Volts magazine by G.Y. Xu, "Follow The Flaqshlight Evolution", that showed how to drive 5 LEDs in series using an ATtiny11L.

The article describes a charge pump using three AA batteries as the supply for the ATtiny11L and the charge pump circuit itself.

I found that article to be extremely well written and very informative as it decribed interfacing multiple LEDs both in series and in parallel to an MCU.

A follow on article using an ATtiny13 appeared in the December 2008 EDN magazine:

http://www.edn.com/article/45930...

Xu's website is:

http://www.geocities.ws/xumicro/

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you all for your replies.

@Chuck Rowst: I am sorry I was not clear.
Actually I have an LED circuit that has 5 IR LEDs,
each has its own Series Resistor and thus I stacked them all together in parallel.
I want the whole circuit to be driven with 20 mA.
If I connect this circuit to an external power supply, its working with 20mA.
So I thought 20mA would be sufficient to drive them.

@Doc Jc: I have no other external power besides XMEGA PS. And I have the LED circuit exactly as U said.
Thank you.

@Larry VC: Thank you. The article was interesting and helpful.

And now
I got my code working in the required way.
I just want to measure the output current on the pin and so I made an output GPIO pin high and
I measured the current on this pin, it was around 33mA. Is this normal?
Because in the data sheet, It was mentioned not to use more than 20mA.
How can I change the output current on the GPIO pins?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You made it output -> high and measured the current... HOW did you measure it, 33 mA isn't normal ? You control Io by the circuit you connect to the output pin. I didn't check the spec for that led but 100mA max. usually means a respectable Vf.

Your circuit is all wrong for driving these types of LEDs, they won't have any range with about 2V and 4mA. If you're doing "hello world" work, it would've been better to use visible LEDs.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

vitsux,

A few comments:

A. I suspect that you measured the 33 ma by simply connecting a current meter between the high GPIO output and ground. Is that correct? If so, you are measuring the output short-circuit current of the GPIO driver because an ammeter has a very low impedance. This is not a recommended way to use a GPIO output. For one thing, you are exceeding the recommended Absolute Maximum Rating of 20 ma output current. For another, you may be permanently damaging the IC in some way by execeeding this Absolute Max.

To make a legitimate output current reading you need to put your current meter in series with a legitimate output load - such as your array of LEDs.

B. Your array of LEDs with a resistor-per-LED is legitimate. All you need do do is calcualte a series resistor value which will give you 4 ma thru the associated LED. Do you know how do do that?

C. As I have previously posted, you need to check the electrical specifoications for the output drive capabilities of this chip's GPIO outputs. I think you may find that you cannot operate them at 20 ma with assurance your LEDs will light. At the least, you are kind of pushing the output capabilites more than you really need to. See my next comment for a more prudent design approach.

D. Why not split the LEDs (and resistors) over several GPIO outputs, them drive them simultaneously in your program?

END

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
counter = counter++;  // increment counter value

No, it never really increment the counter. And even if it did...

      if(counter=31999)           
         {
                counter = 0;    ///Reset the counter
         
            }

Ouch!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

No, it never really increment the counter.

Not true. An experiment lead to the build time warning:

test.c:6: warning: operation on 'counter' may be undefined

However the code generated was:

       counter = counter++;
  96:	80 91 00 01 	lds	r24, 0x0100
  9a:	90 91 01 01 	lds	r25, 0x0101
  9e:	90 93 01 01 	sts	0x0101, r25
  a2:	80 93 00 01 	sts	0x0100, r24
  a6:	01 96       	adiw	r24, 0x01	; 1
  a8:	90 93 01 01 	sts	0x0101, r25
  ac:	80 93 00 01 	sts	0x0100, r24

So the variable is incremented by this.

(but I agree this is a horrendous abuse of the post-increment operator).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

counter = counter++; // increment counter value

Whats wrong with the standard:

counter++;

And...
if(counter=31999)

will always return true (Assignment is always successful) it should probably be:

if(counter == 31999)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Some would argue:

if(31999==counter) 

that way if you miss '=' and use:

if(31999=counter) 

You get an unavoidable error.

(personally I hate this as it looks counter-intuitive but it is often suggested for "safer" code).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just use -Wall --pedantic with gcc and derived compilers. If I made a mistake and used assignment instead of comparison operator I would get a warning:

Quote:
warning: suggest parentheses around assignment used as truth value

If I really wanted that assignment in the if clause I could use an extra set of parentheses and avoid the warning

if ((a = b))