Eigentlich betreibe ich keinen Modellbau. Doch ich wurde gebeten, einige im Modellbau benötigte Fernsteuer-Zusatzmodule mit AVR-Mikrocontrollern zu entwickeln, bzw. die Programme dafür zu schreiben.

Multimode-Schaltmodul für RC-Kanalimpuls mit analoger Programmierung

Multimode bedeutet, dass es mehrere Modi (Betriebsarten) gibt. Dies wären: Zeitschalter, Blinklicht, direkter Schalter und toggelnder Schalter (Flipflop).
Analoge Programmierung bedeutet, dass alle Parameter mit dem Schraubendreher an nur zwei Trimmpotis eingestellt werden. Dabei bestimmt das eine Trimmpoti den Schaltpunkt, also die Abweichung der Eingangsimpulsbreite vom Neutralpunkt (gültig für kurze und lange Impulse, bezogen auf Neutralpunkt). Das andere Trimmpoti dient zum Einstellen der Betriebsart und der Zeiten für Verzögerung bzw. Blinklicht. Der Neutralpunkt wird durch Autoneutralscan ermittelt.
Der Schaltplan ist denkbar einfach. Die Stromversorgung erfolgt zusammen mit dem Fernsteuerimpuls über einen bei Servos üblichen dreipoligen Steckverbinder. Der Fernsteuerimpuls wird über einen Schutzwiderstand an den INT0-Eingang des AVR "Tiny15" gelegt, was eine präzise Impulsbreitenmessung per Interrupt ermöglicht. Die beiden Trimmpotis sind an analogtauglichen Eingängen angeschlossen, die Schalt-Transistoren über Widerstände an die verbliebenen Anschlüsse. Für die meisten Fälle reichen die verwendeten BC337/BC338 aus, man kann aber auch belastbarere Typen einsetzen. Über die Steckbuchsen GND, SA0 (Schaltausgang 0) und SA1 (Schaltausgang 1) kann der Verbraucherstromkreis angeschlossen werden. Dieser kann mit Spannungen über 5V betrieben werden, z.B. mit 12V. Induktive Lasten sind mit Freilaufdioden zu versehen, um die Transistoren gegen Überspannung zu schützen.

Die hier gezeigte Test-Platine ist für Anfertigung durch Fräsen und Oberflächenbestückung vorgesehen. Links sind die beiden Programmierpotis angeordnet, in der Mitte der AVR, rechts die Schalt-Transistoren und Anschlüsse zur Pripherie, oben rechts die Lötpads zum Anschluss eines Servokabels. Elko und Keramik-Kondensatoren standen als SMD-Typen zur Verfügung, die Widerstände sind bedrahtet, lassen sich aber auch recht gut auf der Oberfläche bestücken. Vorteil dieser einseitigen Bestückungsart ist das Einsparen des Bohrens und die Tatsache, dass die Unterseite der Platine nicht gegen Kurzschluss geschützt werden muss. Es experimentiert sich einfach mal leichter...
Das obere Bild zeigt die Leiterzüge, das untere die Fräslinien.

Nebenstehendes Bild zeigt den Versuchsaufbau des Schaltmoduls. Für den Dauereinsatz in Modellen sollte aus Platzgründen eine kleinere Bauform entwickelt werden. Das fällt aber nicht in meinen Zuständigkeitsbereich, ich bin nur für die Software verantwortlich...

Bedienung des Multimode-RC-Schaltmoduls...

Das Modul wird wie ein Servo an den Fernsteuerempfänger angeschlossen. Die zu schaltenden Verbraucher kommen zwischen Schaltausgänge und Plus des Fahrakkus, Minus des Fahrakkus kommt an GND.

Mit dem Betriebsart-Poti wird (wie der Name schon sagt) die Betriebsart eingestellt. Betrachtet man den Stellbereich des Potis durchgehend in Prozent, dann ergeben sich folgende Betriebsarten (Modi):

  • 00% bis 24% Zeitschalter 1 (0,02s bis 2,5s)
    Die Verzögerung wird durch Feineinstellung des Potis innerhalb des Betriebsart-Bereiches eingestellt.

  • 25% bis 49% Zeitschalter 2 (2,5s bis 320s)
    Die Verzögerung wird durch Feineinstellung des Potis innerhalb des Betriebsart-Bereiches eingestellt.

  • 50% bis 74% Blinker (0,25Hz bis 8Hz)
    Die Blinkfrequenz wird durch Feineinstellung des Potis innerhalb des Betriebsart-Bereiches eingestellt.

  • 75% bis 87% direkter Schalter (Tastbetrieb)

  • 88% bis 100% toggelnder Schalter (Flipflop)
Somit kann mit nur einem Poti Modus und Verzögerung bzw. Frequenz eingestellt werden.

Mit dem Schaltpunkt-Poti wird der Schaltpunkt eingestellt, also die Abweichung der Kanalimpulsbreite vom Neutralpunkt, den das Modul als Schwellwert (Blinker) oder Fangbereich (alle anderen Modi) nutzen soll.

Inbetriebnahme...

Um das Multimode-Schaltmodul an die Fernsteueranlage anzupassen, geht man am besten folgendermaßer vor:
  1. Schaltmodul mit dem Empfänger und dem Laststromkreis verbinden
  2. Fernsteuersender einschalten
  3. Beide Potis auf 60% stellen,
    also Blinker-Modus mit sehr hohem Schwellwert
  4. Fernsteuerempfäger einschalten, dabei darauf achten, dass alle Steuerknüppel des Senders in Neutralstellung sind. (Neutralpunkt wird gescannt)
  5. Am Sender den Wert einstellen, bei dem das Modul ansprechen soll
  6. Das Schaltpunkt-Poti so weit zurück drehen, bis ein Ausgang blinkt
  7. Funktion durch Bewegen des Steuerknüppels am Sender in beiden Richtungen testen
    Für Einsatz als Blinkgeber war das schon alles.
  8. Sender wieder auf Neutralpunkt stellen
  9. Betriebsart-Poti auf 80% stellen (direkter Schalter)
  10. Durch Bewegen des Steuerknüppels am Sender in beiden Richtungen und Feinjustage am Schaltpunkt-Poti den Fangbereich optimal einstellen.
  11. Nun mit dem Betriebsart-Poti die gewünschte Betriebsart einstellen, bei Zeitschalter durch Feineinstellung auch die Verzögerungszeit.
Damit ist das Schaltmodul an die Anlage angepasst. Bei jeder Benutzung der Anlage ist darauf zu achten, dass der Sender bereits eingeschaltet ist und Impulse in Neutralstellung sendet, wenn Empfänger und Schaltmodul eingeschaltet werden. Nur so kann der Autoneutralscan korrekt funktionieren.

Software im AVR...

Das Programm ist komplett in Assembler geschrieben. Es ist ein reines Interrupt- Programm, alle Aufrufe von Programmteilen werden von Ereignissen ausgelöst. Diese wären: ADC ist fertig, Impulsflanke am Eingang, Timer0-Überlauf und Timer1-Überlauf. Wenn die jeweilige Interrupt-Service-Routine abgearbeitet ist, wird der AVR in den 'Sleep-Mode' (Schlafen, Nixtun) geschickt, von wo er vom nächsten Hardware-Ereignis geweckt wird.

Die Programmteile und ihre Aufgaben:

  • Analog-Digitalwandler (Vorteiler 128, Messdauer etwa 1,05ms):
    • erste Schaltpunkt-Messung wird durch Reset-Routine aktiviert,
    • jede weitere Schaltpunkt-Messung wird durch das Ende des Kanalimpulses aktiviert, denn da ist genug Zeit für zwei Messungen während der MC schläft, und es kann kein Impuls- Interrupt blockiert (verzögert) werden, was die Genauigkeit der Impulsmessung erhöht.
    • ADC-Interrupt: wechselweise entweder:
      • liest Schaltpunkt-Poti ein,
      • errechnet daraus den Schaltpunkt (0...63),
      • schaltet Quelle auf Betriebsart-Poti um.
      • aktiviert nächste Messung...
    • oder:
      • liest Betriebsart-Poti ein,
      • errechnet daraus Betriebsart (0...3) und Zeitwert (1...127),
      • schaltet Quelle auf Schaltpunkt-Poti um,
        nächste Messung wird erst nach Impulsende von Impuls-ISR aktiviert...
  • Pegelwechsel (Flanke) am Impulseingang (wird durch Kanalimpuls ausgelöst):
    • Steigende Flanke am Impulseingang (Eingangsimpulsanfang)
      • setzt Timer1 auf 0 und startet ihn mit 100kHz (10µs je Wert),
      • zählt im Zeitschalterbetrieb die Verzögerung und schaltet die Ausgänge nach Zeitablauf aus...
    • Fallende Flanke am Impulseingang (Eingangsimpulsende)
      • liest Timer1 aus (Eingangsimpulsbreite),
      • sorgt dafür, dass die ersten 14 empfangenen Impulse verworfen werden und der 15. Impuls als Neutralpunkt des Senders interpretiert wird, und erst ab 16.Impuls nach dem Einschalten Schalthandlungen ausgelöst werden.
      • stoppt Timer1,
      • prüft Impulsbreite auf Gültigkeit (imin, imax),
      • prüft Impulsabstand auf Minimalwert (mittels Timer0),
      • schaltet nach mehreren ungültigen Impulsen (Anzahl in Konstante "errors") Ausgänge ab,
      • setzt Timer0 auf Startwert (25,6ms vor Timeout für Impulsabstand),
      • prüft, ob Eingangsimpuls Schwellwert überschritten hat und schaltet Blinker ein (nur Blinker-Mode),
      • prüft, ob Eingangsimpuls Schwellwert unterschritten hat und schaltet Blinker aus (nur Blinker-Mode),
      • prüft, ob Eingangsimpuls im Fangbereich ist und zählt 8 gültige Impulse ab (außer Blinker-Mode),
      • errechnet im Zeitschalter-Mode die Verzögerung,
      • aktiviert die nächsten zwei ADC-Messungen, da jetzt >18ms Zeit ist...
  • Timer1-Überlauf (Sende-Impulsende, Überlauf bei Impulsmessung wegen zu langem Impuls):
    • deaktiviert Timer1, (gemessener Impulswert ist dann 0, also illegal)...
  • Timer0-Überlauf (Timeout vermisster Eingangsimpuls):
    • setzt Timer0 auf Startwert (25,6ms vor Timeout),
    • schaltet nach mehreren vermissten oder ungültigen Impulsen (Anzahl in Konstante "errors") Ausgänge ab,
  • Reset-Routine (keine Interrupt-Routine, wird aber nur einmal beim Start ausgeführt):
    • kalibriert den internen RC-Oszillator auf 1,6MHz,
    • initialisiert beim Einschalten alle benötigten Ressourcen,
    • aktiviert die ersten beiden ADC-Messungen...
  • Hauptprogramm (keine Interrupt-Routine):
    • schickt den AVR in den Schlafmodus, von dem er von einem der auftretenden Interrupts geweckt wird. Dies erhöht die Genauigkeit der Timer, was aber hier keine große Rolle spielt...
Timing:
  • Alle Programmteile (außer 'Schlafen' und 'Reset') laufen in Interrupts.
  • Zwischen den Auslösungen des Impulsflanken-IRQ vergeht 1...20ms, genug Zeit zur Abarbeitung
  • ADC wird immer nach Impulsende aktiviert, da sind min. 18ms Zeit, er braucht 2,1ms für beide Messungen
  • Timer0-Int tritt nur im Fehlerfall auf (Impulsausfall), kann daher den Ablauf nicht stören
  • Timer1-Int tritt nur im Fehlerfall auf (Impulsbreite zu lang), kann daher den Ablauf nicht stören
Somit ist bei Empfang gültiger Fernsteuerimpulse sichergestellt, dass kein Interrupt aufgerufen wird, während noch eine andere ISR abgearbeitet wird.

Konstanten im Kopf des Assembler-Quelltextes...

Folgende Konstanten werden im Quelltext definiert und können bei Bedarf in sinnvollen Grenzen verändert werden:
  • tsw=96 Timer0-Startwert für 25,6ms Timeout-Error (Impulsausfall)
    Timer0 zählt von diesem Wert bis zum Überlauf (256), falls er nicht vorher vom nächsten Kanalimpuls neu gesetzt wird. Er erreicht also im störungsfreien Normalbetrieb seinen Überlauf nicht. Sollte er ihn doch erreichen, so wird ein Impulserkennungsfehler ausgelöst.
  • tmin=tsw+90 Timer0-Vergleichswert für minimalen Impulsabstand (14,4ms)
    Dies ist der Referenzwert zum Vergleich mit Timer0, der bei Eintreffen eines Impulses nicht unterschritten sein darf. Ist er unterschritten, so war der Impulsabstand (Sollwert 20ms) zu kurz (unter 14,4ms), worauf ein Impulserkennungsfehler ausgelöst wird.
  • imin=70 Minimale Impulsbreite für Error
    Dies ist der Referenzwert für die minimale erlaubte Impulsbreite zum Vergleich mit Timer1, der für die Impulsbreitenmessung genutzt wird. Ist dieser Wert unterschritten, dann wird ein Impulserkennungsfehler ausgelöst.
  • imax=231 Maximale Impulsbreite für Error
    Dies ist der Referenzwert für die maximale erlaubte Impulsbreite zum Vergleich mit Timer1, der für die Impulsbreitenmessung genutzt wird. Ist dieser Wert überschritten, dann wird ein Impulserkennungsfehler ausgelöst.
  • errors=10 Anzahl der erlaubten Impulsfehler
    Das ist der Startwert für den Impulsfehlerzähler. Treten direkt hintereinander 10 Impulserkennungsfehler auf, so werden die Schaltausgänge des Schaltmoduls deaktiviert. Jeder empfangene Impuls mit gültiger Breite unterbricht das Zählen der Fehler, indem der Zähler wieder auf Startwert gestellt wird.
  • blihy=3 Hysterese für Schaltpunkt im Blinker-Mode
    Der Blinker wird durch Überschreiten des Schaltpunktes (als Schwellwert gesehen) aktiviert. Er wird erst wieder deaktiviert, wenn Schaltpunkt und 'blihy' unterschritten sind. Diese Hysterese verhindert ein Flackern des Blinkers bei geringem Lenkeinschlag.
  • basb=2 Basiszeit Blinker
    Hiermit wird die maximale Blinkfrequenz eingestellt. Zu diesem Wert wird dann der Wert der Zeiteinstellung am Betriebsart-Poti (1...127) addiert um ihn als Impulszähler für die Erzeugung der Blinkfrequenz zu benutzen. Die Blinkfrequenz wird durch Zählen der Kanalimpulse generiert. Nach jeweils 'basb' + 'Zeitwert' Impulsen wird der aktive Blinker getoggelt. Der Blinker benutzt als Zeitreferenz den Impulsabstand der Fernsteuerung.
  • basz1=1 Basiszeit, Faktor für Zeitschalter1 (in 20ms-Schritten)
    Das ist die minimale Verzögerungszeit für Zeitschaltermode 1. Sie wird mit dem am Betriebsart-Poti eingestellten 'Zeitwert' (1...127) multipliziert und als Count-down zum Abzählen eintreffender Fernsteuerimpulse genutzt. Bei Ablauf wird der Schaltausgang deaktiviert. Der Zeitschalter benutzt als Zeitreferenz den Impulsabstand der Fernsteuerung.
  • basz2=128 Basiszeit, Faktor für Zeitschalter2 (in 20ms-Schritten)
    Das ist die Basis für Zeitschaltermode 2. Um einen direkten Anschluss an Mode 1 sicherzustellen, Sollte dieser Wert das 128-fache des Wertes von 'basz1' betragen. Die Funktion entspricht der von Zeitschalter-Mode 1.
  • fang=5 Fangbereich Impulserkennung, +/- wirkend in 10µs
    Dies ist die Spreizung des Schaltpunktes in den 'Fangbereich', also den Bereich, der als zum Schalten vereinbarte Impulsbreite gilt. Bei 'fang'=5, einem Schaltpunkt von beispielsweise 20 und einem Neutralpunkt von 150 (1,5ms) werden Impulsbreiten von 1,25ms bis 1,35ms sowie 1,65ms bis 1,75ms als 'gültige Schaltimpulse' interpretiert, alle anderen Impulsbreiten als Neutral-Impulse.

Damit das Timing das Tiny15 stimmt, muss der interne RC-Generator des AVR kalibriert werden. Dazu ist vor dem Brennen mittels eines geeigneten AVR-ISP-Programms das 'Calibrationsbyte' des Exemplars auszulesen und in das L-Byte und H-Byte der letzten Speicherzelle des Flash zu schreiben (wie es ATMEL mit neuen AVRs macht). Nur dann kann das Programm das Calibrationsbyte korrekt in das Kalibrationsregister 'OSCCAL' schreiben.

Erklärung einiger hier verwendeter Begriffe bzw. Features...

Der Kanalimpuls, auch Fernsteuerimpuls, Eingangsimpuls oder Impuls genannt, ist ein Impuls, der vom Fernsteuersender für jeden Übertragungskanal getrennt generiert und vom Fernsteuerempfänger bereitgestellt wird. Er wird etwa alle 20ms wiederholt. Seine Impulsbreite trägt die Information, in welcher Stellung sich der entsprechende Steuerknüppel des Fernsteuersenders momentan befindet. Die Impulsbreite beträgt üblicherweise in Neutralstellung (auch Neutralpunkt genannt, Mitte des Steuerknüppelweges) 1,5ms. In den Endlagen des Steuerknüppelweges beträgt die Impulsbreite 1,0ms bzw. 2,0ms. Die Impulsbreite entspricht also der Steuerknüppelstellung am Sender. Bei einigen Herstellern können die hier genannten Werte etwas differieren, befinden sich aber im Bereich von 0,7ms bis 2,3ms. Und genau das ist das Problem, von Anlage zu Anlage differieren die Impulsbreiten und besonders die Neutralstellung.

Mit Autoneutralscan ist die automatische Erkennung des Neutralpunktes beim Einschalten der Anlage gemeint. Man schaltet ja zuerst den Sender ein, der darauf munter Impulse sendet, die der Neutralstellung der Steuerknüppel entsprechen, da der Sender im Moment nicht bedient wird. Danach schaltet man die Anlage im Modell ein, also Empfänger, Servos, Fahrtregler usw. - und damit auch das Schaltmodul. Dieses empfängt die Impulse und misst deren Impulsbreite. Die ersten 15 empfangenen Impulse werden als Neutralstellung interpretiert (wobei jeder Impulsbreitenwert den vorher eingelesenen ersetzt). Erst ab dem 16. empfangenen Impuls wird die eigentliche Impulsauswertung aktiviert. Dies gibt der Anlage etwa 0,3ms Zeit zum Einschwingen.

Mit Schaltpunkt ist bei diesem Schaltmodul der Wert gemeint, der mit dem Schaltpunkt-Poti eingestellt werden kann. Nun hat das Schaltmodul aber nicht nur einen Schaltpunkt, sondern zwei, nämlich einen für Impulsbreiten unter dem Neutralwert und einen für Impulsbreiten über dem Neutralwert. Da der Abstand vom Neutralpunkt zu beiden Schaltpunkten gleich ist, brauchen wir im Schaltmodul nur einen Schaltpunkt. Dazu wird von der gemessenen Impulsbreite der Wert des Neutralpunktes subtrahiert, dabei das Vorzeichen (entspricht der Schaltrichtung) gesichert und ein evtl. negativer Wert wieder positiv gemacht. Statt einer Impulsbreite von 1ms bis 2ms steht uns nun ein Wert von 0,0ms (Neutral) bis 0,5ms (Endstellung) und besagtes Vorzeichen zur Verfügung. Nun rechnet es sich digital aber schlecht mit Zeiten, daher wurden bei der Impulsmessung die Werte in das Zahlenformat eines Bytes (0...255) gepresst (gerastert, digitalisiert). Dabei wurde eine Auflösung von 10µs pro Ziffernwert gewählt, ein Neutral-Impuls von 1,5ms Breite hat den Zahlenwert 150. Wir rechnen aber mit der Differenz zum Neutralpunkt, also mit Zahlen zwischen 0 und 50 (max 80). Nun wird der Schaltpunkt durch Digitalisieren der vom Poti eingestellten Analogspannung gewonnen. Der gesamte Einstellbereich wird in Zahlenwerte zwischen 0 und 63 gerastert, es lassen sich also Impulsbreiten erkennen, die bis zu 0,63ms vom Neutralpunkt abweichen.

Mit Fangbereich bezeichne ich den Bereich um den Schaltpunkt, der als zum Schalten gültige Impulsbreite anerkannt wird. Dieser wird durch die Konstante 'fang' im Kopf der Assemblerdatei eingestellt. Alle Impuse, die dem Fangbereich entsprechen, werden als Schaltbefehl gewertet, alle anderen als neutral, also auch die, die noch weiter vom Neutralwert abweichen als der Schaltpunkt. Der Fangbereich ist in allen Betriebsarten wichtig, außer im Blinker-Mode.

Im Blinkermode wird der Schaltpunkt als Schwellwert (mit Hysterese 'blihy') interpretiert, bei dessen Überschreiten der Blinker eingeschaltet wird und bei dessen Unterschreiten wieder aus.

Im Gegensatz zur linearen Programmierung kann man ein Programm so strukturieren, dass von außen (von der Hardware-Peripherie) einwirkende Ereignisse den Programmablauf steuern. Nun ist ein Großteil der Peripherie (Timer, ADC...) schon im Mikrocontroller vorhanden. Als Ereignisse gelten alle Hardware-Vorkommnisse, die einen Interrupt auslösen können. In diesem Programm sind das: Überlauf von Timer0 und Timer1, Vorliegen eines neuen ADC-Messwertes und Pegelwechsel (Flanke) am externen Interrupteingang (Pin 7). Es gibt noch mehr Interrupt-Quellen, die aber in diesem Programm nicht genutzt werden.


Dieses Programm unterliegt den allgemeinen Copyright-Regeln. Alle Rechte liegen beim Autor. Gewerbliche Nutzung des Programms bedarf einer schriftlichen Genehmigung des Autors. Nachbau dieses Schaltmoduls unter Nutzung dieses Programms für private Zwecke (Eigenbedarf) ist bei Einzelstücken erlaubt.

hannes@hanneslux.de