Wenn am Anfang und / oder am Ende der Übertragung Raspi<>AVR Murks ankommt, in der Mitte der Übertragung die Daten jedoch komplett sind, hilft als Workaround auch ein eigenes Protokoll. Z.B. Zum Start mehrmals ein CHR(
senden, welche die Gegenstelle immer als "Jetzt kommen neue Daten" versteht und am Ende der Übertragung ein CHR(9) und der Empfänger weiß dann: Datensatz vollständig und verarbeitet diesen und ignoriert alles, bis zum nächsten CHR(
.
Messwerte müssten dann halt z.B. als String übertragen werden.
Z.B. so (nicht getesteter angepasster Code meiner Empfangsroutine):
Code:
// Compile with: GCC /var/scripte/empfangen.c -o /var/scripte/empfangen
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#define BAUDRATE B19200
char MODEMDEVICE[]= "/dev/ttyAMA0"; // Schnittstelle
char eingang[255]=""; //Empfangenes
int anzahl=0; //Anzahl Einträge in der Senderliste
int laenge=0; //Anzahl empfangener Zeichen
int fd; // UART File descriptor
struct termios newtio={};
char WEBDEVICE[]="/tmp/webif.daten"; //Datei, wo die Empfangenen Daten abgespeichert werden, um sie dann per php auszulesen
unsigned char eingangleer() //Eingang nullen
{
int i;
for(i=0; i < laenge; i++){
eingang[i] = 0;
}
strcpy(eingang,"");
laenge==0;
c=0;
}
unsigned char receive() //Zeichen empfangen
{
int res;
unsigned char buffer;
res = read(fd, &buffer, 1);
return buffer;
}
unsigned char auswerten()
{ int fd1;
char ret;
if ((strcmp(eingang,"resetreset") ==0 )){
system("reboot");
}else{
/* Zum Schreiben öffnen */
if (laenge > 0){ // F
fd1 = open (WEBDEVICE, O_WRONLY|O_CREAT|O_TRUNC); //|O_TRUNC, S_IRUSR|S_IWUSR
if (fd1 == -1)
exit (-1);
write (fd1, eingang, laenge);
close (fd1);
system("chmod 644 /tmp/webif.daten");
}
}
}
int init()
{
/*** Init ***/
//O_RDONLY, O_WRONLY or O_RDWR -
//O_NDELAY (geht weiter, wenn keine Daten da sind und gibt "-1" zurueck)
// man 2 open fuer mehr Infos - see "man 2 open" for more info
// O_NOCTTY No ControllTeleType
/*fd1 = open(FILEDEVICE, O_WRONLY);
if (fd1 < 0){
printf("Fehler beim oeffnen von %s\n", FILEDEVICE);
exit(-1);
}*/
fd = open(MODEMDEVICE, O_RDONLY | O_NOCTTY);
if (fd < 0){
printf("Fehler beim oeffnen von %s\n", MODEMDEVICE);
exit(-1);
}
memset(&newtio, 0, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; //setzt die neuen Porteinstellungen
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0; /* set input mode (non-canonical, no echo, ...) */
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = 1; /* blocking read until 1 chars received */
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
return fd;
}
int main(int argc, char** argv)
{
char c;
int empfang=0;
init();
while (1)
{
c=receive();
if(c==8){ //Init-Zeichen >> Neuer Befehl trifft ein
strcpy(eingang,"");
eingangleer();
empfang=1;
}
if (empfang==1){
if((c==9)){ //Ende-Zeichen >> Datensatz fertig >> Auswerten
auswerten();
empfang=0;
eingangleer();
}else if(c>13&&c<128&&laenge<255){ //Keine Sonderzeichen nur ASCII Standard
eingang[laenge]=c; //empfangenes Zeichen anhängen
laenge++;
}
}
}
close (fd);
return 0;
}
Den Gegenpart Raspi>>AVR kann man genauso lösen. Da weiß ich aber nicht, welche Programmiersprache du nutzt.
Lesezeichen