Schalten mit SignalK – Teil 3

In den ersten beiden Beiträgen zum Schalten haben wir zunächst geschaut, wie ein PUT-Request im Node-RED-Plugin des SignalK-Servers verarbeitet werden kann und ihn von einem Arduino aus generiert. In diesem Teil nähern wir uns vom anderen Teil der Kette und nehmen ein Shield mit smarten Leistungstransitoren in Betrieb, dass eine Last schalten und deren Status überwachen kann.

Verwendete Hardware und Software

  • PC mit Debian GNU Linux 10.0
  • Raspberry PI mit Raspbian Buster Lite (02.12.2020)
  • Arduino IDE 1.8.13
  • Arduino MEGA 2560
  • Wiznet W5100 Ethernet Shield
  • Infineon High-Side-Switch Shield BTS7002-1EPP
  • Die Bibliothek ArduinoHttpClient Version 0.4.0
  • Die Bibliothek ArduinoJson Version 6.17.2
  • Die Bibliothek High-Side-Switch Version 0.1.0

Warum ein Smart-FET?

Da die Ausgänge eines Microcontroller wie des Arduinos keine hohen Ströme schalten können, brauchen wir weitere Bauteile, um eine sinvoll große Last schalten zu können. Etabliert sind dafür heute sogennante Feldeffekt-Transitoren (FET), da diese eine sehr hohen Eingangswiderstand haben. So können sie große Ströme schalten, ohne den Ausgang des Microcontrollers stark zu beanspruchen [1]. Grundsätzlich würde ein FET uns also schon weiter helfen. Wir haben uns hier aber mit dem Infineon PROFETTM für einen Smart-FET entschieden, der zusätzlich zum Schalten der Last den Strom messen kann und über diverse Schutzfunktionen wie Übertemperatur, Kurzschluss, Kurzschluss gegen Versorgungsspannung etc. verfügt [2]. Außerdem ist eine Reihe von Arduino-kompatiblen „High-Side-Switch (HSS)-Shields“ mit den PROFETTM’s verfügbar (wir haben hier das BTS7002-1EPP verwendet), wodurch das Aufbauen eines Prototypen einfach möglich ist.

Details zum Sketch

Den Sketch findet ihr auf unserem Github unter https://github.com/Vehicle-Hacks/Arduino-SignalK/releases/tag/v0.4.0 oder ihr ladet es direkt mit git herunter:

git clone -b v0.4.0 https://github.com/Vehicle-Hacks/Arduino-SignalK.git

Der hier vorgestellte Sketch ist eine Erweiterung des im letzten Beitrag vorgestellten Sketches. Grundsätzlich wäre es so möglich, einen Arduino gleichzeitig für das Einlesen von Schaltern und das Schalten von Lasten zu verwenden. Ein Problem dabei ist, dass das Senden eines Put-Requests über UDP oder TCP zur Zeit nicht möglich ist, deswegen mussten wir im letzten Teil eine Websocket-Verbindung verwenden. Bei dieser wird das zu sendende Paket aber komplett im (knappen) SRAM des Arduino zusammen gebaut, was für das Senden einer Statusmeldung über den Lastzustand an den SignalK-Server nicht ausreicht. In diesem Sketch kombinieren wir daher Websocket und UDP-Kommunikation, was nicht schön ist, aber zunächst funktioniert. Insgesamt sind nur wenige Zeilen hinzugekommen, von denen das meiste vom Beitrag „Verwendung des Arduino als Signalquelle“ schon bekannt ist. Daher hier nur eine grobe Übersicht über die Unterschiede und Besonderheiten ohne zu viele Details des Codes zu wiederholen.

Im oberen Teil des Sketches sind die includes für das Infineon HSS-Shield hinzugekommen, außerdem werden globale Variablen für HSS-Shield und UDP-Kommunikation angelegt. Zu den im Flash abgelegten JSON-Strings sind die für eine Rückmeldung des Last- bzw. Smart-FET-Zustands hinzugekommen. Im unteren Teil der setup()-Funktion ist die (bekannte) Initialisierung von UDP hinzugekommen, außerdem wird das HSS-Shield inititalisiert.

In der loop()-Funktion findet sich die erste Änderung in dem Abschnitt, der den Schalter einliest und bei Änderung den Status an den SignalK-Server meldet. Für diesen Beitrag ist hier das Schalten des Smart-FET „hart“ verdrahtet, d.h. es wird nicht der Status des SignalK-Servers abgefragt sondern der FET synchron zum switchState des Arduinos geschaltet. Zum Schalten der FET’s stellt die HSS-Bibliothek jeweils eine Funktion zum Ein- oder Ausschalten der Smart-FET’s zur Verfügung, die an den entsprechenden Stellen eingefügt ist:

      if (switchOutput == false) {
        switchStateChanged(1);
        targetState = 1;
        ledBlinking = true;
        switchOutput = true;
        HSS.switchHxOn(1);
      } else {
        switchStateChanged(0);
        targetState = 0;
        ledBlinking = true;
        switchOutput = false;
        HSS.switchHxOff(1);
      }

Hier ist eine Besonderheit zu beachten: Die FET’s des HSS-Shields werden von 1-4 und nicht, wie in C/C++ üblicherweise zu erwarten, von 0-3 durchnummeriert. Im unteren Teil der loop()-Funktion werden Versorgungsspannung des HSS-Shields sowie Strom des ersten Smart-FET’s mit den Funktionen HSS.readVss(1) bzw. HSS.readIsx(1) ausgelesen und mit dem Schema, das aus dem Beitrag „Arduino UNO als SignalK-Quelle“ bekannt ist, als JSON an den SignalK-Server gesendet. Bevor wir den Sketch ausführen, schauen wir uns erst noch den Hardware-Aufbau für den Test an.

Hardware-Aufbau zum Testen

Wir verwenden zwei Shields, dazu werden eine LED und ein Taster angeschlossen. Um zu überprüfen, ob beide Shields miteinander arbeiten – also keine Konflikte für Pins vorliegt – und damit wir wissen, wo wir LED und Taster anschließen können, brauchen wir zunächst einen Überblick, wie die Pins bei beiden Shields verwendet werden. Die Pinbelegung des HSS-Shields lässt sich dem User Manual entnehmen [3]. Die Pinbelegung des Ethernet Shield haben wir dem Schaltplan entnommen [4]. Die Tabelle unten enthält alle relevanten Pins, d.h. die, bei denen eine Doppelbelegung unkritisch ist (z.B. +5V/+3.3V/GND) sind nicht aufgeführt.

Das HSS-Shield verwendet vier Digital-Ports des Arduino als Ausgänge zum Schalten der PROFETTM’s (im User Manual und der Tabelle aus Sicht der PROFETTM’s als IN1-IN4 bezeichnet). Vier weitere Digital-Ports werden als Ausgang zum Schalten der LED’s auf dem HSS-Shield verwendet. Ein Analogeingang wird zum Messen der Versorgungsspannung, zwei zum Einlesen des Stroms durch FET 1/2 und FET 3/4 verwendet. Für einen ist eine Beschaltung mit einem analog eingelesenen Taster vorgesehen, die jedoch nicht bestückt ist. Zwei weitere Digital-Ports werden für Diagnosis-Enable, einer für „Open Load in OFF“-Detektion und einer für einen optionalen digital eingelesenen Taster verwendet. Damit sind vier von sechs Analog-Ports und 12 der 16 Digital-Ports bereits belegt.

Die große Zahl belegter Pins führt wie zu erwarten zu Doppelbelegungen mit dem Ethernet-Shield2. Einige Doppelbelegungen gibt es mit den sechs Tinker-Kit-Anschlüssen des Ethernet-Shield’s. Diese sind aber unproblematisch solange dort nichts angeschlossen ist. Das Arduino-Ethernet-Shield2 verwendet den ICSP-Header für den SPI-Bus, der vom HSS-Board nicht verwendet wird und so zu keinen Doppelbelegungen führt. Am Pin D13 befindet sich auf beiden Shields – wie auf dem Arduino selbst – eine LED, die aber auch zu keinen Konflikten führt.

Zwei potentielle Konflikt-Pins gibt es dann doch noch: Auf dem Ethernet-Shield ist neben dem Wiznet W5500 noch ein micro-SD Slot enthalten. Beide hängen am gleichen SPI-Bus und es wird jeweils ein PIN vom Arduino verwendet, um sie per Slave Select für die Kommunikation auszuwählen. Für den micro-SD-Slot wird der Pin D4 verwendet, für den W5500 der Pin D10. Theoretisch müssen also entweder aufpassen, dass D4 auf high und D10 auf low bleibt – bei praktischen Tests mit meinem HSS- und Ethernet-Shield gab es aber keine Probleme beim Schalten von D4 und D10, auch nicht mit gesteckter SD-Karte.

Arduino PINShield/KomponenteFunktion
A0High-Side-SwitchTaster – Optional
A1High-Side-SwitchBAT+ über Spannungsteiler
A2High-Side-Switch / Ethernet-ShieldHSS: IS1 + IS2, Eth: TinkerKit IN2
A3High-Side-Switch / Ethernet-ShieldHSS: IS3 + IS4, Eth: TinkerKit IN3
D2High-Side-SwitchTaster – Optional
D3High-Side-SwitchIN4 (FET 4)
D4High-Side-Switch / Ethernet-ShieldHSS: LED1, Eth: Slave Select micro SD
D5High-Side-Switch / Ethernet-ShieldHSS: LED2, Eth: TinkerKit OUT5
D6High-Side-Switch / Ethernet-ShieldHSS: DEN1+DEN3, Eth: TinkerKit OUT6
D7High-Side-SwitchOpen Load OFF
D8High-Side-SwitchDEN2+DEN4
D9High-Side-SwitchIN1 (FET 1)
D10High-Side-Switch / Ethernet-ShieldHSS: IN2 (FET 2), Eth: Slave Select W5500
D11High-Side-SwitchIN3 (FET 3)
D12High-Side-SwitchLED3
D13High-Side-Switch / Ethernet-ShieldHSS: LED4, Eth: LED Green
D18Ethernet-ShieldTinkerKit TWI1/TWI2 SDA
D19Ethernet-ShieldTinkerKit TWI1/TWI2 SCL
ICSP1Ethernet-ShieldMISO
ICSP3Ethernet-ShieldSCK
ICSP4Ethernet-ShieldMOSI
PIN-Belegung von Ethernet- und HSS-Shield

Für den Testaufbau müssen wir unsere Status-LED und den Taster zum Schalten mit dem Arduino Mega verbinden. Die LED wird über einen 220 Ohm-Widerstand mit Pin D48 des Arduino Mega verbunden. Pin D49 wird über einen 10 kOhm-Widerstand auf Masse gehalten und über den Taster auf +5V gezogen. Es ergibt sich damit folgende Aufbau für LED/Taster mit dem Arduino Mega:

Fritzing-Sketch mit dem Aufbau von Status-LED und Taster
Fritzing-Layout für LED und Taster am Arduino Mega

Abschließend muss noch eine Spannungsversorgung und eine Last mit dem HSS-Shield verbunden werden. Die Stromversorgung kann dabei mehr als die +5V Spannungsversorgung des Arduino sein. Ich habe 12V-Netzteil (das im Leerlauf 15V liefert) als Spannungsversorgung und eine Halogen-Birne als Last verwendet. Beides habe ich mit Kroko-Klemmen mit dem HSS-Shield verbunden – kein Betriebssicherer Aufbau, für ein paar erste Tests unter Überwachung hat es aber funktioniert.

Schalten einer Last

Nachdem die Hardware des Arduino aufgebaut und der Sketch compiliert und auf den Arduino geladen ist, können wir einen ersten Test mit dem HSS-Shield durchführen. Das eigentlich schalten wird dabei noch lokal auf dem Arduino durchgeführt. Es werden aber Versorgungsspannung und Strom ausgelesen und an den SignalK-Server geschickt. Ihr müsst also den bereits im vorletzten Beitrag verwendeten SignalK-Server auf dem Raspberry PI (oder eurem PC) starten und danach den Sketch auf den Arduino starten (bzw. reseten). Sofern die IP/Port usw. im Sketch richtig eingestellt sind, solltet ihr im Dashboard des SignalK-Server unter „Connection Activitiy“ nun Botschaften vom Arduino sehen. Öffnet „Webapps – @Signalk/Instrumentpanel“ und konfiguriert euch dort wie im Beitrag „Arduino Uno als SignalK-Quelle“ beschrieben zwei Anzeigen für die Pfade „electrical.load.1.current“ und „electrical.load.1.voltage“. Ohne Last müsstet ihr dann – je nach konfigurierter Anzeige – eine ähnliche Darstellung wie die folgende erhalten:

Screenshot vom SignalK Instrument Panel mit Strom und Spannung bei ausgeschalteter Last
Vom HSS-Shield gemessener Strom und Spannung mit ausgeschalteter Last

Mit eingeschalteter Last ergibt sich bei meinem Aufbau das folgende Bild:

Screenshot vom SignalK Instument Panel mit Strom und Spannung bei eingeschalteter Last
Vom HSS-Shield gemessener Strom und Spannung bei eingeschalteter Last

Ergebnis und nächste Schritte

Wir haben jetzt das HSS-Shield zusätzlich zum Ethernet-Shield am laufen, können mit dem SignalK-Server kommunizieren, eine Last schalten und deren Status auslesen. Neben einer reinen Anzeige lassen sich mit dem ausgelesenen Strom weitere Funktionen wir z.B. per SW einstellbare Sicherungen realisieren. Außerdem lassen sich diverse weitere Statusinformationen auslesen, so dass z.B. auch eine „offene“ oder kurzgeschlossene Last erkennbar ist. Bevor wir aber diese Möglichkeiten vertiefen, wollen wir zunächst die Kette über den SignalK-Server schließen und den Schaltzustand von dort auslesen.

[1] P. Horowitz, W. Hill, Die Hohe Schule Der Elektronik Teil 1: Analogtechnik, deutsche Ausgabe, Aachen: Elektro-Verlag, 1996. S. 137 und S. 149

[2] Infineon, PROFETTM +2 12V Grade 1 Product Brief, München, Infineon, 2021, Document number: B127-I0419-V6-7600-EU-EC-P

[3] Infineon, PROFETTM +2 12V Ardunio Shield User Manual Rev 1.0, 2019, S. 6 und S.10

[4] Arduino Ethernet Shield 2 Schaltplan V2, 8.4.2015