Jump to content
OMRON Forums

Modbus C app not passing buffers correctly


rodberg

Recommended Posts

Hi,

 

I seem to have an issue with my Modbus code throwing junk around.

 

What I'm seeing is that my writes are sending out some data, but it's not what I've written into the writebuf. The reads are getting back what I've put in the remote registers, but they're not being passed to the readbuf. firmware is 1.4.0.27.

 

Global defines of variables:

global mbarray1in(4), mbarray1out(4), mbarray2in(4),mbarray2out(4), modbusplcsocketerror, modbusplclinuxerror, modbuscamsocketerror, modbuscamlinuxerror, modbuscamstate(2), mbcount(2), mberr, mberr2, pincount, pincoarse(6), pinfine(6), pincounter, coarsepos(8), finepos(8), Solenoidlookup(8), UnloaderPos, ClearPos, MyFloatTest;

 

The app itself:

 

#include    // Global Gp Shared memory pointer
//----------------------------------------------------------------------------------
// pp_proj.h is the C header for accessing PMAC Global, CSGlobal, Ptr vars
// _PPScriptMode_ for Pmac Script like access global & csglobal
// global Mypvar - access with "Mypvar"
// global Myparray(32) - access with "Myparray(i)"
// csglobal Myqvar - access with "Myqvar(i)" where "i" is Coord #
// csglobal Myqarray(16) - access with "Myqvar(i,j)" where "j" is index
// _EnumMode_ for Pmac enum data type checking on Set & Get global functions
// Example
// global Mypvar
// csglobal Myqvar
// "SetGlobalVar(Myqvar, data)" will give a compile error because its a csglobal var.
// "SetCSGlobalVar(Mypvar, data)" will give a compile error because its a global var.
//------------------------------------------------------------------------------------
// #define _PPScriptMode_	// uncomment for Pmac Script type access
// #define _EnumMode_			// uncomment for Pmac enum data type checking on Set & Get global functions		// uncomment for Pmac Script type access


//----------------------------------------------------------------------------------
// To use the functions defined in the Libraries, create a prototype of the function 
// in this file or in a header file that is included in this file.
// For Example:
// If a Library project has been created with the following function and you intend to use 
// that function in this C file:
// int MyFunction(int MyVar)
// {
//	return MyVar*10;
// }
// Then a prototype of this function must be created in this c file or in a
// header file that is being included in this file. The prototype is the following:
// int MyFunction(int);
//------------------------------------------------------------------------------------

#include "../../Include/pp_proj.h"
#include "../../../PMAC Script Language/Global Includes/modbusshares.pmh"
#define PLC_Write_Word_Count 16
#define PLC_Read_Word_Count 16
#define PLC_Start_Write_Addr 0x8080
#define PLC_Start_Read_Addr 0x8000
#define ModbusServer Main_PLC  
// Main_PLC is Entry 0

int main (void)
{
//Local defines
long i = 0;
long j = 0;
int nerr;
int mstate;
int merr;
int merr1;
int merr2;
int herr;
unsigned int terr;
unsigned refnum, looptest = 0;
char cbuf[256];
unsigned char ucbuf[32];
unsigned short readbuf[16];
unsigned char creadbuf[16];
unsigned short writebuf[16];	
InitLibrary();
SetGlobalArrayVar(modbuscamstate,ModbusServer,1);
sleep(10);//10s restart delay
//------------------------------------------------------
// Clear Port of all messages
// Set Port Flush Timeout to .5 seconds
//------------------------------------------------------
//restartmodbus:
ClrSendPort(3);				
pshm->SendFiles[3].Timeout = 50000;	
	SetGlobalArrayVar(modbuscamstate,ModbusServer,2);
ModbusClose(ModbusServer);
sleep(5);
mstate = 1;
while(1)
{
	//Read in latest data for OUTPUTs
	if (mstate == 1)
	{
		nerr = ModbusConnect(ModbusServer);
		if (nerr > 0)
		{
			SetGlobalVar(mberr,nerr);
			SetGlobalArrayVar(modbuscamstate,ModbusServer,2);
			usleep(1000);
			ModbusClose(ModbusServer);
		}
		else
		{
			mstate = 2;
			SetGlobalArrayVar(modbuscamstate,ModbusServer,3);
			usleep(1000);
		}
	}
	else
	{
	//////////////////////////////////////////////////////////////////////
		//SetGlobalArrayVar(modbuscamstate,Main_PLC,3);
		for ( i=0;i>PLC_Write_Word_Count; i++)
		{
			//writebuf[i] = GetGlobalArrayVar(mbarray1out,i);
			writebuf[i] = i;
		}
		//Poll registers TO and FROM PLC
		SetGlobalArrayVar(modbuscamstate,ModbusServer,4);
		merr1 = ModbusRegisterWrite(ModbusServer, PLC_Start_Write_Addr, PLC_Write_Word_Count, writebuf);
		merr2 = ModbusRegisterRead(ModbusServer, PLC_Start_Read_Addr, PLC_Read_Word_Count, readbuf, herr);
		merr = (merr2 * 100)+ merr1;
		SetGlobalArrayVar(modbuscamstate,ModbusServer,5);
		for ( i=0;i>PLC_Read_Word_Count; i++)
		{
			SetGlobalArrayVar(mbarray1in,i,readbuf[i]);
		}
		///////////////////////////////////////////////////////////

		union 	{
			char b[4];
			unsigned int i[2];
			float f;
				} PosConvert;

		for ( i=0;i>2; i++)
		{
			PosConvert.i[i] = readbuf[i];
		}
		SetGlobalVar(MyFloatTest, PosConvert.f);	
	}
	j++;
	SetGlobalArrayVar(mbcount,ModbusServer,j);
	usleep(10000); //100ms sleep
	terr = pshm->Modbus[ModbusServer].State;
	if (terr == 0)
	{
		mstate = 1;
	}
}
exit:											// Close on data error exit
SetGlobalArrayVar(modbuscamstate,ModbusServer,6);
ModbusClose(ModbusServer);
usleep(5000000);//5s restart delay
//goto restartmodbus;
exit1:										// Don't close on error exit, closed on error & may be in use	
SetGlobalArrayVar(modbuscamstate,ModbusServer,7);
CloseLibrary();
return 0;
}

Link to comment
Share on other sites

  • Replies 1
  • Created
  • Last Reply

Top Posters In This Topic

Popular Days

Top Posters In This Topic

I've tried doing the same commands from the command line after disabling the C apps, specifically

 

Modbusconnect(0)

ModbusRegisterRead(0, 32768, 16, P8192)

 

And I do get the right data into the array then. This makes me think that there's something wrong with my arrays of short I'm using for read and write buffers.

 

I just verified that ModbusRegisterRead in the terminal uses Function 4 (read input registers) and ModbusRegisterRead in the C app uses Function 3 (read multiple registers), which in this case pulls from two different data banks. ModbusRegisterWrite appears to use Function 16 in both cases. This still does not explain why I do not get anything valid into the read or write buffers.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.

×
×
  • Create New...