2024-08-27 03: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 01: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 03:39 PM - edited 2024-08-27 03: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 04:00 PM - edited 2024-08-27 04: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 04:15 PM - edited 2024-08-27 04: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 04:20 PM
Yes, I have added it on the other comment.
2024-08-27 04: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 05: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 02:53 AM - edited 2024-08-28 02: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 02: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 05: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 *