Solved: ATTINY45 driving IR LEDs at 36kHz?

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

First time coding an AVR and first post, so have mercy.

 

I am driving an ATTINY45-20 PU with 5V, connected on PB0 and PB1 to an IR 940nm LED and 75 Ohm resistor.

The purpose is to drive two leds, each on a different pin, to output 36kHz.

The amount of cycles in the loop function is based on the specifications in the TSOP1236 datasheet.

 

The receiver has two TSOP devices connected to an LM393 connected to pin 2 and 3 of an Arduino. The Arduino's attachInterrupt() should constantly be invoked, since it should receive bursts from the IR LED.

 

However, it reacts that way only with the IR LED on PB0. It doesn't see the IR LED on PB1, except when I put my hand in front of the TSOP and remove it. Then it will report a beam break a couple of times, sometimes twice, sometimes ten times, as if it temporarily notices the bursts.

 

I know the fault is not at the receiver's end, since both TSOP devices accurately register my TV remote. Meaning, as long as I press a button, beam breaks are reported.

 

1/ Is there something wrong with my code? I found it in a simplified version online and modified it after studying Dean Camera's PDF tutorials. 

 

2/ Additionally, I am confused about the value of OCR0A. I thought the formula was (1/36000) / (1/1000000) - 1? Since I'm trying to output 36kHz with a default clock of 1mHz. I put '13' now, or half the outcome of the equation, since that corresponds to online examples I've seen but without really knowing why.

 

void setup(){
  DDRB |= (1<<PB0); //Set pin PB0 as output
  DDRB |= (1<<PB1); //Set pin PB1 as output

  TCNT0 = 0;
  TCCR0A = 0;
  TCCR0B = 0;

  TCCR0A |=(1<<COM0A0); //Timer in toggle mode Table 11-2
  TCCR0A |=(1<<COM0B0); 

  TCCR0A |=(1<<WGM01); //Start timer in CTC mode Table 11.5
  TCCR0B |= (1 << CS00); //Prescaler Table 11.6

  OCR0A = 13; //CTC compare value, 36kHz
}

void loop(){ //cycle = 1/36 = 28μs
  TCCR0A |=(1<<COM0A0); //burst on for 10+ cycles
  TCCR0A |=(1<<COM0B0);
  delayMicroseconds(500); 

  TCCR0A &= ~(1<<COM0A0); //off for 14+ cycles
  TCCR0A &= ~(1<<COM0B0);
  delayMicroseconds(1000);
}

 

 

Last Edited: Thu. Jun 13, 2019 - 07:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Welcome to AVRFreaks!

 

 

NilsDeschrijver wrote:

 TCCR0A |=(1<<COM0A0); //Timer in toggle mode Table 11-2
  TCCR0A |=(1<<COM0B0); 

close, but for CTC mode, to toggle the pin on compare match, you need:

  TCCR0A |=(1<<COM0A0); //Timer in toggle mode Table 11-2
  TCCR0A &=~(1<<COM0A1); 

similar changes are needed in the loop as well.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

hehe Something I've done often, but not with a 45. Tiny 10, yes, 45 no.

 

My IR receivers reject a STEADY 38KHz signal, so I put a 4 ms cycle: on ms 0, start the signal. on ms1, check output of receiver. on ms 2 turn pulses off. on ms3 do nothing.

The largest known prime number: 282589933-1

It's easy to stop breaking the 10th commandment! Break the 8th instead. 

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

Thank you both for the warm welcome and your replies.

I've been struggling with this for months.

 

From your answers and the datasheet, I understand that I need to toggle the pins during the burst and clear them during the gap in the for loop.

Since I need both PB0 and PB1 engaged, I reckon I need both TCCR0A |=(1<<COM0A0) and TCCR0A |=(1<<COM0B0), since register A and B refer to OC0A and OC0B respectively.

Does the code seem correct now?

 

void setup(){
  DDRB |= (1<<PB0); //Set pin PB0 as output
  DDRB |= (1<<PB1); //Set pin PB1 as output

  TCNT0 = 0;
  TCCR0A = 0;
  TCCR0B = 0;

  TCCR0A |=(1<<COM0A0); //Timer in toggle mode Table 11-2
  TCCR0A |=(1<<COM0B0);

  TCCR0A &=~(1<<COM0A1);
  TCCR0A &=~(1<<COM0B1);

  TCCR0A |=(1<<WGM01); //Start timer in CTC mode Table 11.5
  TCCR0B |= (1 << CS00); //Prescaler Table 11.6

  OCR0A = 13; //CTC compare value, 36kHz
}

void loop(){ //cycle = 1/36 = 28μs
  TCCR0A |=(1<<COM0A0); //burst on for 10+ cycles
  TCCR0A |=(1<<COM0B0);
  delayMicroseconds(500); 

  TCCR0A &=~(1<<COM0A1); //off for 14+ cycles
  TCCR0A &=~(1<<COM0B1);
  delayMicroseconds(1000);
}

And does the OCR0A seem correct to you?

EDIT: It's correct, since I'm toggling and therefore the value needs to reflect a half-cycle.

Last Edited: Sat. Jun 8, 2019 - 10:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That should be working now, you may want to find a pair of Atmel app notes on IR sending and receiving AVR410 & AVR415 although IIRC the code examples were in assembler, you may find them helpful.  Good luck.

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Welcome to the Forum.

 

Some people on the Freaks site debug projects with a programmer/debugger.

I tend to use a visible LED and an O'scope.

To each their own!

 

I just posted a link to this $15 USD toy O'scope in another Thread, so I thought I'd post it here, as well.

 

With it you can "see" the output signal you are feeding the LEDs, which I find very helpful in such projects.

 

You can also look at the output of the receiver and see it's signal.

 

As a cheap toy, and single channel, you can't view both signals simultaneously, but take it for what its worth.

 

Question:

Are you driving the IR LED directly with the micro's I/O pin, or via a transistor?

What is the Vf of the IR LED you are using.

A quick check on Mouser for an IR LED at 940 nm showed one with a Vf of 1.2 V.

The current through the resistor and LED is then: (5-1.2)/75 = 50 mA.

 

That is out of spec for the Tiny45.

In the Electrical Characteristics section of the data sheet it says the Absolute Maximum Ratings is 40 mA per I/O pin.

In most of my designs I try to stay well below the Absolute Max, so I might run the pin at 20 mA, (or less).

 

You didn't mention if you are using two LEDs in order to increase your output signal strength, or if they are both present for another reason.

If you merely want more signal strength, then it would be reasonable to use the micro to drive a small NFet transistor, and use the NFet to drive either one or both IR LEDs.

 

Next, IF you were not already exceeding the I/O Pin's output drive current rating, you could put a normal, visible, red or whatever color you like, LED and resistor in parallel to the IR LED and resistor, i.e. the I/O pin drives both LEDs and their resistors, and then you can see when the IR LED is on.  You can't see it flashing at 36 kHz, but you at least easily know when it is powered up.

 

JC

 

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

This schematic shows a better way to driver your IR LEDs, in case you are driving them right from the micro's I/O pins.

 

The micro drivers a small NFet transistor.

The transistor draws almost no current, so you are not exceeding the I/O pin output current limit.

 

The NFet then drives the LEDs.

It turns on and off like a switch, and can carry up to 200 mA, essentially 10 times what the I/O pin can.

 

The 10K R1 resistor holds the Gate low when the micro first powers up, before your software configures it as an output, and sets the level either high or low.

This keeps the NFet turned off, and prevents if from being in its "linear" operating range during power up.

The exact value isn't critical.

 

You can put several LED and resistor pairs in parallel, as is shown here.

You could have one NFet turn on and off both of your IR LEDs, and even add another visible LED in parallel to the IR LEDs.

 

At 50 mA for each IR LED, two in parallel means that the NFet is carrying 100 mA, well within its 200 mA current limit.

 

R2 and R3 set the current for their respective LEDs.

If you have one IR and one visible LED, they can both have their own resistor values.

In your design, mentioned above, you have R2 = 75 ohms.

 

Others, smarter than I, can do the thermal calc's for you and tell you if the NFet needs a small heat sink on it if it is driving 100 mA continuously, or not.

(I don't do thermal calc's very well.)

 

Know that you could also use the micro's I/O pin to drive two NFets, (run the I/O pin signal to both Gates), with only one pull down resistor, R1, needed.

Then each transistor is only drawing 50 mA.

 

I included the 0.1 uF by-pass cap on the schematic.

It should be mounted as close to the microcontroller chip as possible.

It is required for all micros, and goes across the power supply pins.

 

Good luck with your project.

 

JC 

 

Last Edited: Sat. Jun 8, 2019 - 06:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good morning, DocJC. 

 

First of all, a sincere thank you for the clear explanation and the neat schematic!

This is really, really good stuff.

 

I drive two IR LEDs, each for its own purpose, namely being in direct line of sight of its own TSOP, both photodiodes connected in turn, via an LM393, to an Arduino for calling the attachIntterupt() function. 

The receiver's software uses these two LEDs and respective receivers to determine direction; is someone going in or out of a room?

 

The LEDs are indeed directly on the I/O pins, without a transistor.
With a Forward Voltage VF Max: 1.5V, I was indeed trying to drive them at 50mA.

This is the exact LED I bought.

 

I need about a meter, which I currenty reach. 

 

Did I understand correctly that, even though I am not trying to increase signal strength, you would still recommend a transistor?

Possibly because driving the AVR I/O pin at the max. of 40mA is not recommended. Why is that?

 

Finally, somewhat unrelated, a question about interference. Both LEDs are 4 centimeters apart, since my doorframe doesn't allow for more space. Unfortunately, both TSOP receivers are picking up both LEDs, which - obviously - hinders them giving correct readings about people entering and exiting. How can I fix this?
 

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

Cool project.

 

Yes, I'd suggest switching to having an NFet drive the IR LEDs.

There are some very, very, very tiny wires inside the big chip, that connect the pins to the die inside the chip.

Those wires, and the chip's internal transistor dimensions, limit the amount of current that can be handled.

Running the chip, rated at 40 mA per pin, at 50 mA, (which is WAY over the Max), is not a good design for long term success.

It might work for a while, it might die on you.

 

Your question regarding determining which way a person, (forklift, or whatever), is moving through the sensors is a good one.

 

Although I would love to complicate your project with directional ultrasound, or a low powered radar, or swap the IR LED signal with two lasers, or put a pressure sensor on the floor, etc., there is still an "Easy" approach to solving this dilemma.

 

I assume the electronics on each side of the doorway can talk to each other through wires.

 

With that assumption in mind you simply Time-Division-Multiplex your two signal  channels.

That means you don't run them both in an always on state.

 

Run Sensor A for 50 mSec.

Then run Sensor B for 50 mSec.

Then A,

Then B,

...

 

Now, it really doesn't matter if you have cross-talk between the two channels, with both of them receiving the transmitted signal from the "wrong" transmitter.

 

You can now easily, in software, determine which sensor, A or B, had an interrupted signal first, as you know which channel is transmitting at the time you detect an interrupted signal.

 

QED.

 

What the actual time on is for each sensor depends upon how fast the receiver can lock on to a new signal and give a reliable output, perhaps much faster, perhaps not.

 

Good luck with your project!

 

There may be other approaches as well, but that is the first one that crossed my mind.

 

JC

 

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

NilsDeschrijver wrote:
Unfortunately, both TSOP receivers are picking up both LEDs, which - obviously - hinders them giving correct readings about people entering and exiting. How can I fix this?

Place each sensor at the bottom of a tube to restrict which source emitter it can see.   Tube length will need to be long enough so sensor can only see one source.

Lenses may be another way to filter a source as well, but I would start with the tubes.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Thank you again, DocJC, for the suggestion.

I put a film cap and a BS170 Mosfet N-Channel (60V, 0.5A) on my breadboard.

 

However, returning to my original post; I still don't get reliable readings.

I briefly thought it was interference by the other IR LED, but, after disconnecting the second LED and TSOP, I cannot even get decent readings from one 'beam'.

 

I did a day of troubleshooting with only one beam. 

An attachInterrupt() with Serial.println("DETECTED") flags if the TSOP gets a signal, meaning is active-low.

(I understand putting serial in an ISR is bad form, but I think it works for testing purposes.)

 

This is what I found: 

 

  • From only a couple of centimeters away, it works as you would think: DETECTED is spammed to the terminal and stops when I put my hand in front of it.
  • More than a couple of centimeters away, let's say a mere meter, the TSOP/Arduino doesn't see anything all of a sudden. However, when I put my hand directly in front of the receiver, and take my hand away, he very briefly sees the signal and says DETECTED about four to seven times, depending. When I power down the transmitter, the receiver does not react this way.
  • I also had the impression that I got a slighly better result when it got dark in the evening.

 

What could this indicate? 

 

I would think the output signal is bad and doesn't distinguish itself from regular light enough?

Fearing I did something wrong uploading the sketch to the AVR, I burned the bootloader again, so the ATTINY45 clock would in fact be at 1Mhz factory setting.

But it didn't help.

 

For what it is worth, I attach some pictures of the breadboard and the upload.

 

P.S.: I was thinking, ki0bk, that if I have an interference problem, I'll use two different kHz values, for instance 36kHz on IR LED one and 50kHz on IR LED two.

 

Picture breadboard

Picture set-up

Picture ArduinoISP to AVR

Last Edited: Wed. Jun 12, 2019 - 08:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In pictures 1 & 2, it looks like the IR tx led is pointing up, while the IR RX sensor is looking left???,   Try pointing the TX LED at the sensor! (i.e. bend LED at a right angle to the right)

 

NilsDeschrijver wrote:
I would think the output signal is bad and doesn't distinguish itself from regular light enough?

The IR sensor should have a built in IR light filter, but placing the sensor at one end of a tube pointed in the direction of TX led would limit the field of view to a smaller area and limit ambient light from reaching the sensor.

 

This sounds like a fun project, good luck with it.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Bending the LEDs of course did the trick, and it is working perfectly now.

 

Can't believe I missed that.

Not the dumbest thing I've done in my life, but pretty close.

 

Thanks, ki0bk!

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

The board connected to the Arduino lacks a ceramic cap...always put a good cap right at your power pin(s)  (suggest 0.1uF)...an Electrolytic supplies bulk storage against sags, but is rather poor at filtering high freq (xx MHz) noise.

 

At low frequency, Cs increases slightly with increasing temperature. Above a certain temperature-dependent frequency, the capacitance drops rapidly with increasing frequency. This behavior is most dramatic at very cold temperatures and is related to the distributed RC nature of the electrolyte-filled etch tunnels

 

 

I found this guide VERY interesting...describing many "practical" effects going on in electrolytic caps....an interesting read!!!

http://www.cde.com/resources/catalogs/AEappGUIDE.pdf

 

such as:

During the Ageing process, a DC voltage greater than the rated voltage but less than the formation voltage is applied to the capacitor. Usually the voltage is applied at the capacitor’s rated temperature, but other temperatures may be used depending upon performance goals. This process re-forms the edges and any damaged spots on the anode foil such as where the tabs were attached. And bare areas or damaged dielectric is repaired with fresh aluminum oxide dielectric. Proper ageing reduces the instance of early application failures (infant mortals). Low initial DC leakage current is a sign of effective ageing. After ageing, the capacitor is tested, sleeved and labeled, packed and finally shipped.

 

Whenever a polar liquid such as an aqueous electrolyte is in physical contact with a solid conductor— even without an applied voltage— molecular rotations occur in the electrolyte ions near the interface, forming a region of separated, opposite charges. This charge-storage mechanism is called an electric double-layer capacitance, and occurs to a strong degree at the electrolyte-cathode surface and to a lesser degree at the electrolyte-anode surface. This makes the cathode a capacitor in series with the anode. Thus in effect an electrolytic capacitor has several capacitances in series

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Wed. Jun 12, 2019 - 08:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I hope it is not bad manners to return to a solved thread.

Reading more about Mosfets, I discovered Static Drain−Source On Resistance.

 

The max. Rds(on) is 5Ω for my Mosfet BS170 (datasheet).

Using 3 x 1.5 AA batteries in series, gives 2A x 2A x 5 = 20W of power loss.

 

The Mosfet drives two diodes that are always on.

Do you think that is an acceptable power loss or do I need to find a better Mosfet, such as the IRF4905PBF?

 

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

Interational Rect. now Infineon has one of the oldie goldie nFet which is IRLML2502, an SMD SOT-23-3 package. I believe this would be ideal for you. I've looked to your pictures...but maybe if you want to make a PCB in the future for this application this would be good.

 

lg/regards,

Moe

Last Edited: Thu. Aug 29, 2019 - 09:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The max. Rds(on) is 5Ω for my Mosfet BS170 (datasheet).

Using 3 x 1.5 AA batteries in series, gives 2A x 2A x 5 = 20W of power loss.

 

The Mosfet drives two diodes that are always on.

Your numbers don't seem right - you wouldn't be drawing 2A from AA batteries for too long and if the BS170 is loosing 20W, it would have melted by now! As well, you'd want really big IR leds to handle 2A.

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

Kartman wrote:

The max. Rds(on) is 5Ω for my Mosfet BS170 (datasheet).

Using 3 x 1.5 AA batteries in series, gives 2A x 2A x 5 = 20W of power loss.

 

The Mosfet drives two diodes that are always on.

Your numbers don't seem right - you wouldn't be drawing 2A from AA batteries for too long and if the BS170 is loosing 20W, it would have melted by now! As well, you'd want really big IR leds to handle 2A.

 

You are right. 

I can't wrap my head around anything related to current at the moment.

 

Basically, I was wondering what the difference is between 5 ohms and 0.045 ohms in terms of losing battery power measured in hours in the schematic posted by JDoc above.

The LEDs draw 100mA in current together from the 3 x 1.5 AA batteries connected in series.

Last Edited: Thu. Aug 29, 2019 - 10:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NilsDeschrijver wrote:
The LEDs draw 100mA in current together from the 3 x 1.5 AA batteries connected in series.

Batteries are rated in Amp/hour capacity, so if you draw 100mA continuously from a AA (rated ~2000mA/hr) it will last up to 20 hours, although as an engineer I would only estimate 70% of that or 14 hours.

Different battery chemistries have different Amp/hour ratings, so adjust your needs by battery type.  Batteries in series only raise the voltage, not the Amp/hour capacity.

Hope that helps.

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Your mosfet is your only current limiter right now it would seem, and is probably saving your led's from destruction.

 

E = IR

E = 0.1A x 5ohms = 0.5v - this must be the voltage drop across the mosfet (assuming 5 ohms is correct)

4.5v - 0.5v (mosfet) = 4v = voltage drop across 2 led's- makes sense (~2v ea is in the right ballpark)

 

          2.5V  0.5V

             |      |

Vcc>led1|led2|mosfet<0v

 

 

You should calculate what you want for current, then use appropriate resistors.

 

If you want 50ma-

4.5v - 2x 2v (4v) = 0.5v

0.5v / 0.05A = 10 ohms

if mosfet is 5 ohms, then add another 5 ohms to limit to 50ma

if you wanted 100ma, then do nothing (and check if the led's can handle it in the long run)

 

Unless you want to start controlling the voltage to the led's for better efficiency (no wasted voltage drop), you just live with the ~10% wasted energy you currently have through the current limiter (mosfet). Although you will still be wasting some in whatever scheme replaces the normal current limiter. When you are talking about driving 100ma through led's, your better solution for battery life is to limit the current to something that is as minimal as possible, and still works. If 50ma does the job, why use 100ma. If 25ma does the job, why use 50ma. Etc.

 

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

Hello Every Body 

 Great Project 

I did it 4 Months Ago with ATmega8 as a receiver and a bunch of ir leds separately

i made it in to modes : 

1-  putting the ir leds on  one side of the gate and the sensors (with tubes) on the other side 

2- putting the ir leds and the sensors on one side and measuring the reflection (when some one pass the reflection is stronger )

but..

I was still learning Avr 

I made it with a continues emitting ir leds (no freq just always on) .. and the sensors are ir sensors ( like ir photoResisiors)  and then connected the ir sensor to analog input from atmega8

 

that what made my project not fully working i think .. and it made it very VERY sensitive  to environment ( like sun .. fire .. light etc) so it wasn't successful. 

 

my next version of it will be similar to yours 

 

bugs that may happen with you:

- if the beam line was on the level of human arm it will count the arm as a single person then and person it self as a person  (if the man entering was moving his arms )

- it will not function correctly if more than 1 human enters at the same time 

 

Good luck with your project

 

 

A Beam of Light out of the War