Outils pour utilisateurs

Outils du site


spi_documentation_2

Ceci est une ancienne révision du document !


Table des matières

Communication entre Raspberry Pi et Arduino en SPI

Qui ne marche pas

Raspberry

  1. import spidev
  2. import time
  3. spi_bus = 0
  4. spi_device = 0
  5. spi = spidev.SpiDev()
  6. spi.open(spi_bus, spi_device)
  7. spi.max_speed_hz = 1000000
  8. # Send a null byte to check for value
  9. send_byte = 0x80
  10. rcv_byte = spi.xfer2([send_byte])
  11. # repeat to check for a response
  12. rcv_byte = spi.xfer2([send_byte])
  13. data_recv = rcv_byte[0]
  14. if (data_recv != 0x80):
  15. print ("Unable to communicate with Arduino "+str(data_recv))
  16. quit()
  17. # Data is sent as single bytearray
  18. # lower 4 bits = pin number
  19. # returns a value that is used to set a digital pin
  20. # pin = Arduino pin number
  21. # state = True for high, False for low
  22. # returns byte or 0xff = invalid
  23. def req_set_digital (pin, state):
  24. if (pin < 0 or pin > 10):
  25. return 0xff
  26. if (state == True):
  27. pin += 0x60
  28. else :
  29. pin += 0x20
  30. return pin
  31. # read analog pin
  32. def req_read_analog (pin):
  33. if (pin < 0 or pin > 5):
  34. return 0xff
  35. return pin + 0x10
  36. # read digital pin
  37. def req_read_digital (pin):
  38. if (pin < 0 or pin > 10):
  39. return 0xff
  40. return pin
  41. while True:
  42. # Turn LEDs on
  43. for i in range (3, 10) :
  44. send_byte = req_set_digital (i, True)
  45. rcv_byte = spi.xfer2([send_byte])
  46. time.sleep (0.5)
  47. # Turn back off again
  48. for i in range (3, 10) :
  49. send_byte = req_set_digital (i, False)
  50. rcv_byte = spi.xfer2([send_byte])
  51. time.sleep (0.5)
  52. # Get status of pin 2
  53. send_byte = req_read_digital(2)
  54. rcv_byte = spi.xfer2([send_byte])
  55. # Delay to allow Arduino to get answer ready
  56. time.sleep (0.25)
  57. # Send null request
  58. send_byte = 0xf0
  59. rcv_byte = spi.xfer2([send_byte])
  60. print ("Value of digital pin 2 is "+str(rcv_byte[0]))
  61.  
  62. # Get status of analog 0
  63. send_byte = req_read_analog(0)
  64. rcv_byte = spi.xfer2([send_byte])
  65. # Delay to allow Arduino to get answer ready
  66. time.sleep (0.25)
  67. # Send null request
  68. send_byte = 0xf0
  69. rcv_byte = spi.xfer2([send_byte])
  70. print ("Value of A0 is "+str(rcv_byte[0]))

Arduino

  1. #include <SPI.h>
  2. // track if digital pins are set as input or output (saves reading registers)
  3. // Pins 0 to 9 can be used, pin 10 can be used for SS (but can be used if that's not required)
  4. bool pin_output[11];
  5. void setup()
  6. {
  7. // by default all pins are inputs
  8. for (int i=0; i<11; i++)
  9. {
  10. pin_output[i] = false;
  11. }
  12. // Set the Main in Secondary Out as an output
  13. pinMode(MISO, OUTPUT);
  14. // turn on SPI as a secondary
  15. // Set appropriate bit in SPI Control Register
  16. SPCR |= _BV(SPE);
  17. }
  18. void loop ()
  19. { char print_text [50];
  20. byte in_byte;
  21. // SPIF indicates transmission complete (byte received)
  22. if ((SPSR & (1 << SPIF)) != 0)
  23. {
  24. in_byte = SPDR;
  25. // if no action bit sent then return same
  26. if (in_byte & 0x80) SPDR = in_byte;
  27. // if write set
  28. else if (in_byte & 0x20)
  29. {
  30. // set digital pin output - use mask to extract pin and output
  31. if (set_digital_pin (in_byte & 0x0F, in_byte & 0x40) != 0xFF) SPDR = in_byte;
  32. }
  33. // If value is only pin numbers then digital read
  34. else if (in_byte < 0x10)
  35. {
  36. byte return_val = read_digital_pin (in_byte);
  37. SPDR = return_val;
  38. }
  39. else if ((in_byte & 0x10) && !(in_byte & 0x20))
  40. {
  41. byte return_val = read_analog_pin (in_byte & 0x0F);
  42. SPDR = return_val;
  43. }
  44. else // Otherwise an error - return 0xff
  45. {
  46. SPDR = 0xFF;
  47. }}}
  48.  
  49. byte set_digital_pin (byte address, bool high_value)
  50. {
  51. if (address < 0 || address > 10) return 0xFF;
  52. // Is it currently set as output - if not then set to output
  53. if (!pin_output[address])
  54. {
  55. pinMode(address, OUTPUT);
  56. pin_output[address] = true;
  57. }
  58. // set to low if 0, otherwise 1
  59. if (high_value == 0) digitalWrite(address, LOW);
  60. else digitalWrite (address, HIGH);
  61. }
  62.  
  63. // Returns 1 for high and 0 for low
  64. // If invalid then returns 0xff
  65. byte read_digital_pin (byte address)
  66. {
  67. if (address < 0 || address > 10) return 0xFF;
  68. // if currently output then change to input
  69. if (pin_output[address])
  70. {
  71. pinMode(address, INPUT);
  72. pin_output[address] = false;
  73. }
  74. return digitalRead (address);
  75. }
  76. // As full byte is used for value there is no invalid value
  77. // If invalid then returns 0x00
  78. byte read_analog_pin (byte address)
  79. {
  80. if (address < 0 || address > 5) return 0x00;
  81. int analog_val = analogRead (address);
  82. // Analog value is between 0 and 1024 - div by 4 for byte
  83. return (analog_val / 4);
  84. }
spi_documentation_2.1653924795.txt.gz · Dernière modification : de serge