Rasperry Pi mit Arduino: Unterschied zwischen den Versionen
(Die Seite wurde neu angelegt: „== Einführung == Es ist möglich, (mehrere) Arduinos mit einem Rasperry Pi zu koppeln. Es gibt dafür mehrere Wege, die hier vor…“) |
|||
Zeile 29: | Zeile 29: | ||
=== PyFirmata === | === PyFirmata === | ||
Diese Bibliothek erlaubt die | Diese Bibliothek erlaubt die Ausführung von Programmen ohne eigenen Code für den Arduino zu entwickeln, sondern man sendet einfach den Code vom Raspi auf den Arduino. Dazu wird zuerst über die IDE des Arduino der entsprechende Sketch geladen (File -> Examples -> Firmata -> StandardFirmata). Anschliessend wartet der Arduino auf Befehle vom Raspi. Das Problem dabei ist nur, dass der Raspi immer mit dem Arduino verbunden sein muss. Für unabhängige Programme muss man hingegen eigene Sketche für den Arduino schreiben und diese dann laden. | ||
Auf dem Raspi muss zuerst die [[Raspberry_Pi#PySerial|PySerial-Bibliothek]] installiert werden. Danach kann PiFirmata von Git installiert werden. | Auf dem Raspi muss zuerst die [[Raspberry_Pi#PySerial|PySerial-Bibliothek]] installiert werden. Danach kann PiFirmata von Git installiert werden. | ||
Zeile 37: | Zeile 37: | ||
$ cd pyFirmata | $ cd pyFirmata | ||
$ sudo python setup.py install | $ sudo python setup.py install | ||
==== Test der eingebauten LED ==== | |||
Anschliessend kann man testen, ob das Programm auf dem Arduino die eingebaute LED aufblinken lässt: | Anschliessend kann man testen, ob das Programm auf dem Arduino die eingebaute LED aufblinken lässt: | ||
import pyfirmata, time | import pyfirmata, time | ||
board = pyfirmata.Arduino('dev/ttyACMo') # Kommunikation über | |||
board = pyfirmata.Arduino('dev/ttyACMo') # Kommunikation über USB | |||
pin13 = board.get_pin('d:13:o') # Den digitalen Pin 13 als Output schalten | pin13 = board.get_pin('d:13:o') # Den digitalen Pin 13 als Output schalten | ||
pin13.write(1) | pin13.write(1) | ||
sleep(2) | sleep(2) | ||
pin13.write(0) | pin13.write(0) | ||
board.exit() | board.exit() | ||
==== externe LED ansteuern ==== | |||
Die Verwendung einer externen LED (mit Vorwiderstand am Pin 10) ist ähnlich | |||
import pyfirmata, time | |||
board = pyfirmata.Arduino('dev/ttyACMo') # Kommunikation über USB | |||
pin10 = board.get_pin('d:10:o') # Den digitalen Pin 10 als Output schalten | |||
while True: | |||
pin10.write(1) | |||
sleep(1) | |||
pin10.write(0) | |||
sleep(1) | |||
==== Taster einlesen ==== | |||
Möchte man einen Taster einlesen, geht dies natürlich auch. | |||
[[Datei:Taster am Arduino.jpg|200px|thumb|left|Taster am Arduino aus [[Links_und_Bücher|Raspi-Kochbuch]]]] | |||
# https://github.com/simonmonk/raspberrypi_cookbook/blob/master/code/ardu_switch.py | |||
import pyfirmata, time, sys | |||
board = pyfirmata.Arduino('/dev/ttyACM0') | |||
switch_pin = board.get_pin('d:4:i') | |||
it = pyfirmata.util.Iterator(board) | |||
it.start() | |||
switch_pin.enable_reporting() | |||
while True: | |||
input_state = switch_pin.read() | |||
if input_state == False: | |||
print('Button Pressed') | |||
time.sleep(0.2) | |||
PyFirmata braucht fürs Einlesen der Inputs einen Iterator, welcher einen eigenen Thread eröffnet. Damit die Meldungen auch verarbeitet werden, muss das reporting aktiviert werden. Leider kann man den Iterator-Thread nicht mehr einfach beenden. Damit der nicht im Hintergrund weiterläuft bis man den Raspi rebootet, kann man Python mit <code>$ sudo killall python</code> beenden. | |||
<div style="clear: both"></div> | |||
==== analoge Werte einlesen (Potentiometer) ==== | |||
Das Einlesen eines analogen Eingangs geschieht wie beim digitalen Eingang. | |||
# https://github.com/simonmonk/raspberrypi_cookbook/blob/master/code/ardu_adc.py | |||
import pyfirmata, time | |||
board = pyfirmata.Arduino('/dev/ttyACM0') | |||
analog_pin = board.get_pin('a:0:i') | |||
it = pyfirmata.util.Iterator(board) | |||
it.start() | |||
analog_pin.enable_reporting() | |||
while True: | |||
reading = analog_pin.read() | |||
if reading != None: # Verhindern, dass ungültige Werte interpretiert werden, wenn der Eingang noch nicht initialisiert wurde | |||
voltage = reading * 5.0 | |||
print("Reading=%f\tVoltage=%f" % (reading, voltage)) | |||
time.sleep(1) | |||
==== PWM einsetzen ==== | |||
Das Vorgehen ist analog der obigen Vorgänge. Programmbeispiele gibt es dazu auf der Webseite vom Kochbuch. | |||
* [https://github.com/simonmonk/raspberrypi_cookbook/blob/master/code/ardu_pwm.py LED Helligkeit steuern] | |||
* [https://github.com/simonmonk/raspberrypi_cookbook/blob/master/code/ardu_servo.py Servo ansteuern] | |||
==== die serielle Schnittstelle anstatt USB nutzen ==== | |||
[[Datei:Serielle Verbindung.jpg|200px|thumb|left|serielle Verbindung aus [[Links_und_Bücher|Raspi-Kochbuch]]]] | |||
Hier ist es wichtig, dass man sich bewusst ist, dass der Arduino 5V benutzt. Wenn man die Pins also direkt anschliesst, so zerstört man den Eingang des Raspi. Für die Pegelumsetzung gibt es Pegelwandler-Module und sonst verwendet man einfach einen [Raspberry_Pi#Spanungen_wandeln_.285V_-.3E_3.3V.29|Spannungsteiler] wie im Bild. Dieses habe ich im Gegensatz zum Buch angepasst, weil der Arduino eine 5V-Quelle braucht. Als Widerstände nimmt man die beim Spannungsteiler vorgeschlagenen. | |||
Im Unterschied zur Verbindung mit USB muss man nur die Zeile mit der Schnittstelle anpassen: | |||
board = pyfirmata.Arduino('dev/ttyAMAo') # Kommunikation über die serielle Schnittstelle | |||
<div style="clear: both"></div> |
Version vom 3. September 2021, 16:09 Uhr
Einführung
Es ist möglich, (mehrere) Arduinos mit einem Rasperry Pi zu koppeln. Es gibt dafür mehrere Wege, die hier vorgestellt werden.
Arduino über Raspberry Pi programmieren
Man kann die Arduino IDE auch auf dem Raspi installieren. Je nach Version der unterstützten IDE und/oder Arduino-Board muss die Programmierung auch über einen externen Rechner geschehen.
$ sudo apt-get update $ sudo apt-get install arduino
Damit der Raspi über das USB-Kabel mit dem Arduino "sprechen" kann, muss die serielle Konsole deaktiviert werden. Wenn man die serielle Konsole für andere Zwecke brauchen möchte, muss der Arduino extern programmiert werden. Die Kommunikation mit dem Arduino ist aber auch über I2C möglich.
Kommunikation zwischen Arduino und Raspi
serieller Monitor
In der Arduino-IDE kann man Nachrichten der seriellen Schnittstelle anzeigen. Dies geschieht über die Lupe auf der rechten Seite der Werkzeugleiste.
void setup() { Serial.begin(9600); } // end setup void loop() { Serial.println("Hallo Welt"); delay(1000); } // end loop
PyFirmata
Diese Bibliothek erlaubt die Ausführung von Programmen ohne eigenen Code für den Arduino zu entwickeln, sondern man sendet einfach den Code vom Raspi auf den Arduino. Dazu wird zuerst über die IDE des Arduino der entsprechende Sketch geladen (File -> Examples -> Firmata -> StandardFirmata). Anschliessend wartet der Arduino auf Befehle vom Raspi. Das Problem dabei ist nur, dass der Raspi immer mit dem Arduino verbunden sein muss. Für unabhängige Programme muss man hingegen eigene Sketche für den Arduino schreiben und diese dann laden.
Auf dem Raspi muss zuerst die PySerial-Bibliothek installiert werden. Danach kann PiFirmata von Git installiert werden.
$ sudo agt-get install git # Falls Git noch nicht installiert wurde $ git clone https://github.com/tino/pyFirmata.git $ cd pyFirmata $ sudo python setup.py install
Test der eingebauten LED
Anschliessend kann man testen, ob das Programm auf dem Arduino die eingebaute LED aufblinken lässt:
import pyfirmata, time board = pyfirmata.Arduino('dev/ttyACMo') # Kommunikation über USB pin13 = board.get_pin('d:13:o') # Den digitalen Pin 13 als Output schalten pin13.write(1) sleep(2) pin13.write(0) board.exit()
externe LED ansteuern
Die Verwendung einer externen LED (mit Vorwiderstand am Pin 10) ist ähnlich
import pyfirmata, time board = pyfirmata.Arduino('dev/ttyACMo') # Kommunikation über USB pin10 = board.get_pin('d:10:o') # Den digitalen Pin 10 als Output schalten while True: pin10.write(1) sleep(1) pin10.write(0) sleep(1)
Taster einlesen
Möchte man einen Taster einlesen, geht dies natürlich auch.
# https://github.com/simonmonk/raspberrypi_cookbook/blob/master/code/ardu_switch.py import pyfirmata, time, sys board = pyfirmata.Arduino('/dev/ttyACM0') switch_pin = board.get_pin('d:4:i') it = pyfirmata.util.Iterator(board) it.start() switch_pin.enable_reporting() while True: input_state = switch_pin.read() if input_state == False: print('Button Pressed') time.sleep(0.2)
PyFirmata braucht fürs Einlesen der Inputs einen Iterator, welcher einen eigenen Thread eröffnet. Damit die Meldungen auch verarbeitet werden, muss das reporting aktiviert werden. Leider kann man den Iterator-Thread nicht mehr einfach beenden. Damit der nicht im Hintergrund weiterläuft bis man den Raspi rebootet, kann man Python mit $ sudo killall python
beenden.
analoge Werte einlesen (Potentiometer)
Das Einlesen eines analogen Eingangs geschieht wie beim digitalen Eingang.
# https://github.com/simonmonk/raspberrypi_cookbook/blob/master/code/ardu_adc.py import pyfirmata, time board = pyfirmata.Arduino('/dev/ttyACM0') analog_pin = board.get_pin('a:0:i') it = pyfirmata.util.Iterator(board) it.start() analog_pin.enable_reporting() while True: reading = analog_pin.read() if reading != None: # Verhindern, dass ungültige Werte interpretiert werden, wenn der Eingang noch nicht initialisiert wurde voltage = reading * 5.0 print("Reading=%f\tVoltage=%f" % (reading, voltage)) time.sleep(1)
PWM einsetzen
Das Vorgehen ist analog der obigen Vorgänge. Programmbeispiele gibt es dazu auf der Webseite vom Kochbuch.
die serielle Schnittstelle anstatt USB nutzen
Hier ist es wichtig, dass man sich bewusst ist, dass der Arduino 5V benutzt. Wenn man die Pins also direkt anschliesst, so zerstört man den Eingang des Raspi. Für die Pegelumsetzung gibt es Pegelwandler-Module und sonst verwendet man einfach einen [Raspberry_Pi#Spanungen_wandeln_.285V_-.3E_3.3V.29|Spannungsteiler] wie im Bild. Dieses habe ich im Gegensatz zum Buch angepasst, weil der Arduino eine 5V-Quelle braucht. Als Widerstände nimmt man die beim Spannungsteiler vorgeschlagenen.
Im Unterschied zur Verbindung mit USB muss man nur die Zeile mit der Schnittstelle anpassen:
board = pyfirmata.Arduino('dev/ttyAMAo') # Kommunikation über die serielle Schnittstelle