Go Down

Topic: Communication between Arduino and Raspberry PI (Read 155 times) previous topic - next topic

nimams

Hi,

I would like to make a communication between Arduino Uno or Micro and Raspberry PI. I decided to use SPI, and I have to use SPI.

I have a tested code on Raspberry PI and Arduino. However, for some reason the Arduino does not read anything from the PI.
I have checked all my wires and everything. I'm using a SparkFun logic converter to step up and down the logic.
The Arduino gets activated by PI, but it doesn't make any response. The SPI interrupt never never catch anything, although the TX LED remains ON which means the data are coming in.
I have posted my code below.
Thank you :)

#!/usr/bin/python

import time
import RPi.GPIO as GPIO
import sys
#cspin=8
#datapin= 26
#resetpin= 19
LCD_MOSI = 10   
LCD_CLK = 11
LCD_CS = 8 
LCD_MISO = 9

GPIO.setmode(GPIO.BCM)
GPIO.setup(LCD_CS, GPIO.OUT)
GPIO.setup(LCD_CLK, GPIO.OUT)
GPIO.setup(LCD_MOSI, GPIO.OUT)
GPIO.setup(LCD_MISO, GPIO.IN)
GPIO.output(LCD_CLK, 0)         #SCK=0
GPIO.output(LCD_CS, 1)              #CS=1

def readd ):
    """Send a single byte"""
    if type(d)==type('a'):
        d=ord(d)
    GPIO.output(LCD_CS, 0)              #CS=0
    time.sleep(0.01)
    for i in range(8):
        if d&128 > 0:
            GPIO.output(LCD_MOSI, 1)    #MOSI=1
        else:
            GPIO.output(LCD_MOSI, 0)    #MOSI=0
        d = d<<1
        GPIO.output(LCD_CLK, 0)         #SCK=0
        time.sleep(0.005)
        GPIO.output(LCD_CLK, 1)         #SCK=1
        time.sleep(0.005)
    GPIO.output(LCD_CS, 1)              #CS=1

def dataSeq(t ):
        """Send a data sequence"""
        for i in t:
            read(i)



if __name__ == '__main__':
    try:
        while True:
            time.sleep(5)
            dataSeq('Hi\r')
            print "ADC Result: "
    except KeyboardInterrupt:
        GPIO.cleanup()
        sys.exit(0)


#include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;

void setup (void) {
   Serial.begin (115200);
   pinMode(MISO, OUTPUT); // have to send on master in so it set as output
   SPCR |= _BV(SPE); // turn on SPI in slave mode
   indx = 0; // buffer empty
   process = false;
   SPI.attachInterrupt(); // turn on interrupt
}
ISR (SPI_STC_vect) // SPI interrupt routine
{
  Serial.println ("HI");
   byte c = SPDR; // read byte from SPI Data Register
   if (indx < sizeof buff) {
      buff [indx++] = c; // save data in the next index in the array buff
      if (c == '\r') //check for the end of the word
      process = true;
   }
}

void loop (void) {
   if (process) {
      process = false; //reset the process
      Serial.println (buff); //print the array on serial monitor
      indx= 0; //reset button to zero
   }
}

PaulS

Quote
for i in range(8):
What, exactly, is the range of a smiley face?

Code: [Select]
ISR (SPI_STC_vect) // SPI interrupt routine
{
  Serial.println ("HI");

Do NOT use Serial.print() in an ISR.

Code: [Select]
      Serial.println (buff); //print the array on serial monitor
You can not pass an array to println() unless the array is a string. A string is a NULL terminated array of chars. Your array is NOT a string, because it is NOT NULL terminated.
The art of getting good answers lies in asking good questions.

nimams

Thank you for your reply.
Sorry I didn't realize The code hasn't pasted properly.
Well sorry I haven't used Arduino for a long time. I would like to catch the interrupt. I see what you mean. But do you know what the problem would be?

#!/usr/bin/python

import time
import RPi.GPIO as GPIO
import sys
#cspin=8
#datapin= 26
#resetpin= 19
LCD_MOSI = 10    
LCD_CLK = 11
LCD_CS = 8  
LCD_MISO = 9

GPIO.setmode(GPIO.BCM)
GPIO.setup(LCD_CS, GPIO.OUT)
GPIO.setup(LCD_CLK, GPIO.OUT)
GPIO.setup(LCD_MOSI, GPIO.OUT)
GPIO.setup(LCD_MISO, GPIO.IN)
GPIO.output(LCD_CLK, 0)         #SCK=0
GPIO.output(LCD_CS, 1)              #CS=1

def readAdc( d ):
   "Send a single byte to LCD. To be used by lcdCommand or lcdData"
   if type(d)==type('a'):
       d=ord(d)
   GPIO.output(LCD_CS, 0)              #CS=0
   time.sleep(0.01)
   for i in range( 8 ):
       if d&128 > 0:
           GPIO.output(LCD_MOSI, 1)    #MOSI=1
       else:
           GPIO.output(LCD_MOSI, 0)    #MOSI=0
       d = d<<1
       GPIO.output(LCD_CLK, 0)         #SCK=0
       time.sleep(0.005)
       GPIO.output(LCD_CLK, 1)         #SCK=1
       time.sleep(0.005)
   GPIO.output(LCD_CS, 1)              #CS=1

def dataSeq(t ):
       """Send a data sequence to the LCD"""
       for i in t:
           readAdc(i)



if __name__ == '__main__':
   try:
       while True:
           time.sleep(5)
           dataSeq('Hi\r')
           print "ADC Result: "
   except KeyboardInterrupt:
       GPIO.cleanup()
       sys.exit(0)

nimams

Also just to let you know.
This code full works when I do Arduino to Arduino

SurferTim


nimams

#5
Jun 02, 2017, 05:47 pm Last Edit: Jun 02, 2017, 06:04 pm by nimams
The Raspberry PI is the device Master.
I have looked at the SPDR. I can see it gets full and it remains full. When I do it with Arduino to Arduino, SPDR clears itself after each byte. Could this be due to a logic level converter which doesn't latch properly?
Thank you.

Go Up