Forum: Mikrocontroller und Digitale Elektronik 38 kHz Trägerfrequenz mit Mikrocontroller erzeugen(Anfänge


von Markus Reichert (Gast)


Lesenswert?

Hallo zusammen,

ich bin vor kurzem neu in die Mikrocontroller-Programmierung
eingestiegen und hätte da eine, vermutlich recht banale Frage:

und zwar versuche ich eine Fernbedienung zu programmieren. Ich habe die
Trägerfrequenz und das Timing der einzelnen Tasten herausgefunden und
versuche dieses nun in einen Controller zu programmieren.
Leider scheitere ich schon an der ersten Hürde: wie kann ich die
Trägerfrequenz von 38kHz mit einem Controller erzeugen? Geht das
überhaupt? Beim googeln habe ich so gut wie nichts gefunden. :-(

Alles was ich herausgefunden habe ist, dass ich mit Hilfe der
Pulsweitenmodulation und einem D/A-Wandler evtl. die Trägerfrequenz
erzeugen kann. Stimmt das oder gibt es vielleicht noch eine einfachere
Möglichkeit?

Ich programmiere die Atmel ATMega-AVR-Controller mit dem von Atmel
angebotenen Entwicklerboard und der dazugehörigen Software.

Vielen Dank und Gruß
Markus

von TravelRec. (Gast)


Lesenswert?

Wenn Du einen Timer nimmst, diesen im CTC-Mode betreibst und den Timer
mit dem Output-Compare-Register auf den richtigen Teilerfaktor begrenzt
und bei jedem Output-Compare-Event den entsprechenden OCx-Pin wackeln
läßt, kannst Du nahezu jede Frequenz mit einem Tastverhältnis 50:50
erzeugen. Und dies geht alles in Hardware, ohne zusätliche Rechenzeit.
Lies mal im Datenblatt zu Deinem Controller die Sektion "Timer"
durch. Nun mußt Du nur noch eine IR-LED an diesen wackelnden Pin und
mit einem Widerstand an einen anderen Pin anschließen, an dem Du die
Codes sendest. Ohne weitere Außenbeschaltung hast Du so genau das, was
Du brauchst. Die Anschluß-Polarität der LED richtet sich danach, ob
Dein zu sendendes Signal High- oder Low-Aktiv ist. Der wackelnde Pin
wird in jedem Fall die LED für 50: der Zeit ein- und wieder
ausschalten, wenn der passende Gegenpegel an dem Sendepin anliegt.

von Markus Reichert (Gast)


Lesenswert?

Ersteinmal vielen Dank für die super schnelle Anwort und wie es aussieht
recht einfach Lösung des Problems. :-)

Was ich aber dabei nicht verstehe ist die Reihenschaltung von PinX
-IR-Led - Widerstand - PinY.

An PinX lege ich das Trägersignal und an PinY z.B. 110011100 an. Dann
soll ja das Trägersignal genau dann gesendet werden, wenn eine 1 an
PinY anliegt.
Ich verstehe aber nicht, wie die Reihenschaltung genau dieses Verhalten
zeigen soll?

Wäre über eine kurze Erklärung echt dankbar.

von Peter Dannegger (Gast)


Lesenswert?

Du brauchst doch keinen 2. Pin.

Du kannst einfach im Compare-interrupt die Anzahl der Perioden
mitzählen (z.B. 20) und dann ab dem nächsten Compare die Pinaktion auf
dauernd High umstellen.

Dann die Pause zählen, Pinaktion wieder auf Toggle usw.

Damit hast Du immer glatte Impulse ohne Spikes.


Peter

von Rahul (Gast)


Lesenswert?

@Peter:
Wenn man einen USART-Pin und den OCx-Pin benutzt, kann man ziemlich
einfach ein serielles Signal moduliert übertragen...

von Peter Dannegger (Gast)


Lesenswert?

@Rahul

???

Welche FBs haben denn so einen Code ?

Ich kenne nur die mit unterschiedlichen Puls-/Pausezeiten oder
Manchester und das geht definitiv nicht per USART.


Peter

von Rahul (Gast)


Lesenswert?

Das ist schon klar, nur kann man damit eigene Übertragungen auf kurze
Distanz machen, wenn nicht sogar über Glasfaser (nicht ausprobiert).
Deine Variante ist universell...

von TravelRec. (Gast)


Lesenswert?

@Peter: Den 2. Pin brauchst Du, um die Daten auf die LED zu bringen. Der
erste Pin (OCx) toggelt immer fleißig den Träger, über Hardware-Timer
ohne Rechenzeit. Wenn der Pegel vom DatenPin (2) dem Träger-Pin (1)
gegenüber ein in Flußrichtung der LED passendes gegensätzliches
Potential hat, leuchtet die LED für diese Zeit, geht aus wenn der
Träger-Pin wieder umtoggelt und dann wieder an und so fort. Somit hast
Du den aus Pin 2 laufenden Daten entsprechende Trägerpakete, ohne
zusätzlichen Programmieraufwand. Pin 2 kann ein UART-Ausgang sein oder
eben derjenige, an dem die Ferbedienungsdaten repliziert werden (in
diesem Falle). Natürlich kann man einen Pin sparen, braucht dann aber
eine zusätzliche ISR, die ständig mitlaufen muß.

von crazy horse (Gast)


Lesenswert?

das ganze macht aber wirklich nur SInn, wenn du mit der UART-Hardware
die Daten senden willst - in allen anderen Fällen werden die Daten per
Software bereitgestellt. Und dann macht dein Verfahren keinen Sinn
mehr.
Statt per Software einen weiteren Pin mit den Daten zu schalten, kann
man doch lieber gleich den Timer beeinflussen.

von hans dieter (Gast)


Lesenswert?

KISS!!!
Die led an den OC und an VCC oder Masse (natürlich mit Vorwiederstand)
und dann in der Software den Timer an und ausschalten.

bei fclk = 8 MHz ist der teiler 210.
also genügend zeit den timer an und aus zu schalten.

und wenn du es in hardware zählen willst, dann verbindest du den
Timer-clock pin mit dem OC-Pin und stellts dann im 2. Timer die Anzahl
der Impulse ein

von TravelRec. (Gast)


Lesenswert?

@crazy horse:
>>...Statt per Software einen weiteren Pin mit den Daten zu schalten,
>>kann man doch lieber gleich den Timer beeinflussen.

Keinen WEITEREN Pin schalte ich per Software, sondern nur den Datenpin,
der Timer wird nur einmal initialisiert und klappert dann mit 38kHz los,
um den kümmere ich mich dann gar nicht mehr. Lediglich die
Datenbereistellungsroutine läuft immer wieder durch, für meinen Zweck
freilich über UART. Die Datenbereitstellungsroutine kann natürlich auch
die OCx-Pin-Bits im Timerregister löschen und setzen, so daß der Pin
beim Abklemmen vom Timer auf das zuvor festgelegte Potential
zurückkippt. Dann spart man sich den anderen Pin - das ist wohl
korrekt.

von Markus Reichert (Gast)


Lesenswert?

Vielen Dank für die vielen Vorschläge. :-)

Ich werde mal in nächster Zeit schauen, welche Lösung für mich die
beste ist.

Danke + Gruß
Markus

von crazy horse (Gast)


Lesenswert?

@travelrec:
ich habe schon verstanden, was du meinst, du aber wohl nicht, was ich
gesagt habe.
Variante 1: Daten kommen per Hardware-UART, dann macht deine
Vorgehensweise Sinn, steht auch oben.
Variante 2: Daten kommen in irgendeiner Art anders kodiert, also Bit
für Bit per Software - dann macht es keinen Sinn. Zum Zeitpunkt, wenn
die Software den Datenpin schaltet, kann die Software genausogut den
Modus des 38kHz-Timers ändern, von toggle auf clear und zurück
beispielsweise. Der Softwareaufwand ist gleich, den zus. Pin braucht
man dann nicht.

von holm (Gast)


Lesenswert?

Hmm, weiß nicht, warum nimmst Du nicht einfach den dafür direkt
vorgesehenen ATTiny28L?

Der einzige nachteil von dem Ding ist, das er nur HV parallel
Programming versteht, man braucht also ein STK500 oder so.

Di Software für RC5 gibt es fix und fertig als Appnote auf Atmels
Webseite
inclusive der Assebmlersourcen.
Sowas liegt fertig zusammengelötet hier, im Wesentlichen braucht man
noch einen Schalttransistor, eine IR LED und einen 455 oder besser 432
Khz Resonator.

Gruß,

Holm

von Markus Reichert (Gast)


Lesenswert?

Die Fernbedienung ist von Sony und benutzt leider nicht den RC5 Code.
Ich habe bisher nur die Signale analysieren können, habe aber bisher
nicht rausfinden können, welcher Code diese Fernbedienung verwendet.
Ich habe auch schon den Sony-Code (Bezeichnung finde ich gerade nicht)
verglichen, aber der passt auch nicht.

Wer sich das Signal mal anschauen möchte findet es hier:

http://home.arcor.de/mareichert/Signal1.jpg

von TravelRec. (Gast)


Lesenswert?

@ Crazy horse: Alles klar, danke für den Hinweis, hatte ja schon laut
drüber nachgedacht ;-).

von holm (Gast)


Lesenswert?

@markus:
Wer mißt, mißt Mist.

Dir wurde doch schon gesagt, daß die Grenzfrequenz Deiner Soundkarte
um mindestens eine Größenordnung unter dem liegt, was Du brauchst
um das Signal richtig darstellen zu können?

Wenn Sony dann ist das mit höchster Warscheinlichkeit SIRCS...

Gruß,

Holm

von Markus Reichert (Gast)


Lesenswert?

Das weiss ich...

meine Soundkarte hat eine Samplingrate von 44100Hz. Das Signal wo
abgebildet ist hat ca. 6200 Hz. Dann bleibt ein Aliassiganl nach
Shannon von 38kHz übrig.
Ich dachte auch es wäre SIRCS, aber soweit ich rausgefunden habe hat
SIRCS eine Trägerfrequenz von 40kHz. Das passt nicht.
Bei meinen Messungen ist halt das Problem, dass ich kein Speicher-Oszi
habe und nicht weiss, wie ich ansonsten dieses kurze Signal messen soll
bzw. kann.

von Markus Reichert (Gast)


Lesenswert?

Sorry, verschrieben...

das Aliassignal sind natürlich die 6,2kHz.

Dann bleibt eine Trägerfrequenz von 38kHz übrig.

von holm (Gast)


Lesenswert?

Sieh das mit der Trägerfrequenz mal nicht so verbissen, die filtert
der Empfänger eh wieder raus. Das was interessant ist, ist das
Protokoll
was übrig bleibt. Die Trägerfrequenz enthält keinerlei interessante
Information, sondern dient dem Infrarotempfänger dazu, sein Signal
aus dem Sumpf herausfiltern zu können. So lange Dein Träger
also durch den Filter im Empfänger paßt, hast Du mit einer anderen
Trägerfrequenz kein Problem.

Gruß,

Holm

von Markus Reichert (Gast)


Lesenswert?

das Problem bei mir ist nur, dass der Empfänger fest vorgegeben ist und
ich deswegen die Signale der Fernbedienung herausfinden muss.

Aber im Prinzip ist es ja kein Problem die Trägerfrequenz so lange zu
verändern, bis der Empfänger sie erkennt. Ich habe ja nur den Bereich
zwischen 38 und 40 kHz.
Nachher im Programm dürfte das ja bei entsprechender Programmierung nur
das Ändern einer Konstanten ausmachen.

von frankieboy (Gast)


Angehängte Dateien:

Lesenswert?

@Markus

ich weiss ja nicht mit welcher Hardware gemessen wird, aber z.B. mit
einer Photodiode und einem Onboard Soundchip kann man bei 44KHz
Samplerate diese Signale ganz gut analysieren (s. Bild, Pulse ca.
0,6ms, Pausen je nachdem 0,6ms oder 1,2ms).

Gruss

Frank

von Markus Reichert (Gast)


Lesenswert?

@frankieboy

genau so habe ich es auch gemacht. (vgl. weiter oben im Thread) Daher
kommen auch meine 38kHz für die Trägerfrequenz und mein Timing der
einzelnen Tasten.

von frankieboy (Gast)


Angehängte Dateien:

Lesenswert?

@Markus

was mich nur wundert, wenn ich das aus der Vergrößerung richtig sehe,
die Punkte für je eine Abtastung stehen. Eine Periode wird dann mit ca.
10 bis 20 Samples erfasst. Bei 44,1 Khz hat man aber eine Sampleperiode
von ca. 23 us und bei der vergrößerten Darstellung (s. Bild) kann man
die Daten eigentlich recht gut ausmessen. Eine symmetrisches Signal (je
0,6ms) würde dann mit mehr als 50 Samples erfasst. Ist das Signal hinter
dem Empfänger gemessen oder ist es das Sendesignal der Led?

Gruss

Frank

von Markus Reichert (Gast)


Lesenswert?

@frankieboy

Das Signal ist das Sendesignal der LED.

Ich verstehe aber ganz ehrlich gesagt nicht, auf was du hinaus
möchtest.
Habe ich falsch gerechnet?

von Marius S. (lupin) Benutzerseite


Lesenswert?

Ich weiss nicht ob das schon erwähnt wurde (hab den thread nicht
durchgelesen) aber du kannst einfach einen externen 38kHz oszilator
nehmen und den über einen port pin schalten dann hasst du immer deine
38kHz

von TravelRec. (Gast)


Lesenswert?

@ Marius: Du weißt doch - so wenig externe Bauteile, wie möglich. Man
hat doch einen Controller. Ich mach den ganzen Kram in einem Tiny2313
mit 15% Flash-Speicherauslastung und vielleicht 5% Rechenlast und eben
einem Widerstand und einer LED und einem 4MHz-Schwinger...

von Marius S. (lupin) Benutzerseite


Lesenswert?

den swinger kannst du dir eigentlich auch sparen oder? da kann man doch
den internen rc-oszi nehmen (dann bekommt man zwar nicht genau 38khz
aber das macht meistens nichts)

von frankieboy (Gast)


Lesenswert?

@Markus

Es geht nicht um das Rechnen, sondern um das Messergebnis. Ich denke,
das die Amplitude viel zu gering ist, um etwas erkennbar zu messen.
Stelle mal im Aufnahmemixer der Soundkarte den Eingangsregler so ein,
das möglichst die Soundkarte zu 50% oder mehr ausgesteuert wird (siehe
mein Bild SONY_HR.GIF weiter oben) oder benutze nicht den Line-In
sondern den MIC-Eingang.
Sample dann noch einmal und schneide alles überflüssige weg, so das nur
ein Tastendruck übrigbleibt.

Gruss

Frank

von Osterhase (Gast)


Lesenswert?

Soviele unqualifizierte Aussagen habe ich ja schon lange nicht mehr
gehöhrt.

von pebisoft (Gast)


Lesenswert?

ich hatte mal schnell ein kleines einfaches demo geschrieben für avr16
8mhz.
die irdiode geht bei mir vom pinb0 (kann beliebig sein) über
einen 100ohm widerstand an +5volt. der code kann mit dem rc5-programm
aus diesem forum empfangen werden. muss noch so angepasst werden, das
noch andere mhz genommen werden können. ich kann alle rc5-code zahlen
senden.

der code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <string.h>
#include <stdint.h>

#define IR_LED_PORT  PORTB
#define IR_LED_PIN   PB0
#define IR_LED_DDR   DDRB

#define IR_LED_ON    IR_LED_PORT |=  (1<<IR_LED_PIN)
#define IR_LED_OFF   IR_LED_PORT &= ~(1<<IR_LED_PIN)

//89ms pause
void ms_89(void)
{
  uint32_t zaehler;

  for (zaehler=0; zaehler<118666; zaehler++)
  asm volatile("nop");
}

void halbbit_high(void)
{
  uint8_t i,zaehler;

  //890us Impuls mit 36kHz senden
  //Bei 28us Periodendauer ergibt das 32 Impulse
  for(i=0; i<32; i++)
  {
    IR_LED_ON;
    for (zaehler=0; zaehler<18; zaehler++)
    asm volatile("nop");
    IR_LED_OFF;
    for (zaehler=0; zaehler<18; zaehler++)
    asm volatile("nop");
  }
}

void halbbit_low(void)
{
  uint16_t zaehler;

  //890us Pause
  for (zaehler=0; zaehler<1186; zaehler++)
  asm volatile("nop");
}

//Eine 0 oder 1 senden
void Send_Bit(uint8_t code)
{
  if (code==0)
  {
    halbbit_high();
    halbbit_low();
  }
    else
  {
    halbbit_low();
    halbbit_high();
  }
}


void send_code(uint8_t toggle, uint8_t address, uint8_t command)
{
  uint8_t mask,i;

  Send_Bit(1); //Erstes Startbit=1
  Send_Bit(1); //Zweites Startbit=1

  //Togglebit
  if(toggle==0)
  {
    Send_Bit(0);
  }
  else
  {
    Send_Bit(1);
  }

  //5 Bit Addresscode
  mask=0x10; //Beginn bei MSB

  for(i=0; i<5; i++)
    {
     if(address&mask) //Send 1
      {
       Send_Bit(1);
      }
     else //Send 0
      {
       Send_Bit(0);
      }

     mask>>=1;   //Nächstes Bit
    }


  //6 Bit Kommandocode
  mask=0x20; //Beginn bei MSB

  for(i=0; i<6; i++)
    {
     if(command&mask) //Send 1
      {
       Send_Bit(1);
      }
     else //Send 0
      {
       Send_Bit(0);
      }
     mask>>=1;  //Nächstes Bit
    }

  //Übertragung komplett
  PORTB=0; //IR-LED abschalten
  ms_89(); // warte 89ms
}


int main(void)
{
  IR_LED_DDR|=(1<<IR_LED_PIN);

  uint8_t command,i;
  command=32;

  for (i = 14; i < command; i++)
  {
    send_code(1,7,i); // toggle, addresse, commando
  }
}

von Markus Reichert (Gast)


Lesenswert?

@frankieboy

vielen Dank für Deinen Vorschlag, aber ich komme in den Genuß eines
Speicheroszis. Damit sollte es dann doch möglich sein, das Signal ganz
genau inkl. Amplitude zu messen.


@Osterhase

wenn du so davon überzeugt bist, dass das alles unqualifizierte
Kommentare sind - dann mach doch mal einen besseren. Andere angreifen
kann jeder. Und die restlichen, die sich an diesem Thread beteiligen
versuchen mir wenigsten zu helfen!!!


@pebisoft

Vielen Dank für die Bereitstellung deines Codes. Ich werde ihn mir mal
die nächsten Tage genauer anschauen. Eigentlich hatte ich ja vor in
Assembler zu programmieren. Aber man ist ja flexibel. :-)

von pebisoft (Gast)


Lesenswert?

ich kann dir auch eine assembler-source-datei von fastavr-basic
erstellen für den rc5-code. die kannst du dann mal anschauen.
die dann auch mit dem assembler avrasm32 von avrstudio verarbeitet
werden kann.
meine mail : pebisoft@arcoer.de

von pebisoft (Gast)


Lesenswert?

verbesserung meienr mail: pebisoft@arcor.de

mfg pebisoft

von Ithamar G. (antimon)


Lesenswert?

Weil wir grad beim Thema sind - gibts irgendeine Software, die mir
FB-Signale aufzeichnen kann (möglichst als Bitmuster, nicht die
Soundkarten-Variante)?

Ich habe hier einen simplen selbstgebauten Empfänger, der z.B. mit LIRC
wunderbar zusammenspielt - ich kann toll meinen PC fernbedienen. Aber
jetzt hätte ich gern die Codes, die der Empfänger sieht - gibts da auch
irgendwie eine Möglichkeit mit LIRC?

Das Problem besteht darin, dass ich irgendwann mal einen Beamer
anschaffen möchte und diesen von einem Mikrocontroller per Infrarot
fernbedienen will. Ich weiss aber nicht, was für ein Protokoll das sein
wird - gibts eine Möglichkeit ein FB-Signal "aufzuzeichnen" und das
dann als Bitmuster auf den µC zu übertragen? Lernbare Fernbedienungen
müssen das ja auch irgendwie können...

von Marius Schmidt (Gast)


Lesenswert?

wenn du LIRC unter linux benutzt dann gibt es dazu eine Erweiterung,
schau dich einfach mal auf der Seite um.

Ich habe auch mal danach gesucht, aber nix gefunden. Ich habe erst
versucht ein einfaches empfänger-programm selbst zu schreiben aber das
ging nicht (ich glaub ich konnte die zeitabstände nicht genau genug
messen). Ich habe schließlich die soundkarten-variante benutzt.

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.