Lydia - Printhead
Loading...
Searching...
No Matches
Modbus Object Management

Functions

boolean Modbus::getTimeOutState ()
 get communication watch-dog timer state
 
int8_t Modbus::poll ()
 cyclic poll for master
 
int8_t Modbus::poll (uint16_t *regs, uint8_t u8size)
 cyclic poll for slave
 
int8_t Modbus::query (modbus_t telegram)
 only for master
 

Detailed Description

Function Documentation

◆ getTimeOutState()

boolean Modbus::getTimeOutState ( )

get communication watch-dog timer state

Return communication Watchdog state. It could be useful to reset outputs if the watchdog is fired.

Returns
TRUE if millis() > u32timeOut

Definition at line 506 of file ModbusRtu.h.

507{
508 return (millis() > u32timeOut);
509}
uint32_t u32timeOut
Definition ModbusRtu.h:168
Definition xtimer.h:21

◆ poll() [1/2]

int8_t Modbus::poll ( )

cyclic poll for master

*** Only for Modbus Master *** This method checks if there is any incoming answer if pending. If there is no answer, it would change Master state to COM_IDLE. This method must be called only at loop section. Avoid any delay() function.

Any incoming data would be redirected to au16regs pointer, as defined in its modbus_t query telegram.

@params nothing

Returns
errors counter

Definition at line 691 of file ModbusRtu.h.

692{
693 // check if there is any incoming frame
695 if (u8serno < 4)
696 {
697 u8current = port->available();
698 }
699 else
700 {
701 u8current = softPort->available();
702 }
703
704 if (millis() > u32timeOut)
705 {
708 u16errCnt++;
709 return 0;
710 }
711
712 if (u8current == 0)
713 {
714 return 0;
715 }
716
717 // check T35 after frame end or still no frame end
718 if (u8current != u8lastRec)
719 {
721 u32time = millis() + T35;
722 return 0;
723 }
724 if (millis() < u32time)
725 {
726 return 0;
727 };
728
729 // transfer Serial buffer frame to auBuffer
730 u8lastRec = 0;
732 if (i8state < 7)
733 {
735 u16errCnt++;
736 Log.verboseln("Add error : %d - RX-Buffer < 7", i8state);
738 return i8state;
739 }
740
741 // validate message: id, CRC, FCT, exception
743 if (u8exception != 0)
744 {
745 Log.verboseln("ModbusRTU::poll : exception : %d", u8exception);
747 return u8exception;
748 }
749
750 // process answer
751 switch (au8Buffer[FUNC])
752 {
753 case MB_FC_READ_COILS:
755 // call get_FC1 to transfer the incoming message to au16regs buffer
756 get_FC1();
757 break;
760 // call get_FC3 to transfer the incoming message to au16regs buffer
761 get_FC3();
762 break;
763 case MB_FC_WRITE_COIL:
767 // nothing to do
768 break;
769 default:
770 break;
771 }
774 return u8BufferSize;
775}
@ COM_IDLE
Definition ModbusRtu.h:113
@ FUNC
Function code position.
Definition ModbusRtu.h:94
#define T35
Definition ModbusRtu.h:56
@ NO_REPLY
Definition ModbusRtu.h:128
uint8_t u8lastError
Definition ModbusRtu.h:161
uint8_t u8state
Definition ModbusRtu.h:160
uint32_t u32time
Definition ModbusRtu.h:168
HardwareSerial * port
Pointer to Serial class object.
Definition ModbusRtu.h:155
uint16_t u16errCnt
Definition ModbusRtu.h:166
uint8_t rxBuffer[MAX_BUFFER]
Definition ModbusRtu.h:217
uint8_t au8Buffer[MAX_BUFFER]
Definition ModbusRtu.h:162
uint8_t u8serno
serial port: 0-Serial, 1..3-Serial1..Serial3; 4: use software serial
Definition ModbusRtu.h:158
modbus_t * currentQuery
Definition ModbusRtu.h:178
SoftwareSerial * softPort
Pointer to SoftwareSerial class object.
Definition ModbusRtu.h:156
uint8_t u8lastRec
Definition ModbusRtu.h:164
uint8_t u8BufferSize
Definition ModbusRtu.h:163
uint8_t validateAnswer()
This method validates master incoming messages.
Definition ModbusRtu.h:1201
int8_t getRxBuffer()
This method moves Serial buffer data to the Modbus au8Buffer.
Definition ModbusRtu.h:905
void get_FC1()
Definition ModbusRtu.h:1261
void get_FC3()
Definition ModbusRtu.h:1280
uint8_t flags
Definition ModbusRtu.h:74
void printHex(uint8_t *data, uint8_t length)
Definition utils.cpp:3

◆ poll() [2/2]

int8_t Modbus::poll ( uint16_t * regs,
uint8_t u8size )

cyclic poll for slave

*** Only for Modbus Slave *** This method checks if there is any incoming query Afterwards, it would shoot a validation routine plus a register query Avoid any delay() function !!!! After a successful frame between the Master and the Slave, the time-out timer is reset.

Parameters
*regsregister table for communication exchange
u8sizesize of the register table
Returns
0 if no query, 1..4 if communication error, >4 if correct query processed

Definition at line 790 of file ModbusRtu.h.

791{
792
793 au16regs = regs;
796
797 // check if there is any incoming frame
798 if (u8serno < 4)
799 u8current = port->available();
800 else
801 u8current = softPort->available();
802
803 if (u8current == 0)
804 return 0;
805
806 // check T35 after frame end or still no frame end
807 if (u8current != u8lastRec)
808 {
810 u32time = millis() + T35;
811 return 0;
812 }
813 if (millis() < u32time)
814 return 0;
815
816 u8lastRec = 0;
819 if (i8state < 7)
820 return i8state;
821
822 // check slave id
823 if (au8Buffer[ID] != u8id)
824 {
825 return 0;
826 }
827
828 // validate message: CRC, FCT, address and size
830 if (u8exception > 0)
831 {
832 Serial.println("exception : 1");
833 if (u8exception != NO_REPLY)
834 {
836 sendTxBuffer();
837 }
839 return u8exception;
840 }
841
843 u8lastError = 0;
844
845 Log.verboseln("mb : process message : %d", FUNC);
846
847 // process message
848 switch (au8Buffer[FUNC])
849 {
850 case MB_FC_READ_COILS:
852 return process_FC1(regs, u8size);
853 break;
856 return process_FC3(regs, u8size);
857 break;
858 case MB_FC_WRITE_COIL:
859 return process_FC5(regs, u8size);
860 break;
862 return process_FC6(regs, u8size);
863 break;
865 return process_FC15(regs, u8size);
866 break;
868 return process_FC16(regs, u8size);
869 break;
870 default:
871 break;
872 }
874 return i8state;
875}
@ ID
ID field.
Definition ModbusRtu.h:93
uint8_t u8id
0=master, 1..247=slave number
Definition ModbusRtu.h:157
uint16_t * au16regs
Definition ModbusRtu.h:165
uint8_t u8regsize
Definition ModbusRtu.h:169
uint16_t u16timeOut
Definition ModbusRtu.h:167
void buildException(uint8_t u8exception)
This method builds an exception message.
Definition ModbusRtu.h:1244
uint8_t validateRequest()
This method validates slave incoming messages.
Definition ModbusRtu.h:1128
void sendTxBuffer()
This method transmits au8Buffer to Serial line. Only if u8txenpin != 0, there is a flow handling in o...
Definition ModbusRtu.h:962
int8_t process_FC15(uint16_t *regs, uint8_t u8size)
This method processes function 15 This method writes a bit array assigned by the master.
Definition ModbusRtu.h:1447
int8_t process_FC1(uint16_t *regs, uint8_t u8size)
This method processes functions 1 & 2 This method reads a bit array and transfers it to the master.
Definition ModbusRtu.h:1302
int8_t process_FC5(uint16_t *regs, uint8_t u8size)
This method processes function 5 This method writes a value assigned by the master to a single bit.
Definition ModbusRtu.h:1389
int8_t process_FC6(uint16_t *regs, uint8_t u8size)
This method processes function 6 This method writes a value assigned by the master to a single word.
Definition ModbusRtu.h:1421
int8_t process_FC16(uint16_t *regs, uint8_t u8size)
This method processes function 16 This method writes a word array assigned by the master.
Definition ModbusRtu.h:1502
int8_t process_FC3(uint16_t *regs, uint8_t u8size)
This method processes functions 3 & 4 This method reads a word array and transfers it to the master.
Definition ModbusRtu.h:1357

◆ query()

int8_t Modbus::query ( modbus_t telegram)

only for master

*** Only Modbus Master *** Generate a query to an slave with a modbus_t telegram structure The Master must be in COM_IDLE mode. After it, its state would be COM_WAITING. This method has to be called only in loop() section.

See also
modbus_t
Parameters
modbus_tmodbus telegram structure (id, fct, ...)
Todo
finish function 15

Definition at line 592 of file ModbusRtu.h.

593{
594
596 if (u8id != 0)
597 return -2;
598 if (u8state != COM_IDLE)
599 return -1;
600
601 if ((telegram.u8id == 0) || (telegram.u8id > 247))
602 return -3;
603
604 au16regs = telegram.au16reg;
605 telegram.flags = QUEUED;
607
608 // telegram header
609 au8Buffer[ID] = telegram.u8id;
610 au8Buffer[FUNC] = telegram.u8fct;
611 au8Buffer[ADD_HI] = highByte(telegram.u16RegAdd);
612 au8Buffer[ADD_LO] = lowByte(telegram.u16RegAdd);
613
614 switch (telegram.u8fct)
615 {
616 case MB_FC_READ_COILS:
620 au8Buffer[NB_HI] = highByte(telegram.u16CoilsNo);
621 au8Buffer[NB_LO] = lowByte(telegram.u16CoilsNo);
622 u8BufferSize = 6;
623 break;
624 case MB_FC_WRITE_COIL:
625 au8Buffer[NB_HI] = ((telegram.u16CoilsNo > 0) ? 0xff : 0);
626 au8Buffer[NB_LO] = 0;
627 u8BufferSize = 6;
628 break;
630 au8Buffer[NB_HI] = highByte(telegram.u16CoilsNo);
631 au8Buffer[NB_LO] = lowByte(telegram.u16CoilsNo);
632 u8BufferSize = 6;
633 break;
634 case MB_FC_WRITE_MULTIPLE_COILS: // TODO: implement "sending coils"
635 u8regsno = telegram.u16CoilsNo / 16;
636 u8bytesno = u8regsno * 2;
637 if ((telegram.u16CoilsNo % 16) != 0)
638 {
639 u8bytesno++;
640 u8regsno++;
641 }
642
643 au8Buffer[NB_HI] = highByte(telegram.u16CoilsNo);
644 au8Buffer[NB_LO] = lowByte(telegram.u16CoilsNo);
646 u8BufferSize = 7;
647
648 u8regsno = u8bytesno = 0;
649 break;
650
652 {
653
654 break;
655 }
657 au8Buffer[NB_HI] = highByte(telegram.u16CoilsNo);
658 au8Buffer[NB_LO] = lowByte(telegram.u16CoilsNo);
659 au8Buffer[NB_LO + 1] = (uint8_t)(telegram.u16CoilsNo * 2);
660 u8BufferSize = 7;
661
662 for (uint16_t i = 0; i < telegram.u16CoilsNo; i++)
663 {
665 u8BufferSize++;
667 u8BufferSize++;
668 }
669 break;
670 }
671
672 sendTxBuffer();
674 return 0;
675}
@ COM_WAITING
Definition ModbusRtu.h:114
@ NB_LO
Number of coils or registers low byte.
Definition ModbusRtu.h:98
@ ADD_LO
Address low byte.
Definition ModbusRtu.h:96
@ NB_HI
Number of coils or registers high byte.
Definition ModbusRtu.h:97
@ ADD_HI
Address high byte.
Definition ModbusRtu.h:95
#define ku8MBLinkTestOmronMX2Only
Modbus function 0x08 Test.