rllib  1
Classes | Public Types | Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
rlModbus Class Reference

#include <rlmodbus.h>

Collaboration diagram for rlModbus:
Collaboration graph
[legend]

Classes

union  DATA
 

Public Types

enum  Modbus {
  MODBUS_CHECKSUM_ERROR = -2, MODBUS_ERROR = -1, MODBUS_SUCCESS = 0, MODBUS_RTU = 1,
  MODBUS_ASCII = 2
}
 
enum  ModbusFunctionCodes {
  ReadCoilStatus = 1, ReadInputStatus = 2, ReadHoldingRegisters = 3, ReadInputRegisters = 4,
  ForceSingleCoil = 5, PresetSingleRegister = 6, ReadExceptionStatus = 7, FetchCommEventCtr = 11,
  FetchCommEventLog = 12, ForceMultipleCoils = 15, PresetMultipleRegs = 16, ReportSlaveID = 17,
  ReadGeneralReference = 20, WriteGeneralReference = 21, MaskWrite4XRegisters = 22, ReadWrite4XRegisters = 23,
  ReadFifoQueue = 24
}
 

Public Member Functions

 rlModbus (long max_telegram_length=1024, int mode=MODBUS_RTU, char end_delimitor=0x0a)
 
virtual ~rlModbus ()
 
int write (int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
 
int request (int slave, int function, int start_adr, int num_register)
 
int response (int *slave, int *function, unsigned char *data, int timeout=1000)
 
int readRequest (int *slave, int *function, unsigned char *data, int timeout=1000, int *transactionID=NULL)
 
void registerSocket (rlSocket *socket)
 
void registerSerial (rlSerial *serial)
 
int data2int (const unsigned char *data)
 
int int2data (int val, unsigned char *data)
 
int intsize ()
 
int readCoilStatus (int slave, int start_adr, int number_of_coils, unsigned char *status, int timeout=1000)
 
int readInputStatus (int slave, int start_adr, int number_of_inputs, unsigned char *status, int timeout=1000)
 
int readHoldingRegisters (int slave, int start_adr, int number_of_registers, int *registers, int timeout=1000)
 
int readInputRegisters (int slave, int start_adr, int number_of_registers, int *registers, int timeout=1000)
 
int forceSingleCoil (int slave, int coil_adr, int value, int timeout=1000)
 
int presetSingleRegister (int slave, int register_adr, int value, int timeout=1000)
 
int forceMultipleCoils (int slave, int coil_adr, int number_of_coils, unsigned char *coils, int timeout=1000)
 
int presetMultipleRegisters (int slave, int start_adr, int number_of_registers, int *registers, int timeout=1000)
 

Public Attributes

int autoreconnectSocket
 

Private Member Functions

int buf2int_rtu (unsigned char *buf)
 
void int2buf_rtu (int i, unsigned char *buf)
 
int buf2int_ascii (unsigned char *buf)
 
void int2buf_ascii (int i, unsigned char *buf)
 
void insertLRC (int len)
 
void insertCRC (int len)
 
int LRCerror (int len)
 
int CRCerror (int len)
 

Private Attributes

rlSockets
 
rlSerialtty
 
unsigned char * tel
 
long maxtel
 
int mode
 
char delimitor
 

Detailed Description

This class implements the modbus protocol.
You can use serial interfaces or TCP/IP.
Modbus RTU and ASCII are available.
All Modbus requests include "slave" and "function".
Then some bytes follow, which are specific to a given function.
The request is then terminated by a checksum.
This table shows the bytes that are specific to a given function.
Function Query Response
01 Read Coil Status Start adr high
Start adr low
Number of points high
Number of points low
Data Byte Count
Data1
Data2 …
8 points per byte
02 Read Input Status Start adr high
Start adr low
Number of points high
Number of points low
Data Byte Count
Data1
Data2 …
8 points per byte
03 Read Holding Registers Start adr high
Start adr low
Number of points high
Number of points low
Data Byte Count
Data1 high
Data1 low
Data2 high
Data2 low…
1 point needs 2 bytes
04 Read Input Registers Start adr high
Start adr low
Number of points high
Number of points low
Data Byte Count
Data1 high
Data1 low
Data2 high
Data2 low…
1 point needs 2 bytes
05 Force Single Coil Coil adr high
Coil adr low
Force data high
Force data low
Coil adr high
Coil adr low
Force data high
Force data low
Force data ON = 0x0ff00
Force data OFF = 0
06 Preset Single Register Register adr high
Register adr low
Preset data high
Preset data low
Register adr high
Register adr low
Preset data high
Preset data low

07 Read Exception Status
Coil data 8 exception status coils returned
11 Fetch Comm Event Counter
Status high
Status low
Event Count high
Event Count low

12 Fetch Comm Event Log

See: PI_MODBUS_300.pdf
15 Force Multiple Coils Coil adr high
Coil adr low
Number of coils high
Number of coils low
Force data byte count
Force data1
Force data2 ...
Coil adr high
Coil adr low
Number of coils high
Number of coils low
8 coils per byte
16 Preset Multiple Registers Start adr high
Start adr low
Number of registers high
Number of registers low
Data byte count
Data1 high
Data1 low
Data2 high
Data2 low …
Start adr high
Start adr low
Number of registers high
Number of registers low

17 Report Slave ID
Data Byte count ~ device specific See: PI_MODBUS_300.pdf
20 Read General Reference

See: PI_MODBUS_300.pdf
21 Write General Reference

See: PI_MODBUS_300.pdf
22 Mask Write 4X Register

See: PI_MODBUS_300.pdf
23 Read/Write 4X Registers

See: PI_MODBUS_300.pdf
24 Read FIFO Queue

See: PI_MODBUS_300.pdf

Definition at line 148 of file rlmodbus.h.

Member Enumeration Documentation

◆ Modbus

Enumerator
MODBUS_CHECKSUM_ERROR 
MODBUS_ERROR 
MODBUS_SUCCESS 
MODBUS_RTU 
MODBUS_ASCII 

Definition at line 173 of file rlmodbus.h.

◆ ModbusFunctionCodes

Enumerator
ReadCoilStatus 
ReadInputStatus 
ReadHoldingRegisters 
ReadInputRegisters 
ForceSingleCoil 
PresetSingleRegister 
ReadExceptionStatus 
FetchCommEventCtr 
FetchCommEventLog 
ForceMultipleCoils 
PresetMultipleRegs 
ReportSlaveID 
ReadGeneralReference 
WriteGeneralReference 
MaskWrite4XRegisters 
ReadWrite4XRegisters 
ReadFifoQueue 

Definition at line 182 of file rlmodbus.h.

Constructor & Destructor Documentation

◆ rlModbus()

rlModbus::rlModbus ( long  max_telegram_length = 1024,
int  mode = MODBUS_RTU,
char  end_delimitor = 0x0a 
)

Definition at line 20 of file rlmodbus.cpp.

21 {
22  if(max_telegram_length < 256) max_telegram_length = 256;
23  tel = new unsigned char[max_telegram_length];
24  maxtel = max_telegram_length;
25  mode = _mode;
26  delimitor = end_delimitor;
27  s = NULL;
28  tty = NULL;
30 }
int mode
Definition: rlmodbus.h:252
rlSerial * tty
Definition: rlmodbus.h:249
long maxtel
Definition: rlmodbus.h:251
int autoreconnectSocket
Definition: rlmodbus.h:214
unsigned char * tel
Definition: rlmodbus.h:250
rlSocket * s
Definition: rlmodbus.h:248
char delimitor
Definition: rlmodbus.h:253

◆ ~rlModbus()

rlModbus::~rlModbus ( )
virtual

Definition at line 32 of file rlmodbus.cpp.

33 {
34  if(tel != NULL) delete [] tel;
35 }
unsigned char * tel
Definition: rlmodbus.h:250

Member Function Documentation

◆ buf2int_ascii()

int rlModbus::buf2int_ascii ( unsigned char *  buf)
private

Definition at line 614 of file rlmodbus.cpp.

615 {
616  int val;
617 
618  sscanf((char *) buf,"%04X",&val);
619  return val;
620 }

◆ buf2int_rtu()

int rlModbus::buf2int_rtu ( unsigned char *  buf)
private

Definition at line 599 of file rlmodbus.cpp.

600 {
601  return (buf[0]*256 + buf[1]);
602 }

◆ CRCerror()

int rlModbus::CRCerror ( int  len)
private

Definition at line 748 of file rlmodbus.cpp.

749 {
750  unsigned char crc_high, crc_low;
751  unsigned index;
752  int i;
753 
754  if(len < 2) return 1;
755  crc_high = crc_low = 0xff;
756  for(i=0; i<len-2; i++)
757  {
758  index = crc_low ^ tel[i];
759  crc_low = crc_high ^ array_crc_low[index];
760  crc_high = array_crc_high[index];
761  }
762  if(crc_low != tel[len-2]) return 1;
763  if(crc_high != tel[len-1]) return 1;
764  return 0;
765 }
static const unsigned char array_crc_low[]
Definition: rlmodbus.cpp:669
static const unsigned char array_crc_high[]
Definition: rlmodbus.cpp:700
unsigned char * tel
Definition: rlmodbus.h:250

◆ data2int()

int rlModbus::data2int ( const unsigned char *  data)

Definition at line 37 of file rlmodbus.cpp.

38 {
39  return (data[0]*256)+data[1];
40 }

◆ forceMultipleCoils()

int rlModbus::forceMultipleCoils ( int  slave,
int  coil_adr,
int  number_of_coils,
unsigned char *  coils,
int  timeout = 1000 
)
We assume positive values for registers: 0 <= registers < 256*256

Definition at line 922 of file rlmodbus.cpp.

923 {
924  int ret;
925  int ret_slave, ret_function;
926  unsigned char data[256];
927 
928  data[0] = (coil_adr / 256) & 0x0ff;
929  data[1] = coil_adr & 0x0ff;
930  data[2] = (number_of_coils / 256) & 0x0ff;
931  data[3] = number_of_coils & 0x0ff;
932  data[4] = (number_of_coils / 8) + 1;
933  int i;
934  for(i=0; i<data[4]; i++) data[5+i] = coils[i];
935  ret = write(slave, ForceMultipleCoils, data, 5+i);
936  if(ret < 0) return MODBUS_ERROR;
937 
938  ret = response(&ret_slave, &ret_function, data, timeout);
939  if(ret < 0 || ret_slave != slave || ret_function != ForceMultipleCoils)
940  {
941  printf("rlMOdbus::ERROR response ret=%d slave=%d ret_slave=%d function=%d ret_function=%d timeout=%d\n",
942  ret, slave, ret_slave, ForceMultipleCoils, ret_function, timeout);
943  return MODBUS_ERROR;
944  }
945 
946  return ret;
947 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54
int response(int *slave, int *function, unsigned char *data, int timeout=1000)
Definition: rlmodbus.cpp:132

◆ forceSingleCoil()

int rlModbus::forceSingleCoil ( int  slave,
int  coil_adr,
int  value,
int  timeout = 1000 
)

Definition at line 873 of file rlmodbus.cpp.

874 {
875  int ret;
876  int ret_slave, ret_function;
877  unsigned char data[256];
878 
879  data[0] = (coil_adr / 256) & 0x0ff;
880  data[1] = coil_adr & 0x0ff;
881  data[2] = 0;
882  data[3] = 0;
883  if(value) data[2] = 0x0ff;
884  ret = write(slave, ForceSingleCoil, data, 4);
885  if(ret < 0) return MODBUS_ERROR;
886 
887  ret = response(&ret_slave, &ret_function, data, timeout);
888  if(ret < 0 || ret_slave != slave || ret_function != ForceSingleCoil)
889  {
890  printf("rlMOdbus::ERROR response ret=%d slave=%d ret_slave=%d function=%d ret_function=%d timeout=%d\n",
891  ret, slave, ret_slave, ForceSingleCoil, ret_function, timeout);
892  return MODBUS_ERROR;
893  }
894 
895  return ret;
896 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54
int response(int *slave, int *function, unsigned char *data, int timeout=1000)
Definition: rlmodbus.cpp:132

◆ insertCRC()

void rlModbus::insertCRC ( int  len)
private

Definition at line 730 of file rlmodbus.cpp.

731 {
732  unsigned char crc_high, crc_low;
733  unsigned index;
734  int i;
735 
736  if(len < 0) return;
737  crc_high = crc_low = 0xff;
738  for(i=0; i<len; i++)
739  {
740  index = crc_low ^ tel[i];
741  crc_low = crc_high ^ array_crc_low[index];
742  crc_high = array_crc_high[index];
743  }
744  tel[len] = crc_low;
745  tel[len+1] = crc_high;
746 }
static const unsigned char array_crc_low[]
Definition: rlmodbus.cpp:669
static const unsigned char array_crc_high[]
Definition: rlmodbus.cpp:700
unsigned char * tel
Definition: rlmodbus.h:250

◆ insertLRC()

void rlModbus::insertLRC ( int  len)
private

Definition at line 627 of file rlmodbus.cpp.

628 {
629  unsigned char lrc;
630  int i,high,low,val;
631 
632  if(len < 0) return;
633  lrc = 0;
634  for(i=1; i<len; i+=2) // exclude starting ':' and trailing <CR><LF>
635  {
636  sscanf((const char *) &tel[i], "%1X", &high);
637  sscanf((const char *) &tel[i+1], "%1X", &low);
638  val = high*16 + low;
639  lrc += val;
640  }
641  lrc = ((unsigned char)(-((char) lrc)));
642  sprintf((char *) &tel[len],"%02X",(unsigned int) lrc);
643 }
unsigned char * tel
Definition: rlmodbus.h:250

◆ int2buf_ascii()

void rlModbus::int2buf_ascii ( int  i,
unsigned char *  buf 
)
private

Definition at line 622 of file rlmodbus.cpp.

623 {
624  sprintf((char *) buf,"%04X",i);
625 }

◆ int2buf_rtu()

void rlModbus::int2buf_rtu ( int  i,
unsigned char *  buf 
)
private

Definition at line 604 of file rlmodbus.cpp.

605 {
606  int high, low;
607 
608  high = i / 256;
609  low = i & 0x0ff;
610  buf[0] = (unsigned char) high;
611  buf[1] = (unsigned char) low;
612 }

◆ int2data()

int rlModbus::int2data ( int  val,
unsigned char *  data 
)

Definition at line 42 of file rlmodbus.cpp.

43 {
44  data[0] = (unsigned char) val / 256;
45  data[1] = (unsigned char) val & 0x0ff;
46  return 0;
47 }

◆ intsize()

int rlModbus::intsize ( )

Definition at line 49 of file rlmodbus.cpp.

50 {
51  return 2;
52 }

◆ LRCerror()

int rlModbus::LRCerror ( int  len)
private

Definition at line 645 of file rlmodbus.cpp.

646 {
647  unsigned char *cptr;
648  unsigned char lrc;
649  int i,high,low,val;
650 
651  if(len < 0) return 1;
652  tel[maxtel-1] = '\0';
653  cptr = (unsigned char *) strchr((char *)tel,':');
654  if(cptr == NULL) return 1;
655  cptr++;
656  lrc = 0;
657  for(i=1; i<len+2; i+=2) // exclude starting ':' and trailing <CR><LF>
658  { // len is without lrc -> len+2
659  sscanf((const char *) cptr++, "%1X", &high);
660  sscanf((const char *) cptr++, "%1X", &low);
661  val = high*16 + low;
662  lrc += val;
663  }
664  if(lrc == 0) return 0; // lrc ok
665  return 1; // lrc error
666 }
long maxtel
Definition: rlmodbus.h:251
unsigned char * tel
Definition: rlmodbus.h:250

◆ presetMultipleRegisters()

int rlModbus::presetMultipleRegisters ( int  slave,
int  start_adr,
int  number_of_registers,
int *  registers,
int  timeout = 1000 
)
We assume positive values for registers: 0 <= registers < 256*256

Definition at line 949 of file rlmodbus.cpp.

950 {
951  int ret;
952  int ret_slave, ret_function;
953  unsigned char data[256];
954 
955  data[0] = (start_adr / 256) & 0x0ff;
956  data[1] = start_adr & 0x0ff;
957  data[2] = (number_of_registers / 256) & 0x0ff;
958  data[3] = number_of_registers & 0x0ff;
959  data[4] = (number_of_registers * 2) & 0x0ff;
960  int j=5;
961  for(int i=0; i<number_of_registers; i++)
962  {
963  data[j++] = (registers[i] / 256) & 0x0ff;
964  data[j++] = registers[i] & 0x0ff;
965  }
966  ret = write(slave, PresetMultipleRegs, data, j);
967  if(ret < 0) return MODBUS_ERROR;
968 
969  ret = response(&ret_slave, &ret_function, data, timeout);
970  if(ret < 0 || ret_slave != slave || ret_function != PresetMultipleRegs)
971  {
972  printf("rlMOdbus::ERROR response ret=%d slave=%d ret_slave=%d function=%d ret_function=%d timeout=%d\n",
973  ret, slave, ret_slave, PresetMultipleRegs, ret_function, timeout);
974  return MODBUS_ERROR;
975  }
976 
977  return ret;
978 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54
int response(int *slave, int *function, unsigned char *data, int timeout=1000)
Definition: rlmodbus.cpp:132

◆ presetSingleRegister()

int rlModbus::presetSingleRegister ( int  slave,
int  register_adr,
int  value,
int  timeout = 1000 
)
We assume positive values for registers: 0 <= value < 256*256

Definition at line 898 of file rlmodbus.cpp.

899 {
900  int ret;
901  int ret_slave, ret_function;
902  unsigned char data[256];
903 
904  data[0] = (register_adr / 256) & 0x0ff;
905  data[1] = register_adr & 0x0ff;
906  data[2] = (value / 256) & 0x0ff;
907  data[3] = value & 0x0ff;
908  ret = write(slave, PresetSingleRegister, data, 4);
909  if(ret < 0) return MODBUS_ERROR;
910 
911  ret = response(&ret_slave, &ret_function, data, timeout);
912  if(ret < 0 || ret_slave != slave || ret_function != PresetSingleRegister)
913  {
914  printf("rlMOdbus::ERROR response ret=%d slave=%d ret_slave=%d function=%d ret_function=%d timeout=%d\n",
915  ret, slave, ret_slave, PresetSingleRegister, ret_function, timeout);
916  return MODBUS_ERROR;
917  }
918 
919  return ret;
920 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54
int response(int *slave, int *function, unsigned char *data, int timeout=1000)
Definition: rlmodbus.cpp:132

◆ readCoilStatus()

int rlModbus::readCoilStatus ( int  slave,
int  start_adr,
int  number_of_coils,
unsigned char *  status,
int  timeout = 1000 
)

Definition at line 767 of file rlmodbus.cpp.

768 {
769  int ret;
770  int ret_slave, ret_function;
771  unsigned char data[256];
772 
773  data[0] = (start_adr / 256) & 0x0ff;
774  data[1] = start_adr & 0x0ff;
775  data[2] = (number_of_coils / 256) & 0x0ff;
776  data[3] = number_of_coils & 0x0ff;
777  ret = write(slave, ReadCoilStatus, data, 4);
778  if(ret < 0) return MODBUS_ERROR;
779 
780  ret = response(&ret_slave, &ret_function, status, timeout);
781  if(ret < 0 || ret_slave != slave || ret_function != ReadCoilStatus)
782  {
783  printf("rlMOdbus::ERROR response ret=%d slave=%d ret_slave=%d function=%d ret_function=%d timeout=%d\n",
784  ret, slave, ret_slave, ReadCoilStatus, ret_function, timeout);
785  return MODBUS_ERROR;
786  }
787 
788  return ret;
789 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54
int response(int *slave, int *function, unsigned char *data, int timeout=1000)
Definition: rlmodbus.cpp:132

◆ readHoldingRegisters()

int rlModbus::readHoldingRegisters ( int  slave,
int  start_adr,
int  number_of_registers,
int *  registers,
int  timeout = 1000 
)
We assume positive values for registers: 0 <= registers < 256*256

Definition at line 815 of file rlmodbus.cpp.

816 {
817  int ret;
818  int ret_slave, ret_function;
819  unsigned char data[256];
820 
821  data[0] = (start_adr / 256) & 0x0ff;
822  data[1] = start_adr & 0x0ff;
823  data[2] = (number_of_registers / 256) & 0x0ff;
824  data[3] = number_of_registers & 0x0ff;
825  ret = write(slave, ReadHoldingRegisters, data, 4);
826  if(ret < 0) return MODBUS_ERROR;
827 
828  ret = response(&ret_slave, &ret_function, data, timeout);
829  if(ret < 0 || ret_slave != slave || ret_function != ReadHoldingRegisters)
830  {
831  printf("rlMOdbus::ERROR response ret=%d slave=%d ret_slave=%d function=%d ret_function=%d timeout=%d\n",
832  ret, slave, ret_slave, ReadHoldingRegisters, ret_function, timeout);
833  return MODBUS_ERROR;
834  }
835  int j = 0;
836  for(int i=0; i<ret; i+=2)
837  {
838  registers[j++] = ((data[i] * 256) & 0x0ff) + (data[i+1] & 0x0ff);
839  }
840 
841  return ret;
842 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54
int response(int *slave, int *function, unsigned char *data, int timeout=1000)
Definition: rlmodbus.cpp:132

◆ readInputRegisters()

int rlModbus::readInputRegisters ( int  slave,
int  start_adr,
int  number_of_registers,
int *  registers,
int  timeout = 1000 
)
We assume positive values for registers: 0 <= registers < 256*256

Definition at line 844 of file rlmodbus.cpp.

845 {
846  int ret;
847  int ret_slave, ret_function;
848  unsigned char data[256];
849 
850  data[0] = (start_adr / 256) & 0x0ff;
851  data[1] = start_adr & 0x0ff;
852  data[2] = (number_of_registers / 256) & 0x0ff;
853  data[3] = number_of_registers & 0x0ff;
854  ret = write(slave, ReadInputRegisters, data, 4);
855  if(ret < 0) return MODBUS_ERROR;
856 
857  ret = response(&ret_slave, &ret_function, data, timeout);
858  if(ret < 0 || ret_slave != slave || ret_function != ReadInputRegisters)
859  {
860  printf("rlMOdbus::ERROR response ret=%d slave=%d ret_slave=%d function=%d ret_function=%d timeout=%d\n",
861  ret, slave, ret_slave, ReadInputRegisters, ret_function, timeout);
862  return MODBUS_ERROR;
863  }
864  int j=0;
865  for(int i=0; i<ret; i+=2)
866  {
867  registers[j++] = ((data[i] * 256) & 0x0ff) + (data[i+1] & 0x0ff);
868  }
869 
870  return ret;
871 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54
int response(int *slave, int *function, unsigned char *data, int timeout=1000)
Definition: rlmodbus.cpp:132

◆ readInputStatus()

int rlModbus::readInputStatus ( int  slave,
int  start_adr,
int  number_of_inputs,
unsigned char *  status,
int  timeout = 1000 
)

Definition at line 791 of file rlmodbus.cpp.

792 {
793  int ret;
794  int ret_slave, ret_function;
795  unsigned char data[256];
796 
797  data[0] = (start_adr / 256) & 0x0ff;
798  data[1] = start_adr & 0x0ff;
799  data[2] = (number_of_inputs / 256) & 0x0ff;
800  data[3] = number_of_inputs & 0x0ff;
801  ret = write(slave, ReadInputStatus, data, 4);
802  if(ret < 0) return MODBUS_ERROR;
803 
804  ret = response(&ret_slave, &ret_function, status, timeout);
805  if(ret < 0 || ret_slave != slave || ret_function != ReadInputStatus)
806  {
807  printf("rlMOdbus::ERROR response ret=%d slave=%d ret_slave=%d function=%d ret_function=%d timeout=%d\n",
808  ret, slave, ret_slave, ReadInputStatus, ret_function, timeout);
809  return MODBUS_ERROR;
810  }
811 
812  return ret;
813 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54
int response(int *slave, int *function, unsigned char *data, int timeout=1000)
Definition: rlmodbus.cpp:132

◆ readRequest()

int rlModbus::readRequest ( int *  slave,
int *  function,
unsigned char *  data,
int  timeout = 1000,
int *  transactionID = NULL 
)

Definition at line 352 of file rlmodbus.cpp.

353 {
354  unsigned char *telptr;
355  int ret,len,byte_count,i,itel,val;
356 
357  len = 0;
358  if(mode != MODBUS_ASCII && mode != MODBUS_RTU) return MODBUS_ERROR;
359  if(s != NULL)
360  {
361  if(s->isConnected() == 0) return MODBUS_ERROR;
362  if(mode == MODBUS_RTU)
363  {
364  if(s->read((char *) tel, 6, timeout) <= 0) return MODBUS_ERROR;
365  if(transactionID != NULL) *transactionID = tel[0] * 256 + tel[1]; // return transactionID
366  // bytes 0,1 Transaction ID faithfully copied from the request message
367  // bytes 2,3 Protocol number always zero
368  // byte 4 Response length (upper byte) Always zero
369  // byte 5 Response length (lower byte). Equal to the number of bytes which follow
370  // Here comes the normal Modus telegram
371  if(s->read((char *) tel, 2, timeout) <= 0) return MODBUS_ERROR;
372  *slave = tel[0];
373  *function = tel[1];
374  switch(*function)
375  {
376  case ReadCoilStatus:
377  case ReadInputStatus:
379  case ReadInputRegisters:
380  case ForceSingleCoil:
382  if(s->read((char *) data, 4, timeout) <= 0) return MODBUS_ERROR;
383  return 4;
384  case ReadExceptionStatus:
385  case FetchCommEventCtr:
386  case FetchCommEventLog:
387  case ReportSlaveID:
388  return 0;
389  case ForceMultipleCoils:
390  case PresetMultipleRegs:
391  if(s->read((char *) data, 5, timeout) <= 0) return MODBUS_ERROR;
392  byte_count = data[4];
393  if(s->read((char *) &data[4], byte_count, timeout) <= 0) return MODBUS_ERROR;
394  return 4+byte_count;
397  if(s->read((char *) data, 1, timeout) <= 0) return MODBUS_ERROR;
398  byte_count = data[0];
399  if(s->read((char *) data, byte_count, timeout) <= 0) return MODBUS_ERROR;
400  return byte_count;
402  if(s->read((char *) data, 6, timeout) <= 0) return MODBUS_ERROR;
403  return 6;
405  if(s->read((char *) data, 9, timeout) <= 0) return MODBUS_ERROR;
406  byte_count = data[8];
407  if(s->read((char *) &data[8], byte_count, timeout) <= 0) return MODBUS_ERROR;
408  return 8+byte_count;
409  case ReadFifoQueue:
410  if(s->read((char *) data, 2, timeout) <= 0) return MODBUS_ERROR;
411  return 2;
412  default:
413  return MODBUS_ERROR;
414  }
415  }
416  }
417  else if(tty != NULL)
418  {
419  if(mode == MODBUS_ASCII)
420  {
421  //printf("modbus ascii\n");
422  for(i=0; i<maxtel; i++)
423  {
424  ret = tty->select(timeout);
425  if(ret == 0) return MODBUS_ERROR;
426  //printf("readChar\n");
427  itel = tty->readChar();
428  if(itel < 0) return MODBUS_ERROR;
429  tel[i] = (unsigned char) itel;
430  if(tel[i] == 0x0d && delimitor != 0x0a) break;
431  if(tel[i] == 0x0a) break;
432  }
433  tel[i] = '\0';
434  telptr = (unsigned char *) strchr((const char *) tel,':');
435  if(telptr == NULL) return MODBUS_ERROR;
436  len++;
437  sscanf((char *) &telptr[len],"%02X",slave); len += 2;
438  sscanf((char *) &telptr[len],"%02X",function); len += 2;
439  switch(*function)
440  {
441  case ReadCoilStatus:
442  case ReadInputStatus:
444  case ReadInputRegisters:
445  case ForceSingleCoil:
447  sscanf((char *) &telptr[len],"%02X",&val); data[0] = (unsigned char) val; len += 2;
448  sscanf((char *) &telptr[len],"%02X",&val); data[1] = (unsigned char) val; len += 2;
449  sscanf((char *) &telptr[len],"%02X",&val); data[2] = (unsigned char) val; len += 2;
450  sscanf((char *) &telptr[len],"%02X",&val); data[3] = (unsigned char) val; len += 2;
451  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
452  return 4;
453  case ReadExceptionStatus:
454  case FetchCommEventCtr:
455  case FetchCommEventLog:
456  case ReportSlaveID:
457  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
458  return 0;
459  case ForceMultipleCoils:
460  case PresetMultipleRegs:
461  sscanf((char *) &telptr[len],"%02X",&val); data[0] = (unsigned char) val; len += 2;
462  sscanf((char *) &telptr[len],"%02X",&val); data[1] = (unsigned char) val; len += 2;
463  sscanf((char *) &telptr[len],"%02X",&val); data[2] = (unsigned char) val; len += 2;
464  sscanf((char *) &telptr[len],"%02X",&val); data[3] = (unsigned char) val; len += 2;
465  sscanf((char *) &telptr[len],"%02X",&byte_count); len += 2;
466  for(i=0; i<byte_count; i++)
467  {
468  sscanf((char *) &telptr[len],"%02X",&val); data[4+i] = (unsigned char) val; len += 2;
469  }
470  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
471  return 4+byte_count;
474  sscanf((char *) &telptr[len],"%02X",&byte_count); len += 2;
475  for(i=0; i<byte_count; i++)
476  {
477  sscanf((char *) &telptr[len],"%02X",&val); data[i] = (unsigned char) val; len += 2;
478  }
479  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
480  return byte_count;
482  sscanf((char *) &telptr[len],"%02X",&val); data[0] = (unsigned char) val; len += 2;
483  sscanf((char *) &telptr[len],"%02X",&val); data[1] = (unsigned char) val; len += 2;
484  sscanf((char *) &telptr[len],"%02X",&val); data[2] = (unsigned char) val; len += 2;
485  sscanf((char *) &telptr[len],"%02X",&val); data[3] = (unsigned char) val; len += 2;
486  sscanf((char *) &telptr[len],"%02X",&val); data[4] = (unsigned char) val; len += 2;
487  sscanf((char *) &telptr[len],"%02X",&val); data[5] = (unsigned char) val; len += 2;
488  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
489  return 6;
491  sscanf((char *) &telptr[len],"%02X",&val); data[0] = (unsigned char) val; len += 2;
492  sscanf((char *) &telptr[len],"%02X",&val); data[1] = (unsigned char) val; len += 2;
493  sscanf((char *) &telptr[len],"%02X",&val); data[2] = (unsigned char) val; len += 2;
494  sscanf((char *) &telptr[len],"%02X",&val); data[3] = (unsigned char) val; len += 2;
495  sscanf((char *) &telptr[len],"%02X",&val); data[4] = (unsigned char) val; len += 2;
496  sscanf((char *) &telptr[len],"%02X",&val); data[5] = (unsigned char) val; len += 2;
497  sscanf((char *) &telptr[len],"%02X",&val); data[6] = (unsigned char) val; len += 2;
498  sscanf((char *) &telptr[len],"%02X",&val); data[7] = (unsigned char) val; len += 2;
499  sscanf((char *) &telptr[len],"%02X",&byte_count); len += 2;
500  for(i=0; i<byte_count; i++)
501  {
502  sscanf((char *) &telptr[len],"%02X",&val); data[8+i] = (unsigned char) val; len += 2;
503  }
504  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
505  return 8+byte_count;
506  case ReadFifoQueue:
507  sscanf((char *) &telptr[len],"%02X",&val); data[0] = (unsigned char) val; len += 2;
508  sscanf((char *) &telptr[len],"%02X",&val); data[1] = (unsigned char) val; len += 2;
509  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
510  return 2;
511  default:
512  return MODBUS_ERROR;
513  }
514  }
515  else if(mode == MODBUS_RTU)
516  {
517  ret = tty->select(timeout);
518  if(ret == 0) return MODBUS_ERROR;
519  if(tty->readBlock(tel, 2, timeout) <= 0) return MODBUS_ERROR;
520  *slave = tel[len++];
521  *function = tel[len++];
522  ret = tty->select(timeout);
523  if(ret == 0) return MODBUS_ERROR;
524  switch(*function)
525  {
526  case ReadCoilStatus:
527  case ReadInputStatus:
529  case ReadInputRegisters:
530  case ForceSingleCoil:
532  if(tty->readBlock(data, 4+2, timeout) <= 0) return MODBUS_ERROR;
533  memcpy(&tel[len],data,4+2); len += 4+2;
534  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
535  return 4;
536  case ReadExceptionStatus:
537  case FetchCommEventCtr:
538  case FetchCommEventLog:
539  case ReportSlaveID:
540  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
541  return 0;
542  case ForceMultipleCoils:
543  case PresetMultipleRegs:
544  if(tty->readBlock(data, 5, timeout) <= 0) return MODBUS_ERROR;
545  memcpy(&tel[len],data,5); len += 5;
546  byte_count = data[4];
547  if(tty->readBlock(&data[4], byte_count+2, timeout) <= 0) return MODBUS_ERROR;
548  memcpy(&tel[len],&data[4],byte_count+2); len += byte_count+2;
549  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
550  return 4+byte_count;
553  if(tty->readBlock(data, 1, timeout) <= 0) return MODBUS_ERROR;
554  memcpy(&tel[len],data,1); len++;
555  byte_count = data[0];
556  if(tty->readBlock(data, byte_count+2, timeout) <= 0) return MODBUS_ERROR;
557  memcpy(&tel[len],data,byte_count+2); len += byte_count+2;
558  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
559  return byte_count;
561  if(tty->readBlock(data, 6+2, timeout) <= 0) return MODBUS_ERROR;
562  memcpy(&tel[len],data,6+2); len += 6+2;
563  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
564  return 6;
566  if(tty->readBlock(data, 9, timeout) <= 0) return MODBUS_ERROR;
567  memcpy(&tel[len],data,9); len += 9;
568  byte_count = data[8];
569  if(tty->readBlock(&data[8], byte_count+2, timeout) <= 0) return MODBUS_ERROR;
570  memcpy(&tel[len],&data[8],byte_count+2); len += byte_count+2;
571  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
572  return 8+byte_count;
573  case ReadFifoQueue:
574  if(tty->readBlock(data, 2+2, timeout) <= 0) return MODBUS_ERROR;
575  memcpy(&tel[len],data,2+2); len += 2+2;
576  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
577  return 2;
578  default:
579  return MODBUS_ERROR;
580  }
581  }
582  }
583  else return MODBUS_ERROR;
584  return MODBUS_SUCCESS;
585 }
int LRCerror(int len)
Definition: rlmodbus.cpp:645
int readBlock(unsigned char *buf, int len, int timeout=-1)
Definition: rlserial.cpp:498
int mode
Definition: rlmodbus.h:252
rlSerial * tty
Definition: rlmodbus.h:249
long maxtel
Definition: rlmodbus.h:251
unsigned char * tel
Definition: rlmodbus.h:250
int select(int timeout=500)
Definition: rlserial.cpp:719
int read(void *buf, int len, int timeout=0)
Definition: rlsocket.cpp:191
rlSocket * s
Definition: rlmodbus.h:248
int readChar()
Definition: rlserial.cpp:405
char delimitor
Definition: rlmodbus.h:253
int isConnected()
Definition: rlsocket.cpp:559
int CRCerror(int len)
Definition: rlmodbus.cpp:748

◆ registerSerial()

void rlModbus::registerSerial ( rlSerial serial)

Definition at line 593 of file rlmodbus.cpp.

594 {
595  s = NULL;
596  tty = serial;
597 }
rlSerial * tty
Definition: rlmodbus.h:249
rlSocket * s
Definition: rlmodbus.h:248

◆ registerSocket()

void rlModbus::registerSocket ( rlSocket socket)

Definition at line 587 of file rlmodbus.cpp.

588 {
589  tty = NULL;
590  s = socket;
591 }
rlSerial * tty
Definition: rlmodbus.h:249
rlSocket * s
Definition: rlmodbus.h:248

◆ request()

int rlModbus::request ( int  slave,
int  function,
int  start_adr,
int  num_register 
)

Definition at line 121 of file rlmodbus.cpp.

122 {
123  unsigned char data[4];
124 
125  data[0] = (unsigned char) ( start_adr / 256 );
126  data[1] = (unsigned char) ( start_adr & 0x0ff );
127  data[2] = (unsigned char) ( num_register / 256 );
128  data[3] = (unsigned char) ( num_register & 0x0ff );
129  return write(slave, function, data, 4);
130 }
int write(int slave, int function, const unsigned char *data, int len, int *transactionID=NULL)
Definition: rlmodbus.cpp:54

◆ response()

int rlModbus::response ( int *  slave,
int *  function,
unsigned char *  data,
int  timeout = 1000 
)

Definition at line 132 of file rlmodbus.cpp.

133 {
134  unsigned char *telptr;
135  int ret,len,byte_count,idata,i,itel,val;
136 
137  len = 0;
138  if(mode != MODBUS_ASCII && mode != MODBUS_RTU) return MODBUS_ERROR;
139  if(s != NULL)
140  {
141  if(s->isConnected() == 0) return MODBUS_ERROR;
142  if(mode == MODBUS_RTU)
143  {
144  if(s->read((char *) tel, 6, timeout) <= 0) return MODBUS_ERROR;
145  // bytes 0,1 Transaction ID faithfully copied from the request message
146  // bytes 2,3 Protocol number always zero
147  // byte 4 Response length (upper byte) Always zero
148  // byte 5 Response length (lower byte). Equal to the number of bytes which follow
149  // Here comes the normal Modus telegram
150  if(s->read((char *) tel, 2, timeout) <= 0) return MODBUS_ERROR;
151  *slave = tel[0];
152  *function = tel[1];
153  byte_count = tel[5] - 3;
154  if(s->read((char *) tel, 1, timeout) <= 0) return MODBUS_ERROR;
155  switch(*function)
156  {
157  case ReadCoilStatus:
158  case ReadInputStatus:
160  case ReadInputRegisters:
161  case FetchCommEventLog:
162  case ReportSlaveID:
166  //byte_count = tel[0];
167  if(s->read((char *) data, byte_count, timeout) <= 0) return MODBUS_ERROR;
168  return byte_count;
169  case ForceSingleCoil:
171  case FetchCommEventCtr:
172  case ForceMultipleCoils:
173  case PresetMultipleRegs:
174  //byte_count = 4;
175  if(s->read((char *) data, byte_count, timeout) <= 0) return MODBUS_ERROR;
176  return byte_count;
177  case ReadExceptionStatus:
178  //byte_count = 1;
179  if(s->read((char *) data, byte_count, timeout) <= 0) return MODBUS_ERROR;
180  return byte_count;
182  //byte_count = 6;
183  if(s->read((char *) data, byte_count, timeout) <= 0) return MODBUS_ERROR;
184  return byte_count;
185  case ReadFifoQueue:
186  if(s->read((char *) tel, 2, timeout) <= 0) return MODBUS_ERROR;
187  //byte_count = tel[0]*256 + tel[1];
188  if(s->read((char *) data, byte_count, timeout) <= 0) return MODBUS_ERROR;
189  return byte_count;
190  default:
191  return MODBUS_ERROR;
192  }
193  }
194  }
195  else if(tty != NULL)
196  {
197  if(mode == MODBUS_ASCII)
198  {
199  //printf("modbus ascii\n");
200  for(i=0; i<maxtel; i++)
201  {
202  ret = tty->select(timeout);
203  if(ret == 0) return MODBUS_ERROR;
204  //printf("readChar\n");
205  itel = tty->readChar();
206  if(itel < 0) return MODBUS_ERROR;
207  tel[i] = (unsigned char) itel;
208  if(tel[i] == 0x0d && delimitor != 0x0a) break;
209  if(tel[i] == 0x0a) break;
210  }
211  tel[i] = '\0';
212  telptr = (unsigned char *) strchr((const char *) tel,':');
213  if(telptr == NULL) return MODBUS_ERROR;
214  len++;
215  sscanf((char *) &telptr[len],"%02X",slave); len += 2;
216  sscanf((char *) &telptr[len],"%02X",function); len += 2;
217  switch(*function)
218  {
219  case ReadCoilStatus:
220  case ReadInputStatus:
222  case ReadInputRegisters:
223  case FetchCommEventLog:
224  case ReportSlaveID:
228  sscanf((char *) &telptr[len],"%02X",&byte_count); len += 2;
229  for(idata=0; idata<byte_count; idata++)
230  {
231  sscanf((const char *) &telptr[len], "%02X", &val); len += 2;
232  data[idata] = val;
233  }
234  data[idata] = 0x0ff; // terminator, this data can't come over modbus
235  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
236  return byte_count;
237  case ForceSingleCoil:
239  case FetchCommEventCtr:
240  case ForceMultipleCoils:
241  case PresetMultipleRegs:
242  byte_count = 8;
243  for(idata=0; idata<(byte_count/2); idata++)
244  {
245  data[idata] = buf2int_ascii(&telptr[len]); len += 2;
246  }
247  data[idata] = 0x0ff; // terminator, this data can't come over modbus
248  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
249  return byte_count;
250  case ReadExceptionStatus:
251  byte_count = 2;
252  for(idata=0; idata<(byte_count/2); idata++)
253  {
254  data[idata] = buf2int_ascii(&telptr[len]); len += 2;
255  }
256  data[idata] = 0x0ff; // terminator, this data can't come over modbus
257  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
258  return byte_count;
260  byte_count = 12;
261  for(idata=0; idata<(byte_count/2); idata++)
262  {
263  data[idata] = buf2int_ascii(&telptr[len]); len += 2;
264  }
265  data[idata] = 0x0ff; // terminator, this data can't come over modbus
266  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
267  return byte_count;
268  case ReadFifoQueue:
269  sscanf((char *) &telptr[len],"%04X",&byte_count); len += 4;
270  for(idata=0; idata<(byte_count/2); idata++)
271  {
272  data[idata] = buf2int_ascii(&telptr[len]); len += 2;
273  }
274  data[idata] = 0x0ff; // terminator, this data can't come over modbus
275  if(LRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
276  return byte_count;
277  break;
278  default:
279  return MODBUS_ERROR;
280  }
281  }
282  else if(mode == MODBUS_RTU)
283  {
284  ret = tty->select(timeout);
285  if(ret == 0) return MODBUS_ERROR;
286  if(tty->readBlock(tel, 2, timeout) <= 0) return MODBUS_ERROR;
287  *slave = tel[len++];
288  *function = tel[len++];
289  byte_count = tel[5] - 3;
290  switch(*function)
291  {
292  case ReadCoilStatus:
293  case ReadInputStatus:
295  case ReadInputRegisters:
296  case FetchCommEventLog:
297  case ReportSlaveID:
301  if(tty->select(timeout) == 0) return MODBUS_ERROR;
302  if(tty->readBlock(&tel[len], 1, timeout) <= 0) return MODBUS_ERROR;
303  //byte_count = tel[len++];
304  if(tty->select(timeout) == 0) return MODBUS_ERROR;
305  if(tty->readBlock(data, byte_count+2, timeout) <= 0) return MODBUS_ERROR;
306  memcpy(&tel[len],data,byte_count+2); len += byte_count + 2;
307  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
308  return byte_count;
309  case ForceSingleCoil:
311  case FetchCommEventCtr:
312  case ForceMultipleCoils:
313  case PresetMultipleRegs:
314  //byte_count = 4;
315  if(tty->select(timeout) == 0) return MODBUS_ERROR;
316  if(tty->readBlock(data, byte_count+2, timeout) <= 0) return MODBUS_ERROR;
317  memcpy(&tel[len],data,byte_count+2); len += byte_count + 2;
318  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
319  return byte_count;
320  case ReadExceptionStatus:
321  //byte_count = 1;
322  if(tty->select(timeout) == 0) return MODBUS_ERROR;
323  if(tty->readBlock(data, byte_count+2, timeout) <= 0) return MODBUS_ERROR;
324  memcpy(&tel[len],data,byte_count+2); len += byte_count + 2;
325  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
326  return byte_count;
328  //byte_count = 6;
329  if(tty->select(timeout) == 0) return MODBUS_ERROR;
330  if(tty->readBlock(data, byte_count+2, timeout) <= 0) return MODBUS_ERROR;
331  memcpy(&tel[len],data,byte_count+2); len += byte_count + 2;
332  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
333  return byte_count;
334  case ReadFifoQueue:
335  if(tty->select(timeout) == 0) return MODBUS_ERROR;
336  if(tty->readBlock(&tel[len], 2, timeout) <= 0) return MODBUS_ERROR;
337  //byte_count = tel[len]*256 + tel[len+1]; len += 2;
338  if(tty->select(timeout) == 0) return MODBUS_ERROR;
339  if(tty->readBlock(data, byte_count+2, timeout) <= 0) return MODBUS_ERROR;
340  memcpy(&tel[len],data,byte_count+2); len += byte_count + 2;
341  if(CRCerror(len) == 1) return MODBUS_CHECKSUM_ERROR;
342  return byte_count;
343  default:
344  return MODBUS_ERROR;
345  }
346  }
347  }
348  else return MODBUS_ERROR;
349  return MODBUS_SUCCESS;
350 }
int LRCerror(int len)
Definition: rlmodbus.cpp:645
int readBlock(unsigned char *buf, int len, int timeout=-1)
Definition: rlserial.cpp:498
int mode
Definition: rlmodbus.h:252
rlSerial * tty
Definition: rlmodbus.h:249
long maxtel
Definition: rlmodbus.h:251
int buf2int_ascii(unsigned char *buf)
Definition: rlmodbus.cpp:614
unsigned char * tel
Definition: rlmodbus.h:250
int select(int timeout=500)
Definition: rlserial.cpp:719
int read(void *buf, int len, int timeout=0)
Definition: rlsocket.cpp:191
rlSocket * s
Definition: rlmodbus.h:248
int readChar()
Definition: rlserial.cpp:405
char delimitor
Definition: rlmodbus.h:253
int isConnected()
Definition: rlsocket.cpp:559
int CRCerror(int len)
Definition: rlmodbus.cpp:748

◆ write()

int rlModbus::write ( int  slave,
int  function,
const unsigned char *  data,
int  len,
int *  transactionID = NULL 
)

Definition at line 54 of file rlmodbus.cpp.

55 {
56  int len,i;
57 
58  if(slave < 0 || slave > 255) return MODBUS_ERROR;
59  len = 0;
60  if(mode == MODBUS_ASCII)
61  {
62  tel[len++] = ':';
63  sprintf((char *) &tel[len], "%02X", slave); len += 2;
64  sprintf((char *) &tel[len], "%02X", function); len += 2;
65  for(i=0; i<datalen; i++)
66  {
67  sprintf((char *) &tel[len], "%02X",(int) data[i]); len += 2;
68  if((len+4) > maxtel) return MODBUS_ERROR;
69  }
70  insertLRC(len); len += 2;
71  tel[len++] = 0x0d;
72  if(delimitor == 0x0a) tel[len++] = 0x0a;
73  }
74  else if(mode == MODBUS_RTU)
75  {
76  if(s != NULL)
77  {
78  if(transactionID == NULL)
79  {
80  tel[len++] = 0; // bytes 0,1 Transaction ID. Not important. Usually zero when making a request, the server will copy them faithfully into the response.
81  tel[len++] = 0;
82  }
83  else
84  {
85  tel[len++] = ((*transactionID) & 0xFF00) / 256; // bytes 0,1 Transaction ID.
86  tel[len++] = (*transactionID) & 0xFF;
87  }
88  tel[len++] = 0; // bytes 2,3 Protocol number. Must be zero.
89  tel[len++] = 0;
90  tel[len++] = 0; // byte 4 Length (upper byte). Since all requests will be less than 256 bytes in length (!), this will always be zero.
91  tel[len++] = 2+datalen; // byte 5 Length (lower byte). Equal to the number of bytes which follow
92  }
93  tel[len++] = (unsigned char) slave;
94  tel[len++] = (unsigned char) function;
95  for(i=0; i<datalen; i++)
96  {
97  tel[len++] = data[i];
98  if((len+2) > maxtel) return MODBUS_ERROR;
99  }
100  insertCRC(len); len += 2;
101  }
102  else return MODBUS_ERROR;
103 
104  if(s != NULL)
105  {
106  if(s->isConnected() == 0)
107  {
109  if(s->isConnected() == 0) return MODBUS_ERROR;
110  }
111  if(s->write(tel,len-2) < 0) return MODBUS_ERROR; // don't send LRC or CRC
112  }
113  else if(tty != NULL)
114  {
115  if(tty->writeBlock(tel,len) < 0) return MODBUS_ERROR;
116  }
117  else return MODBUS_ERROR;
118  return MODBUS_SUCCESS;
119 }
void insertCRC(int len)
Definition: rlmodbus.cpp:730
int write(const void *buf, int len)
Definition: rlsocket.cpp:292
int mode
Definition: rlmodbus.h:252
void insertLRC(int len)
Definition: rlmodbus.cpp:627
rlSerial * tty
Definition: rlmodbus.h:249
long maxtel
Definition: rlmodbus.h:251
int autoreconnectSocket
Definition: rlmodbus.h:214
unsigned char * tel
Definition: rlmodbus.h:250
rlSocket * s
Definition: rlmodbus.h:248
int connect()
Definition: rlsocket.cpp:321
char delimitor
Definition: rlmodbus.h:253
int isConnected()
Definition: rlsocket.cpp:559
int writeBlock(const unsigned char *buf, int len)
Definition: rlserial.cpp:584

Member Data Documentation

◆ autoreconnectSocket

int rlModbus::autoreconnectSocket

Definition at line 214 of file rlmodbus.h.

◆ delimitor

char rlModbus::delimitor
private

Definition at line 253 of file rlmodbus.h.

◆ maxtel

long rlModbus::maxtel
private

Definition at line 251 of file rlmodbus.h.

◆ mode

int rlModbus::mode
private

Definition at line 252 of file rlmodbus.h.

◆ s

rlSocket* rlModbus::s
private

Definition at line 248 of file rlmodbus.h.

◆ tel

unsigned char* rlModbus::tel
private

Definition at line 250 of file rlmodbus.h.

◆ tty

rlSerial* rlModbus::tty
private

Definition at line 249 of file rlmodbus.h.


The documentation for this class was generated from the following files: