Sehr schnelle Pulse erzeugen für spezielles IR-Protokoll

Hallo erst Mal.

Hab mir jetzt den Mega 2560 Rev3 besorgt im Set mit allem möglichen um da Mal einzusteigen und habe mir gleich mal FreeRTOS angeschaut, weil ich eben gerne Aufgaben voneinander unabhängig ausführe.
Erfahrungen habe ich mit dem Basic-Tiger von Wilke (da hab ich früher einiges mit gemacht) und Pascal, Delphi, PHP, Javascript ... C++ erscheint mir nicht zu kompliziert. Sicher muss ich mich da auch erst dran gewöhnen, aber wird schon. Aber ich brauche sicher noch manchmal genauere Informationen, weil mir noch nicht alles so geläufig ist.

Als Aufgabe habe ich hier eine IR-Remote von Logitech für eine PTZ-Kamera, die ich durch einen Arduino ersetzen will, den ich über RS485 steuern möchte.

Das mit dem RS485 ist soweit klar.

Aber leider benutzt Logitech ein selbst gestricktes IR-protokoll, welches ich so rausgeklingelt habe.

Danach habe ich dann das hier gefunden, was als NEC-Protokoll beschrieben wird.

Aber bei längerem Tastendruck weichen sie (Logitech) von dieser Vorgabe ab und wiederholen das ganze Signal anstelle der im Protokoll sonst üblichen "wiederhole das"-Pulsfolge.

Ich habe mir verschiedene IR-Bibliotheken angeschaut. Viele seit Jahren nicht gepflegt und praktisch keine Dokumentation. Außerdem auch für meinen Zweck zu fett.

Also würde ich mir gerne hier selber jetzt die gewünschten Pulsfolgen basteln. Ist ja auch ne gute Übung.

Träger ist 38kHz. Die Pulse und Pausen sind 560µs(kürzester Puls und kürzeste Pause) bis 39ms(Pause zwischen zwei Pulsfolgen)

Es ist kein Problem für mich die Adressen und Befehle zu berechnen, aber ...

Jetzt die Frage:

Wie erzeugt man sinnvoll ein vom Timing genaues IR-Signal, wenn man genau weiß wie das Signal nachher aussehen soll?

Ich habe jetzt ne Weile rumgesucht und habe den Vorschlag gelesen ( Foren-Beitrag von 2012) man könne einfach auf einem Ausgang einen tone(PIN,38000) dauerhaft absetzen und auf einem zweiten Ausgang das gewünschte Muster durch ein- und ausschalten der IR-LED (die sitzt mit Widerstand in Reihe zwischen den beiden Ausgängen) erzeugen. Die Zeiten mit delayMicroseconds() dazuwischen steuern.

Ist das der beste Weg?

Danke für Input

So wie es auch dir von dir kritisierten IR Bibliotheken machen. Mit einem Hardware Timer:
https://github.com/z3t0/Arduino-IRremote/blob/master/src/private/boarddefs.h

Und von wegen nicht gepflegt:

Die Grundlagen funktionieren einfach. Daher muss praktisch nur Modell-Pflege für neue Controller betrieben werden

Verzögerungen mit delay() u.ä. gehen auch, aber während der Zeit kannst du dann nichts anderen tun

Ich hätte mich mit dieser BIB gerne beschäftigt, wenn die für mich erforderlichen Infos in irgendeiner Datei oder in Kommentaren stünden. Leider gibt es da nur schlecht kommentierte Beispiele.

Also Syntax, Parameter, Optionen ... Das kann man leider nur erraten. Wenn es mit Copy und Paste geht hat man eben Glück ... ich hatte das nicht. Weil eben meine Remote einen Code erzeugt, der nicht ganz dem Protokoll entspricht.

Und deshalb wollte ich es selber machen ... und was dabei lernen.

Ich habe mit auch FreeRTOS gespielt ... Aber noch keine Erfahrung wie genau man da das Timing hinbekommt, wenn man den Task freigibt und darauf warten muss dass er zur rechten Zeit wieder aufgerufen wird. Da kann man mit delay() effektiv CPU-Zeit an andere Tasks abgeben. Aber ich weiß nicht ob das auch für delayMicroseconds() klappt und wie groß der Jitter dann wird.

Wenn es mit delay... zu ungenau wird, würde ich es mit den Timern mal schauen ... danke schon Mal für den Tip!

Du hast hier kein Echtzeitbetriebssystem. Oder überhaupt ein Betriebssystem. Es gibt keine Tasks

FreeRTOS

Es gibt keine Tasks

Ist eins davon wahr?
Oder gar beides?

Natürlich gibt es auch FreeRTOS für kleine AVR, wie dem UNO.
Sowohl preemptiv als auch kooperativ.
Und damit auch Tasks, mit all ihren Vor- und Nachteilen.

Wenn ich FreeRTOS einbinde habe ich Echtzeit und Tasks, aber das war ja auch nur ein Nebenthema...

Ich kämpfe mich derweil durch Tutorials bezüglich Timern ... Und ich rolle mit den Augen.
Da steht dann so Zeug wie:

#define ledPin 13

void setup()
{
  pinMode(ledPin, OUTPUT);  // Ausgabe LED festlegen

  // Timer 1
  noInterrupts();           // Alle Interrupts temporär abschalten
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;                // Register mit 0 initialisieren
  OCR1A = 31250;            // Output Compare Register vorbelegen 
  TCCR1B |= (1 << CS12);    // 256 als Prescale-Wert spezifizieren
  TIMSK1 |= (1 << OCIE1A);  // Timer Compare Interrupt aktivieren
  interrupts();             // alle Interrupts scharf schalten
}
// Hier kommt die selbstdefinierte Interruptbehandlungsroutine 
// für den Timer Compare Interrupt
ISR(TIMER1_COMPA_vect)        
{
  TCNT1 = 0;                // Register mit 0 initialisieren   
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1); // LED ein und aus
}

void loop()
{
  // Wir könnten hier zusätzlichen Code integrieren
}

Ich habe das jetzt soweit verstanden, dass das vorne Register für die Timer sind die wie Variablen gelesen und beschrieben werden? Und hinten sind Konstanten, die zum Verschieben eines Bits genutzt werden.
Tutorial auf MC.net

Also CS12 enthält den Wert 2 ... und 1 << CS12 verschiebt die 1 um zwei nach links wodurch man den Wert 4 erhält... das zweite bit. Dann bekommt TCCR1B das zweite bit auf 1 gesetzt, falls es nicht schon gesetzt war...

Warum macht man das auf diese Art? Mir kommt es ziemlich umständlich vor und es hat mich 2h gekostet bis ich die Infos soweit zusammen hatte ... Hat es Vorteile das so zu machen, dass man jedes Mal mit Bitshift und Konstanten arbeitet?

Und auch das mit dem ISR finde ich schwer für Anfänger ... was ein Vector ist und so...
http://ee-classes.usc.edu/ee459/library/documents/avr_intr_vectors/

Kennt jemand ein GUTES Buch, wo auch solche Dinge alle drin stehen? Das auf Zig Seiten zusammenzusuchen kostet so viel Zeit, da wäre selbst ein teures Buch das Geld wert.

Erstmal: Das ist ganz sticknormales C++, oder C.

Die Definitionen/Bezeichner der Register, Ports und Bit Codes findest du in den betreffende *.h Dateien zu deinem µC.
Und ebenso im Datenblatt.

Du brauchst also nur ein C++ Buch auswendig zu lernen, und das Datenblatt zum µC, dann wirst du alle Tutorials verstehen, und auch sehen welche Mist sind.

Ok?

Also hat das was damit zu tun, dass man so viele unterschiedliche Hardware (mit Ähnlichkeiten) in einer IDE so sauberer ansprechen kann? Ich frag ja weil ich neu in C++ und Arduino-IDE bin.

Aber weiter im Thema...

beste Übersicht aus meiner Sicht bisher:

Ich habe ein Array mit den ON/OFF Zeiten. Und ich habe einen Timer jetzt. Jedes Mal wenn der Timer eine Zeit durch hat lese ich die nächste aus dem Array und belege damit den Timer neu. So mache ich die Modulation.

Dann brauche ich noch einen PWM Ausgang mit 38kHz und Duty-Cycle von 1:3 ... und den de/aktiviere ich dann über den Timer.

Und ich darf für das PWM keinen Pin benutzen, der dem Timer zugeordnet ist, der die Modulation steuert?

Hi

Da das PWM-Signal von einem Timer kommt, müsste sich der dem Pin zugehörige Timer um den PWM kümmern - kann Der aber nicht, wenn Der schon die Pausenzeiten durchackert.

MfG

Ok ... dann hab ich erst Mal alle Infos DANKE! Das ging echt schnell hier!

Also ich bastle das dann mal :slight_smile: Bin sicher, ich hab dann später noch mal ne Frage ...