---
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