Bonjour !
Quelques nouvelles : les communications I2C et série ont été éliminées, preuves à l'appui ; l'Ethernet également à cause d'un manque de fiabilité du shield fourni (marche, marche pas, marche, marche pas, etc.), donc de retour en SPI.
Dans un premier temps, je suis reparti de zéro avec un petit soft simple : j'envoie un mot, j'en reçois un autre ; j'ai choisi d'envoyer "Hello" et de recevoir "World", pas très original, mais les mots possèdent 5 caractères chacun, donc bien pratique pour du SPI.
J'ai un soft en C sur le RPi qui utilise WiringPi :
Code : Tout sélectionner
#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);
while (1)
{
char buf[5] = {'H', 'e', 'l', 'l', 'o'};
printf("Sending : %s\n", buf); // Censé afficher "Hello".
wiringPiSPIDataRW(SPI_CHANNEL, buf, 5);
printf("Receiving : %s\n\n", buf); // Censé afficher "World".
sleep(1);
}
return 1;
}
Et le soft Arduino :
Code : Tout sélectionner
#include <SPI.h>
char receivingBuffer[5];
char sendingBuffer[5] = {'W', 'o', 'r', 'l', 'd'};
volatile char bytes_received = 0;
volatile boolean process_it = false;
void setup()
{
Serial.begin(230400);
SPCR |= bit(SPE);
pinMode(MISO, OUTPUT);
SPI.attachInterrupt();
SPDR = sendingBuffer[bytes_received];
}
ISR(SPI_STC_vect)
{
receivingBuffer[bytes_received] = SPDR;
if (++bytes_received == 5)
{
bytes_received = 0;
process_it = true;
}
SPDR = sendingBuffer[bytes_received];
}
void loop()
{
int i, c;
if (process_it == true)
{
receivingBuffer[bytes_received] = 0;
Serial.print("Receiving : ");
Serial.println(receivingBuffer); // Censé afficher "Hello".
Serial.print("Sending : ");
Serial.println(sendingBuffer); // Censé afficher "World".
bytes_received = 0;
process_it = false;
}
}
Ce code Arduino est basé sur
une question posée sur Stack Exchange.
Comme spécifié par mes commentaires, je souhaite envoyer "Hello" à l'Arduino, tandis que celui-ci me répond "World". J'ai compris comment fonctionnait la fonction
wiringPiSPIDataRW(), à envoyer le contenu d'un tableau tout en recevant le contenu d'un autre, et de les permuter index par index (je m'acharnais à tenter d'utiliser sa valeur de retour...).
Avec ce code en l'état, j'envoie "Hello" et le reçoit sur l'Arduino, mais alors que je pense renvoyer "World", c'est "WHell" qui revient sur le RPi.
Auriez-vous une indication sur la provenance de ce curieux résultat ?
Je poste ici pour rester dans mon sujet sur le SPI et ne pas trop m'éparpiller, mais je reconnais que c'est peut-être plutôt un problème de code, donc dites-moi si je dois poster ailleurs !
C'est peut-être aussi un problème d'Arduino, mais comme je pense que le problème vient de mon algo, on reste dans du C. Pareil, je posterai ailleurs si ça n'a pas sa place ici !
EDIT : passer la fréquence du SPI de 1 000 000 Hz à 100 000 Hz corrige le souci. Reste à voir si je peux trouver une fréquence entre ces deux valeurs qui me permettra de transférer mes données dans le temps imparti !
A ce propos, j'ai calculé qu'il me fallait un débit de transfert d'au moins 524 288 bit/s pour tout transférer en temps et en heure ; pourriez-vous m'aiguiller sur une correspondance bit/s <-> Hz afin que je puisse choisir une fréquence de SPI suffisante ? Pour l'instant je suppose que c'est comme pour l'I2C, avec 1 Hz = 1 kbit/s.