Page 1 of 1
RS485 bus with MODBUS communication protocol
Posted: Thu Aug 08, 2024 5:11 pm
by marc_256
Hi,
For my DIY solar system I want to use a energy meter.
So, I can read the voltage, current, power in watt, ...
Is here someone who used PB with a RS485 bus with MODBUS communication protocol ?
I already installed a USB to RS485 converter.
Thanks,
marc
Re: RS485 bus with MODBUS communication protocol
Posted: Thu Aug 08, 2024 7:32 pm
by HeX0R
Yes, I'm working all day with modbus (RTU / TCP), but I have nothing to share, all my codes are integrated into different tools.
I also made a modbus.dll, but it is too specific (for a terminal program I did) and not of much general use.
But it is a very simple protocol, this here is usually all you need to get it done:
https://www.simplymodbus.ca/FAQ.htm
Each command and the result is explained there.
Good luck!
Re: RS485 bus with MODBUS communication protocol
Posted: Thu Aug 08, 2024 9:43 pm
by marc_256
Hi HeX0R,
Thanks for the link, very interesting data there.
Just what I need to start.
Marc
Re: RS485 bus with MODBUS communication protocol
Posted: Fri Aug 09, 2024 10:39 am
by mk-soft
Modbus/TCP is easier because you do not have to form a CRC there.
Here is an approach for Modbus/RTU
Code: Select all
;-TOP
; Link: https://stackoverflow.com/questions/65734589/understand-modbus-rtu-crc
;
; uint16_t calculate16CRC(uint16_t Length, uint8_t *Data)
; {
; /* Reversed Modbus polynomial of 0x8005 -> CRC-16 POLYNOMIAL: P(x) = x16 + x15 + x2 + 1 */
; uint16_t Poly = 0xa001;
;
; uint16_t CRCRegister = 0xFFFF; // Initialize CRC register with all 1's
;
; uint16_t b; // Carry Over Checker
; uint16_t c; // Data Array Index
; uint16_t i; // Bit Index
;
; for (c = 0; c < Length; c++) {
; CRCRegister ^= Data[c]; // XOR CRC with Byte
; for (i = 0; i < 8; i++) {
; b = CRCRegister & 1;
; CRCRegister >>= 1; // Shift to the right
; if (b != 0){ // Carry over?
; CRCRegister ^= Poly; // Yes
; }
; }
; }
;
; return CRCRegister;
; }
Structure ArrayOfByte
StructureUnion
a.a[0]
b.b[0]
EndStructureUnion
EndStructure
Structure ArrayOfAny
StructureUnion
a.a[0]
b.b[0]
u.u[0]
w.w[0]
l.l[0]
q.q[0]
EndStructureUnion
EndStructure
Procedure calculate16CRC(Length, *Data.ArrayOfByte)
;/* Reversed Modbus polynomial of 0x8005 -> CRC-16 POLYNOMIAL: P(x) = x16 + x15 + x2 + 1 */
Protected Poly = $A001;
Protected CRCRegister = $FFFF ; // Initialize CRC register with all 1's
Protected b; // Carry Over Checker
Protected c; // Data Array Index
Protected i; // Bit Index
For c = 0 To Length-1
CRCRegister = (CRCRegister ! *Data\a[c]) & $FFFF; // XOR CRC with Byte
For i = 0 To 7
b = CRCRegister & 1;
CRCRegister >> 1 ; // Shift to the right
If (b <> 0) ; // Carry over?
CRCRegister = (CRCRegister ! Poly) & $FFFF; // Yes
EndIf
Next
Next
ProcedureReturn CRCRegister;
EndProcedure
; ----
Procedure bswap16(value.u)
CompilerIf #PB_Compiler_Backend = #PB_Backend_C
!return __builtin_bswap16(v_value);
CompilerElse
!xor eax,eax
!mov ax, word [p.v_value]
!rol ax, 8
ProcedureReturn
CompilerEndIf
EndProcedure
; ----
Procedure fc03request(Slave, Offset, Count, *SendData) ; Build Read Holding Registers
Protected *request.ArrayOfAny = *SendData
*request\a = Slave
*request + 1
*request\a = 3
*request + 1
*request\u = bswap16(Offset)
*request + 2
*request\u = bswap16(Count)
*request + 2
*request\u = calculate16CRC(6, *SendData)
ProcedureReturn 8
EndProcedure
*fc04request = AllocateMemory(100)
len = fc03request(17, 107, 3, *fc04request)
Debug "Len to send = " + len
ShowMemoryViewer(*fc04request, 16)
Re: RS485 bus with MODBUS communication protocol
Posted: Fri Aug 09, 2024 1:14 pm
by infratec
Re: RS485 bus with MODBUS communication protocol
Posted: Fri Aug 09, 2024 1:39 pm
by marc_256
hi mk-soft and infratec,
Thank you very much for your help.
This is very good stuff.
This will help me to communicate with the energy meter.
Greetings,
marc