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

Prochaine révision
Révision précédente
spi_documentation_2 [2022/05/30 13:10] – créée 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>
  
-{{tag>sb spi communication}}+=====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 }}
spi_documentation_2.1653916242.txt.gz · Dernière modification : de serge