arduino_spi_slave.py

# Ce travail est publié sous licence MIT.
# Copyright (c) 2013-2023 OpenMV LLC. Tous droits réservés.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# SPI avec l'Arduino comme périphérique maître et l'OpenMV Cam comme esclave.
#
# Veuillez câbler votre OpenMV Cam à votre Arduino comme ceci :
#
# 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 est un caractère de synchronisation.
# Utilisez « struct » pour construire les paquets de données à envoyer.
# « < » place les données de la struct en ordre little endian.
# « b » place un caractère signé dans le flux de données.
# « i » place un entier signé dans le flux de données.
# « %ds » place une chaîne dans le flux de données. Par ex. « 13s » pour « Hello World!\n » (13 caractères).
# Voir https://docs.python.org/3/library/struct.html

# LISEZ-MOI !!!
#
# Veuillez comprendre que lorsque votre OpenMV Cam n'est pas le maître SPI, elle peut manquer de répondre à
# l'envoi de données en tant qu'esclave SPI, que vous appeliez « spi.send() » dans un callback d'interruption ou dans la
# boucle principale ci-dessous. Pour cette raison, vous devez absolument concevoir votre protocole de communication de manière
# à ce que, si le périphérique esclave (l'OpenMV Cam) n'appelle pas « spi.send() » à temps, les données erronées
# lues depuis le périphérique SPI par le maître (l'Arduino) soient rejetées. Pour cela, nous utilisons un
# caractère de synchronisation 85 (binaire 01010101) que l'Arduino recherchera comme premier octet lu.
# S'il ne le voit pas, il annule la transaction SPI et réessaiera. Ensuite, afin de
# purger l'état du périphérique SPI, nous envoyons toujours un multiple de quatre octets ainsi que quatre octets zéro
# supplémentaires pour garantir que le périphérique SPI ne conserve pas de données obsolètes qui pourraient être 85. Notez
# que l'OpenMV Cam manquera aléatoirement la fenêtre de « spi.send() » car elle doit traiter
# des interruptions. Les interruptions se produiront beaucoup plus souvent lorsqu'elle est connectée à votre PC.

# Le bus SPI matériel de votre OpenMV Cam est toujours le bus SPI 2.
# polarity = 0 -> l'horloge est au repos à l'état bas.
# phase = 0 -> échantillonne les données sur front montant d'horloge, sort les données sur front descendant d'horloge.
spi = pyb.SPI(2, pyb.SPI.SLAVE, polarity=0, phase=0)


# Callback NSS.
def nss_callback(line):
    global spi, data
    try:
        spi.send(data, timeout=1000)
    except OSError as err:
        pass  # Peu importe les erreurs - donc pass.
        # Notez qu'il existe 3 erreurs possibles. Une erreur de timeout, une erreur d'usage général, ou
        # une erreur d'occupation (busy). Les codes d'erreur sont respectivement 116, 5, 16 pour « err.arg[0] ».


# Configurez NSS/CS en mode IRQ pour envoyer des données lorsque le maître le demande.
pyb.ExtInt(pyb.Pin("P3"), pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, nss_callback)

while True:
    time.sleep_ms(1000)

###################################################################################################
# Code Arduino
###################################################################################################
#
# #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); // Laisse à l'OpenMV Cam le temps de démarrer.
# }
#
# void loop() {
#   int32_t len = 0;
#   char buff[CHAR_BUF] = {0};
#   digitalWrite(SS_PIN, LOW);
# delay(1); // Laisse à l'OpenMV Cam un peu de temps pour se préparer à envoyer des données.
#
# if(SPI.transfer(1) == 85) { // caractère de synchronisation détecté ?
# SPI.transfer(&len, 4); // récupère la longueur
#     if (len) {
#       SPI.transfer(&buff, min(len, CHAR_BUF));
#       len -= min(len, CHAR_BUF);
#     }
# while (len--) SPI.transfer(0); // consomme les octets restants
#   }
#
#   digitalWrite(SS_PIN, HIGH);
#   Serial.print(buff);
# delay(1); // Ne pas boucler trop rapidement.
# }

results matching ""

    No results matching ""