Modbus-Kommunikation

Ich bin mit C# ist die Kommunikation über modbus rs485 rs232 2-phase-Meter, die unter anderem Protokoll der Versorgungsspannung.

Ich habe zum senden von Daten über den bus, so dass ich für den Empfang der Messwerte.

Ich habe angeschlossen einen normalen Draht und kurzgeschlossen, die senden und empfangen.

Den Daten empfangen wird, und dieses Ereignis wird gefeuert:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    byte[] buff = new byte[sp.BytesToRead];

    //Read the Serial Buffer
    sp.Read(buff, 0, buff.Length);
    string data= sp.ReadExisting();

    foreach (byte b in buff)
    {
        AddBuffer(b); //Add byte to buffer
    }
}

Dann dieser Puffer wird gesendet, um eine weitere Funktion, die ist diese:

private void AddBuffer(byte b)
{
    buffer.Add(b);

    byte[] msg =  buffer.ToArray();

    //Make sure that the message integrity is correct
    if (this.CheckDataIntegrity(msg))
    {
        if (DataReceived != null)
        {
            ModbusEventArgs args = new ModbusEventArgs();
            GetValue(msg, args);
            DataReceived(this, args);
        }
        buffer.RemoveRange(0, buffer.Count);

    }
}

Ich denke, das problem liegt an die Integrität der Daten überprüfen:

public bool CheckDataIntegrity(byte[] data)
{
    if (data.Length < 6)
        return false;
    //Perform a basic CRC check:
    byte[] CRC = new byte[2];
    GetCRC(data, ref CRC);
    if (CRC[0] == data[data.Length - 2] && CRC[1] == data[data.Length - 1])
        return true;
    else
        return false;
}

Es ist ein CRC-check und das seltsame ist, dass es nie wahr wird. Die CRC-Berechnung:

private void GetCRC(byte[] message, ref byte[] CRC)
{

    ushort CRCFull = 0xFFFF;
    byte CRCHigh = 0xFF, CRCLow = 0xFF;
    char CRCLSB;

    for (int i = 0; i < (message.Length) - 2; i++)
    {
        CRCFull = (ushort)(CRCFull ^ message[i]);

        for (int j = 0; j < 8; j++)
        {
            CRCLSB = (char)(CRCFull & 0x0001);
            CRCFull = (ushort)((CRCFull >> 1) & 0x7FFF);

            if (CRCLSB == 1)
                CRCFull = (ushort)(CRCFull ^ 0xA001);
        }
    }
    CRC[1] = CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
    CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
}
Gibt es online-Ressourcen, die Abschrift eines typischen Kommunikations-session, komplett mit CRC? Dann könnte man sich zumindestens Ihre Algorithmus zu denen beispielsweise Nachrichten und sehen, wenn Sie kommen mit den gleichen CRC.
Was ist der "Puffer" - Variablen? Ist es eine Liste<byte>? Sind Sie sicher, dass Ihre "msg" variable ist immer größer als 6? Warum nicht einfach die Puffer aus dem Seriellen Port, anstatt zu brechen es unten in einer Schleife von byte zu rekonstruieren, es in eine Liste, dann die Umwandlung Sie zurück zu einem globalen byte-array? Sie rufen ReadExisting auf die Serielle Schnittstelle sofort nach dem Lesen der Inhalt des Puffers, warum?
Die CRC korrekt zu sein scheint @AndyzSmith. was meinst du den Aufruf readexisting wirklich wo kann ich es nennen? und ja, der buffer ist eine Liste
Oder noch besser: gibt es irgendeine Art der Beendigung der Zeichen, das Sie verwenden können, um zu bedeuten das Ende des gültigen Daten-übertragung anstelle der Anhäufung von bytes ad infinitum und überprüfung einer Länge?
Nach Ihrer sp.Read() Online, Sie sofort rufen Sie sp.ReadExisting(). Es ist unnötig und kann sogar das problem sein, oder zumindest einen Teil davon. Du bist schon richtig Lesen, indem Sie die BytesToRead Immobilie und erstellen einen Puffer dieser Größe.

InformationsquelleAutor Combinu | 2013-08-28

Schreibe einen Kommentar