Raspberry Pi + Arduino + SPI

  

This tutorial will show you how to communicate from your raspberry pi to your arduino using 3-wire SPI.

Requirements

  • 1 Raspberry pi (running Raspbian)
  • 1 Arduino
  • 4 wires

Your raspberry pi should be running the newest version of Raspbian.  To ensure your system is up-to-date please download and run rpi-update.

Wiring

 

Arduino

Open your Arduino ide and flash the below code to your Arduino.

Arduino code

Raspberry Pi

With your updated rasbian system you should have the drivers that you need. Now it’s time to load them.

modprobe spi_bcm2708
modprobe spidev

Check to be sure the modules loaded:

lsmod
Module Size Used by
spidev 5944 0
spi_bcm2708 5350 0
snd_bcm2835 21681 0
snd_pcm 81170 1 snd_bcm2835
snd_seq 59528 0
snd_timer 21602 2 snd_seq,snd_pcm
snd_seq_device 6924 1 snd_seq
snd 57427 5 snd_seq_device,snd_timer,snd_seq,snd_pcm,snd_bcm2835
snd_page_alloc 5343 1 snd_pcm
i2c_bcm2708 3822 0

Raspberry Pi Code

Save the below code as spidev_test.c on to your Raspberry Pi and compile it

gcc spidev_test.c -o spidev_test

Running

Plug your Arduino to your desktop via the serial cable. Open the arduino Serial Monitor and set the bitrate to 115200. Now, on the Raspberry Pi, run the compiled code

sudo ./spidev_test

You should see HELLO WORLD print in the Arduino IDE Serial Monitor.

Debugging

    • Make sure that your kernel has the required drivers (spi-bcm2708.ko and spidev.ko)

pi@raspberrypi ~/spi $ ls -al /lib/modules/`uname -r`/kernel/drivers/spi/
total 64
drwxrwxr-x 2 pi pi 4096 Aug 10 10:53 .
drwxrwxr-x 23 pi pi 4096 Aug 10 10:53 ..
-rw-rw-r– 1 pi pi 14428 Aug 10 10:53 spi-bcm2708.ko
-rw-rw-r– 1 pi pi 10852 Aug 10 10:53 spi-bitbang.ko
-rw-rw-r– 1 pi pi 15803 Aug 10 10:53 spidev.ko
-rw-rw-r– 1 pi pi 10693 Aug 10 10:53 spi-gpio.ko

Thanks to Nick Gammon for the SPI slave code.

Thanks to Anton Vorontsov for the kernel Documentation spidev_test.c example code.

 

38 Comments

  1. Wow, can the 3.3V RPi tolerate the 5V TTL levels of the Arduino?

  2. It might work only because the example doesn’t send any information from the Arduino back to the Pi and thus putting 5v on the Pi input pin.

  3. First of all thank you for sharing this code!

    I am new in this, and i would like to know how can the arduino send back the data received to the raspberry.

    Thanks!

  4. Maybe a bus switch from 5V to 3.3V could be useful in order to avoid harming the Raspberry Pi. Something like this: http://www.ti.com/lit/ds/symlink/sn74cbtd3384c.pdf

  5. It would be interesting to learn how the spi-kernel-driver might be used to
    read an SPI ADC (e.g. ADS1100). Additionally this would be more save for the hardware, because this ADC works on 2.7 to 5.5V. Where to find more documentation and/or examples using this kernel-driver ? Thank you!

  6. venkatesh

    im beginner doing spi interface. i tried with above code to start learning. i connected wires as described but i got o/p “can’t able open device”. one thing which is different from above of mine is the broadcom pheripheral mine is BCM2835. is there any change in the code for my bcm. and one more thing spi may be blacklisted when i google for solution how to unlock them. and not able to find spidev under dev. how to resolve it?

    • You can observe the blacklisting or not of the spi drivers by following the guide above. Specifically, the lsmod section. Don’t think of blacklisting a driver as locking but rather as a convenience mechanism for specifying that a driver not be loaded when the distribution starts up for one reason or another.

      After you have verified the driver is loaded ensure that the driver created the device nodes. Specifically /dev/spidev0.0

      Let me know if you have further problems.

      • venkatesh

        when i try lsmod, i cant find spidev0.0 how to load it. please guide me. for lsmod i got this

        Module Size Used by
        evdev 8682 4
        joydev 9102 0
        snd_bcm2835 12808 0
        snd_pcm 74834 1 snd_bcm2835
        snd_seq 52536 0
        snd_timer 19698 2 snd_seq,snd_pcm
        snd_seq_device 6300 1 snd_seq
        snd 52489 5 snd_seq_device,snd_timer,snd_seq,snd_pcm,snd_bcm2835
        snd_page_alloc 4951 1 snd_pcm

        • venkatesh

          now i got spi enabled

          Module Size Used by
          snd_bcm2835 12808 0
          snd_pcm 74834 1 snd_bcm2835
          snd_seq 52536 0
          snd_timer 19698 2 snd_seq,snd_pcm
          snd_seq_device 6300 1 snd_seq
          snd 52489 5 snd_seq_device,snd_timer,snd_seq,snd_pcm,snd_bcm2835
          snd_page_alloc 4951 1 snd_pcm
          spidev 5136 0
          evdev 8682 4
          joydev 9102 0
          spi_bcm2708 4401 0

          and in ls /dev/spi*

          /dev/spidev0.0 /dev/spidev0.1

          now im getting output
          “can’t open device : permission denied”

          • Try prepending the command you are running with sudo. For example if you are running the command ‘ls’ try ‘sudo ls’.

          • venkatesh

            had u wrote code for receiving data from arduino?

        • how did u get spi enabled? when i am trying to install spi_bcm2708 i am getting “unable locate package spi_bcm2708″… please guide me..

  7. Arduino example spi receiver code is included in The above tutorial.

    • venkatesh

      two things i want to clarify with you. im sending command byte 0xFE from rpi after its received in arduino im sending {0xAA,0xAB,0xAC} from arduino

      1. while transmitting a buffer why its necessary to add 0x0A at the end of the buffer (arduino) when i look at serial monitor it shows 0xAA,0xAB,0xAC “0x0A” 0xAA,0xAB,0xAC if 0x0A is added it sendinding as 0xAA,0x0A,0xAB,0x0A.

      2.while receiving in rpi, each received byte in sent buffer follwed by command byte(0xFE) for 9 times. eg: if im receiving in rpi as 0xAA 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xAB…….

  8. I am pretty new to pro­gram­ming. I have a device which I want to con­nect to the RPi using SPI. I tried out the spi_devtest.c and it works. But the SPI frame of the slave device requires 24 bits. I have searched high and low and have not been able to find a solu­tion. I tried chang­ing the num­ber of bits per word but that does not work. I won­der if I would have to just send 3 bytes instead of 24 bits. In that case, I don’t know how to send 3 bytes with­out the chip select going inac­tive after each word. Any help would be greatly appreciated.

    • nevermind. i figured it out. thanks anyways :)

      • pi-ray

        TT or anyone. I have the same issue of requiring 24 bits without raising syncb. Do tell how you “figured it out”. Wondering if I can use a different gpio bit and create and control my own sincb, but this seems ugly.

        • Sorry for taking so long to respond, I ended up just sending 3 8bit words. I don’t know if there’s any other way to do it, or if there exists a better way.

  9. venkatesh

    why the byte being returned back to rpi which sent to arduino? is any voltage converter required?

  10. Hey,

    I have some errors while compiling the RasPi code..

    They are:
    pi@raspberrypi ~ $ gcc spidev_test.c -o spidev_test
    spidev_test.c:234:13: error: redefinition of ‘pabort’
    spidev_test.c:26:13: note: previous definition of ‘pabort’ was here
    spidev_test.c:240:20: error: redefinition of ‘device’
    spidev_test.c:32:20: note: previous definition of ‘device’ was here
    spidev_test.c:242:16: error: redefinition of ‘bits’
    spidev_test.c:34:16: note: previous definition of ‘bits’ was here
    spidev_test.c:243:17: error: redefinition of ‘speed’
    spidev_test.c:35:17: note: previous definition of ‘speed’ was here
    spidev_test.c:246:13: error: redefinition of ‘transfer’
    spidev_test.c:38:13: note: previous definition of ‘transfer’ was here
    spidev_test.c:279:13: error: redefinition of ‘print_usage’
    spidev_test.c:71:13: note: previous definition of ‘print_usage’ was here
    spidev_test.c:295:13: error: redefinition of ‘parse_opts’
    spidev_test.c:87:13: note: previous definition of ‘parse_opts’ was here
    spidev_test.c:364:5: error: redefinition of ‘main’

    I got the /dev/spidev0.0 and spidev0.1. The RasPi is updated and everything is ok, except the “pi@raspberrypi ~/spi $ ls -al /lib/modules/`uname -r`/kernel/drivers/spi/” part, where I only get: “total 64″.

    Please, help:)

  11. Hello,
    Great tuto, just may be asking a stupid question but there is no wire with CE0 ou CE1 between the Arduino and the PI, does the arduino hardware SPI work even if the Chip Enable pin is floating ?
    Thanks

  12. this shows great potential for fast raspi to arduino transfers! what is the fastest this can work?

  13. I get this error: spi_slave.ino: In function ‘void setup()’:
    spi_slave:24: error: ‘SPCR’ was not declared in this scope
    spi_slave:24: error: ‘SPE’ was not declared in this scope
    spi_slave:24: error: ‘_BV’ was not declared in this scope
    spi_slave.ino: In function ‘void SPI_STC_vect()’:
    spi_slave:39: error: ‘SPDR’ was not declared in this scope
    Does anyone know what could be the problem and/or know how to fix this? I’m using this code with the arduino due

  14. when i am running this code i am getting output as “cant open device” in the raspberry pi terminal.. please help me..

  15. when i am trying to run the raspberry pi code iam getting the error ‘cant open the device’. please guide me…

  16. Hi, awesome job here!! I got this working nicely. I am working on a new pi project that is coded in C++ and I am having issues integrating. I’ve tried linking the the above pi C code to my C++ code but get “undefined reference” to the C function (from pi code). Can anyone help convert the above Raspberry Pi code into C++? It will be greatly appreciated! Thank You

  17. Hello,
    I’m looking to do this exact some thing (use SPI between a Pi and an Arduino). But something might’ve happened to this post. The Arduino code seems to have gone missing from this post. If someone could repost this, I’d appreciate it.

  18. How to convert hello word to the uint8_t . I’m planning to mod spidev_test to send data in argument

  19. Just have got it running on an AlaMode Board from wyolum. One note:
    Pull the SS input (Arduino Pin 10) input down to ground by some jumper.

Trackbacks/Pingbacks

  1. Raspberry Piの資料リンク集 « nanoblog - [...] How to use your Raspberry Pi like an Arduino | Limina.Log Raspberry PiとArduinoがSPI通信 Raspberry Pi + Arduino + …
  2. The Great Raspberry Pi Post | Jason Raimondi - [...] Raspberry Pi + Arduino + SPI http://mitchtech.net/raspberry-pi-arduino-spi/ [...]
  3. SPI-Python: Hardware SPI for RasPi | Louis Thiery - [...] things up as shown on MitchTech and upload the sample Arduino sketch from Github. Make sure spi.so is locally …
  4. RaspberryPI: un po di link utili - [...] pi + arduino http://mitchtech.net/raspberry-pi-arduino-spi/ gertboard http://www.raspberrypi.org/archives/tag/gertboardworking WIFI USB DONGLE Tp-Link [...]
  5. 手把手教你树莓派与Arduino Uno的对接(USB及GPIO方式) | 木子目詹 - [...] 参考资料 (USB对接)http://blog.oscarliang.net/conne … -arduino-usb-cable/ (I2C对接)http://blog.oscarliang.net/raspberry-pi-arduino-connected-i2c/ (GPIO对接)http://blog.oscarliang.net/raspb … nected-serial-gpio/ (SPI对接)http://mitchtech.net/raspberry-pi-arduino-spi/ [...]

Leave a Reply