arduino_spi_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
#
# SPI 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 Out Slave In (P0) - Arduino Uno MOSI (11)
# OpenMV Cam Master In Slave Out (P1) - Arduino Uno MISO (12)
# OpenMV Cam Serial Clock        (P2) - Arduino Uno SCK  (13)
# OpenMV Cam Slave Select        (P3) - Arduino Uno SS   (10)
# OpenMV Cam Ground                   - Arduino Ground

import pyb
import struct
import time

text = "Hello World!\n"
data = struct.pack("<bi%ds" % len(text), 85, len(text), text)  # 85 ist ein Sync-Zeichen.
# Verwenden Sie "struct", um zu sendende Datenpakete zu erstellen.
# "<" ordnet die Daten im struct im Little-Endian-Format an.
# "b" fügt ein vorzeichenbehaftetes Zeichen (char) in den Datenstrom ein.
# "i" fügt eine vorzeichenbehaftete Ganzzahl in den Datenstrom ein.
# "%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, wenn sie nicht der SPI-Master ist, möglicherweise nicht rechtzeitig antwortet, um
# Daten als SPI-Slave zu senden, unabhängig davon, ob Sie "spi.send()" in einem Interrupt-Callback oder in der
# Hauptschleife unten aufrufen. Aus diesem Grund müssen Sie Ihr Kommunikationsprotokoll unbedingt so gestalten,
# dass, falls das Slave-Gerät (die OpenMV Cam) "spi.send()" nicht rechtzeitig aufruft, Datenmüll,
# der vom Master (dem Arduino) aus dem SPI-Peripheriegerät gelesen wird, verworfen wird. Um dies zu erreichen, verwenden wir ein
# Sync-Zeichen mit dem Wert 85 (binär 01010101), nach dem der Arduino als erstes gelesenes Byte sucht.
# Sieht er dieses nicht, bricht er die SPI-Transaktion ab und versucht es erneut. Zweitens, um
# den Zustand des SPI-Peripheriegeräts zurückzusetzen, senden wir immer ein Vielfaches von vier Bytes sowie vier zusätzliche Null-
# Bytes, um sicherzustellen, dass das SPI-Peripheriegerät keine veralteten Daten hält, die 85 sein könnten. Beachten Sie,
# dass die OpenMV Cam das "spi.send()"-Zeitfenster gelegentlich zufällig verpasst, weil sie
# Interrupts bedienen muss. Interrupts treten deutlich häufiger auf, wenn sie mit Ihrem PC verbunden ist.

# Der Hardware-SPI-Bus Ihrer OpenMV Cam ist immer SPI-Bus 2.
# polarity = 0 -> Takt ist im Ruhezustand low.
# phase = 0 -> Daten werden bei steigender Taktflanke abgetastet, bei fallender Taktflanke ausgegeben.
spi = pyb.SPI(2, pyb.SPI.SLAVE, polarity=0, phase=0)


# NSS-Callback.
def nss_callback(line):
    global spi, data
    try:
        spi.send(data, timeout=1000)
    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.


# NSS/CS im IRQ-Modus konfigurieren, um Daten zu senden, wenn der Master sie anfordert.
pyb.ExtInt(pyb.Pin("P3"), pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, nss_callback)

while True:
    time.sleep_ms(1000)

###################################################################################################
# Arduino-Code
###################################################################################################
#
# #include <SPI.h>
# #define SS_PIN 10
# #define BAUD_RATE 19200
# #define CHAR_BUF 128
#
# void setup() {
#   pinMode(SS_PIN, OUTPUT);
#   Serial.begin(BAUD_RATE);
#   SPI.begin();
#   SPI.setBitOrder(MSBFIRST);
#   SPI.setClockDivider(SPI_CLOCK_DIV16);
#   SPI.setDataMode(SPI_MODE0);
# delay(1000); // Der OpenMV Cam Zeit zum Hochfahren geben.
# }
#
# void loop() {
#   int32_t len = 0;
#   char buff[CHAR_BUF] = {0};
#   digitalWrite(SS_PIN, LOW);
# delay(1); // Der OpenMV Cam etwas Zeit geben, um sich zum Senden von Daten vorzubereiten.
#
# if(SPI.transfer(1) == 85) { // Sync-Zeichen gesehen?
# SPI.transfer(&len, 4); // Länge abrufen
#     if (len) {
#       SPI.transfer(&buff, min(len, CHAR_BUF));
#       len -= min(len, CHAR_BUF);
#     }
# while (len--) SPI.transfer(0); // verbleibende Bytes verwerfen
#   }
#
#   digitalWrite(SS_PIN, HIGH);
#   Serial.print(buff);
# delay(1); // Nicht zu schnell schleifen.
# }

results matching ""

    No results matching ""