---

RPi Pico Kosmos IR-Interface                   

            

Elektronik-Labor  Projekte  Mikrocontroller  Raspberry     






Der Kosmos-Mikrocontroller von 2007 hat eine Infrarotschnittstelle zur seriellen Datenübertragung mit 1200 Baud. Damit wird eine vollständige Potentialtrennung erreicht, was der Sicherheit beim Experimentieren zugutekommt. Eine solche Schnittstelle, diesmal mit USB-Anschluss, wollte ich mit dem RPI Pico nachbauen. Jedes vom PC gesendete Byte muss dazu auf einen 36kHz-Träger moduliert werden und an eine IR-Sendediode gehen. Umgekehrt müssen serielle Daten eines IR-Empfängers an den PC weitergeleitet werden. Das ganze geschieht Byte-weise. Die Kosmos-Software sendet z.B. eine Kommando-Byte und erhält ein Byte zurück. 

Das Pico-Programm öffnet zwei serielle Schnittstellen und stellt über PWM den 36-kHz-Träger bereit. Der Aufbau ähnelt stark dem bereits mit MicroPython vorgestellten IR-Transceiver. Aber weil diesmal Einzelbytes übertragen werden müssen, war die Aufgabe mit Arduino-C leichter zu lösen.

//Pico_Kosmos IR-Schnittstelle
#include <Arduino.h>

void setup() {
  Serial.begin(1200);  // USB-Serial
  Serial1.begin(1200); // UART-Serial1
  gpio_set_function(2, GPIO_FUNC_PWM);
  pwm_set_wrap(1, 3288);  //38 kHz an P2, Pin 4
  pwm_set_chan_level(1, PWM_CHAN_A, 1644);
  pwm_set_enabled(1, true);
}

void loop() {
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte); //USB >> Pin 0
  }
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte); //Pin1 >> USB
  }
}

Bei der Entwicklung mit der Arduino-IDE ist ein unerwartetes Problem aufgetreten. Zum Test hatte ich mein Terminal.exe verwendet. Beim Öffnen der Schnittstelle gab es regelmäßig eine Fehlermeldung, und zugleich meldete sich der Pico als Speicherstick, so als solle ein neues Programm geladen werden.






Eine Recherche im Netz ergab, dass dies nur bei 1200 Baud passiert, andere Baudraten funktionieren problemlos. Ein Test mit 9600 Baud brachte Erfolg. Mit einer direkten Verbindung von Pin1 (Serial1, TXD) zu Pin 2 (Serial1, RXD) wurden alle Bytes wieder an den PC zurückgesandt. Dass Serial vom PC aus über USB mit 9600 Baud geöffnet wurde, stört nicht, weil die USB-Daten in jedem Fall mit maximaler Geschwindigkeit übertragen werden. Auf der Hardwareseite an Serial1 bleibt es bei 1200 Baud. Achtung, damit tatsächlich Daten gesendet werden, muss man DTR einschalten.


Leider hilft mir das nicht, weil ich keinen Einfluss auf die Baudrate habe, mit der die Software zum Kosmos-Mikrocontroller die Verbindung aufbaut. Inzwischen hatte ich im Netz die Information gefunden, dass die Arduino-Umgebung das Öffnen mit 1200 Baud als Signal nutzt, um den Pico zu resetten und in den Speicher-Modus zu setzen. Ausgerechnet 1200 Baud! Ich hatte mich schon öfter gefragt, mit welchem Trick die IDE den Programm-Upload erzwingen kann. Jetzt weiß ich es.



Um das Projekt doch noch zu retten, habe ich es mit VSCode und PlatformIO versucht. Man kann ein Arduino-Projekt direkt importieren. Kompilieren und Hochladen ging problemlos. Bei Hochladen ist mir eine interessant Meldung aufgefallen: Forcing reset using 1200bps open/close on port COM9. Heißt das etwa, dass erst nach dem Schließen der mit 1200 Baud geöffneten Schnittstelle ein Reset passiert? Das wäre ein Unterschied zur Arduino-IDE oder zumindest zur von mir verwendeten Version.



Der Versuch mit Terminal.exe bestätigte die Vermutung. Jetzt kann ich mit 1200 Baud öffnen und beliebig lange damit arbeiten. Erst nach dem Schließen erscheint das Dateifenster. Um neu zu verbinden muss ich einem einen Hardware-Reset ausführen oder das Kabel einmal neu anstecken.



Die Infrarotschnittstelle empfängt also nun ihr eigenes Echo, und ich dachte, damit bin ich schon fertig. Aber ein Versuch mit dem Kosmos-Mikrocontroller war nicht erfolgreich, ich konnte die Verbindung zwischen der PC-Software und dem Controller nicht herstellen. Aber ich konnte mit meinem neuen Pico-Interface den Datenverkehr mit der originalen IR-Schnittstelle belauschen. Irgendwas läuft hier anders. Obwohl ich damals an der Entwicklung beteiligt war, konnte ich nur noch einen vorläufigen Schaltplan finden. Also half nur Aufschrauben und nachmessen. Dabei ist mir klar geworden, dass in der Schaltung das Echo der eigenen Aussendung unterdrückt wurde. Jeder High-Zustand an TXD schaltet zwar das 36-kHz-Signal an der IR-Sendediode ein und wird praktisch gleichzeitig am IR-Empfängerausgang sichtbar. Aber das TXD-Signal unterdrückt einen High-Zustand an RXD. Also musste ich mein Projekt ändern.

Meine erste Lösung war eine logische Schaltung mit einem N-FET BS170, die das vom IR-Empfänger aufgenommene Signal blockiert, wenn gleichzeitig das vom PC kommende Signal aktiv ist. Damit hat die Schnittstelle perfekt funktioniert. Zwar gibt es noch kurze Impulse jeweils am Ende eines Impulses, die auf eine kleine Verzögerung im IR-Empfänger zurückgehen. Aber diese Impulse werden nicht als serielle Signale gewertet und haben daher keine Auswirkung.

Weil ich mit möglichst wenige zusätzlicher Hardware auskommen wollte, habe ich die Signal-Blockierung für ausgesendete und als Echo empfangene Zeichen dann in Software nachgebildet. Dazu ist nur eine Zeile nötig: gpio_put(3,!(gpio_get(0)&!gpio_get(8))); Am Ausgang 3 erscheint nur noch das vom Mikrocontroller zurückgesandte Signal. Nur wenn der TX-Ausgang am Pin 0 gerade high ist und der Empfänger-Ausgang am Port 8 gerade low, wird auch der Ausgang am Port 3 low. Von da muss ein Draht zum RXD-Eingang am Port 1 gelegt werden. Die Abfrage von zwei Ports, logische Verknüpfung und Ausgabe am Port 3 läuft ausreichen schnell, um serielle Daten mit 1200 Baud durchzulassen oder zu blockieren. Alles geschieht in der gemeinsamen Hauptschleife. Die Weiterreichung von Daten ist so schnell, dass keine merkliche Verzögerung auftritt. Die Zeile mit der logischen Verknüfung wird deshalb mit hoher Frequenz aufgerufen.


//Pico_Kosmos IR-Schnittstelle
#include <Arduino.h>
#include "hardware/pwm.h"


void setup() {
  Serial.begin(1200);  // USB-Serial
  Serial1.begin(1200); // UART-Serial1
  gpio_set_function(2, GPIO_FUNC_PWM);
  pwm_set_wrap(1, 3288);  //38 kHz an P2, Pin 4  
  pwm_set_chan_level(1, PWM_CHAN_A, 400);
  pwm_set_enabled(1, true);

  gpio_set_dir(8,0);
  gpio_pull_up(8);  
  gpio_pull_up(1); //Daten vom IR-Empfänger
  pinMode(3,1);
  gpio_put(3,1);
  pinMode(3,1);
  gpio_put(3,1); //Ausgang Echo-Unterdrückung
  gpio_put(6,1);
  pinMode(6,1);
  gpio_put(6,1); //3,3V an IR-Empfänger
}

void loop() {
  if (Serial.available()){ //Daten vom PC
    int inByte = Serial.read();
    Serial1.write(inByte); //USB >> Pin 0
   }
  if (Serial1.available()) {  //Antwort vom µC
    int inByte = Serial1.read();
    Serial.write(inByte); //Pin1 >> USB
  }
  gpio_put(3,!(gpio_get(0)&!gpio_get(8)));
}

Zusätzlich wurde auch der Port 6 dauerhaft hochgeschaltet, um die Betriebsspannung für den IR-Empfänger zu liefern. So wird nur noch eine minimale Verdrahtung benötigt.



Der Kosmos-Mikrocontroller läuft nun mit dem nachgebauten Interface genauso gut wie mit dem Original. Alles funktioniert prima, mit einer Ausnahme: Wenn man das Kosmos-Programm beendet, wird auch die Schnittstelle mit 1200 Baud geschlossen. Dann geht der Pico in seinen Reset-Zustand und öffnet das Upload-Fenster. Vor einem Neustart muss man den Reset-Taster drücken oder das USB-Kabel neu verbinden.






Elektronik-Labor  Projekte  Mikrocontroller  Raspberry