Invalid parameter modbus

Hello everyone,

Here, I use the library function MBM_ReadRegs MODBUS. When I read the return value, which means I get a MBM_INVALID_PARAMETER … I mean this type of error. Here’s how I wrote the instruction:

b = MBM_ReadRegs (0x05, &RegsValue[0], 0xC552, 10 );


The reason for this is that that the starting register parameter in the DC 9.62 version of the modbusmaster library is a signed int and there is an explicit check for the value being < 0 in the code. 0xC552 is negative if viewed as a signed 16 bit value. You can change the type in the library to unsigned int and remove the check for < 0 in the code and it should work.

The DC 10.66 version of the lib has unisgned int and no check for < 0.

Yoy may need to make similar changes to some of the other library functions as well if you are using them with register start addresses > 0x7FFF.


Thank you for your quick and accurate response. you’re right, I changed the library. Now the return value is -3, while the address of my slave is 05. I try to repair:)

When I run my program in the window STDIO, a message appears:
Tx: 10 00 00 1E 84 EC

when I enter 05 for the slave address. Why is writing 10?

If you can help me Peter, thank you:)

The correct packet for that command should be:

Tx: 05 04 C5 52 00 0A EC 94

What you have looks nothing like it which is very strange.

I’ll have a quick look at the lib again and see if I can make sense of it.


I can’t see anything obvious at this stage. Can you post your current code for me to have alook at?


Yes, this is my code

#define Mesure
#define MODBUS_DEBUG_PRINT 1 // define to 1 to print transactions
#define CINBUFSIZE 31
#define COUTBUFSIZE 31
#define _RS485 485
#use modbus_master.lib

void brdInit();
int MBM_Send_ADU ( char *Packet, int ByteCount );
int MBM_Rcv_Resp ( char * Packet );
void serInit ( void );
void ser485Tx( void ) ;
void ser485Rx( void );

main ()
{ int b,p, RegsValue[50];
b = MBM_ReadRegs(5, &RegsValue[0], 0x1000, 30 ); // read reg 0
for ( p=0; p<50; p++ )
", b);

/* START FUNCTION DESCRIPTION ********************************************
END DESCRIPTION **********************************************************/

void brdInit()
{ WrPortI(PCFR, &PCFRShadow, PCFRShadow&0xEA); //clear bit 4,2,0 to normal function
//bits 5,3,1 normally inputs
WrPortI(PCDR, &PCDRShadow, PCDRShadow|0x15); //set bits 4,2,0 high
WrPortI(PDCR, &PDCRShadow, 0x00); //clear all bits to pclk/2
WrPortI(PDFR, &PDFRShadow, 0x00); //clear all bits to normal function
WrPortI(PDDCR, &PDDCRShadow, 0x00); //clear all bits to drive high and low
WrPortI(PDDR, &PDDRShadow, 0x0b); //set bits 3,1,0 high
WrPortI(PDDDR, &PDDDRShadow, 0x8b); //set bits 7,3,1,0 to output, rest inputs
WrPortI(PECR, &PECRShadow, 0x00); //clear all bits to pclk/2
WrPortI(PEFR, &PEFRShadow, 0x00); //clear all bits to normal function
WrPortI(PEDR, &PEDRShadow, 0xc0); //set bits 7,6 output high
WrPortI(PEDDR, &PEDDRShadow, 0xc8); //set bits 7,6,3 to output, rest inputs
WrPortI(PFCR, &PFCRShadow, 0x00); //clear all bits for pclk/2
WrPortI(PFFR, &PFFRShadow, 0x00); //clear all bits for normal function
WrPortI(PFDR, &PFDRShadow, 0x0f); //set bits 7,6,5,4 output low
WrPortI(PFDDR, &PFDDRShadow, 0xf0); //set bits 7,6,5,4 to output
WrPortI(PGCR, &PGCRShadow, 0x00); //clear all bits for pclk/2
WrPortI(PGFR, &PGFRShadow, 0x00); //clear all bits for normal function
WrPortI(PGDDR, &PGDDRShadow, 0x30); //set bits 5,4 to output, clear rest to input
WrPortI(PGDCR, &PGDCRShadow, 0x00); //clear all bits to drive output
WrPortI(PGDR, &PGDRShadow, 0x30); //set bit 5,4 high
WrPortI(PBDR, &PBDRShadow, PBDRShadow|0xfc); //set all bits high, except bit 1,0
WrPortI(PBDDR, &PBDDRShadow, PBDDRShadow|0xfc); //set all bits to output, except bit 1,0
WrPortI(PADR, &PADRShadow, 0xff); //set to output all high
WrPortI(SPCR, &SPCRShadow, 0x8c); //Enables Auxiliary i/o bus

void serInit ( void )
serCopen (9600);

void ser485Tx( void )
ld a,(PDDRShadow)
set 7,a ;set bit 7
ld (PDDRShadow),a
ioi ld (PDDR),a ;set PD7 high

void ser485Rx( void )
ld a,(PDDRShadow)
set 7,a ;set bit 7
ld (PDDRShadow),a
ioi ld (PDDR),a ;set PD7 high

int MBM_Send_ADU ( char *Packet, int ByteCount )
{ auto unsigned CRCvalue;
auto unsigned long Endtime;
int i;

// insert CRC
CRCvalue = MODBUS_CRC ( Packet, ByteCount );
Packet[ByteCount+1] = CRCvalue; // store low byte
Packet[ByteCount] = CRCvalue>>8; // store high byte
ByteCount+=2; // adjust for CRC

printf ( “Tx:” );
for ( i=0; i

the printfs for the dump of the tx and rx packets should be:

printf ( " %02X", Packet[ i ] );

for some reason, posting them with no space between the [ and the i causes the text to appear wrong!

Can you trace throught the call to ReadRegs and see what gets put into the packet at each step. The dump of the transmit data and the number of bytes are wrong and I can’t see off hand why that should be.


Hello Peter,

There is no space between [and pa i.
I have not understand what you says.


I still have a problem now. When I compile a mistake at the library modbus.master appears:
line 689: ERROR MODBUS_MASTER.LIB: Return type (re) Declared Differently after use.
line 689: ERROR MODBUS_MASTER.LIB: Syntax error - Gold garbage at end of program.
line 689: ERROR MODBUS_MASTER.LIB: Need function definition or declaration.

It is at this level:
MODBUS_CRC unsigned (unsigned char * pcMess, unsigned Wlen)

at the end of the library.

MODBUS_CRC unsigned (unsigned char * pcMess, unsigned Wlen)
auto unsigned char chi, clo / / CRC Accumulators (MSB & LSB)
auto unsigned w / / CRC Index Shift In

chi = clo = 0xFF / / Init CRC
while (Wlen -)
{/ / For Each Byte
w = chi ^ * pcMess + + / / Next Table Index
chi ^ = clo MODBUS_CRC_MSB [w] / / Next CRC
return ((unsigned) chi <<8) | CLO / / The merge bytes and return

/ *** * BeginHeader /

endif / / __MBMASTER

/ *** * EndHeader /

How come,??

it should be "unsigned MODBUS_CRC(…) and not “MODBUS_CRC unsigned(…”

Incidentily why are you not using the much faster table driven CRC in the modbus_master.lib?


Hey Peter, thank you first offers. But I still have a problem.
When I view the return value of MBM_ReadRegs I 0 even if I do not have my slave connected or if I put the address of a nonexistent slave.
I always eproblème c values ​​in eronnées RegsValue []. even if no slave is connected, I have random values​​. Similarly, if the slave address does not exist.

I explained my problem to technical support voilàa what they said:

Given the code as you sent it, ececutes this line only once:

b = MBM_ReadRegs(5, &RegsValue[0], 0x1000, 30 ); // read reg 0

And looking at the function description for MBM_ReadRegs:
PARAMETER1: MODBUS addresss of the target device

PARAMETER2: Starting address to put the results

PARAMETER3: Starting register number, 1 relative, to read

PARAMETER4: Number of registers to read

You might provide this info and write the code so that the above mentioned line executes more than once.

But even when writing a loop that does not change. The connection is not my slave. I have not changed ds modbus_master library, except that I put the following statement in comment if I had an error like:
MODBUS_MASTER.LIB ERROR: Undefined (object used) global label_initMBMpacket

/ / _initMBMpacket (PDUbyteCount +1) / / Function include byte code - TCP only!

I do not understand why even if I’m not a slave connected, the return value is 0.

The modbus_serial_master.c example is a very minimal implementation of modbus transmitting and receiving and has several short comings as I noted before.

another short coming is that if the wait for a response times out it returns 0 which is the same as MB_SUCCESS!

I’d change the code to return a value like MBM_PACKET_ERROR if there is a timeout or even add a new error code “#define MBM_TIMEOUT -6” and use this.


Hey thank you Peter.

You’re right. Instead of writing a instcrution for a timeout, I changed the value of MBSUCESS (# define MB_SUCCESS 10) and I still have the value 0 returned.

We can now say that the connection with the slave does not. I also TX: ** ** ** ** ** ** ** that appears. Is it normal to have ‘*’?

The online support does not help me … And I really understand nothing.
Can anyone help me?

What should I add? Someone there a full program of example …??

Thank you, friendly.

the ** ** indicates that the value to be printed does not fit in 2 digits. Have a look at the documentation for printf.