cancel
Showing results for 
Search instead for 
Did you mean: 

'undefined reference to..' error, after defining in main.h and creating a function.

Odd_coder
Associate III

Hello,

 

Am working on a code to control a robot and receive data from IMUs on the robot using NUCLEO-L4R5ZI-P. The generated code is proper but am having issues with the with my used code. below is what i have in main.c

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "functions.h"
#include "math.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
TIM_HandleTypeDef htim6;
TIM_HandleTypeDef htim15;

UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart3_rx;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_TIM1_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM3_Init(void);
static void MX_TIM4_Init(void);
static void MX_TIM6_Init(void);
static void MX_TIM15_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_NVIC_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void enable_elbow_motor(void);
void disable_elbow_motor(void);
void close_gripper(void);
void open_gripper(void);
void disable_gripper(void);
void enable_SD_card(void);
void disable_SD_card(void);
//------------LED functionality---------
void display_off(void);
void display_on(void);
void display_brachiate(void);
void display_swingup(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */
	data2start=0;

		dir=0;
	//---------------------------------decimation integer set to take every 5th sample
		decimation=5;
	//---------------------------------initialize system state to zero
		states[0]=0;
		states[1]=0;
		states[2]=0;
		states[3]=0;
	//---------------------------------initial errors to zero
		e[0]=0;
		e[1]=0;
		e[2]=0;
		r[0]=0;
	//--------------------------------initial control action to zero
		u[0]=0;
		u[1]=0;
		u[2]=0;

		v[0]=0;
		v[1]=0;
		v[2]=0;

		v_tilde[0]=0;
		v_tilde[1]=0;
		v_tilde[2]=0;
	//--------------------------------initialize prefilter coefficients
		r_p[0]=0.578;
		r_p[1]=0;

		rf_p[0]=1;
		rf_p[1]=1;
	//--------------------------------initialize controller coefficients
		u_p[0]= 1;
		u_p[1]= 0.63305;
		u_p[2]= 0;
		e_p[0]= 307.995;
		e_p[1]= -302.767;
		e_p[2]= 0;
		u_tilde[0]=0;
	// -------------------------------initialize system parameters
	//-----------------------parameters ={ m1 , m2 I1 I2 l1 l2 r1 r2 g}
		parameters[0]=3.2287;
		parameters[1]=1.5155;
	    parameters[2]=0.1539;
		parameters[3]=0.2191;
		parameters[4]=0.9091 ;
		parameters[5]=1.2451;
		parameters[6]=0.2167;
		parameters[7]=0.5459;
		parameters[8]=9.8;

	// ------------------------------pi
		pi=3.14159265359;
	// ----------------------------initialse DP controller gains
		P_Gain=100;
		D_Gain=0;
		sampling_time=0.01;
		counter=0;
	//-----------------------------initialise starter  to zero
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_TIM6_Init();
  MX_TIM15_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();

  /* Initialize interrupts */
  MX_NVIC_Init();
  /* USER CODE BEGIN 2 */
  // Initialise CNT values for the input capture timers for the encoders
  TIM1->CNT=2000;
  TIM2->CNT=148000;

 //initialise gripper to closed(200) or open (500)
  HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);
  HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_ALL);

  HAL_TIM_Base_Init(&htim6); //Configure the timer
  HAL_TIM_Base_Start_IT(&htim6);
        //wait for iNemo boards to et up and start sending data before commencing with
        //Start the timer
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  //-----------------------------------------------ensure that initial state is OFF
    mode='F';

    disable_elbow_motor();
    disable_gripper();
    //Start timer to produce PWM signal on PC6
    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim15,TIM_CHANNEL_1);

    //Alternate integer duty to accomplish desired duty cycle, let duty be a global variable and continually set it in
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  //------begin receiving data from IMU modules---------------
	  HAL_UART_Receive_DMA(&huart3,temp_data2,DATASIZE);
	  HAL_UART_Receive_DMA(&huart1,temp_data1,DATASIZE);

//-------------------------EKF-------------------------------------//
//-------------------------------- current system measurements

	  if (mode=='F'){ //Off mode
		  	 //--------------------------------disable SD Data transmission
		  	 //disable_gripper();
		  	 starter=0;
		     disable_gripper();
		  //  open_gripper();
 		 	 disable_elbow_motor();
		  	 disable_SD_card();
		  	 //--------------------------------disable elbow motor
		     display_off();
	  }
	  else if(mode=='B'){	//Brachiating mode

//		     if (counter>50){
//		  	 enable_elbow_motor();}
		     enable_elbow_motor();
		  	 enable_SD_card();
		  	 open_gripper();
		  	 //disable_gripper();
		  	 //------------------------compute link 2 reference signal


		 	 r[0]=OTG(states,'B',final_state, parameters);
		 	 //r[0]=pi/4;
		  	 //v_tilde[0]=v_tilde[1]*0.8383 + r[1]*0.1622;
//
		 	 //r[0]=1.58;
		 	 e[0]=1.5*r[0]-states[1];
		 	 // e[0]=states[0];

		 	 // ---------------------------Proportional Derivative Control (PD)
		 	  //v[0]=PD(e, P_Gain, D_Gain, sampling_time);
		 	 //v[0]=v[1]*0.99 -57.554*e[0]+57.554*0.8915*e[1];
//v[0]=50;
		 	 v[0]=e[0]*-95;
		 	 //---------------------------Implement bumpless transfer here (AWBT)

		 	 //--------------------------Implement Collocated Feedback Linearisation (PFL)

		 	  u[0]=PFL(parameters,states,v[0]);

		 	  //--------------------------implement input saturation
		 	  u_tilde[0]=saturation(u[0]);

		 	  //duty=convertToDuty(u_tilde[0]);

		 	  duty=convertToDuty(u_tilde[0]);

		 	 //duty=8400;
		  	  display_brachiate();

	  }else if (mode=='S'){//Swing-up mode
		  	  mode='O';
		     enable_SD_card();
		   //  disable_elbow_motor();
		     disable_gripper();
		     display_swingup();
	  }
	  else if (mode=='O'){ //On mode (Standby)
		  	// disable_elbow_motor();

		     disable_elbow_motor();
		  	 enable_SD_card();
		  	 //disable_gripper();
		  	 open_gripper();
		  	// disable_gripper();
		  	 starter=0;
		  	 //------------Update initial and final states for trajectory generator----------------//
		  	 initial_state[0]=states[0];
		  	 initial_state[1]=states[1];
		  	 initial_state[2]=states[2];
		  	 initial_state[3]=states[3];

		  	 final_state[0]= -initial_state[0];
		  	 final_state[1]= -initial_state[1];
		  	 final_state[2]=0;
		  	 final_state[3]=0;

		 	 //-------------------continuously calculate control action to prevent discontinuities when implementation occurs
		 	 r[0]=pi/4;
		  	 v_tilde[0]=v_tilde[1]*0.8383 + r[1]*0.1622;
//
		 	 //r[0]=1.58;
		 	 e[0]=v_tilde[0]-states[1];
		 	 // e[0]=states[0];

		 	 // ---------------------------Proportional Derivative Control (PD)
		 	  //v[0]=PD(e, P_Gain, D_Gain, sampling_time);
		 	 v[0]=v[1]*0.99 -57.554*e[0]+57.554*0.8915*e[1];
//v[0]=50;

		 	 //---------------------------Implement bumpless transfer here (AWBT)

		 	 //--------------------------Implement Collocated Feedback Linearisation (PFL)

		 	  u[0]=PFL(parameters,states,v[0]);

		 	  //--------------------------implement input saturation
		 	  u_tilde[0]=saturation(u[0]);

		 	  //duty=convertToDuty(u_tilde[0]);

		 	  duty=convertToDuty(u_tilde[0]);
		  	 display_on();

	  }

  }
  /* USER CODE END 3 */
}

 

here is the functions.h that defines the variables:

#include "stm32l4xx_hal.h"

#ifndef FUNCTIONS_H_
#define FUNCTIONS_H_

//private function prototypes
float saturation(float u);
float PD(float* error, float P_Gain,float D_Gain, float sample_time);
float PID(float* error, float Kp,float Ti,float Ts,float Td, float* v );
void dutyConvert(int count,uint8_t* cycle);
int convertToDuty(float u);
float OTG(float* state,char mode ,float* final_states, float* p);
float PFL(float* p,float* s,float v);
void countConvert(uint16_t count,uint8_t* countArray);
void countConvert2(uint32_t count,uint8_t* countArray);
void sortData(uint8_t* temp_data, uint8_t* data,uint8_t dataStart);
void convertDatatoFloat(uint8_t* data,float* gyro ,float* mag ,float* acc, int temperature);
int findDataStart(uint8_t* data,uint16_t datasize );
int wrap(uint16_t index, uint16_t datasize);
void writetoSD(uint8_t idx, uint8_t size,uint8_t* data);
void Filter_to_uint8_t(float t1, float t2, float t1_d, float t2_d, uint8_t* countArray);
void cast(float value,uint8_t* Temp_Array);

void enable_elbow_motor(void);
void disable_elbow_motor(void);
void close_gripper(void);
void open_gripper(void);
void disable_gripper(void);
void enable_SD_card(void);
void disable_SD_card(void);
//------------LED functionality---------
void display_off(void);
void display_on(void);
void display_brachiate(void);
void display_swingup(void);


#endif /* FUNCTIONS_H_ */

 

And here is main.h:

 

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stm32l4xx_hal.h"
#include "stdint.h"

#define DATASIZE 35
#define HEADER 2
#define FilterSize 16
#define DATAPACKET 100

// Timer 3 PC6 timer configuration
extern int32_t duty;
extern int gripper_duty;
extern int ride_duty;
extern int counter;

extern char mode;
extern float gyro1[3];
extern float acc1[3];
extern float mag1[3];

extern float gyro2[3];
extern float acc2[3];
extern float mag2[3];
extern int temperature1;
extern int temperature2;
extern float sampling_time;
//Data flags to determine start of data packet for each IMU

extern int dataflag1;
extern int dataflag2;
extern int data1start;
extern int data2start;
extern int starter;
extern uint8_t data1[DATASIZE];
extern uint8_t data2[DATASIZE];
extern uint8_t temp_data1[DATASIZE];
extern uint8_t temp_data2[DATASIZE];
extern uint8_t SDData[DATAPACKET]; //(+4 accounts for teh duty cylce float value)
extern uint8_t TestData[255];
extern uint8_t countArray[2];
extern uint8_t countArray2[4];
extern uint8_t cycle[4];
extern uint8_t Temp_Array[4];
extern uint16_t count;
extern uint32_t count1;
extern uint16_t datasize;
extern uint8_t KalmanFlag;
extern uint8_t FilterOutput[12];
extern uint8_t writeEnable;
// --parameters ={ m1 , m2 I1 I2 l1 l2 r1 r2 g}
extern float parameters[9];
//---system state in the form {th1 th2 th1_d th2_d}
extern float states[4];
extern float states_previous[4];
extern float initial_state[4];
extern float final_state[4];
extern float pi;
extern float t2ref;
extern float P_Gain;
extern float D_Gain;

extern float e[3];
extern float u[3];
// error, control action, reference, filtered reference sample coefficients
extern float e_p[3];
extern float u_p[3];
extern float r_p[2];
extern float rf_p[2];
extern float r[2];
extern float rf[2];
extern int dir;

//------------------------
extern float Kp;
extern float Ts;
extern float Ti;
extern float Td;

// -------------------diagnostics signals
extern float v[3];
extern float v_tilde[3];
extern float u_tilde[3];
extern int decimation;
extern int counter;
//----------------------------------data structure for SD card-----------

/* USER CODE END Includes */

 

In my understanding, all the variables have been defined. but am still getting the errors on all the data defined in main.h below:

capture.PNG

apologies for the long post, but I have tried a lot of fixes to try to clear and have the code build but no luck. Any help is appreciated on how to define these items. 

16 REPLIES 16

Your link to the definition is helpful. But it i think it is what i have done in the definition code shared. I did not show it in the main.c as the code was too long.  

They seem to be defined as 'static', but prototyped without the 'static' ?

Yes, I have changed that a couple times to both static and not static. I still get the 'undefined reference' error. And when i remove the 'extern' on the variables in main.h i get the 'first defined here' error. 

I see there are many ping pongs here and enable to converge.

So could you please either share your project here so we could check or send it to me over private message as .rar or .7z if you want to keep the confidentiality of your code.

Thank you.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Can't share everything here due to word limits. Will send the zipped folder

Done here

Hello,

The project was shared in private as the user requested.

The issue was solved:

Basically the issue:

All variables were declared in main.h. That file is included in more than location which induced to object multiple definitions.

Fix: all these variables declaration was moved from main.h to function.c file and exported in function.h as extern. 

 

 

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.