Forum: Mikrocontroller und Digitale Elektronik Probleme bei IR-Schalter mit XMega


von Highii H. (highii)


Angehängte Dateien:

Lesenswert?

Hallo,

ich will mittels XMega eine einfache IR-Reflexschranke aufbauen. Als 
IR-Diode verwende ich TSUS-5202. Als Empfänger TSOP-4836. Der 
Vorwiderstand zur IR-Diode sind 100Ohm. Die Beschaltung des TSOP-4836 
ist identisch der im Datenblatt vorgeschriebenen Beschaltung. Die 
Taktung der IR-Diode ist 36kHz. Dazu will ich 22 Takte (mit 36kHz) die 
IR-Diode ein/ausschalten. Und dann Pause für 22 Takte. So wie laut 
Datenblatt gefordert.
Sobald ich meine Hand als Reflektor benutze, möchte ich, dass eine rote 
LED aufleuchtet. Jedoch blinkt sie nur sehr unrhythmisch. Ich erwarte 
eigentlich, dass die LED durchgehen rot leuchtet, sobald ich meine Hand 
über die IR-Diode bzw. Empfänger halte.
Im Anhang habe ich Video beigefügt.

Leider kann ich einfach keinen Fehler in meinem Code finden. Könnt ihr 
vielleicht erkennen, woran es liegen kann?
Das ist mein Code:
1
#define F_CPU 2e6
2
#include <avr/io.h>
3
#include <asf.h>
4
#include <gfx_mono.h>
5
#include <sysfont.h>
6
7
volatile int zaehler = 0;
8
int ADC_result;
9
char strng[20];
10
11
ISR(TCD1_OVF_vect) {
12
  if(zaehler<44) { //44-> 22 mal Aufleuchten
13
    PORTB.OUTTGL = 0b00000001;
14
  }
15
  zaehler++;
16
  if(zaehler>87) { // 87 -> 22 Impulse Pause
17
    zaehler = 0;
18
  }
19
}
20
21
22
int main(void)
23
{    
24
  board_init();
25
  
26
  // Ausgänge für rote LED (bit 1) und IR-LED setzen (bit 0)
27
  PORTB.DIR = 0b00000011;
28
  
29
  // Interrupts freigeben
30
  PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
31
  
32
    //Oszillator auf 32Mhz stellen
33
    OSC.CTRL |= OSC_RC32MEN_bm;
34
    // Warten bis der Oszillator bereit ist
35
    while(!(OSC.STATUS & OSC_RC32MRDY_bm));
36
    //Schützt I/O Register, Interrupts werden ignoriert
37
    CCP = CCP_IOREG_gc;
38
    //aktiviert den internen Oszillator
39
    CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
40
    
41
    //Prescaler 64, PER 7, Takt 32Mhz --> 600Mikrosekunden Burst bei 22 Impulsen. Impulsfrequenz ist dann bei 36kHz
42
    // oder
43
    //Prescaler 1, PER 444, Takt 32Mhz --> 600Mikrosekunden Burst bei 22 Impulsen. Impulsfrequenz ist dann bei 36kHz
44
    TCD1.CTRLA = TC_CLKSEL_DIV1_gc; // Pre-Scaler
45
    TCD1.PER = 444; // Wert zu dem gezählt wird
46
    TCD1.CTRLB = 0x00; // Normal-Modus
47
    TCD1.INTCTRLA = 0x03; // Höchste Interrupt Priorität
48
    
49
// initialize ADC
50
PORTA.DIR = 0x00;
51
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc|ADC_CONMODE_bm;  // 12 bit signed
52
ADCA.REFCTRL |= 0b00010000;        // Ref = VCC/1.6 = 2.06 V
53
ADCA.PRESCALER = ADC_PRESCALER_DIV4_gc;
54
ADCA.CTRLA = ADC_ENABLE_bm;
55
56
sei(); // Interrupts aktivieren
57
58
while(1)
59
{  
60
  // ADC channel lesen
61
  ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
62
  ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN4_gc;
63
  ADCA.CH0.CTRL |= ADC_CH_START_bm;
64
  while(!ADCA.CH0.INTFLAGS);
65
  ADC_result= ADCA.CH0.RES;
66
67
  if (ADC_result<1000) // ca. 50: Hand drangehalten, 1700: Hand weg
68
  {  // Rote LED an
69
    PORTB.OUT |= (1<<1);
70
  }
71
  else
72
  {  // Rote LED aus
73
    PORTB.OUT &= ~(1<<1);
74
  }
75
}
76
}

von Hubert G. (hubertg)


Lesenswert?

Hast du dir das Ausgangssignal der TSOP angesehen?

von Highii H. (highii)


Lesenswert?

Ja das habe ich. Es sieht korrekt aus.
Ich habe vergessen zu erwähnen, dass ich glaube, dass es an der IR-LED 
liegt. ich habe den Eingang der IR-LED per ADC eingelesen und mir den 
Wert auf nem Display darstellen lassen. Da erkenne ich dieses 
unrhythmische Gezappel.
Leider habe ich kein Oszi. Damit könnte ich viel genauere Analysen 
machen.

von Hubert G. (hubertg)


Lesenswert?

Ohne Oszi wirst du nicht viel sehen. Ein Multimeter ist dafür nicht 
geeignet.
Probier mal das Signal zu glätten, 1k und 4,7µ sollten reichen. Das 
ganze wird dann zwar etwas träger.
Eine andere Möglichkeit wäre den ADC mit dem Taktsignal synchronisieren.

von Highii H. (highii)


Lesenswert?

Hubert G. schrieb:
> Probier mal das Signal zu glätten, 1k und 4,7µ sollten reichen.

Mit ist nicht bewusst, wo ich Widerstand und Kondensator anbringen muss. 
Dafür fehlt mir leider das Wissen. Kannst du es genauer erklären?

von Hubert G. (hubertg)


Lesenswert?

Von Pin 1 des TSOP gehst du über den Widerstand auf den µC. Auf der µC 
Seite den 4,7µ nach GND. Die Werte sind nicht kritisch, nur der Elko 
sollte nicht zu groß sein.

von Highii H. (highii)


Lesenswert?

Hubert G. schrieb:
> Von Pin 1 des TSOP gehst du über den Widerstand auf den µC. Auf der µC
> Seite den 4,7µ nach GND. Die Werte sind nicht kritisch, nur der Elko
> sollte nicht zu groß sein.

Vielen Dank. Das werde ich mal ausprobieren.
Hast du dir den Code mal angeschaut? Konntest du irgendwas sehen, dass 
nicht ganz passt?

von Hubert G. (hubertg)


Lesenswert?

Gesehen habe ich nichts im Code, kann ihn allerdings nicht ausprobieren.
Es ist aber so, das du einmal während eines Pulses misst und dann wieder 
in einer Pause. Das ganze vollkommen unrhythmisch.
Daher mein Vorschlag des synchronisieren, sodass du immer während eines 
Pulses misst.

von Bastian W. (jackfrost)


Lesenswert?

Hi,

laut dem Datenblatt gibt es eine Verzögerung zwischen dem Ausgang an 
deinem IR-Empfänger und dem start der Burstpakete.

Ausgehend vom Datenblatt ist die Verzögerung :

Bei den 36 kHz dürften das zwischen 0,19 ms und 0,41 ms liegen.
Erst dann solltest du dein Signal messen , wenn du das Signal nicht über 
ein RC-Glied glättest.

Gruß JackFrost

von Highii H. (highii)


Lesenswert?

Ich habe es gelöst. Es lag an der Synchronisierung von ADC mit den 
Bursts. Ich lese jetzt ADC nur noch dann aus, wenn ich Pulse. Und zwar 
nehme ich den Mittelwert über 4 Messungen. Jetzt funktioniert es 
wunderbar!
Vielen Dank!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.