Używam C# do komunikowania się przez modbus rs485 rs232
do 2 fazomierzy, które między innymi rejestrują napięcie zasilania.Komunikacja Modbus
Muszę przesłać dane przez magistralę, aby móc odbierać odczyty.
Podłączyłem normalny przewód i zwróciłem wysyłkę i odbiór.
Dane otrzymałem i to zdarzenie jest opalane:
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
}
}
Wtedy ten bufor jest wysyłany do innej funkcji, która jest taka:
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);
}
}
Myślę, że problem leży w danych kontrola integralności:
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;
}
Istnieje kontrola CRC i co jest dziwne, to nigdy nie było omuje prawdę. Obliczenie CRC:
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);
}
Czy istnieją zasoby online zawierające transkrypcję typowej sesji komunikacyjnej wraz z CRC? Następnie możesz przynajmniej zastosować algorytm do tych przykładowych wiadomości i sprawdzić, czy wymyślisz tę samą CRC. –
Co to jest zmienna "bufor"? Czy to jest lista? Czy jesteś pewien, że twoja "msg" zmienna jest zawsze większa niż 6? Dlaczego nie wystarczy użyć bufora z portu szeregowego, zamiast rozbić go w bajt po bajcie, zrekonstruować go na liście, a następnie przekonwertować z powrotem na globalną tablicę bajtów? Możesz także wywołać ReadExisting na porcie szeregowym natychmiast po odczytaniu zawartości bufora, dlaczego? –
CRC wydaje się poprawne @AndyzSmith. co masz na myśli, nazywając czytanie naprawdę, gdzie mogę to nazwać?i tak bufor jest listą – Combinu