Ich verwende C#, um über modbus rs485 rs232
mit 2-Phasen-Messgeräten zu kommunizieren, die unter anderem die Netzspannung protokollieren.Modbus Kommunikation
Ich muss Daten über den Bus senden, damit ich die Messwerte erhalten kann.
Ich habe eine normale Leitung angeschlossen und das Senden und Empfangen kurzgeschlossen.
Die Daten empfangen und dieses Ereignis ausgelöst wird:
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 wird dieser Puffer auf eine andere Funktion gesendet, die diese ist:
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, dass das Problem bei der Daten liegt Integritätsprüfung:
Es gibt eine CRC-Prüfung und was ist seltsam ist, dass es nie bec omes wahr. 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 eine Abschrift einer typischen Kommunikationssitzung mit dem CRC enthalten? Dann könnten Sie Ihren Algorithmus zumindest auf diese Beispielnachrichten anwenden und sehen, ob Sie mit demselben CRC kommen. –
Was ist die "Puffer" Variable? Ist es eine Liste? Sind Sie sicher, dass Ihre "msg" Variable immer größer als 6 ist? Warum nicht einfach den Puffer vom seriellen Port verwenden, anstatt ihn in einer Schleife nach Byte zu zerlegen, ihn in einer Liste zu rekonstruieren und ihn dann in ein globales Byte-Array umzuwandeln? Sie rufen auch direkt nach dem Lesen des Pufferinhalts ReadExisting am seriellen Port auf, warum? –
Die CRC scheint richtig zu sein @AndyzSmith. was meinst du reaindaisting nennen wirklich wo kann ich es nennen?und ja Puffer ist eine Liste – Combinu