arduino_i2c_slave.py

# Questo lavoro è concesso in licenza MIT.
# Copyright (c) 2013-2023 OpenMV LLC. Tutti i diritti riservati.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# I2C con l'Arduino come dispositivo master e la OpenMV Cam come slave.
#
# Collega la tua OpenMV Cam al tuo Arduino come segue:
#
# 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)
# Usa "struct" per costruire i pacchetti di dati da inviare.
# "<" inserisce i dati nella struct in ordine little endian.
# "%ds" inserisce una stringa nel flusso di dati. Ad es. "13s" per "Hello World!\n" (13 caratteri).
# Vedi https://docs.python.org/3/library/struct.html

# LEGGIMI!!!
#
# Tieni presente che quando la tua OpenMV Cam non è il master I2C potrebbe non rispondere a
# l'invio di dati come slave I2C, indipendentemente dal fatto che tu chiami "i2c.send()" in un callback di interrupt o nel
# loop principale qui sotto. Quando ciò accade, l'Arduino riceverà un NAK e dovrà provare a leggere di nuovo dalla
# OpenMV Cam. Nota che sia i driver I2C dell'Arduino che quelli della OpenMV Cam non sono bravi a
# sbloccarsi dopo aver incontrato errori I2C. Sulla OpenMV Cam e sull'Arduino è possibile ripristinare la situazione
# disattivando e poi reinizializzando le periferiche I2C.

# Il bus I2C hardware della tua OpenMV Cam è sempre il bus I2C 2.
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
bus.deinit()  # Reset completo del dispositivo I2C...
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
print("Waiting for Arduino...")

# Nota che, affinché la sincronizzazione funzioni correttamente, la OpenMV Cam deve eseguire questo script prima che
# l'Arduino inizi a interrogare (poll) la OpenMV Cam per i dati. Altrimenti il framing dei byte I2C si rovina,
# eccetera. Quindi, mantieni l'Arduino in reset finché la OpenMV Cam non è in stato "Waiting for Arduino...".

while True:
    try:
        bus.send(
            struct.pack("<h", len(data)), timeout=10000
        )  # Invia prima la lunghezza (16 bit).
        try:
            bus.send(data, timeout=10000)  # Invia poi i dati.
            print("Sent Data!")  # Raggiunto solo in assenza di errori.
        except OSError as err:
            pass  # Non ci interessano gli errori, quindi pass.
            # Nota che ci sono 3 possibili errori. Un errore di timeout, un errore generico oppure
            # un errore di occupato. I codici di errore sono rispettivamente 116, 5, 16 per "err.arg[0]".
    except OSError as err:
        pass  # Non ci interessano gli errori, quindi pass.
        # Nota che ci sono 3 possibili errori. Un errore di timeout, un errore generico oppure
        # un errore di occupato. I codici di errore sono rispettivamente 116, 5, 16 per "err.arg[0]".

###################################################################################################
# Codice Arduino
###################################################################################################
#
# #include <Wire.h>
# #define BAUD_RATE 19200
# #define CHAR_BUF 128
#
# void setup() {
#   Serial.begin(BAUD_RATE);
#   Wire.begin();
# delay(1000); // Dai tempo alla OpenMV Cam di avviarsi.
# }
#
# void loop() {
#   int32_t temp = 0;
#   char buff[CHAR_BUF] = {0};
#
#   Wire.requestFrom(0x12, 2);
# if(Wire.available() == 2) { // lunghezza ricevuta?
#
#     temp = Wire.read() | (Wire.read() << 8);
# delay(1); // Concedi un po' di tempo di setup...
#
#     Wire.requestFrom(0x12, temp);
# if(Wire.available() == temp) { // messaggio completo ricevuto?
#
#       temp = 0;
#       while(Wire.available()) buff[temp++] = Wire.read();
#
#     } else {
# while(Wire.available()) Wire.read(); // Scarta i byte spazzatura.
#     }
#   } else {
# while(Wire.available()) Wire.read(); // Scarta i byte spazzatura.
#   }
#
#   Serial.print(buff);
# delay(1); // Non ciclare troppo velocemente.
# }

results matching ""

    No results matching ""