0

I have a Raspberry Pi 3 sending a string to an Arduino Uno Chinese clone with SPI, and the Arduino writes the received string in its console.

The C software on the master RPi has a while (1) loop that sends the string once every second, and the slave Arduino is supposed to display it in its console everytime it receives the message in its loop() function.

The problem is that the Arduino displays the message only once, instead of writing it every second, or sometimes it displays the message, follower by one or two words made with the letters of the message. I assume the problem comes from the Arduino as the while loop works fine on the RPi.

Could you help me find what's wrong with my code ?

Here a the Arduino code I use, based on a Nick Gammon's example :

#include <SPI.h>

char buf[6];
volatile byte pos;
volatile boolean process_it;

void setup()
{
  Serial.begin(230400);

  SPCR |= bit(SPE);
  pinMode(MISO, OUTPUT);
  pos = 0;
  process_it = false;

  SPI.attachInterrupt();
}

ISR(SPI_STC_vect)
{
  byte c = SPDR;
  if (pos < sizeof(buf))
  {
    buf[pos++] = c;
    if (c == '\n')
    {
      process_it = true;
    }
  }
}

void loop()
{
  int i, c;

  if (process_it == true)
  {
    buf[pos] = 0;
    Serial.println(buf);
    pos = 0;

    process_it = false;
  }
}

And if needed, the C RPi code, using WiringPi :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPiSPI.h>

#define SPI_CHANNEL 0
#define SPI_SPEED   1000000 // Hz.

int main(void)
{
    wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED);
    char buf[6] = {"Hello\n"};
    while (1)
    {
        wiringPiSPIDataRW(SPI_CHANNEL, buf, 6);
        sleep(1);
    }
    return 1;
}

Examples of output :

Hello

Or things like :

Hello

HHello

Edit : interesting results I just got :

Hello

ello
llo
ello
llo
ello
Hello

ello

Perhaps a buffer issue ?

  • Looks ok considering that wiringPiSPIDataRW() will update the buffer with what is received from the Arduino. – Mikael Patel Jul 31 '17 at 13:15
  • But what is received from the Arduino, as I'm not sending anything ? When I try to printf("%d") the data returned by wiringPiSPIDataRW(), the C program runs but doesn't display anything. – Thesaurus Rex Jul 31 '17 at 13:31
  • Normally SPI exchanges the contents of the Slave and Master on ever transaction. But I don't think that is your problem. More likely you are running the SPI too fast and are over writing the Arduino SPI receive register before the Arduino's interrupt can copy the data to the Arduino's buffer. Slow down the SPI by an order of magnitude or more and test again. Specifically, when you task the Arduino to do something (like print to the console), you can't expect it to react quickly with respect to other tasks. Let me know if this works, then I'll copy this to an answer and you can approve it. – st2000 Jul 31 '17 at 14:08
  • It appears that the wiringPiSPIDataRW() function replaces the sent buffer by the received one, char by char, so I displayed the buffer after sending it, and I receive what is written in the Arduino console. @st2000 I modified the frequency, but the issue is still there, even with low frequencies like 100 Hz. :/ Thanks for the help though ! :) – Thesaurus Rex Jul 31 '17 at 14:30
  • The SPI hardware is responsible for swapping the contents of the Master SPI send/receive register with that of the Slave send/receive register. That is the hardware. If the wiringPiSPIDataRW() method is populating the local buffer ("buf") in the RasPi's memory with the received data, then initialize the buffer in side the while(1) loop each time before calling wiringPiSPIDataRW(). – st2000 Jul 31 '17 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.