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. 

1 ACCEPTED SOLUTION

Accepted Solutions

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.

View solution in original post

16 REPLIES 16
TDK
Guru

Start with the first error.

I don't see a definition for disable_gripper anywhere. It's declared (not defined) in main.c and in functions.h.

Is there a function.c that defines it? Is that getting compiled?

 

Similarly, for variables, I don't see a definition for u_tilde anywhere. What file is this defined in and is that file getting compiled?

If you feel a post has answered your question, please click "Accept as Solution".
SofLit
ST Employee

Hello,

Where did you define all these "undefined" objects?

You exported them in function.h but you need somthing like a "function.c" file where these objects need to be defined and function.c to be added to your project.

 

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.

Yes, I have a functions.c below that is being compiled. 

#include "stm32l4xx_hal.h"
#include "math.h"
#include "main.h"
#include <stdio.h>
#include <stdlib.h>
/*
 * Define External variables
*/
extern TIM_HandleTypeDef htim4;
extern TIM_HandleTypeDef htim8;

float saturation(float u){
	float limit=20;
	float ut;
	if (u>limit){ut=limit;}
	else if (u<-limit){ut=-limit;}
	else{ut=u;}


	return ut;
}
void cast(float values,uint8_t* Temp_Array){

	union myFloat {
		float value;
		uint8_t bytes[sizeof(float)];

	} myCast;//, myMag;
	myCast.value=values;

	Temp_Array[0]=myCast.bytes[0];
	Temp_Array[1]=myCast.bytes[1];
	Temp_Array[2]=myCast.bytes[2];
	Temp_Array[3]=myCast.bytes[3];

}
float PD(float* error, float P_Gain,float D_Gain, float sample_time){
	//assuming collocated feedback linearisation

	return (P_Gain + (D_Gain/sample_time))*error[0]-(D_Gain/sample_time)*error[1];//-(sample_time-1)*v[1] + e[0]*( P_Gain + D_Gain ) +e[1]*(P_Gain*(sample_time-1)-D_Gain);

}

float PID(float* error, float Kp,float Ti,float Ts,float Td, float* v ){

	float a1= Kp*Ti*Ts+Kp*(pow(Ts,2)) + Kp*Td*Ti;
	float a2=-Kp*Ti*Ts-2*Kp*Td*Ti;
	float a3= Kp*Td*Ti;

	return (1/(Ti*Ts))*(  Ti*Ts*v[1] +a1*error[0] + a2*error[1] + a3*error[2]);
}

int convertToDuty(float u){
	//take in torque signal u nad produce a pwm duty cyle integer
	float u_abs=abs(u);
	//first convert teh desired torque to desired current
	float i=u_abs/1.323;
	//compute desired PWM signal
	float pwm= (i+1.875)*(80/15);
	int duty= (pwm/100)*16799;
//	float gradient=312.5;
//	float intercept=-3125;
//	float pwm=(abs(u)-intercept)/gradient;
//	int duty= (pwm/100)*16799;
//	if (pwm<=0){
//		int ***=1;
//		int add_= *** +20;
//	}

	//clip pwm value
	if(duty>15119){
		duty=15119;
	}
	else if (duty<1680){
		duty=1680;
	}

	return (int)duty ;
}

float OTG(float* state,char mode ,float* final_states, float* p){
	// --parameters ={ m1 , m2 I1 I2 l1 l2 r1 r2 g}

	// initialise general trajectory for swing torque
    //float ref= (final_states[1]/final_states[0])* state[0];
    // velocity reference
    float ref=(final_states[1]/final_states[0])*state[0];//*state[2]*(30/pi);
    //------compute distance to ceiling assuming horizontal line
    // 1. Compute straight distance from end-effector to fixed point
  //  float d = sqrt((pow(p[4],2))+(pow(p[5],2))- 2*p[4]*p[5]*cos(M_PI -state[1]));
    // 2. compute  x =theta_line -theta_1 -theta
  //  float x = asin((p[5]*sin(pi-state[1]))/(d));
//    float theta=(pi/2)-asin((p[4]*sin(state[1]))/d)-state[0]


	return ref;
}
/**
  * @brief  Online trajectory generation function which takes in the system state and the mode
  * produces a reference signal for th2 assuming collocated feedback linearisation
  * mode 'F' = Off 'S'= swing up 'B' = Brachiate and 'O'=on
  * 			[  0   1   2   3   4   5   6   7  8]
  * state s={th1, th2, th1_d, th2_d}
  */

float PFL(float* p,float* s,float v){

	//The following model is based on the model in the dissertation for a two-link acrobot
	//-----------------------parameters ={ m1 , m2 I1 I2 l1 l2 r1 r2 g}

	float m1=p[0];
	float m2=p[1];
	float I1=p[2];
	float I2=p[3];
	float l1=p[4];
	float l2=p[5];
	float r1=p[6];
	float r2=p[7];
	float g=9.8;
	float t1=s[0];
	float t2=s[1];
	float t1_d=s[2];
	float t2_d=s[3];

	//creat Mass matrix elements m11 m12 m21 m22
	// state s =[theta1 theta2 dtheta1 dtheta2]
	float m11= m1* pow(r1,2) + m2*(pow(l1,2) +pow(r2,2)+ 2*l1*r2*cos(t2)) +I1 +I2 ; // p[0]*pow(p[6],2) + p[2] + p[1]*(pow(p[4],2) + 2*p[4]*p[7]*cos(s[1]) + pow(p[7],2))+ p[3];
	float m12= m2*(pow(r2,2) +l1*r2*cos(t2)) + I2; 	//p[1]*(	 pow(p[7],2) + p[4]*p[7]*cos(s[2])	) + p[3];
	/// note that m21=m12
	float m22= m2*pow(r2,2) +I2;

	//compute inverse of mass matrix
	float n21= -m12/(m11*m22-pow(m12,2));
	float n22= m11/(m11*m22-pow(m12,2));

	//calculate elements of Coriolis and Gravity vector
	float c1=-m2*l1*r2*sin(t2) *(2*t1_d*t2_d +pow(t2_d,2));
	float c2=-m2*l1*r2*sin(t2) *(-pow(t1_d,2));

	float g1= (m1*r1 +m2*l1)*g*sin(t1) +m2*r2*g*sin(t1+t2);
	float g2= m2*r2*g*sin(t1+t2);

	//implement partial feedback linearisation which takes in v and produces the corresponding torque signal
	float torque= (1/n22)*( n21*(c1+g1) + n22 *(c2 + g2) +v);

	return torque;

}

/**
  * @brief  Collocated partial feedback linearisation of link 2
  * parameters p={ m1, m2, I1, I2, l1, l2, r1, r2, g}
  * 			[  0   1   2   3   4   5   6   7  8]
  * state s={th1, th2, th1_d, th2_d}
  */
void dutyConvert(int count,uint8_t* cycle){
	union myFloat {
		int value;
		uint8_t bytes[sizeof(int)];

	} myCount;//, myMag;
	myCount.value=count;
	cycle[0]=myCount.bytes[0];
	cycle[1]=myCount.bytes[1];
	cycle[2]=myCount.bytes[2];
	cycle[3]=myCount.bytes[3];

}

void countConvert2(uint32_t count,uint8_t* countArray){
	union myFloat {
		uint32_t value;
		uint8_t bytes[sizeof(uint32_t)];

	} myCount;//, myMag;
	myCount.value=count;
	countArray[0]=myCount.bytes[0];
	countArray[1]=myCount.bytes[1];
	countArray[2]=myCount.bytes[2];
	countArray[3]=myCount.bytes[3];

}

/**
  * @brief  casts uint16_t as a uint8_t array.
  */
void countConvert(uint16_t count,uint8_t* countArray){
	union myFloat {
		uint16_t value;
		uint8_t bytes[sizeof(uint16_t)];

	} myCount;//, myMag;
	myCount.value=count;
	countArray[0]=myCount.bytes[0];
	countArray[1]=myCount.bytes[1];

}

/**
  * @brief  Converts filter data  which is an array of floats to uint8_t's

  */

void Filter_to_uint8_t(float t1, float t2, float t1_d, float t2_d, uint8_t* countArray){

	union myFloat {
		float value;
		uint8_t bytes[sizeof(float)];

	} myCount;//, myMag;

	myCount.value=t1;
	countArray[0]=myCount.bytes[0];
	countArray[1]=myCount.bytes[1];
	countArray[2]=myCount.bytes[2];
	countArray[3]=myCount.bytes[3];

	myCount.value=t2;
	countArray[4]=myCount.bytes[0];
	countArray[5]=myCount.bytes[1];
	countArray[6]=myCount.bytes[2];
	countArray[7]=myCount.bytes[3];

	myCount.value=t1_d;
	countArray[8]=myCount.bytes[0];
	countArray[9]=myCount.bytes[1];
	countArray[10]=myCount.bytes[2];
	countArray[11]=myCount.bytes[3];

	myCount.value=t1_d;
	countArray[12]=myCount.bytes[0];
	countArray[13]=myCount.bytes[1];
	countArray[14]=myCount.bytes[2];
	countArray[15]=myCount.bytes[3];
}
/**
  * @brief  Converts IMU data which is an array of uint8_t's to floats

  */

void convertDatatoFloat(uint8_t* data,float* gyro ,float* mag ,float* acc, int temperature){

	union myFloat {
		float data;
		uint8_t bytes[sizeof(float)];

	} myGyro, myAcc;//, myMag;

	myGyro.bytes[0]=data[10];
	myGyro.bytes[1]=data[11];
	myGyro.bytes[2]=data[12];
	myGyro.bytes[3]=data[13];
	gyro[0]=myGyro.data;

	myGyro.bytes[0]=data[14];
	myGyro.bytes[1]=data[15];
	myGyro.bytes[2]=data[16];
	myGyro.bytes[3]=data[17];
	gyro[1]=myGyro.data;

	myGyro.bytes[0]=data[18];
	myGyro.bytes[1]=data[19];
	myGyro.bytes[2]=data[20];
	myGyro.bytes[3]=data[21];
	gyro[2]=myGyro.data;

	myAcc.bytes[0]=data[22];
	myAcc.bytes[1]=data[23];
	myAcc.bytes[2]=data[24];
	myAcc.bytes[3]=data[25];
	acc[0]=myAcc.data;

	myAcc.bytes[0]=data[26];
	myAcc.bytes[1]=data[27];
	myAcc.bytes[2]=data[28];
	myAcc.bytes[3]=data[29];
	acc[1]=myAcc.data;

	myAcc.bytes[0]=data[30];
	myAcc.bytes[1]=data[31];
	myAcc.bytes[2]=data[32];
	myAcc.bytes[3]=data[33];
	acc[2]=myAcc.data;

	temperature= data[34];


}

Yes, I have added it on the other comment. 

Why don't your line numbers line up?

The first error complains about disable_gripper on line 221, but line 221 is a comment. It could just be the formatting from the forum, but ...

And why are there so many global variables? It's a style thing, but globals have been considered harmful since 1973.

> Yes, I have a functions.c below that is being compiled. 

The definition for disable_gripper is not in the file you posted.

If you feel a post has answered your question, please click "Accept as Solution".

Ok but I don't see the undefined objects declared in function.c file.

for example "disable_gripper", "decimation" .. etc ..

They were not declared in your function.c!

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.

@TDK wrote:

The definition for disable_gripper is not in the file you posted.


Neither are any of these:

AndrewNeil_1-1724838706298.png

I didn't check the rest!

The fundamental problem does, indeed, seem to be that you have just declared these things, but not defined them.

https://c-faq.com/decl/decldef.html

https://community.st.com/t5/stm32cubeide-mcus/adding-new-c-source-files-to-my-project-and-navigating-through/m-p/657455/highlight/true#M25847

 

I did not show them in the main.c, they come after GPIO_Init as below: 

* USER CODE BEGIN 4 */
static void disable_elbow_motor(void){
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1,GPIO_PIN_RESET);
	duty=1680;

}
static void enable_elbow_motor(void){
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1,GPIO_PIN_SET);

}
static void close_gripper(void){
	gripper_duty= 500;
}

static void open_gripper(void){
	gripper_duty=250;
}
static void disable_gripper(void){
	gripper_duty=0;
}
static void enable_SD_card(void){
	writeEnable=1;
}
static void disable_SD_card(void){
	writeEnable=0;
}

static void display_off(void){
	 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,GPIO_PIN_SET);
}

static void display_on(void){
 	 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4,GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,GPIO_PIN_RESET);
}

static void display_brachiate(void){

 	 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12,GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,GPIO_PIN_RESET);

}
static void display_swingup(void){
     HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2,GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4,GPIO_PIN_RESET);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,GPIO_PIN_RESET);

}
/* USER CODE END 4 *