Pointer initialization issue

Hello Everyone,
I hope you’re all doing great and looking forward to a fantastic weekend ahead! :wink:

I would really appreciate any insights on an issue I’m facing while programming. I am using a pointer array, pODCommVar (CommVarODType[0..2]), where each structure instance contains a member wSystemCommand. This member is assigned a constant value based on specific conditions. Below is the relevant part of my code:

#include <bur/plctypes.h>

#ifdef _DEFAULT_INCLUDES
#include <AsDefault.h>
#endif

#include <string.h>
#include <math.h>
#include "AuxFunction.h"

void _INIT ProgramInit(void)
{
	if (!PointersValid()) return;				
}

void _CYCLIC ProgramCyclic(void)
{
	for (i = 0; i < OD_COUNT; i++)
	{
		pCmd = &gpODx3[i].Cmd;
		pSetup = &gpSetupODx3[i];
//		pODCommVar[i] = &CommVarOD[i];
		pODCommVar = &CommVarOD[i];		
		
///***************** Edge Commands for three OD sensors ********************************/
RisingEdge(&pCmd->RestoreFactorySettingsSensor, &Cmd[i].RestoreFactorySettingsSensor, &Edges[i].RestoreFactorySettingsSensor);
RisingEdge(&pCmd->FactorySettingsSetup, &Cmd[i].FactorySettingsSetup, &Edges[i].FactorySettingsSetup);
RisingEdge(&pCmd->Reset, &Cmd[i].Reset, &Edges[i].Reset);
RisingEdge(&pCmd->TeachInChanelSP1, &Cmd[i].TeachInChanelSP1, &Edges[i].TeachInChanelSP1);
RisingEdge(&pCmd->ZeroPointReset, &Cmd[i].ZeroPointReset, &Edges[i].ZeroPointReset);
RisingEdge(&pCmd->ZeroPointTeach, &Cmd[i].ZeroPointTeach, &Edges[i].ZeroPointTeach);
		
/*********************** Factory Reset ****************************/
		if (Cmd[0].FactorySettingsSetup) 
		{
			FactorySettingsOD0(&gpSetupODx3[0]);         
		}
		if (Cmd[1].FactorySettingsSetup) 
		{
			FactorySettingsOD1(&gpSetupODx3[1]);         
		}
		if (Cmd[2].FactorySettingsSetup) 
		{
			FactorySettingsOD2(&gpSetupODx3[2]);         
		}
/***************************< Reset var >****************************************/
		Cmd[0].FactorySettingsSetup = 0;
		Cmd[1].FactorySettingsSetup = 0;
		Cmd[2].FactorySettingsSetup = 0;

/**************************< State machine >*********************************/
		switch (StateOD[i]) 
		{
			case W_SYSTEM_COMMAND:
				if (Cmd[i].ZeroPointTeach)
				{
					LocalVar[i].ODWrite = 1;		
					pODCommVar[i]->wSystemCommand = 194;	
				}
				else if (Cmd[i].ZeroPointReset)
				{
					LocalVar[i].ODWrite = 1;
					pODCommVar[i]->wSystemCommand = 195;		
				}
				else if (Cmd[i].RestoreFactorySettingsSensor)
				{
					LocalVar[i].ODFactorySetting = 1;
					pODCommVar[i]->wSystemCommand = 130;		
				}

				/* Write operation for system command */
				if (LocalVar[i].ODWrite || LocalVar[i].ODFactorySetting)
				{
					StateOD[i] = WR_CYCLE_TIME;
				}
				break;

			case WR_CYCLE_TIME:
				if (Cmd[i].Reset)
				{
					LocalVar[i].ODWrite = 0;
					LocalVar[i].ODFactorySetting = 0;
					memset(&Cmd[i], 0, sizeof(Cmd[i]));		// Reset All commands
					StateOD[i] = W_SYSTEM_COMMAND;
				}	
				break;
		}	
	}
}

Issue:
For Cmd[0].ZeroPointTeach, Cmd[0].ZeroPointReset, and Cmd[0].RestoreFactorySettingsSensor, everything works as expected—LocalVar[0].ODWrite is correctly set, and pODCommVar[0]->wSystemCommand holds the correct assigned value.

However, for i = 1 and i = 2, LocalVar[i].ODWrite is correctly set, but pODCommVar[i]->wSystemCommand is displaying unexpected values:

pODCommVar[1]->wSystemCommand = 2
pODCommVar[2]->wSystemCommand = 0

(Screenshot attached for reference)

Question:
Is there something I’m missing in my pointer assignment or array indexing? Any guidance on what could be causing this discrepancy would be greatly appreciated.

Thanks in advance!

Best regards,
Tabish

Hi there,

can you please export this into a task with all types in use so it’s compilable? Just from looking at the code it’s hard to tell…

Best regards

pODCommVar is double assigned. In the last line you assign the pointer array to &CommVarOD[i].

1 Like

Hello Michael / ALL,
Apologies for responding late as I was stucked with something else. I am attaching a zip file
PointerCheck.zip (87.9 KB)
after exporting the project (Save Project As zip without upgrades is exceeding the upload size limit).
Hopefully this way will work or let me know if you are unable to open it.
TIA.

Hi Markus,
pODCommVar is not double assigned. The second line is commented out :slight_smile:

Hi @Syed_Karim ,

unfortunately this export is not complete. After i manually imported only the task, the code does not compile. It is missing various datatypes, so basically not much more useful to me/us as the initial example.
Regarding file sizes, maybe this helps:

Please export the task, import it into a new project (no need to configure any hardware besides the PLC there) and make sure it compiles - that way you can make sure it also compiles for us trying to help.

Best regards

Hello @Syed_Karim,
In your task, you have provided, I can see 2 issues:
Firstly, lets take a look on your variable and pointer declarations:

CommVarOD : ARRAY[0..2] OF CommVarODType;
pODCommVar : REFERENCE TO ARRAY[0..2] OF CommVarODType;

First, on line 27, you need to use & to assign an address of CommVarOD to a ponter pODCommVar. It should look like this:
Line 27: pODCommVar = &CommVarOD;

Second, in your code, you use the pointer as “an array of pointers”.
Line 83: pODCommVar[i]->wSystemCommand = 194;
But your declaration and assignment are actually “pointer to an array”.
A way how to make your code work is, to dereference the pointer to the array and then accesses the element at the specified index. Here is corrected notation:
Line 83: (*pODCommVar)[i].wSystemCommand = 194;

By editing lines 27, 83, 89 and 94 according to provided examples, your code should work. :slight_smile:

2 Likes

Ahoj Jirko,
Mohu potvrdit, že tvůj návrh byl naprosto správný! :right_facing_fist:

Díky moc a přeji hezký den!

Tabish

1 Like