gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 16:57:51 27 4
gpt4 key购买 nike

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

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

我在两个平台上都使用 C/C++ 以保持统一。从属代码使用 Arduino IDE 剪辑在一起,主代码基于 Pi 的 BCM2835 SPI 库示例。

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

这是我现在拥有的:

奴隶

/*************************************************************
ARDUINO BREAKER READ/SPI PRE-PROC/TRANSMIT CASES
****************************************************************/

/***************************************************************
Global Variables
***************************************************************/

byte command = 0; //command from PI
byte bytes[4]; //

int sensorVoltage, sensorCurrent; //eventual live reading vars
float Voltage, Current, RealCurrent, RealVoltage, Power;

/***************************************************************
Set Up
-designate arudino as slave
-turn on interrupts
***************************************************************/

void setup (void)
{
//debugging with serial monitor
Serial.begin(9600);

// Set up arduino as slave
pinMode(MOSI, INPUT);
pinMode(SCK, INPUT);
pinMode(SS, INPUT);
pinMode(MISO, OUTPUT);

// turn on SPI in slave mode
SPCR |= _BV(SPE);

// turn on interrupts
SPCR |= _BV(SPIE);

} // end of setup

/*************************************************************
Interrupt Service Routine
************************************************************/

// SPI interrupt routine
ISR (SPI_STC_vect)
{
delay(500); //for errors

// Create union of shared memory space
union
{
float f_var;
unsigned char bytes[4];
} u;

// Overwrite bytes of union with float variable
u.f_var = RealVoltage;

// Assign bytes to input array
memcpy(bytes, u.bytes, 4);

byte c = SPDR;
command = c;

switch (command)
{
// null command zeroes register
case 0:

SPDR = 0;
break;

// case a - d reserved for voltage
case 'a':
SPDR = bytes[3];
break;

// incoming byte, return byte result
case 'b':

SPDR = bytes[2];
break;

// incoming byte, return byte result
case 'c':

SPDR = bytes[1];
break;


// incoming byte, return byte result
case 'd':

SPDR = bytes[0];
break;

/** // case e -h reserved for current
case 'e':

SPDR = amps.b[0];
break;

// incoming byte, return byte result
case 'f':

SPDR = amps.b[1];
break;

// incoming byte, return byte result
case 'g':

SPDR = amps.b[2];
break;

// incoming byte, return byte result
case 'h':

SPDR = amps.b[3];
break;

// case i - l reserved for wattage
case 'i':

SPDR = watts.b[0];
break;

// incoming byte, return byte result
case 'j':

SPDR = watts.b[1];
break;

// incoming byte, return byte result
case 'k':

SPDR = watts.b[2];
break;

// incoming byte, return byte result
case 'l':

SPDR = watts.b[3];
break;**/

} // end of switch

} // end of interrupt service routine (ISR) SPI_STC_vect

/***************************************************************
Loop until slave is enabled by Pi.
****************************************************************/
void loop (void)
{
/*************************************************************
Read and Calculate
****************************************************************/

/**
sensorVoltage = analogRead(A2);
sensorCurrent = analogRead(A3);
Voltage = sensorVoltage*(5.0/1023.0);
Current = sensorCurrent*(5.0/1023.0);
RealCurrent = Current/0.204545;
RealVoltage = (Voltage/0.022005);
Power = RealVoltage*RealCurrent;
**/
RealVoltage = 1.234;
/*************************************************************
Loop Check for SS activation
****************************************************************/

// if SPI not active, clear current command, else preproc floats and pass to SPI
if (digitalRead (SS) == HIGH){
command = 0;
}
/*************************************************************
Debug with serial monitor
****************************************************************/
/*
Serial.print("Byte 3: ");
Serial.println(bytes[3],BIN);
delay(500);
Serial.print("Byte 2: ");
Serial.println(bytes[2],BIN);
delay(500);
Serial.print("Byte 1: ");
Serial.println(bytes[1],BIN);
delay(500);
Serial.print("Byte 0: ");
Serial.println(bytes[0],BIN);
delay(1000);
Serial.println();*/
}

大师

#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;
}

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

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

最佳答案

据猜测,我会说这是发送者和接收者之间的时间问题。尝试查看您正在接收的数据位,看看它们是否向前或向后移动。这可能表明 pi 等待时间太长而无法开始接收,或者等待所有数据的时间不够长。我认为问题可能在于延迟:

delay(500); //for errors

在 Arduino 上,以及

delay(1000); 

在接收器上。你为什么使用这些? 500ms 是让 pi 等待 SPI 数据响应的较长时间。

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

树莓派 github 站点上有一个很好的示例:https://github.com/raspberrypi/linux/blob/rpi-4.4.y/Documentation/spi/spidev_test.c

关于c++ - 从 Arduino 到 Raspberry Pi 的不可靠 SPI 字节数组传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39258593/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com