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.
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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist die Verwendung von ReadExisting(). Es war nicht verwendet werden, die Art und Weise, wie der Puffer war gefüllt mit nutzlosen Daten aus der seriellen Schnittstelle. Dieses problem wurde identifiziert durch @glace in die Kommentare!
InformationsquelleAutor Combinu
Müssen Sie zuerst eine Kommunikation mit Ihrem Meter durch einige vorhandene MODBUS master-Anwendung wie MODPOLL. Dann, wenn Sie Kommunikation arbeiten und die Gültigkeit der Antworten von Ihrem Gerät, dann und nur dann beginnen, testen Sie Ihren code. Auf diese Weise stellen Sie sicher, dass problem kann nur im code und sonst nichts.
Zum Beispiel, eine Verbindung zu zwei slave-Geräten gleichzeitig RS485 verwendet werden muss, anstelle von RS232, und diese Anforderungen verschiedener Verdrahtungs-und RS485-zu-RS232-Konverter auf PC-Seite.
Dass RX und TX angeschlossen RS232 für die simulation Zweck ist nicht eine gute Idee, da jeder MODBUS Nachricht vom master (mit Ausnahme von broadcast-Nachrichten) braucht eine Antwort, die anders ist, aus nur Meldung echo. Auch, jedes MODBUS Nachricht vom master MODBUS-client-Adresse eingebettet ist, und nur einzelne Kunde sollte darauf zu Antworten (MODBUS ist master-mehrere slaves protocol).
Als für eine CRC-Berechnung, dies könnte helfen, für die MODBUS-RTU-Protokoll (ASCII):
Das ist ein Zitat aus einer lauffähigen embedded AVR Gerät mit implementierten MODBUS-RTU-slave-Protokoll.
ist es möglich, fügen Sie Ihre Lösung als Antwort (Sie können Ihre eigene Frage zu beantworten) und es akzeptieren? Ich denke, dass dies helfen würde, zukünftige Leser, wenn Sie in ähnliche Probleme. ( Ich beziehe mich auf xkcd für die Referenz)
ich glaube nicht, dass diese c#
InformationsquelleAutor avra