1

I am working on a project to fetch sensor data from an Arduino with a RPi3B+ board. I use SPI bus to perform the data transmission. Every time when the data in Arduino is ready, Arduino will pull down 5 ms and pull up one pin in RPi3 to trigger an interrupt. In the ISR, a flag is set so that in the main function, RPi starts the SPI transmission procedure. However, I find that the program in RPi3 is not always working, sometimes (or in many cases), the interrupt is not triggered at all so the program just stalls there and does nothing. I have to terminate the program and restart again. Does anyone have experiences with this problem? Or is there a better way to implement this task? Thanks.

The wiring between Arduino and RPi is as this:

Arduino <---> RPi

GND <---> GND

Pin10 <---> Pin24

Pin13 <---> Pin23

Pin12 <---> Pin21

Pin11 <---> Pin19

Pin7 <---> Pin26 (Interrupt triggered by Rising edge)

The main code is as follows:

#define PINISR 26
#define PINCS1 24
#define PINSCK 23
#define PINMOSI 19
#define PINMISO 21
volatile static bool alarmFlag = false;
volatile static bool terminateFlag = false;

//other variables initializations here

static void isr()
{
    alarmFlag = true;
    return;
}

static void terminateHandler(int s)
{
    terminateFlag = true;
    return;
}

int main() 
{
    const struct sched_param priority = { 1 };
    sched_setscheduler(0, SCHED_FIFO, &priority);

    CS1 = mraa_gpio_init(PINCS1);
    mraa_gpio_dir(CS1, MRAA_GPIO_OUT);
    mraa_gpio_write(CS1, 1);
    SCK = mraa_gpio_init(PINSCK);
    mraa_gpio_dir(SCK, MRAA_GPIO_OUT);
    mraa_gpio_write(SCK, 0);
    MOSI = mraa_gpio_init(PINMOSI);
    mraa_gpio_dir(MOSI, MRAA_GPIO_OUT);
    mraa_gpio_write(MOSI, 0);
    MISO = mraa_gpio_init(PINMISO);
    mraa_gpio_dir(MISO, MRAA_GPIO_IN);
    mraa_gpio_read(MISO);

    //set up interrupt
    mraa_gpio_context pin_isr = mraa_gpio_init(PINISR);
    mraa_gpio_dir(pin_isr, MRAA_GPIO_IN);
    mraa_gpio_isr(pin_isr, MRAA_GPIO_EDGE_RISING, &isr,NULL);

    //set ctrl+C handler
    signal(SIGINT, terminateHandler);
    while(!terminateFlag)
    {
        if (alarmFlag)
        {
            printf("enter \n");
            //SPI transmission code here

           alarmFlag = false;
        }
    }
    return MRAA_SUCCESS;
}
  • As a minimum we also need sight of the code to set up the interrupt and clear photos of the wiring. – joan Apr 4 at 14:25
  • Hi @joan , I have added the wiring information to the question. The interrupt is set up with this line mraa_gpio_isr(pin_isr, MRAA_GPIO_EDGE_RISING, &isr,NULL); I choose MRAA library since I am more familiar with it. I also tested with WiringPi library but it didn't trigger an interrupt so I stick to MRAA in the end. The SPI transmission code has been tested in other projects for years and it should work without any problem so I skipped that part for simplicity. – yulius Apr 4 at 15:06
  • I know nothing of the mraa_* software. All I can suggest is don't use pin 26 (GPIO 7) which is CE1 and may well have been taken by the SPI driver. Try another GPIO. – joan Apr 4 at 15:24
  • Hi @joan, thank you for your comment. I have tried other GPIOs and it seems pin 26 works better than other pins. With other pins, some of them do not trigger interrupts at all, some of them only trigger once and then the program stalls there. In my program, the SPI transmission is refering to the code here link, which is self-implemented pure digital read and write code without using any library or driver, so I guess pin 26 is still usable. – yulius Apr 4 at 16:23
  • @joan I am thinking of a workaround that is to write a daemon to monitor the program, if it stalls there for any reason, the daemon will try to terminate it and restart it. do you have any comments on that? thanks! – yulius Apr 4 at 16:23

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.