arduino_i2c_slave.py
# Dieses Werk ist unter der MIT-Lizenz lizenziert.
# Copyright (c) 2013-2023 OpenMV LLC. Alle Rechte vorbehalten.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# I2C mit dem Arduino als Master-Gerät und der OpenMV Cam als Slave.
#
# Bitte verkabeln Sie Ihre OpenMV Cam wie folgt mit Ihrem Arduino:
#
# OpenMV Cam Master I2C Data (P5) - Arduino Uno Data (A4)
# OpenMV Cam Master I2C Clock (P4) - Arduino Uno Clock (A5)
# OpenMV Cam Ground - Arduino Ground
import pyb
import struct
text = "Hello World!\n"
data = struct.pack("<%ds" % len(text), text)
# Verwenden Sie "struct", um zu sendende Datenpakete zu erstellen.
# "<" ordnet die Daten im struct im Little-Endian-Format an.
# "%ds" fügt eine Zeichenkette in den Datenstrom ein. Z. B. "13s" für "Hello World!\n" (13 Zeichen).
# Siehe https://docs.python.org/3/library/struct.html
# LIES MICH!!!
#
# Bitte beachten Sie, dass Ihre OpenMV Cam es versäumen kann, zu reagieren, wenn sie nicht der I2C-Master ist,
# wenn sie als I2C-Slave Daten sendet, egal ob Sie "i2c.send()" in einem Interrupt-Callback oder in der
# Hauptschleife unten aufrufen. Wenn dies passiert, erhält der Arduino ein NAK und muss erneut versuchen, von der
# OpenMV Cam zu lesen. Beachten Sie, dass sowohl die I2C-Treiber des Arduino als auch der OpenMV Cam nicht gut darin sind, sich
# nach I2C-Fehlern wieder zu lösen. Auf der OpenMV Cam und dem Arduino können Sie sich erholen, indem Sie
# die I2C-Peripherie de-initialisieren und anschließend erneut initialisieren.
# Der Hardware-I2C-Bus Ihrer OpenMV Cam ist immer I2C-Bus 2.
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
bus.deinit() # I2C-Gerät vollständig zurücksetzen...
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
print("Waiting for Arduino...")
# Beachten Sie, dass die OpenMV Cam dieses Skript bereits ausführen muss, bevor der
# Arduino beginnt, die OpenMV Cam nach Daten abzufragen, damit die Synchronisierung korrekt funktioniert. Andernfalls gerät das I2C-Byte-Framing durcheinander,
# und so weiter. Halten Sie den Arduino daher im Reset, bis die OpenMV Cam "Waiting for Arduino..." anzeigt.
while True:
try:
bus.send(
struct.pack("<h", len(data)), timeout=10000
) # Senden Sie zuerst die Länge (16 Bit).
try:
bus.send(data, timeout=10000) # Senden Sie danach die Daten.
print("Sent Data!") # Wird nur bei fehlerfreiem Ablauf erreicht.
except OSError as err:
pass # Fehler werden ignoriert - daher pass.
# Beachten Sie, dass es 3 mögliche Fehler gibt: einen Timeout-Fehler, einen allgemeinen Fehler oder
# einen Busy-Fehler. Die Fehlercodes für "err.arg[0]" sind entsprechend 116, 5, 16.
except OSError as err:
pass # Fehler werden ignoriert - daher pass.
# Beachten Sie, dass es 3 mögliche Fehler gibt: einen Timeout-Fehler, einen allgemeinen Fehler oder
# einen Busy-Fehler. Die Fehlercodes für "err.arg[0]" sind entsprechend 116, 5, 16.
###################################################################################################
# Arduino-Code
###################################################################################################
#
# #include <Wire.h>
# #define BAUD_RATE 19200
# #define CHAR_BUF 128
#
# void setup() {
# Serial.begin(BAUD_RATE);
# Wire.begin();
# delay(1000); // Der OpenMV Cam Zeit zum Hochfahren geben.
# }
#
# void loop() {
# int32_t temp = 0;
# char buff[CHAR_BUF] = {0};
#
# Wire.requestFrom(0x12, 2);
# if(Wire.available() == 2) { // Länge erhalten?
#
# temp = Wire.read() | (Wire.read() << 8);
# delay(1); // Etwas Einrichtungszeit geben...
#
# Wire.requestFrom(0x12, temp);
# if(Wire.available() == temp) { // vollständige Nachricht erhalten?
#
# temp = 0;
# while(Wire.available()) buff[temp++] = Wire.read();
#
# } else {
# while(Wire.available()) Wire.read(); // Unbrauchbare Bytes verwerfen.
# }
# } else {
# while(Wire.available()) Wire.read(); // Unbrauchbare Bytes verwerfen.
# }
#
# Serial.print(buff);
# delay(1); // Nicht zu schnell schleifen.
# }