Outils pour utilisateurs

Outils du site


spi_documentation_2

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
spi_documentation_2 [2022/05/30 13:13] sergespi_documentation_2 [2022/05/31 07:45] (Version actuelle) serge
Ligne 1: Ligne 1:
 ====== Communication entre Raspberry Pi et Arduino en SPI ====== ====== Communication entre Raspberry Pi et Arduino en SPI ======
 +<WRAP center round box 60% centeralign>
 +**{{tagpage>spi|Toutes les pages sur protocol SPI}}**
 +</WRAP>
  
 +=====Une ESP32 n'est pas une carte Arduino=====
 +**Les sketchs ci-dessous ne fonctionnent pas avec une ESP32**
 +
 +=====Exemple 1=====
 +https://roboticsbackend.com/raspberry-pi-master-arduino-uno-slave-spi-communication-with-wiringpi/
 +
 +Raspberry Pi (master) Arduino Uno (slave) SPI communication with WiringPi
 +
 +<code csharp>
 +#include <SPI.h>
 +void setup() {
 +  // have to send on master in, *slave out*
 +  pinMode(MISO, OUTPUT);
 +  // turn on SPI in slave mode
 +  SPCR |= _BV(SPE);
 +  // turn on interrupts
 +  SPI.attachInterrupt();
 +}
 +// SPI interrupt routine
 +ISR (SPI_STC_vect)
 +{
 +  byte c = SPDR;
 +  SPDR = c+10;
 +}  // end of interrupt service routine (ISR) for SPI
 +
 +void loop () { }
 +</code>
 +
 +**Raspberry Pi avec wiringPi**
 +<code>
 +#include <iostream>
 +#include <wiringPiSPI.h>
 +#define SPI_CHANNEL 0
 +#define SPI_CLOCK_SPEED 1000000
 +int main(int argc, char **argv)
 +{
 +    int fd = wiringPiSPISetupMode(SPI_CHANNEL, SPI_CLOCK_SPEED, 0);
 +    if (fd == -1) {
 +        std::cout << "Failed to init SPI communication.\n";
 +        return -1;
 +    }
 +    std::cout << "SPI communication successfully setup.\n";
 +   
 +    unsigned char buf[2] = { 23, 0 };
 +    wiringPiSPIDataRW(SPI_CHANNEL, buf, 2);
 +    std::cout << "Data returned: " << +buf[1] << "\n"; 
 +    return 0;
 +}
 +</code>
 +Voir le lien pour la compilation de wiringPi et de ce script
 +
 +=====Exemple 2=====
 +Tiré de [[http://www.penguintutor.com/electronics/rpi-arduino-spi|penguintutor.com Using Raspberry Pi and Arduino together through SPI serial communications]]**\\
 +Arduino: SPCR et SPDR pas défini !
 +====Raspberry====
 +<code python>
 +import spidev
 +import time
 +spi_bus = 0
 +spi_device = 0
 +spi = spidev.SpiDev()
 +spi.open(spi_bus, spi_device)
 +spi.max_speed_hz = 1000000
 +# Send a null byte to check for value
 +send_byte = 0x80
 +rcv_byte = spi.xfer2([send_byte])
 +# repeat to check for a response
 +rcv_byte = spi.xfer2([send_byte])
 +data_recv = rcv_byte[0]
 +if (data_recv != 0x80):
 +    print ("Unable to communicate with Arduino "+str(data_recv))
 +    quit()
 +# Data is sent as single bytearray
 +# lower 4 bits = pin number
 +# returns a value that is used to set a digital pin
 +# pin = Arduino pin number
 +# state = True for high, False for low
 +# returns byte or 0xff = invalid
 +def req_set_digital (pin, state):
 +    if (pin < 0 or pin > 10):
 +        return 0xff
 +    if (state == True):
 +        pin += 0x60
 +    else :
 +        pin += 0x20
 +    return pin
 +# read analog pin
 +def req_read_analog (pin):
 +    if (pin < 0 or pin > 5):
 +        return 0xff
 +    return pin + 0x10
 +# read digital pin
 +def req_read_digital (pin):
 +    if (pin < 0 or pin > 10):
 +        return 0xff
 +    return pin
 +while True:
 +    # Turn LEDs on
 +    for i in range (3, 10) :
 +        send_byte = req_set_digital (i, True)
 +        rcv_byte = spi.xfer2([send_byte])
 +        time.sleep (0.5)
 +    # Turn back off again
 +    for i in range (3, 10) :
 +        send_byte = req_set_digital (i, False)
 +        rcv_byte = spi.xfer2([send_byte])
 +        time.sleep (0.5)
 +    # Get status of pin 2
 +    send_byte = req_read_digital(2)
 +    rcv_byte = spi.xfer2([send_byte])
 +    # Delay to allow Arduino to get answer ready
 +    time.sleep (0.25)
 +    # Send null request
 +    send_byte = 0xf0
 +    rcv_byte = spi.xfer2([send_byte])
 +    print ("Value of digital pin 2 is "+str(rcv_byte[0]))
 +
 +    # Get status of analog 0
 +    send_byte = req_read_analog(0)
 +    rcv_byte = spi.xfer2([send_byte])
 +    # Delay to allow Arduino to get answer ready
 +    time.sleep (0.25)
 +    # Send null request
 +    send_byte = 0xf0
 +    rcv_byte = spi.xfer2([send_byte])
 +    print ("Value of A0 is "+str(rcv_byte[0]))
 +</code>
 +
 +====Arduino====
 +<code csharp>
 +#include <SPI.h>
 +// track if digital pins are set as input or output (saves reading registers) 
 +// Pins 0 to 9 can be used, pin 10 can be used for SS (but can be used if that's not required) 
 +bool pin_output[11];
 +void setup() 
 +{
 +  // by default all pins are inputs
 +  for (int i=0; i<11; i++) 
 +  {
 +    pin_output[i] = false;  
 +  }
 +  // Set the Main in Secondary Out as an output
 +  pinMode(MISO, OUTPUT);
 +  // turn on SPI as a secondary
 +  // Set appropriate bit in SPI Control Register
 +  SPCR |= _BV(SPE);
 +}
 +void loop () 
 +{ char print_text [50];
 +  byte in_byte;
 +  // SPIF indicates transmission complete (byte received)
 +  if ((SPSR & (1 << SPIF)) != 0)
 +  {
 +    in_byte = SPDR;
 +    // if no action bit sent then return same 
 +    if (in_byte & 0x80) SPDR = in_byte;
 +    // if write set
 +    else if (in_byte & 0x20) 
 +    {
 +      // set digital pin output - use mask to extract pin and output
 +      if (set_digital_pin (in_byte & 0x0F, in_byte & 0x40) != 0xFF) SPDR = in_byte;
 +    }    
 +    // If value is only pin numbers then digital read
 +    else if (in_byte < 0x10) 
 +    {
 +      byte return_val = read_digital_pin (in_byte);
 +      SPDR = return_val;
 +    }
 +    else if ((in_byte & 0x10) && !(in_byte & 0x20))
 +    {
 +      byte return_val = read_analog_pin (in_byte & 0x0F);
 +      SPDR = return_val;
 +    }
 +    else // Otherwise an error - return 0xff
 +    {
 +      SPDR = 0xFF;
 +    }}}
 +
 +byte set_digital_pin (byte address, bool high_value) 
 +{
 +  if (address < 0 || address > 10) return 0xFF;
 +  // Is it currently set as output - if not then set to output
 +  if (!pin_output[address]) 
 +  {
 +    pinMode(address, OUTPUT);
 +    pin_output[address] = true;
 +  }
 +  // set to low if 0, otherwise 1
 +  if (high_value == 0) digitalWrite(address, LOW);
 +  else digitalWrite (address, HIGH);
 +}
 +
 +// Returns 1 for high and 0 for low
 +// If invalid then returns 0xff
 +byte read_digital_pin (byte address)
 +{
 +  if (address < 0 || address > 10) return 0xFF;
 +  // if currently output then change to input
 +  if (pin_output[address]) 
 +  {
 +    pinMode(address, INPUT);
 +    pin_output[address] = false;
 +  }
 +  return digitalRead (address);
 +}
 +// As full byte is used for value there is no invalid value
 +// If invalid then returns 0x00
 +byte read_analog_pin (byte address)
 +{
 +  if (address < 0 || address > 5) return 0x00;
 +  int analog_val = analogRead (address);
 +  // Analog value is between 0 and 1024 - div by 4 for byte
 +  return (analog_val / 4);
 +}
 +</code>
  
  
 {{tag> communication sb spi }} {{tag> communication sb spi }}
spi_documentation_2.1653916385.txt.gz · Dernière modification : de serge