CALCULAR CRC DE UMA REDE 485

HELIO.COSTA 31/01/2017 13:50:25
#471186
Boa tarde,

VB.net 2013 windoes form.

Tenho um código [Ô]04 01 02 00 20 00 DD 22[Ô] de uma solicitação de um leitor. Pelo que andei lendo, seria:
04 --> endereço que quero a resposta.
01 --> Leitura de bloco de bits do tipo coil(saída discreta).
02 --> Endereço do registrador inicial (byte high)
00 --> Endereço do registrador inicial (byte low)
20 --> Número de registradores (byte high)
00 --> Número de registradores (byte low)
DD --> CRC- checksum
22 --> CRC+ checksum

Estou enviando para o equipamento com endereço 1, para ler bloco de bits, iniciando do endereço 02, campo de 20 caracteres.

Como calcular este checksum?
Todos que verifiquei, nenhum deu este resultado.
LVFIOROT 31/01/2017 16:59:54
#471193
achei isso

http://ecatalog.weg.net/files/wegnet/WEG-srw01-manual-da-comunicacao-modbus-10000013033-6.0x-manual-portugues-br.pdf
HELIO.COSTA 31/01/2017 17:27:05
#471194
LVFIOROT, obrigado pelo interesse.

Já tinha verificado este artigo.
O problema está em como implementar isto via código.
WEBMASTER 31/01/2017 23:05:23
#471198
Confesso que tive pouca experiência com portas COMM (tá bom...faz pelo menos uns 18 anos que mexi com isso), mas lembro que na época a coisa que deu mais trabalho foi converter para HEXA os comandos, de resto foi relativamente tranquilo pois o material de apoio do fornecedor era muito bom.

Aqui ficam alguns links que podem ajudar quando a COMM
http://www.vbforums.com/showthread.php?584150-Sending-and-receiving-data-to-RS232-MSComm-thru-a-VB6-0-app
http://stackoverflow.com/questions/17423733/reading-writing-data-via-com-port-in-vb6
http://forum.arduino.cc/index.php?topic=189062.0

Aqui alguns links com relação à checksum (basicamente uma confirmação do protocolo que envia/recebe)
http://www.vbforums.com/showthread.php?671352-RESOLVED-CRC-16-Calculation-on-an-Array
http://www.freevbcode.com/ShowCode.asp?ID=655
http://forums.codeguru.com/showthread.php?527955-CRC-calculation

Um CRC é um monte de XOR ... rsrsrs .... depois que se entende
HELIO.COSTA 01/02/2017 14:01:33
#471223
Obrigado WEBMASTER,

Encontrei esta função na net, mas preciso que seja como este padrão: [txt-color=#080808]CRC-CCITT (Kermit)[/txt-color] .
Não sei o que muda no código.

[ô]
[ô] CRC16CCIT.ComputeCheckSum will return ushort with CRC16
[ô] CRC16CCIT.ComputeCheckSumBytes will return 2 bytes (hi and low)

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim checksumcalculator = New CRC16CCITT(CRC16CCITT.InitialCRCValue.NonZero1)
Dim value() As Byte = System.Text.Encoding.ASCII.GetBytes([Ô]123456789[Ô])
MsgBox(Format(checksumcalculator.ComputeCheckSum(value), [Ô]X2[Ô])) [ô] 29B1
End Sub

Public Class CRC16CCITT
Public Enum InitialCRCValue
Zeroes = 0
NonZero1 = &HFFFF
NonZero2 = &H1D0F
End Enum

Private Const poly As UShort = &H1021
Dim table(255) As UShort
Dim intValue As UShort = 0

Public Function ComputeCheckSum(ByVal bytes As Byte()) As UShort
Dim crc As UShort = Me.intValue
For i As Integer = 0 To bytes.Length - 1
crc = CUShort(((crc << 8) Xor table(((crc >> 8) Xor (&HFF And bytes(i))))))
Next
Return crc
End Function

Public Function ComputeCheckSumBytes(ByVal bytes As Byte()) As Byte()
Dim crc As UShort = ComputeCheckSum(bytes)
Return BitConverter.GetBytes(crc)
End Function

Public Sub New(ByVal initialvalue As InitialCRCValue)
Me.intValue = CUShort(initialvalue)
Dim temp, a As UShort
For i As Integer = 0 To table.Length - 1
temp = 0
a = CUShort(i << 8)
For j As Integer = 0 To 7
If ((temp Xor a) And &H8000) <> 0 Then
temp = CUShort((temp << 1) Xor poly)
Else
temp <<= 1
End If
a <<= 1
Next
table(i) = temp
Next
End Sub
End Class

Se alguém souber de como alterar...
HELIO.COSTA 10/02/2017 14:23:27
#471537
Encontrei este código. Parece que vai funcionar, mas preciso passar para VB.Net windows form.
Se alguém puder ajudar, desde já agradeço.

static int ComputeCRC(byte[] val) {
int crc;
int q;
byte c;
crc = 0x0000;
for (int i = 0; i < val.length; i++) {
c = val[i];
q = (crc ^ c) & 0x0f;
crc = (crc >> 4) ^ (q * 0x1081);
q = (crc ^ (c >> 4)) & 0x0f;
crc = (crc >> 4) ^ (q * 0x1081);
}
int crcend = ((byte) crc << 8 | (byte) (crc >> 8)) & 0xffff;
//Swap bytes
int byte1 = (crcend & 0xff);
int byte2 = ((crcend >> 8) & 0xff);
int result = ((byte1 << 8) | (byte2));
//Swap
return result;
}
LVFIOROT 10/02/2017 14:59:17
#471540
Resposta escolhida
usa conversor on line : http://converter.telerik.com/

  
Private Shared Function ComputeCRC(val As Byte()) As Integer
Dim crc As Integer
Dim q As Integer
Dim c As Byte
crc = &H0
For i As Integer = 0 To val.length - 1
c = val(i)
q = (crc Xor c) And &Hf
crc = (crc >> 4) Xor (q * &H1081)
q = (crc Xor (c >> 4)) And &Hf
crc = (crc >> 4) Xor (q * &H1081)
Next
Dim crcend As Integer = (CByte(crc) << 8 Or CByte(crc >> 8)) And &Hffff
[ô]Swap bytes
Dim byte1 As Integer = (crcend And &Hff)
Dim byte2 As Integer = ((crcend >> 8) And &Hff)
Dim result As Integer = ((byte1 << 8) Or (byte2))
[ô]Swap
Return result
End Function

[ô]=======================================================
[ô]Service provided by Telerik (www.telerik.com)
[ô]Conversion powered by NRefactory.
[ô]Twitter: @telerik
[ô]Facebook: facebook.com/telerik
[ô]=======================================================
HELIO.COSTA 16/02/2017 11:13:31
#471696
Muito Obrigado LVFIOROT.
HELIO.COSTA 20/02/2017 18:19:19
#471847
Boa noite pessoal,

Ativei o tópico novamente para mais uma tentativa.
como podem ver preciso de um CRC-CCITT (Kermit) .
No link https://www.lammertbies.nl/comm/info/crc-calculation.html tem um calculo on line.
Para o código [Ô]01 00 20 00[Ô] me retorna [Ô]883F[Ô] - para entrada de dados hexadecimal e [Ô]2582[Ô] em ASCII.
Consegui este código que funciona para entrada ASCII.
O que fazer para que quando entrar como o mesmo código [Ô]01 00 20 00[Ô] me retornar [Ô]883F[Ô] .

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim CRC_POLYNOM As Long = &H8408
Dim CRC_PRESET As Long = &H0
Dim CRC1 As Long = CRC_PRESET
Dim RetStr As String = TextBox1.Text

Dim Data As Byte() = System.Text.Encoding.Default.GetBytes(RetStr)
Dim cnt As Integer = Len(RetStr)
For i = 0 To cnt - 1 [ô] cnt = number of protocol bytes without CRC
CRC1 = CRC1 Xor Data(i)
For j = 0 To 7
If CRC1 And &H1 Then
CRC1 = (CRC1 >> 1) Xor CRC_POLYNOM
Else
CRC1 = (CRC1 >> 1)
End If
Next
Next
Dim tmp As String
tmp = Hex(CRC1)
If Len(tmp) < 4 Then tmp = [Ô]0[Ô] & tmp
TextBox2.Text = Mid(tmp, 3, 2) & Mid(tmp, 1, 2)
End Sub

Já fiz a conversão para hex e não funcionou.
Tópico encerrado , respostas não são mais permitidas