Ich arbeite an einem Projekt, das Daten von einem Arduino Pro Mini sammelt und es mit SPI zu einem Raspberry Pi für die Speicherung sendet.Unzuverlässige SPI-Byte-Array-Übertragung von Arduino zu Raspberry Pi
Der Pro Mini liest den analogen Eingang und berechnet die Spannung (sobald ich fertig bin) und übergibt Werte an den Pi, wenn er mit einem ISR dazu aufgefordert wird.
Ich verwende C/C++ für beide Plattformen, um es einheitlich zu halten. Der Slave-Code wird mithilfe der Arduino-IDE zusammengeschnitten und der Master-Code basiert auf einem BCM2835-SPI-Bibliotheksbeispiel für das Pi.
Arduino-Code soll einen float Wert berechnen und den Float-Wert in ein Array von 4 Bytes/Zeichen vorverarbeiten (Ich bin für binäre Dreharbeiten, weil ich denke, es ist der beste Weg zu gehen). Sobald vom Pi aufgefordert, wird jedes Byte gesendet und in einem Float neu kompiliert.
Hier ist, was ich habe jetzt:
Slave
/*************************************************************
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();*/
}
Meister
#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;
}
ich einen festen Wert mit dem Code zu debuggen. Manchmal ist die Ausgabe von SPI auf dem Pi genau, aber ansonsten ändert sie sich und gibt teilweise genaue und/oder zufällige Bytes aus.
Das Problem, das ich nicht ausarbeiten konnte, ist Stabilität auf der Seite des Pi, also suche ich nach Hilfe, ob mein Code Ungenauigkeiten verursacht oder ob es meine Hardware ist.
Dank für Ihre Antwort js441. Ich wechselte zu python mit spiDev, weil es viel einfacher ist. Lassen Sie mich Sie fragen, glauben Sie, dass Python über C in Bezug auf den Industriestandard gleichermaßen akzeptabel ist? – giri
@giri Das ist eine schwierige Frage zu beantworten. Beide werden in der Industrie verwendet, es geht eher darum, was für Sie funktioniert. Wenn Sie eine gültige Arbeitslösung in einer Sprache einfacher als die andere machen können, dann ist das die Sprache für Sie. – js441