Passing a Struct to a Function

I am trying to pass the struct

typedef struct{
	int kP;
	int kI;
	int kD;
	int proportion;
	int integral;
	int derivative;
	int target;
	int error;
	int lasterror;
	int speed;
} dataPID;

to the function

void runPID(dataPID)
{
	error = target; //- (SensorValue(armQuad))
	if (error == 0)
	{
		integral = 0;
	}
	if (abs(error) > 100)
	{
		integral = 100;
	}
	proportion = error;
	integral = integral + error;
	derivative = error - lasterror;
	speed = proportion*kp + integral*ki + derivative*kd;
	lasterror = error;
	delay(25);
}	

and it doesn’t recognize any of the variables. What is the correct way to pass a struct to a function?

Make sure you address the variables as member variables of the struct:


dataPID->error

instead of just


error

(same applies to the other member variables).

In addition to what Barin said, you need to pass the pointer to the struct to the method, not the value of the struct.

You don’t ** have ** to pass a pointer to a struct in RobotC, and because it’s not a pointer you’re working with you actually need to use a dot to access member variables of the struct, like dataPID.error

To elaborate more on why @sazrocks pointed out that you should be using pointers has to do with the fact that in actual C/C++ a function will make a copy of the data passed into it, and any changes will be made to the copy which gets destroyed when the function exits. For some reason RobotC doesn’t behave this way and passing structs into functions keeps a reference to the original struct instance.

Here’s a reference to some code I’ve written to do this same thing:

#ifndef NERD_PID_h
#define NERD_PID_h


typedef struct{
	float m_fKP;
	float m_fKI;
	float m_fKD;
	float m_fEpsilonInner;
	float m_fEpsilonOuter;
	float m_fSigma;
	float m_fLastValue;
	unsigned long m_uliLastTime;
	float m_fLastSetPoint;
} PID;


#endif
#include "NERD_pid.h"
#ifndef PID_C
#define PID_C
/**
 * initialize pid structure, set parameters
 *
 * @param pid instance of PID structure
 * @param fKP PID KP constant
 * @param fKI PID KI constant
 * @param fKD PID KD constant
 * @param fEpsilonInner inner bound of PID I summing cutoff
 * @param fEpsilonOuter outer bound of PID I summing cutoff
 */
void
pidInit (PID pid, float fKP, float fKI, float fKD, float fEpsilonInner, float fEpsilonOuter) {
	pid.m_fKP = fKP;
	pid.m_fKI = fKI;
	pid.m_fKD = fKD;
	pid.m_fEpsilonInner = fEpsilonInner;
	pid.m_fEpsilonOuter = fEpsilonOuter;
	pid.m_fSigma = 0;
	pid.m_fLastValue = 0;
	pid.m_uliLastTime = nPgmTime;
}

/**
 * calculate pid output
 *
 * @param pid instance of PID structure
 * @param fSetPoint set point of PID controller
 * @param fProcessVariable sensor/feedback value
 *
 * @return output value constrained from -127 to 127
 */
float
pidCalculate (PID pid, float fSetPoint, float fProcessVariable) {
	float fDeltaTime = (float)(nPgmTime - pid.m_uliLastTime) / 1000.0;
	pid.m_uliLastTime = nPgmTime;

	float fDeltaPV = 0;
	if(fDeltaTime > 0)
		fDeltaPV = (fProcessVariable - pid.m_fLastValue) / fDeltaTime;
	pid.m_fLastValue = fProcessVariable;

	float fError = fSetPoint - fProcessVariable;

	if(fabs(fError) > pid.m_fEpsilonInner && fabs(fError) < pid.m_fEpsilonOuter)
		pid.m_fSigma += fError * fDeltaTime;

	if (fabs (fError) > pid.m_fEpsilonOuter)
		pid.m_fSigma = 0;

	float fOutput = fError * pid.m_fKP
					+ pid.m_fSigma * pid.m_fKI
					- fDeltaPV * pid.m_fKD;

	fOutput = fabs(fOutput) > 127 ? 127 * fOutput/fabs(fOutput) : fOutput;
	return fOutput;
}
#endif

Okay. Thanks everyone!