comunicazione seriale arcuino C++

ciao a tutti sono nuovo dell’ambiente arduino e avrei alcune domande.

sto facendo un programma in c++ che legge valori inviati dall’arduino via seriale.
il problema è che a volte sembra che il programma scritto in c++ non risece a sincronizzarsi con l’arduino, quindi non risce a prendere il carattere che mi dice di iniziare a memorizzare("|") e resta all’interno del while di lettura da seriale all’infinito.
qualcuno di voi mi sa dire come fare o eventualmente se sbaglio qualcosa nell’impostazione della comunicazione??
in pratica l’arduino mi butta su seriale il valore che voglio leggere(somma) più il CRC(mC) che mi serve poi per verificare che il dato inviato sia corretto.
in c leggo da seriale, quando leggo una stringa che può esserre corretta faccio il controllo sul CRC, se va bene la salvo in un file, se va male la salvo cmq ma salvo anche la scritta NO. il problema è che se non riesce a leggere correttamente da seriale e non vede l’inizio della registrazione non esce più.

codice C++

// My_serial.cpp : Defines the entry point for the console application.
//
//#include “stdafx.h”
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include “crc.h”

FILE *stream, *fopen();

BOOL setComm(HANDLE hComm)
{
DCB dcb;
BOOL res;

FillMemory(&dcb, sizeof(dcb), 0);
res = GetCommState(hComm, &dcb); // get current DCB
if (!res)
// Error in GetCommState
return FALSE;
printf("\nBaudRate %d ByteSize %d StopBits %d\n", dcb.BaudRate, dcb.ByteSize, dcb.StopBits);
// Update DCB rate.
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.BaudRate = CBR_9600;
dcb.Parity =NOPARITY;// none
dcb.fAbortOnError = 0; // no abort

// Set new state.
res = SetCommState(hComm, &dcb);

// Error in SetCommState. Possibly a problem with the communications
// port handle or a problem with the DCB structure itself.
if (!res)
return FALSE;

DWORD err = GetLastError();
if ( err)
printf("\n ERROR % d\n", err);

return TRUE;
}
void state(HANDLE hComm)
{
DCB dcb;
BOOL res;

FillMemory(&dcb, sizeof(dcb), 0);
res = GetCommState(hComm, &dcb); // get current DCB

DWORD err = GetLastError();
if ( err)
printf("\n receive ERROR % d\n", err);

SetLastError(0);
}
BOOL write(HANDLE hComm, char * buf)
{
DWORD nNumberOfBytesToWrite = strlen(buf);
DWORD NumberOfBytesWritten;
LPOVERLAPPED lpOverlapped = NULL;
BOOL res = WriteFile(
hComm, // handle to file to write to
buf, // pointer to data to write to file
nNumberOfBytesToWrite, // number of bytes to write
&NumberOfBytesWritten, // pointer to number of bytes written
lpOverlapped // pointer to structure for overlapped I/O
);
if (res)
printf("\nwrite OK\n");
else
{
DWORD err = GetLastError();
printf("\nwrite ERROR %d \n", err);
}
return res;
}
int main(int argc, char* argv)
{
stream=fopen(“prova.txt”,“w”);

if ((stream = fopen (“prova.txt”,“w”)) == NULL)
{
printf(“non posso aprire il file %s\n”, “prova.txt”);
}
printf(“Hello World!\n”);
char gszPort = “COM6”;

HANDLE hComm;
hComm = CreateFile( gszPort,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0, // NO ! FILE_FLAG_OVERLAPPED,
0);

if (hComm == INVALID_HANDLE_VALUE)
{
printf(“error opening\n”);
// error opening port; abort
}

else

{
// write(hComm,“r”);

char c;
DWORD nNumberOfBytesToRead = 1;
DWORD NumberOfBytesRead=0;
LPOVERLAPPED lpOverlapped = NULL; // pointer to structure for data
BOOL bResult;

bResult = setComm(hComm);

int ho=0;
const int LUNG_MAX = 30; //definisco la lunghezza massima della stringa in cui memorizzo i valori
int ax = 0, ay = 0; //posizione x e y del touch
char str[LUNG_MAX]; //stringa in cui memorizzo il buffer della x e y
char buff[5];
int count=0; //definisco un contatore
int yu=0; //variabile di controllo di uscita dal ciclo della seriale
int i=0, j = 0;

int rec = 0; //variabile di controllo che mi dice se iniziare a memorizzare la stringa

for(ho=0;ho<20000;ho++){

//state(hComm);
ax = 0;
ay = 0;
yu = 0;
i = 0;
j = 0;
rec = 0;
buff[0]=’\0’;
str[0] = ‘\0’; //inizializzo la stringa di memorizzazione dei dati della seriale
do
{
nNumberOfBytesToRead = 1;
bResult = ReadFile(
hComm,// handle of file to read
&c,// pointer to buffer that receives data
nNumberOfBytesToRead,// number of bytes to read
&NumberOfBytesRead,// pointer to number of bytes read
lpOverlapped// pointer to structure for data
);

////////////////// stampo il carattere letto dal buffer che punta alla seriale//////////////////////
printf(“Ciclo %d\n”, j++);
printf(“leggo ASCII :%i\n”,c);
printf(“leggo ESA :%c\n”,c);

if(c == ‘|’) { //se leggo | inizio a memorizzare i valori nella stringa
rec = 1;
}
// Ricostruisco a stringa
if(rec == 1 && i < LUNG_MAX)
{ //se sono i rec e non ho riempito oltre il limite la stringa str
if(c == ‘|’) {}
else if(c != ‘<’)
{ //se non leggo il carattere \r copio nella stringa il carattere letto da seriale
str[i++] = c;
printf(“memorizzo %c”,c);
}
else
{ //se ho letto \r metto il terminatore di stringa in fondo a str perchè ho letto tutto quello che mi serve
str*= ‘\0’;*

  • printf(“esciiiiiiii”);*
  • yu++; //incremento yu e quindi esco dal ciclo do*
  • }*
  • }*
  • if (i>LUNG_MAX || yu==1)*
  • {*
  • sscanf(str ,"%d\t%d", &ax, &ay); //trasformo la stringa nelle coordinate x e y e le memorizzo*
  • printf(“Memorizzo: ax = %d; ay = %d \n”, ax, ay);*
  • itoa(ax,buff,16);*
  • printf(“The check value for the %s standard is 0x%X\n”, CRC_NAME, CHECK_VALUE);*
  • crcInit();*
  • printf(“The crcFast() of %i is %u, 0x%X\n”,ax, ay, crcFast(buff, strlen(buff)));*
  • if(crcFast(buff, strlen(buff))==ay)fprintf(stream,“ciclo = %i ok somma = %i CRC_arduino = 0x%X CRC_calc = 0x%X%\n”,ho,ax,ay,crcFast(buff, strlen(buff)));*
  • else*
  • {*
  • if(crcFast(buff, strlen(buff))==ay)fprintf(stream,“ciclo = %i NO somma = %i CRC_arduino = 0x%X CRC_calc = 0x%X%\n”,ho,ax,ay,crcFast(buff, strlen(buff)));*
  • yu=0;*
  • }*
  • rec = 0;*
  • str[0]=’\0’;*
  • i = 0;*
  • j=0;*
  • }*
  • if (j>200)*
  • {*
  • CloseHandle(hComm); //chiudo la seriale*
  • hComm = CreateFile( gszPort,*
  • GENERIC_READ | GENERIC_WRITE,*
  • 0,*
  • 0,*
  • OPEN_EXISTING,*
  • 0, // NO ! FILE_FLAG_OVERLAPPED,*
  • 0);*
  • rec = 0;*
  • str[0]=’\0’;*
  • i = 0;*
  • j=0;*
  • }*
  • printf(“rec := %i”,rec);*
  • } while(yu==0);// se yu è diverso da 0 esco dal ciclo id lettura dalla seriale perchè ho memorizzato in stringa il valore di x e y*
    }
    fclose (stream);
    CloseHandle(hComm); //chiudo la seriale
    }
  • getch();*
  • return 0;*
    }
    [/quote]

codice arduino:

/*

programma che ha in ingresso : somma—> valoro intero di cui voglio fare il CRC
mi manda in uscita il CRC
Cosa fa: converto il valore somma in un numero esadecimale in formato ASCII con la funzione itoAsciiEx
itoAsciiEx mi converte il valore di somma che viene memorizzato nella variabile hexa di typo byte e in più mi restituisce la lunghezza di hexa
hexa viene inviato alla funzione crc_1021 che mi restituiscwe il CRC.
Da notare che la stringa che contiene il numero in esadecimale è lunga al massimo 4(uno spazio è riservato a \0)

*/

int rit=5;
char CheckSumC[5];
int somma=2300;
unsigned mC=0;

int GetCRC(char crcCheckSumC[5])
{
// Common register
int aLen =0; // Length of the array that contains the base array
// End common register

// Register for the convert function from String HEX value to ascii
byte hexa[5];
int i =0; // Master index
// End of register for the convert function from String HEX value to ascii

// Register for the checksum convert the value to string
char strConvBuffer[40]; // Temporary buffer
long int crcCheckSumD; // Crc checksum that contain the decimal value of the checksum
int d =0;
unsigned short crcBuffer =0; // Temporary buffer for the checksum calc
String crcCheckSumS; // String that contain the HEX value of the checksum and is convertet to upper case
// End register for the checksum convert the value to string

aLen= itoAsciiEx(somma,hexa);
for (i=0; i < aLen; i++) // Convert function from String HEX value to ascii
{
// Serial.println(hexa*);*

  • }*
  • crcCheckSumD =crc_1021(crcBuffer,hexa, aLen); // Calc the crc checksum and convert the value to string and upper case*
  • //Serial.print(crcCheckSumD);*
  • // Serial.println(“bbbbbbbbbbbbb”);*
  • itoa (crcCheckSumD,strConvBuffer,16);*
  • for (d = 0; d < 4; d++)*
  • {*
  • crcCheckSumC[d] = strConvBuffer[d];*
  • crcCheckSumS = strConvBuffer;*
  • crcCheckSumS = crcCheckSumS.toUpperCase();*
  • crcCheckSumC[d] = crcCheckSumS[d];*
  • Serial.print(crcCheckSumC[d]);*
  • }*
  • return crcCheckSumD;*
    }
    unsigned short crc_1021(unsigned short crc, unsigned char const *buffer, int len)
    {
  • unsigned short cmpt;*
  • //For all char*
  • while (len–) {*
    _ crc = crc ^ *buffer++ << 8;_
  • //For All bit*
  • for (cmpt = 0; cmpt < 8; cmpt++) {*
  • if (crc & 0x8000)*
  • crc = crc << 1 ^ 0x1021;*
  • else*
  • crc = crc << 1;*
  • } //End bit*
  • } //Frame end*
  • return crc;*
    }
    //
    void setup()
    {
    Serial.begin(9600);
    mC = GetCRC(CheckSumC);
    }
    void loop()
    {
    // int d = 0;
  • Serial.print("|");*
  • Serial.print(somma);*
  • Serial.print("\t");*
  • Serial.print(mC);*
  • Serial.print("<");*
  • delay(rit);*
    }
    int itoAsciiEx(int val, byte *hexa)
    {
  • int n = 0;*
  • char stringa [5];*
  • itoa(val, stringa,16);*
  • while( stringa[n] != ‘\0’ )*
  • {*
  • hexa[n] = (byte)stringa[n];*
  • n++; *
  • }*
  • return n–;*
    }
    [/quote]

In teoria il protocollo rs232 dovrebbe già avere il controllo di errore

scusa ma non ho capito cosa intendi...