从Arduino到Raspberry Pi的不可靠SPI字节数组传输

时间:2016-08-31 20:37:42

标签: c++ c arduino spi raspberry-pi3

我正在开发一个项目,该项目从Arduino Pro Mini收集数据并使用SPI将其发送到覆盆子Pi进行存储。

Pro Mini将读取模拟输入并计算电压(一旦完成),并在使用ISR提示时将值传递给Pi。

我在两个平台上使用C / C ++来保持统一。使用Arduino IDE将从代码剪切在一起,并且主代码基于Pi的BCM2835 SPI库示例。

Arduino代码用于计算 float 值并将浮点值预处理为4字节/字符的数组(我正在为二进制文件拍摄,因为我觉得这是最好的方法走)。 一旦Pi提示,每个字节都会被发送并重新编译成浮点数。

以下是我现在所拥有的:

#include <bcm2835.h>
#include <stdio.h>


void setup()
{
    bcm2835_spi_begin();
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_LSBFIRST);      // The default
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);                   // The default
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); // The default
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);      // the default
}

char getByte(const char command){

    char read_data = bcm2835_spi_transfer(command);
    delay(100);
    return read_data;
}

int main(int argc, char **argv)
{
//If you call this, it will not actually access the GPIO
//Use for testing
//bcm2835_set_debug(1);

    if (!bcm2835_init())
        return 1;
    setup();

//Start communication       
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);// Enable 0

    //voltage 1-4  
    char read_data = getByte('a');
    printf("byte is %02d\n", read_data);

    read_data = getByte('b');
    printf("byte is %02d\n", read_data);

    read_data = getByte('c');
    printf("byte is %02d\n", read_data);

    read_data = getByte('d');
    printf("byte is %02d\n", read_data);    

   /** voltage = volts.f;   
    printf("%.6f", voltage);
    printf("\n");
    **/
    delay(1000);   

    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, HIGH);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);// Disable 0
    bcm2835_spi_end();
    bcm2835_close();

    return 0;
}

android:tint

我使用固定值来调试代码。有时,Pi上SPI的输出是准确的,但是否则会改变并输出部分准确和/或随机字节。

我一直无法解决的问题是Pi的稳定性,所以我正在寻找帮助来评估我的代码是否导致不准确或是否是我的硬件。

1 个答案:

答案 0 :(得分:0)

猜测我会说这是发送者和接收者之间的时间问题。尝试查看您正在接收的数据位,看看它们是向前还是向后移动。这可能表明pi等待太长时间才开始接收,或者没有等待足够长的时间来处理所有数据。我认为这些问题可能是由于延误造成的:

delay(500); //for errors

在Arduino上,

delay(1000); 

在接收器上。你为什么用这些?保持pi等待对SPI数据的响应需要500ms。

请注意,现在还有一个用于pi的SPI内核驱动程序(spidev) - 这是一种更加行业标准的方法,并且可能是一种更强大的方法。

在raspberry pi github网站上有一个很好的例子:https://github.com/raspberrypi/linux/blob/rpi-4.4.y/Documentation/spi/spidev_test.c