====== 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 }}