static byte bcc; // byte BCC (Block Check Character) private void serialPort_DataReceived(object sender, EventArgs e) // fonction de réception de donnée(s) : dès que quelque chose arrive sur le port série, la fonction est appélée { int valeur = 0; // entier pour pouvoir exploiter la valeur reçue FLAG_TIMER0 = true; // on initialise le flag du timer0 à false byte[] c = new byte[serialPort.BytesToRead]; // on mettra les bytes reçus dans le tableau de bytes c serialPort.Read(c, 0, serialPort.BytesToRead); // lit les bytes reçus et met dans c serialPort.DiscardInBuffer(); // vide le tampon if (c.Length == 1 && c[0] == STX && flag_debut == false) //si on reçoit un STX comme premier caractère [la FOX envoie un STX pour commencer une communication => on répond un DLE] { parent.EcritureSerie("DLE"); flag_debut = true; // on indique que la communication a débuté : passage du flag à true timer0.BeginInit(); timer0.Start(); // on démarre le timer0 pour attendre réception des données sivantes bcc = 0; // initialisation du BCC } else // si on ne reçoit pas le premier caractère (STX) de début de communication { if (flag_debut == true) // si on a déjà entamé la communication, càd STX reçu et DLE envoyé { if (FLAG_TIMER0 == true && c.Length == 3 && flag_longueur_trame_3 == true && c[0] == DLE && c[1] == ETX) //FIN DE COMMUNICATION : longueur trame = 3 , DLE-ETX-BCC reçus et BCC ok => envoi de DLE { if (c[2] == Convert.ToChar("bcc")) // si le BCC reçu et celui calculé condcordent : envoi de DLE => communication réussie { timer0.Stop(); parent.EcritureSerie("DLE"); flag_debut = true; // remise à zéro du flag pour attendre une nouvelle communication } else // si les deux BCC sont différents : on envoie un NAK { parent.EcritureSerie("NAK"); flag_debut = true; // remise à zéro du flag pour attendre une nouvelle communication timer0.Stop(); } flag_longueur_trame_3 = false; // remise à zéro du flag } else // sinon (pas fin ou début de communication) { if (FLAG_TIMER0 == true && c.Length >= 3 && flag_longueur_trame_3 == false) // si le timer n'est pas arrivé à son terme, que la trame de bytes reçue est de longueurs de min. 3 et qu'on n'a pas encore reçu les données utiles { char[] data = new char[3]; // création d'un tableau de caractères de taille = 3 int k = 0, l = 0; // indices pour les boucles dans le cas de réception de deux (ou plus) DLE d'affilée bcc ^= c[0]; // calcul du BCC data[l] = Convert.ToChar(c[0]); // on convertit le premier byte en caractère, il déterminera le type de valeur reçue (le type du capteur) l++; do // boucle de traitement en cas de double DLE { if (c[k] == DLE && c[k + 1] == DLE) // si deux DLE d'affilée : si le byte présent et le suivant sont = DLE : on passe au suivant (k+1) et on ne tient pas compte du byte présent (k) { k++; } else { if (l == 1) // cas de data[1] { data[l] = Convert.ToChar(c[k + 1]); // sinon on convertit le byte suivant (k+1) en caractère l++; bcc ^= c[k + 1]; // continue le calcul de BCC k++; // passage au byte suivant } else // cas de data[2] { if (c[k] == DLE && c[k + 1] == DLE) // si deux DLE d'affilée : si le byte présent et le suivant sont = DLE : on passe au suivant (k+1) et on ne tient pas compte du byte présent (k) { k++; } else { data[l] = Convert.ToChar(c[k + 1]); // sinon on convertit le byte suivant (k+1) en caractère bcc ^= c[k + 1]; // continue le calcul de BCC k++; } } } } while (data.Length == 3); // boucle effectuée tant que la taille du tableau data n'est pas égale à 3 valeur = valeur = Convert.ToInt32((data[1] * 256) + data[2]); // traitement des données utiles : deux derniers des trois bytes = valeur envoyée par la Fox flag_longueur_trame_3 = true; // remise à zéro (false) du flag switch (data[0]) // traitement dans les différents cas en fonction du premier octet utile { case 'A': // Cas : Profondeur tableau_de_donnee.setProfondeur(valeur); // Stocke la valeur dans la base de données et bascule un flag de confirmation newProfondeur = true; break; case 'C': // Cas : Axe X tableau_de_donnee.setInclinaisonX(valeur); newInclinaisonX = true; break; case 'E': // Cas : Axe Y tableau_de_donnee.setInclinaisonY(valeur); newInclinaisonY = true; break; case 'G': // Cas : Ballast 0 tableau_de_donnee.setBallastAvant(valeur); newPositionAvant = true; break; case 'I': // Cas : Ballast 1 tableau_de_donnee.setBallastArriere(valeur); newPositionArriere = true; break; default: break; } } else // Sinon envoi de NAK et attente de nouvelle communication { parent.EcritureSerie("NAK"); flag_debut = true; timer0.Stop(); } } } else // sinon on envoi un NAK { parent.EcritureSerie("NAK"); flag_debut = true; } } }
///////////////////////////////////////////////////////////////////////////////////////////////////// private void serialPort_DataReceived(object sender, EventArgs e) // On entre dans cette fonction dès que quelque chose arrive sur le port série { char[] buffer = new char[serialPort.BytesToRead]; // Crée un tableau de caractères (buffer) de taille égale au nombre de bytes présents sur le ports série serialPort.Read(buffer, 0, serialPort.BytesToRead); // Stocke les bytes présents sur le port série dans un tableau de caractères : buffer serialPort.DiscardInBuffer(); // Vide le tampon du port série //for (int i = 0; i < buffer.Length ; i++) //{ // dataSerie += buffer[i]; //} newData = true; if (buffer.Length == 3) // Si la taille du tableau est égale à 3 { int valeur; valeur = (buffer[1] * 256) + buffer[2]; // On exploite les données utiles : les deux derniers des 3 bytes = valeur réelle switch (buffer[0]) // Le premier byte = indique le type de valeur reçue { case 'A': // Cas : Profondeur tableau_de_donnee.setProfondeur(valeur); // Stocke la valeur dans la base de données et bascule un flag newProfondeur = true; parent.flag_A = true; // Flag pour indiquer dans FormTelecommande.cs que la réception est effectuée break; case 'C': // Cas : Inclinaison axe X tableau_de_donnee.setInclinaisonX(valeur); newInclinaisonX = true; parent.flag_C = true; break; case 'E': // Cas : Inclinaison axe Y tableau_de_donnee.setInclinaisonY(valeur); newInclinaisonY = true; parent.flag_E = true; break; case 'G': // Cas : Position Ballast 0 tableau_de_donnee.setBallastAvant(valeur); newPositionAvant = true; parent.flag_G = true; break; case 'I': // Cas : Position Ballast 1 tableau_de_donnee.setBallastArriere(valeur); newPositionArriere = true; parent.flag_I = true; break; default: break; } serialPort.DiscardInBuffer(); // Vide le tampon du port série } else { serialPort.DiscardInBuffer(); // Vide le tampon du port série } }