====== Communication entre Raspberry Pi et Arduino en SPI ====== **{{tagpage>spi|Toutes les pages sur protocol SPI}}** =====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 #include 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 () { } **Raspberry Pi avec wiringPi** #include #include #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; } 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==== 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])) ====Arduino==== #include // 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); } {{tag> communication sb spi }}