2010-10-14 24 views
1

Je crée une bibliothèque de classes pour les connexions Modbus et série, j'ai besoin de retourner un tableau d'octets, mais lorsque j'utilise l'événement DataReceived de System.IO.Ports, je ne peux pas retourner tout puisque son type est nul. Aussi, je remarque que le DataReceived ne tire pas. Ce qui suit est mon code:modifier le type de sortie de l'événement datareceived system.io.port

 public void ConnectSerialModBus_Loopback(string COM, int baud, int meter_address, int function, int Code_HighByte, int Code_LowByte, int data_high_byte, int data_low_byte) 
    { 
     SerialPort port = new SerialPort(COM, baud); 
     try 
     { 

      if (!(port.IsOpen)) 
      { 
       byte[] sendPacket = BuildPacket(meter_address, function, Code_HighByte, Code_LowByte, data_high_byte, data_low_byte); 
       double dataBytes = 2.0; 

       port.Open(); 
       port.RtsEnable = false;//rts = high 
       port.Handshake = Handshake.None; 
       //SEND PACKET TO DEVICE 
       port.Write(sendPacket, 0, sendPacket.Length); 

       #region RECEIVE DATA FROM SERIAL 
       //MAKE DELAY TO SEND 
       Thread.Sleep(10); 

       port.RtsEnable = true; 
       //MAKE DELAY TO RECEIVE 
       port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); 
       //Thread.Sleep(CalculateDelay(dataBytes)+90); 

       port.Close(); 
       port.Dispose(); 
       #endregion 

      } 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
     finally 
     { 
      if (port != null) 
      { 
       if (port.IsOpen) 
       { 
        port.Close(); 
       } 
       port.Dispose(); 
      } 
     } 
    } 

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     SerialPort port = (SerialPort)sender; 
     byte[] readingbyte = new byte[port.BytesToRead]; 
     if (port.BytesToRead > 0) 
     { 
      port.Read(readingbyte, 0, readingbyte.Length); 
     } 
    } 

d'une certaine façon, je veux retourner les octets ont reçu soit du port_DataReceived ou du ConnectSerialModBus_Loopback aussi DataReceived ne se déclenche pas. Aidez s'il vous plaît ceci est très urgent

Répondre

0

Ne dormez pas l'événement datareceived. Lorsque l'événement se déclenche, placez les octets dans une file d'attente. Vous aurez besoin de méthodes que l'interface utilisateur peut utiliser pour reconstituer les blocs d'octets. Pour plus d'informations, voir SerialPort101.

21

DataReceived ne se déclenche pas

Le DataReceived ne se déclenche pas parce que vous appelez port.Close() immédiatement après la fixation du gestionnaire et avant de recevoir le fil du SerialPort a eu la chance de courir.

Retour un tableau d'octets retour - réponse simple

Dans l'exemple simple code que vous fournissez, vous pouvez créer un membre Byte[] privé et affecter l'objet readingbyte à elle à partir de votre gestionnaire d'événements port_DataReceived.

Retour un tableau d'octets en arrière - OO soupçon réponse

Cependant, dans une application plus rubust, vous devriez envisager la création d'une classe de transaction qui encapsule les parties du protocole Modbus ADU, manipuler à la fois la transmission du client demande et (couche 2) traitement de la réponse du serveur.

En plus de la couche ADU, vous devez séparer la couche PDU en une classe de base ModbusFunction abstraite qui fournit une interface à la classe ADU pour obtenir les octets de requête et renvoyer les octets de réponse. Ensuite, chaque fonction modbus que vous voulez que votre client utilise sera réalisée dans une classe qui lui est propre et qui dérive de la classe de base PDU. De cette façon, lorsque vous devez interagir avec le serveur, vous créez une instance d'une classe de fonctions PDU, avec les paramètres appropriés pour former le paquet de données PDU correct, et passez-le à l'objet Transaction qui gère la requête/réessayer./logique de réponse et renvoie les données renvoyées à l'objet PDU pour analyser de manière appropriée.

L'ajout d'un événement à la classe de base PDU permet à d'autres parties de votre code de se connecter à l'événement de la classe PDU et de recevoir une notification lorsque la fonction s'est terminée avec succès. Avec un serveur ayant plusieurs propriétés adressables, implémentées par l'intermédiaire des fonctions Modbus, vous créez une instance de la classe de fonction Modbus appropriée pour chaque propriété (ou un ensemble de celles-ci pour les registres contigus, par exemple) et vous attachez à l'événement , mise à jour de votre modèle et/ou de votre interface utilisateur chaque fois que l'objet déclenche son événement de mise à jour.Accrochez les commandes de l'interface utilisateur pour transmettre les objets Fonction Modbus Function à l'objet Transaction si vous souhaitez interroger le serveur manuellement ou implémenter un thread minuteur qui le fait dans un planning si vous souhaitez que les propriétés soient interrogées régulièrement.