Du bist hier:Start»Linux»Raspberry Pi»USB

USB Geräte am Raspberry Pi ein- und ausschalten

17.07.2016

USB

Im Internet taucht öfter die Frage auf, ob einzelne USB-Anschlüsse des Mini-Computers Raspberry Pi per Software ein- beziehungsweise ausgeschaltet werden können. Die Standard-Antwort lautet dann, dass nur alle USB Ports auf einmal ausgeschaltet werden können. In folgendem Artikel zeige ich, wie mit geringen Kosten und geringem Hardware-Aufwand einzelne USB Ports per Relais aus- beziehungsweise eingeschaltet werden können. So läßt sich zum Beispiel ein stromsparendes NAS (Netzwerkspeicher) am Raspberry Pi realisieren.

Alle USB Anschlüsse per Software schalten

Zunächst stelle ich noch einmal kurz die Software-Methode vor, mit der sich alle USB-Anschlüsse auf einmal an- bzw. abschalten lassen. Diese Methode ist am einfachsten und führt dazu, dass der Raspberry Pi weniger als 0,5 Watt benötigt. Die folgenden System-Pfade sind von der Hardware-Version des Raspberry Pi und des Betriebssystems abhängig:

# disable USB at Raspberry Pi 1 and 2 on Raspbian Wheezy
echo 0 > /sys/devices/platform/bcm2708_usb/buspower

# disable USB at Raspberry Pi 1 on Raspbian Jessie
echo 0 > /sys/devices/platform/soc/20980000.usb/buspower

# disable USB at Raspberry Pi 2 on Raspbian Jessie
echo 0 > /sys/devices/platform/soc/3f980000.usb/buspower

# to enable USB use the same line as above with "echo 1"
echo 1 > /sys/devices/platform/... (see above)

Das Problem beim Raspberry Pi 1 und 2 ist allerdings, dass die LAN-Schnittstelle zusammen mit USB abgeschaltet wird und die Verbindung zum Pi verloren geht. Beim Raspberry Pi 3 läßt sich durch das Onboard-WLAN die Netzwerkverbindung zum Pi noch halten. Durch ein Shell-Skript läßt sich das Problem der LAN-Schnittstelle aber umgehen, indem die USB-LAN-Schnittstelle jede Minute wieder eingeschaltet wird und dann per Internet geprüft wird, ob der Raspberry Pi die USB-LAN-Schnittstelle dauerhaft eingeschaltet lassen soll. Details dazu habe ich in einem weiteren Artikel zum Stromsparen geschrieben.

Einzelnes USB Gerät schalten

Um ein einzelnes USB-Gerät per Hardware aus- beziehungsweise einzuschalten, wird ein Relais benötigt, das mit den Stromspannungen des Raspberry Pi kompatibel ist. Eine fertige Platine mit 4 Relais gibt es zum Beispiel bei Amazon für unter 3 Euro. Allerdings muss bei diesem Angebot etwas länger gewartet werden, da das Relais aus China kommt. Der Raspberry Pi wird über 3 sogenannte Jumperwire female zu female mit dem Relais verbunden. Von einem USB-Verlängerungskabel muss der rote Draht aufgeschnitten und in das Relais gesteckt werden. Das folgende Bild zeigt die schematische Darstellung der Verkabelung:

Raspberry Pi mit Relais und einzelnem USB-Kabel

Raspberry Pi mit Relais und einzelnem USB-Kabel (zum Vergrößern klicken)

"This image was created with Fritzing." Das obere Bild ist mit der Layout-Software Fritzing erstellt. Die schematische Darstellung zeigt einen Raspberry Pi 1. Der Raspberry Pi 2 hat 40 GPIO-Pins. Die Verkabelung sieht aber genauso aus wie beim Raspberry Pi 1 - nur dass sich zwischen den Kabeln und der USB-Buchse weitere Pins befinden, die nicht genutzt werden.

Leitung Kabelfarbe Pin beim Raspberry Pi 2 Pin beim Relais
5 Volt rot 2 VCC
GND (Ground / Erdung) schwarz 6 GND
Relais 1 gelb 8 (GPIO 14) IN1

Statt 5 Volt vom physikalischen Pin 2 kann beim Raspberry Pi auch Pin 1 mit 3,3 Volt für das Relais benutzt werden. Allerdings ergibt sich daraus kein großer Unterschied beim Stromverbrauch des Raspberry Pi. In folgendem Foto habe ich das USB-Kabel an Relais Nummer 4 angeschlossen (Beschriftung: IN4).

Raspberry Pi mit Relais und USB-Kabel

Raspberry Pi 2 mit Relais und USB-Kabel (zum Vergrößern klicken)

Für diesen Aufbau muss ein USB-Verlängerungskabel zunächst mit einem Teppichmesser vorsichtig längs aufgeschnitten werden. Unter der Kunststoffisolierung und der Metallabschirmung des USB-Kabels befinden sich vier kleine dünne Kabel: weiß, grün, schwarz und rot. Das kleine rote Kabel ist für die Spannungsversorgung von USB mit 5 Volt zuständig.

aufgeschnittenes USB-Kabel, roter Draht

aufgeschnittenes USB-Kabel, roter Draht (zum Vergrößern klicken)

Das rote Kabel muss durchgeschnitten und die Kunststoffisolierung an den Enden dieses roten Kabels vorsichtig mit dem Teppichmesser schräg abgeschabt werden. Schließlich muss das aufgeschnittene Kabel noch mit ein wenig Isolierband abgeklebt werden, damit es nicht zu einem Kurzschluss kommen kann. Das fertige Ergebnis sollte so aussehen, dass die Metalldrähte des roten Kabels abisoliert sind und der Rest isoliert, wie auf folgendem Foto dargestellt:

aufgeschnittenes USB-Kabel

aufgeschnittenes USB-Kabel (zum Vergrößern klicken)

Da das aufgeschnittene USB-Kabel nur schwer in das Relais eingeschraubt werden kann, empfiehlt es sich noch zwei Verlängerungskabel an die Enden des kleinen roten Kabels anzulöten. Wer keinen Lötkolben oder Bekannte mit einem Lötkolben hat, kann es auch so lassen und muss das USB-Kabel zum Einschrauben ins Relais ein wenig knicken.

Raspberry Pi mit Relais und aufgeschnittenem USB-Kabel

Raspberry Pi 2 mit Relais und aufgeschnittenem USB-Kabel (zum Vergrößern klicken)

Software

Das Ein- und Ausschalten des Relais und damit die Anbindung eines USB-Geräts an den Raspberry Pi geht bei der oben beschriebenen Verkabelung durch Setzen des GPIO 14 (General Purpose Input / Output):

# become root
sudo bash

# enable gpio 14
echo 14 > /sys/class/gpio/export

# set gpio 14 as 3.3 V output
echo out > /sys/class/gpio/gpio14/direction

# disable relay
echo 1 > /sys/class/gpio/gpio14/value

# enable relay
echo 0 > /sys/class/gpio/gpio14/value

Stromverbrauch und Kosten

Durch einen USB-Stick wurde ein Watt mehr am Raspberry Pi verbraucht, wie in folgendem Video zu sehen:

Wann lohnen sich also die Kosten von 2,70 Euro für ein 4er-Relais ?

Dazu ein kleines Rechenbeispiel. Angenommen der Raspberry Pi wird als NAS benutzt (network attached storage) - also um Daten übers Netzwerk zu schicken und auf einer USB-Festplatte zu speichern. Mit einer externen USB-Festplatte ohne Netzteil werden am Raspberry Pi zusätzlich 2,5 Watt verbraucht. Außerdem setze ich voraus, dass ein USB-Verlängerungskabel und die 3 farbigen Jumperwire bereits vorhanden sind - so dass keine weiteren Kosten anfallen. Bei einem Szenario mit Dauerbetrieb der externen Festplatte am Raspberry Pi aber nur 2 Stunden tatsächlicher Nutzung pro Tag ergeben sich folgende Werte:

  • 2 Stunden tatsächlicher Festplattenbetrieb am Tag gegenüber 24 Stunden Dauerbetrieb mit 2,5 Watt ohne Relais-Schaltung
  • 22 Stunden (Idle/Leerlauf) * 2,5 Watt pro Tag gespart
  • das sind 55 Wattstunden pro Tag, die gespart werden können
  • das sind 365 * 55 Wattstunden pro Jahr, die gespart werden können = 20 kWh im Jahr
  • 20 kWh * 0,3 Euro/kWh = eine Einsparung von 6 Euro im Jahr

Das oben beschriebene Szenario zum Stromsparen per USB-Relais rentiert sich also spätestens nach einem Jahr (6 Euro Energiekosten vs. 3 Euro Relaiskosten). Selbst für USB-Geräte, die häufiger benötigt werden und weniger Strom verbauchen, kann sich eine USB-Schaltung nach kurzer Zeit rentieren. Eine eigene, kleine Berechnung dazu kann helfen.

USB-Hub mit mehreren Geräten per Relais schalten

Die Schaltung für einen externen USB-Hub sieht so ähnlich aus, wie die für ein einzelnes USB-Gerät. Zusätzlich wird jetzt allerdings noch das Netzteil-Kabel des USB-Hubs mit einem Relais geschaltet.

Raspberry Pi mit Relais und Netzteil für USB-Hub

Raspberry Pi mit Relais und Netzteil für USB-Hub (zum Vergrößern klicken)

Das obere Bild wurde ebenfalls mit der Layout-Software Fritzing erstellt und funktioniert auch für den Raspberry Pi 2. "This image was created with Fritzing."

Leitung Kabelfarbe Pin beim Raspberry Pi 2 Pin beim Relais
5 Volt rot 2 VCC
GND (Ground / Erdung) schwarz 6 GND
Relais 3 gelb 8 (GPIO 14) IN3
Relais 1 orange 10 (GPIO 15) IN1

WARNUNG

ACHTUNG !!! Die Arbeit mit nicht isolierten Leitungen kann zu einem Kurzschluss führen. Außerdem sollte die Arbeit an einem Netzteil-Kabel immer bei _AUSGESCHALTETEM_ Netzteil vorgenommen werden. Ich übernehme keine Verantwortung bei unsachgemäßen Umgang mit Strom.

Um den USB-Hub später mit einem Relais stromlos zu schalten, muss die spannungsführende Leitung des Netzteils aufgeschnitten werden. Beim Aufschneiden gibt es eine 50%-Chance die richtige Leitung zu erwischen (entweder die Spannung oder die Erdung). Deshalb sollte zunächst die Isolierung einer Leitung vorsichtig längs mit einem Teppichmesser aufgeschnitten, aber noch nicht durchgeschnitten werden. Danach wird mit einem Multimeter geprüft, ob es die richtige Leitung war. Bei meinem Netzteil liegt die Spannung innen im zylinderförmigen Stecker und die Erdung außen. Wenn die spannungsführende Leitung erwischt wurde, dann sollte das Multimeter einen Piepton abgeben. Jetzt kann die spannungsführende Leitung durchgeschnitten und ein Stück weit abisoliert werden.

Multimeter am Netzteil für USB-Hub, Kabel aufgeschnitten

Multimeter am Netzteil für USB-Hub, Kabel aufgeschnitten (zum Vergrößern klicken)

Wie auf dem oberen Foto zu sehen, hatte ich beim ersten Aufschneiden kein Glück und habe die Leitung für die Erdung erwischt. Durch ein wenig Isolierband (blaues Band rechts oben im Foto) konnte ich die aufgeschnittene Isolierung wieder schließen. Die durchgeschnittene Leitung des USB-Hub-Netzteils habe ich in ein Relais der 4-fach Relais-Karte und die durchgeschnittene rote Leitung eines zugehörigen USB-Kabels in ein anderes Relais geschraubt. Das folgende Foto zeigt die Konstruktion:

Raspberry Pi mit USB-Hub und Relais

Raspberry Pi mit USB-Hub und Relais (zum Vergrößern klicken)

Die durchgeschnittenen Leitungen sind so in die Relais geschraubt, dass ein Relais in ausgeschaltetem Zustand die Leitungen nicht verbindet. Die Verbindungen können durch Einschalten der Relais hergestellt werden. Danach sind das USB-Kabel und der USB-Hub mit dem Raspberry Pi verbunden. Die Software-Befehle zum Einschalten sehen so ähnlich aus, wie bei einem einzelnen USB-Gerät. Diesmal kommt noch GPIO 15 für das zweite Relais dazu.

# become root
sudo bash

# enable gpio 14 and 15
echo 14 > /sys/class/gpio/export
echo 15 > /sys/class/gpio/export

# set gpio 14 and 15 as 3.3 V output
echo out > /sys/class/gpio/gpio14/direction
echo out > /sys/class/gpio/gpio15/direction

# disable relays
echo 1 > /sys/class/gpio/gpio14/value; echo 1 > /sys/class/gpio/gpio15/value

# enable relays
echo 0 > /sys/class/gpio/gpio14/value; echo 0 > /sys/class/gpio/gpio15/value

Die Befehle lassen sich natürlich in ein Shell-Skript kopieren und automatisiert oder remote benutzen.

USB-Hub oder USB-Gerät mit Arduino schalten

Wer einen USB-Hub oder ein USB-Gerät am Computer aus- beziehungsweise einschalten möchte, kann das auch mit einem Arduino erreichen. Dazu ist dann kein Raspberry Pi nötig. Die folgende schematische Darstellung zeigt den Aufbau und die Verkabelung eines Arduino Nano mit der 4-fach Relais-Platine.

Arduino Nano mit USB-Hub und Relais

Arduino Nano mit USB-Hub und Relais (zum Vergrößern klicken)

Das obere Bild wurde ebenfalls mit der Layout-Software Fritzing erstellt und sollte in abgewandelter Form auch für andere Arduino-Typen funktionieren. "This image was created with Fritzing." In der Realität sieht der Aufbau an einem Laptop zum Beispiel so aus:

Arduino Nano mit USB-Hub und Relais

Arduino Nano mit USB-Hub und Relais (zum Vergrößern klicken)

Der Arduino kann so den USB-Hub über das Netzteil einschalten und die USB-Verbindung zum Laptop herstellen.

Software

Die Software für den Arduino ist eigentlich relativ trivial. Ich habe den Quellcode für eine einfachere Bedienung über die serielle USB-Schnittstelle etwas erweitert. Durch das Senden der Zeichen "1" (ASCII-Code 49 = 0x31) und "2" (ASCII-Code 50 = 0x32) über die serielle Schnittstelle können die USB-Relais ein- bzw. ausgeschaltet werden.
Der folgende Quellcode arduino_relay.ino kann in die Arduino IDE geladen und an den Arduino übertragen werden.

// define pin D7 and D8 to control the two relays
int relay[2] = {7, 8};
int MAX_RELAYS = 2;

// for the incoming serial data
int incomingByte = 0;
int togglePin = 0;

void setup() {

  // initialize the digital pins as output
  for (int index = 0; index < MAX_RELAYS; index++) {
    pinMode(relay[index], OUTPUT);
    digitalWrite(relay[index], HIGH);
  }

  // use the serial port with 9600 bps
  Serial.begin(9600);
}

void loop() {

  // wait for data on the serial line
  if (Serial.available() > 0) {

    // read the incoming byte
    incomingByte = Serial.read();

    // print received character as decimal value
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);

    togglePin = 2;

    // enable or disable the relay(s)
    if (incomingByte == 49) {
      togglePin = 1;
    } else if (incomingByte == 50) {
      togglePin = 0;
    }

    if (togglePin != 2) {
      for (int index = 0; index < MAX_RELAYS; index++) {
        pinMode(relay[index], OUTPUT);
        digitalWrite(relay[index], togglePin);
      }
    }

  }
}

Wer sich den Umweg über die Arduino IDE sparen möchte, kann auch gleich die Intel-Hex-Datei arduino_relay.hex herunterladen und über avrdude auf den Arduino hochladen. Nach dem Hochladen können über eine serielle Verbindung die Relais gesteuert werden.

# become root
sudo bash

# change permissions of the USB to serial device
chmod 777 /dev/ttyUSB0

# connect to the Arduino with 9600 bps
cu -l /dev/ttyUSB0 -s 9600

# type "1" to enable the relays
# type "2" to disable the relays

cu -l /dev/ttyUSB0 -s 9600
Connected.

# now press the keys "1" or "2"

I received: 50
I received: 49
I received: 50

# stop cu with Ctrl + C, ~, Ctrl + D and again Ctrl + C

Statt manuell funktioniert das Ein- und Ausschalten der USB-Geräte auch Skript-gesteuert mit einem Expect-Skript. Das Expect-Skript wird automatisch über Udev-Regeln beim Einstecken des Arduino Nano gestartet. Eventuell müssen noch in der Datei 99-arduino.rules die USB-IDs angepaßt werden. Diese können mit dem Befehl "lsusb" herausgefunden werden. Durch meinem Arduino Nano habe ich die Werte Hersteller-ID: 1a86 und Modell-ID: 7523 eingetragen.

# become root
sudo bash

# install the cu command and the expect framework
apt-get install cu expect

# download necessary files and scripts
wget http://torsten-traenkner.de/linux/raspberry/99-arduino.rules -O /etc/udev/rules.d/99-arduino.rules

# download the expect script
wget http://torsten-traenkner.de/linux/raspberry/arduino.exp -O /usr/bin/arduino.exp
chmod 755 /usr/bin/arduino.exp

cd /root/
wget http://torsten-traenkner.de/linux/raspberry/connect_serial.sh
wget http://torsten-traenkner.de/linux/raspberry/stop_serial.sh
chmod 755 connect_serial.sh stop_serial.sh

# usage as "normal" user (after the Arduino has been plugged in)
# switch off:
echo 2 > /tmp/usb.fifo

# switch on:
echo 1 > /tmp/usb.fifo

Wenn das Programm Avrdude wieder benutzt werden soll, muss die Datei /etc/udev/rules.d/99-arduino.rules vorübergehend nach /tmp verschoben werden. Ansonsten würde die USB-zu-seriell-Verbindung des Arduino blockiert werden.

Falls du Fragen hast, dann kannst du die Kommentar-Funktion benutzen.

Kommentar schreiben