IR-diod

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
Luckan
Inlägg: 11
Blev medlem: 11 mars 2007, 17:31:53
Ort: Borås

IR-diod

Inlägg av Luckan »

Hej!
Jag ska koppla in en ir-diod (http://www.elfa.se/elfa-bin/inforuta.pl ... ld=7522519) på ett breadboard tillsammans med ett ATMega 16 eller Tiny 13. Min fråga är hur ir-dioden skall kopplas in, vilka motstånd behövs? Krävs en kondensator? osv....
Användarvisningsbild
strombom
Inlägg: 3305
Blev medlem: 27 maj 2003, 10:50:20
Ort: Västra Götaland
Kontakt:

Inlägg av strombom »

Enligt databladet klarar den max 100mA, dock klarar inte pinnarna på en AVR mer än 40mA. Så säg 20mA ?

Spänningen över ir-dioden är enligt databladet ca 1.3 volt. Jag gissar att du driver AVR med 5 volt. Då blir det 3.7 volt över motståndet.

3.7 volt / 0.020 ampere = 185 ohm

Standardmotstånd är på 180 ohm och 220 ohm, så något i den trakten borde duga.
Luckan
Inlägg: 11
Blev medlem: 11 mars 2007, 17:31:53
Ort: Borås

[b]Ny fråga[/b]

Inlägg av Luckan »

Jag har nu kopplat in dioden och har suttit ett tag med att försöka skriva ett program som skickar en signal till min stereo. Det funkar tyvärr inte alls. Vad kan det vara för fel??
Jag vill skicka en signal med 38kHz bärvåg med hjälp av timer1. Om nån kan hitta något i koden som verkar vara fel får denne gärna hojta till:) Eller är det nåt som är otydligt i koden är det oxå bara att fråga...

Kod: Markera allt

#include <avr/io.h>
 int main(void){
	TCCR1A=0x00;
	TCCR1B=0x09; 
	OCR1A=13; 
                DDRD=0x20;
	unsigned int i,j;
	unsigned char switch_zero;
	unsigned char one_or_zero;
	unsigned int volume_down=0x50AF;

	void send_one(void){
		for(j=0;j<500;j++){
			TCCR1A=0x40; 
			}
		for(j=0;j<1800;j++){
			TCCR1A=0x00;
			}	
		}

	void send_zero(void){
		for(j=0;j<500;j++){
			TCCR1A=0x40;
			}
		for(j=0;j<600;j++){
			TCCR1A=0x00;
			}
		}

	void send_startbit(void){
		for(i=0;i<9000;i++){
			TCCR1A=0x40; 
			}
		for(i=0;i<4600;i++){
			TCCR1A=0x00;
			}
		for(i=0;i<8;i++){
			send_zero();
			}
		for(i=0;i<8;i++){
			send_one();
			}
		}

	void check_one_or_zero(unsigned int one_or_zero){
		if(one_or_zero==1){
			send_one();
			}
		else{
			send_zero();
			}
		}

             while(1){
	switch_zero = PINB & 0x01; //0000 0001
	if(switch_zero==0){
		send_startbit();
		for(i=15;i>0;i--){
			one_or_zero=volume_down>>i;
			one_or_zero &= 0x0001;
			check_one_or_zero(one_or_zero);
			}
		one_or_zero = volume_down & 0x0001;
		check_one_or_zero(one_or_zero);
		for(i=0;i<10000;i++){
			}
		}
	}
}
Senast redigerad av Luckan 18 mars 2007, 23:12:46, redigerad totalt 2 gånger.
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Använd "CODE"-taggarna när du skriver in kod så det blir läsbart!
Luckan
Inlägg: 11
Blev medlem: 11 mars 2007, 17:31:53
Ort: Borås

Inlägg av Luckan »

Fixat! Kanske lite lättare att läsa nu :D
mke
Inlägg: 32
Blev medlem: 22 maj 2006, 20:00:39
Ort: Gbg

Inlägg av mke »

Jag ser inte hur du har tänkt att utnyttja timer1. Du har inte ha någon interruptrutin som tar hand om räknaravbrott.

Sen är jag inte riktigt med på dina for-loopar typ:

Kod: Markera allt

void send_zero(void){
      for(j=0;j<500;j++){
         TCCR1A=0x40;
         }
      for(j=0;j<600;j++){
         TCCR1A=0x00;
         }
      } 
Vad har du tänkt att göra här?

Sen så har du inte kommenterat något av koden vilket gör det mycket svårare att följa.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

Att försöka fixa det med for-loopar för att få rätt "timing" är dömt att misslyckas.
Varför inte använda en timer som du föreslog !?
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Inlägg av MicaelKarlsson »

"Att försöka fixa det med for-loopar för att få rätt "timing" är dömt att misslyckas. "

Håller med!
I detta fall så är det säkert lättare att använda en delayfunktion, om det nu är så att pulserna skall vara 600μs. Då ser jag två alternativ:
- Använda delayfunktion. För WinAVR: _delay_us(delay_time);
- Använda t.ex. timer2

Tänk på:
The maximal possible delay is 768 us / F_CPU in MHz.

The maximal possible delay is 262.14 ms / F_CPU in MHz.
Detta är hämtat från delay.h

EDIT:
"Jag har nu kopplat in dioden och har suttit ett tag med att försöka skriva ett program som skickar en signal till min stereo."

Har du kopplat den direkt till din AVR? Om du drar mer ström än vad din AVR klarar så kan ju det ställa till det för dig.

Har du kollat att du får ut det du vill?
Luckan
Inlägg: 11
Blev medlem: 11 mars 2007, 17:31:53
Ort: Borås

Inlägg av Luckan »

Tack för alla svar! Har insett nu efter mätning med flukemetern att mina for-loopar var helt uppe på läktaren och införskaffade korv med mos... :shock:

Men om jag då istället använder tex TIMER2, hur ska den användas? För att t.ex. skicka en logisk etta vill jag sända en 38kHz våg i cirka 500us, vilket sedan skall följas av "ingenting" i cirka 600us. Kan jag göra det genom att helt enkelt först nollställa TIMER2 och sedan låta den räkna upp till 500 och sedan nollställa igen och räkna upp till 600?
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

När jag har gjort IR-sändere (i och för sig med en PIC, men det är
ingen principiell skillnad), så har jag konfigurerat PWM modulen
för att generera bärvågen (t.ex 38 Khz). Sedan genererade jag
signalen (d.v.s *moduleringen* av bärvågen) genom att helt enkelt
stänga av/på PWM modulen. På en PIC är det en enda bit som
ska sättas/clearas, borde vara något liknande på en AVR...

Timingen av signalen (d.v.s de 600 us pulserna) fixade jag via en
*annan* timer (än den som styr PWM modulen).
mke
Inlägg: 32
Blev medlem: 22 maj 2006, 20:00:39
Ort: Gbg

Inlägg av mke »

du använder t.ex. timer0 för att skapa interrupts (CTC-mode) med en frekvens på 38kHz. Vid varje interrupt så flippar du utsignal så du får 1-0-1-0-1-.... För att bestämma när du ska flippa utsignalen och när du ska ha den låg använder du timer1.

Hoppas du blir något klokare utav mitt försök till förklaring
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Inlägg av MicaelKarlsson »

Luckan: for-lopen glömde väl inte senapen? :lol:

Skämt åsido!!

Kod: Markera allt

	
// Setup timer0 and timer2
TIMSK |= (1 << TOIE0)|(1 << TOIE2);  // Enable timer0 & 2  overflow  nterupt.
TCCR0 |= (1 << CS00); //  timer0 CLK = internal clock
TCCR2 |= (1 << CS22)|(1 << COM20); // timer2 CLK  = internal clock/64
Sedan kan du köra timer0 som "togglar" en pinne

Kod: Markera allt

	
#define bit_flip(p,m) ((p) ^= (m))

ISR(TIMER0_OVF_vect)
{
  bit_flip(PORTB,1); 
}
Om du inte får rätt frekvens kan du använda:
TCNTx för att sätta ett startvärde för räknaren så du får 38kHz.


Edit: mke, tycker det var en bra förklaring! :)
Luckan
Inlägg: 11
Blev medlem: 11 mars 2007, 17:31:53
Ort: Borås

Inlägg av Luckan »

Har skrivit lite ny kod men det vill fortfarande inte fungera...
Nedan följer en liten del av programmet. Nån som ser något som inte borde vara där eller något som borde vara där :D

Kod: Markera allt

void send_one(void){ //metod som sänder etta
		TCCR0|=(1 << COM00); //Toggle OC0 on compare match
		TCNT1=0x00; //Nollställ timer1
		while(TCNT1<=540){ //delay 540us
			}
		TCNT1=0x00; //Nollställ timer1
		TCCR0 &= 0xEF; // OC0 disconnected
		while(TCNT1<=1800){ //delay 1800us
			}
		}
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

> Har skrivit lite ny kod.....

Någon speciell anledning att du dels gör exakt som alla har sagt att
du *INTE* ska göra samt inte gör på något av de sätt som du har
blivit rekomendera *ATT* göra ??

> Nån som ser något som inte borde vara där...

Ja.
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Inlägg av MicaelKarlsson »

Luckan: Vad vill du att koden skall göra? Jag tror att du bör sätta dig och skriva ner lite pseudokod eller möjligen ett detaljerat flödesschema och sedan när det är klart skriva koden.

"Någon speciell anledning att du dels gör exakt som alla har sagt att
du *INTE* ska göra samt inte gör på något av de sätt som du har
blivit rekomendera *ATT* göra ?? "

Skulle jag också vilja ha svar på.
Skriv svar