/// <summary> /// Vérifie le CRC présent à la fin d'une trame : /// le booléen retourné est vrai si le CRC trouvé à la fin de la trame est identique à celui calculé /// </summary> /// <param name="trameAvecCRC"></param> /// <returns></returns> static public bool VerifierCRC(byte[] trameAvecCRC) { if (trameAvecCRC.Length < 2) { return(false); } byte[] reponseSansCRC = new byte[trameAvecCRC.Length - 2]; byte[] tempCRCRecu = new byte[2]; Buffer.BlockCopy(trameAvecCRC, trameAvecCRC.Length - 2, tempCRCRecu, 0, 2); ushort crcRecu = ADUModbus.OctetsFortFaibleVersEntier16(tempCRCRecu); Buffer.BlockCopy(trameAvecCRC, 0, reponseSansCRC, 0, reponseSansCRC.Length); ushort crcCalcule = ADUModbus.calculCRC(reponseSansCRC); return(crcRecu == crcCalcule); }
private void creerTrameRequete(string chaineHexadecimale) { trameRequete = ADUModbus.ajouterMBAP(ADUModbus.ChaineHexaVersOctets(chaineHexadecimale)); }
public string LireRequete() { return(ADUModbus.OctetsVersChaineHexa(TrameRequete)); }
/// <summary> /// Envoie une requête Modbus présentée sous la forme d'une chaîne de caractères hexadécimaux /// et attend la réponse /// </summary> /// <param name="trameSansCRC"></param> public void EnvoyerRequete(string trameSansCRC) { try { portCOM.DiscardInBuffer(); trameReponse = null; finLecture = false; attenteEnCours = false; // Lancement d'un Thread séparé qui mettra le flag finTimeout à vrai si le délais d'attente de réponse est dépassé threadTimeout = new Thread(attenteReponse); threadTimeout.Start(); // On attend que threadTimeout ait effectivement démarré while (!attenteEnCours) { } // La méthode lectureReponse() sera appellée lors de la réception de quelque chose sur le port série portCOM.DiscardInBuffer(); portCOM.DataReceived += lectureReponse; // Envoi effectif de la requête envoyerTrame(trameSansCRC); } catch (Exception ex) { throw new ModbusException("Erreur lors de l'envoi d'une requête", ex); } // On n'a plus qu'à attendre la réception d'une réponse complète ou la fin du Timeout while (!finLecture && attenteEnCours) { } portCOM.DataReceived -= lectureReponse; // attenteEnCours devient faux quand le timeout de réponse est atteint avant de recevoir une réponse if (!attenteEnCours) { throw new ModbusException("Expiration du timer d'attente de réponse !"); } else { try { // Si on est arrivé là, c'est qu'une réponse a été reçue // On arrête le thread qui surveille le timeout de réponse threadTimeout.Abort(); threadTimeout.Join(); } catch (Exception ex) { throw new ModbusException("Erreur lors de l'arrêt du thread de timeout", ex); } // On vérifie la réponse reçue qui a été stockée dans trameReponse par lectureReponse() if (trameReponse == null) { throw new ModbusException("Lecture finie avant le timeout mais la réponse est vide."); } else if (!ADUModbus.VerifierCRC(trameReponse)) { throw new ModbusException("Réponse incomplète ou corrompue (erreur de CRC)."); } } }