[résolu]perte de données en serial

Bonjour à tous

voilà j'ai un petit soucis de perte de données,

J'ai un PC qui envoie des données sur le port usb de l'arduino.
quand le PC est peu sollicité il envoie les données de cette manière:
<a200
=b100
#g1500
...
quand le PC commence à accélérer les données sont envoyé comme ça:
<a200=b100#g1500...

Dans le premier cas je n'ai pas trop de soucis, je récupère tous les paquet.
Dans le second cas, j'en perd 1/3.

Après vérification, tous arrive à l'arduino et il le voit bien, donc j'ai un soucis dans mon code, soit je le bloc quelque part ou je découpe mal la chaîne de caractère

Les données envoyé sont de se format là
signe+lettre= identifiant <A
chiffre = donnée 200

Voici la partie du prg qui gère la découpe

void serialEvent() 
	{
		while (Serial.available()) 
			{
				char Bloc = (char)Serial.read(); 
				//Serial.println(Bloc);

				if(inputString.length()==0)
					{
						inputString= "";
						if((Bloc == '=') || (Bloc == '#') || (Bloc == '<') || (Bloc == '?') || (Bloc == '/'))
							{
								inputString+= Bloc;
							}
						
					}

				else
					{
						if((Bloc == '=') || (Bloc == '#') || (Bloc == '<') || (Bloc == '?') || (Bloc == '/') || (Bloc == '\r') || (Bloc == '\n'))
							{
								Clean (inputString);
								inputString= "";

								//if((Bloc != '\r') || (Bloc != '\n'))
									//{
										inputString+= Bloc;
									//}
							}
						else{inputString+= Bloc;}
					}

			}
	}

et le code complet

String inputString = "";
boolean stringComplete = false;
#include <SoftwareSerial.h>
#define RX 9
#define TX 8
#define EMER 7
#define ESCLAVE1 6
#define ESCLAVE2 5
#define ESCLAVE3 4
#define ESCLAVE4 3
#define ESCLAVE5 2

SoftwareSerial portOne(RX,TX);

int Buffer_size;
String data2;

char buf [100];//tampon de réception
volatile byte pos;//position dans le tampon
volatile boolean process_it;//information récupérée



void setup()
	{
		Serial.begin (115200);
		Serial.println ("Communication de la carte ok");
		Serial.println ("Maitre en ligne");
		inputString.reserve(200);
		portOne.begin(9600);
		pinMode(ESCLAVE1, OUTPUT);digitalWrite(ESCLAVE1, HIGH);
		pinMode(ESCLAVE2, OUTPUT);digitalWrite(ESCLAVE2, HIGH);
		pinMode(ESCLAVE3, OUTPUT);digitalWrite(ESCLAVE3, HIGH);
		pinMode(ESCLAVE4, OUTPUT);digitalWrite(ESCLAVE4, HIGH);
		pinMode(ESCLAVE5, OUTPUT);digitalWrite(ESCLAVE5, HIGH);
	}

void loop()
	{
		while (portOne.available()) 
					{
							// get the new byte:
							char inChar = (char)portOne.read();
							byte c = inChar;  
							if (pos < sizeof (buf))
								{
									buf [pos++] = c;
									if (c == '\n')
									process_it = true;
								}
					}
		if (process_it)
			{
				buf [pos] = 0;
				pos = 0;

				String Buffer  = buf;
				Serial.println(Buffer);

			}
		process_it = false;
	}

void Clean(String& Commande)
	{
		if(Commande.length()>=3)
			{
				if(Commande.substring(0,2)=="<D")
					{
						String role="0001";
						String data=Commande.substring(2);
						int esclave=ESCLAVE1;
						Format_Send_Data(data,role,esclave);
					}
				if(Commande.substring(0,2)=="<L")
					{
						String role="0002";
						String data=Commande.substring(2);
						int esclave=ESCLAVE1;
						Format_Send_Data(data,role,esclave);
					}
				if(Commande.substring(0,2)=="=b")
					{
						String role="0003";
						String data=Commande.substring(2);
						int esclave=ESCLAVE1;
						Format_Send_Data(data,role,esclave);
					}
				if(Commande.substring(0,2)=="=c")
					{
						String role="0004";
						String data=Commande.substring(2);
						int esclave=ESCLAVE1;
						Format_Send_Data(data,role,esclave);
					}
				

			}
	}

void Format_Send_Data(String& data,String& role,int esclave)
	{

		String size=String(role.length()+data.length()+3);
		String size_to_send;
		if(size.length()<3)
			{
				for(int i=0; i<3-size.length(); i++)
					{
						size_to_send+="0";
					}
				size_to_send+=size;
			}

		digitalWrite(esclave, LOW);delay(2);
		portOne.print(size_to_send);portOne.print(role); portOne.println(data);
		delay(2);digitalWrite(esclave,HIGH);
	}

void serialEvent() 
	{
		while (Serial.available()) 
			{
				char Bloc = (char)Serial.read(); 
				//Serial.println(Bloc);

				if(inputString.length()==0)
					{
						inputString= "";
						if((Bloc == '=') || (Bloc == '#') || (Bloc == '<') || (Bloc == '?') || (Bloc == '/'))
							{
								inputString+= Bloc;
							}
						
					}

				else
					{
						if((Bloc == '=') || (Bloc == '#') || (Bloc == '<') || (Bloc == '?') || (Bloc == '/') || (Bloc == '\r') || (Bloc == '\n'))
							{
								Clean (inputString);
								inputString= "";

								//if((Bloc != '\r') || (Bloc != '\n'))
									//{
										inputString+= Bloc;
									//}
							}
						else{inputString+= Bloc;}
					}

			}
	}

voyez vous une anomalie ou quelque chose qui pourrait être optimisé?

merci d'avance

Flo

Salut,

J'ai pas encore étudié tout ton code mais pour commencer il faudrait ajouter un delay(5) après if(Serial.available()) histoire de laisser le temps à la trame entière d'arriver

ok, alors avec le delay(5) il y a déja un grand mieux, mais j'aimerai comprendre.

le tampon du sérial est t'il totalement indépéndant, et donc même si j'ai un loop bloquant, il continu de se charger en attendant que le loop se débloque?

Oui il est indépendant, mais l'Arduino elle fonctionne très vite, bien plus vite que la transmission série.

Ta trame arrive, Serial.available() devient supérieur à zéro => déclenchement du découpage

Oui sauf que l'Arduino va plus vite à découper que la liaison série, donc tu auras fini ton traitement que toute ta trame n'était pas encore arrivée ... Avec un delay() ça permet de laisser le temps au buffer (indépendant) de se charger avec la trame entière, puis d'executer ta routine sur la trame complète.

merci beaucoup