2024-08-27 3:25 PM
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:
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.
Solved! Go to Solution.
2024-08-29 1:44 AM
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.
2024-08-27 3:39 PM - edited 2024-08-27 3:40 PM
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?
2024-08-27 4:00 PM - edited 2024-08-27 4:01 PM
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.
2024-08-27 4:15 PM - edited 2024-08-27 4:18 PM
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];
}
					
				
			
			
				
			
			
				
			
			
			
			
			
			
		2024-08-27 4:20 PM
Yes, I have added it on the other comment.
2024-08-27 4:24 PM
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.
2024-08-27 5:17 PM
> Yes, I have a functions.c below that is being compiled.
The definition for disable_gripper is not in the file you posted.
2024-08-28 2:53 AM - edited 2024-08-28 2:53 AM
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!
2024-08-28 2:54 AM
@TDK wrote:The definition for disable_gripper is not in the file you posted.
Neither are any of these:
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
2024-08-28 5:16 AM
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 *