Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!

Robotic Arm For Sorting Materials Using Hexabitz Platform

Hexabitz Modules based, a PID- controller has been implemented to sort the materials (Plastic and metal) in two different places.

IntermediateFull instructions provided3 hours492
Robotic Arm For Sorting Materials Using Hexabitz Platform

Things used in this project

Story

Read more

Custom parts and enclosures

Arm design using Solid Work

Schematics

H18R1x Factsheet

Dual H-Bridg Motor Driver (H18R1x) Hardware

Code

STM32 processor code

C/C++
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

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

#include "robot.h"
uint8_t flag=0;
uint8_t material_type=0;
uint8_t base_position_now = 0;
uint16_t AD_RES=0;
uint32_t AD1=0;
uint32_t AD2=0;
uint32_t AD3=0;
uint32_t AD4=0;
uint8_t i=0;
uint16_t j=0;
uint8_t AD[4];
uint8_t pwm1 = 0,pwm2 = 0,pwm3 = 0,pwm4 = 0;
uint8_t series = 10;
float time_now=0,time_previous=0;
float Ts=0.0;
float out1,out2=0.0,out3=0.0,out4=0.0;
float old1=0.0,old2=0.0,old3=0.0,old4=0.0;
float error1=0.0,error2=0.0,error3=0.0,error4=0.0;
float theta1=0.0,theta2=0.0,theta3=0.0,theta4=0.0;
float velocity1=0.0,velocity2=0.0,velocity3=0.0,velocity4=0.0;
float velocity_ref1=0.0,velocity_ref2=0.0,velocity_ref3=0.0,velocity_ref4=0.0;
char direc[4];
char conveyor[1];
char end_effector[1];




uint8_t x =0; // counter as a timer

/* 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 ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void arm_up(void)
{
	error2 = theta2_up - theta2;
	velocity_ref2 = P(error2,kp12);
	if(velocity_ref2 != 0)
	{
		out2 = PI(velocity_ref2 - velocity2, kp2, ki2, Ts);

	      if(out2 < 0)
	      {
	    	  direc[1] = 'f';
	    	  pwm2 = (uint8_t)(-out2);
	      }
	      else
	      {
	    	  direc[1] = 'b';
	    	  pwm2 = (uint8_t)out2;
	      }
	}
	else // velocity_ref2 = 0  (motor2 off)
	{
		//motor2 off
		direc[1] = 's';
		pwm2 = 0;


	}
	error3 = theta3_up - theta3;
			error4 = theta4_up - theta4;
			velocity_ref3 = P(error3, kp13);
			velocity_ref4 = P(error4, kp14);
			if(velocity_ref3 != 0)
			{
				out3 = PI(velocity_ref3 - velocity3, kp3, ki3, Ts);
			      if(out3 < 0)
			      {
			    	  direc[2] = 'f';
			    	  pwm3 = (uint8_t)(-out3);
			      }
			      else
			      {
			    	  direc[2] = 'b';
			    	  pwm3 = (uint8_t)out3;
			      }

			}
			else // velocity_ref3 = 0 (motor3 off)
			{
				direc[2] = 's';
				pwm3 = 0;
			}

			if(velocity_ref4 != 0)
			{
				 out4 = PI(velocity_ref4 - velocity4, kp4, ki4, Ts);
				  if(out4 < 0)
				  {
				      direc[3] = 'f';
				      pwm4 = (uint8_t)(-out4);
				  }
				  else
				  {
				      direc[3] = 'b';
				      pwm4 = (uint8_t)out4;
				  }
			}
			else // velocity_ref4 = 0 (motor4 off)
			{
				direc[3] = 's';
				pwm4 = 0;
			}

			if(velocity_ref3 == 0 && velocity_ref4 == 0 && velocity_ref2 == 0)
			{
				flag = arm_is_up;
			}



	// saturation limits
	if(pwm2>100)
		pwm2=100;
	else if(pwm2<15 && pwm2>2 && direc[1] == 'b')//up
		pwm2=15;
	else if(pwm2<10 && pwm2>2 && direc[1] == 'f')// down
		pwm2=5;
	else if(pwm2 <= 2) {
		direc[1] = 's';
		pwm2=0;
	}

	if(pwm3>50 && direc[2] == 'b'){
		pwm3=50;
	}
	else if(pwm3 > 15 && direc[2] == 'f'){
		pwm3=5;
	}
	else if(pwm3<10 && pwm3>2 && direc[2] == 'f')
	{
		pwm3=5;
	}
	else if(pwm3<18 && pwm3>2 && direc[2] == 'b')
	{
		pwm3=18;
	}
	else if(pwm3 <= 2) {
		direc[2] = 's';
		pwm3=0;
	}

	if(pwm4>40 && direc[3] == 'b') // max speed up
		pwm4=40;
	if(pwm4>10 && direc[3] == 'f')// max speed down
		pwm4=10;
	else if(pwm4<18 && pwm4>3 && direc[3] == 'b')// min  speed up
		pwm4=18;
	else if(pwm4<5 && pwm4>3 && direc[3] == 'f')// min speed down
		pwm4=5;
	else if(pwm4 <= 3)
	{
		direc[3] = 's';
		pwm4=0;
	}

}


void arm_down(void)
{
	error3 = theta3_down - theta3; //     ADC
	error4 = theta4_down - theta4 ;
	velocity_ref3 = P(error3, kp13);
	velocity_ref4 = P(error4, kp14);
	if(velocity_ref3 != 0)
	{
	    out3 = PI(velocity_ref3 - velocity3, kp3, ki3, Ts);
	      if(out3 < 0)
	      {
	          direc[2] = 'f';
	          pwm3 = (uint8_t)(-out3);
	      }
	      else
	      {
	    	  direc[2] = 'b';
	    	  pwm3 = (uint8_t)out3;
	      }

	 }
	 else // velocity_ref3 = 0 (motor3 off)
	 {
		  direc[2] = 's';
		  pwm3 = 0;
	 }

	 if(velocity_ref4 != 0)
	 {
		  out4 = PI(velocity_ref4 - velocity4, kp4, ki4, Ts);
		  if(out4 < 0)
		  {
			  direc[3] = 'f';
			  pwm4 = (uint8_t)(-out4);
		  }
		  else
		  {
			  direc[3] = 'b';
		      pwm4 = (uint8_t)out4;
		  }
	 }
	 else  // velocity_ref4 = 0 (motor4 off)
	 {
		  direc[3] = 's';
		  pwm4 = 0;
	 }
	 error2 = theta2_down - theta2;
	 	      velocity_ref2 = P(error2,kp12);
	 	   	  if(velocity_ref2 != 0)
	 		  {
	 			  out2 = PI(velocity_ref2 - velocity2, kp2, ki2, Ts);

	 			  if(out2 < 0)
	 			  {
	 			      direc[1] = 'f';
	 			      pwm2 = (uint8_t)(-out2);
	 			  }
	 			  else
	 			  {
	 			      direc[1] = 'b';
	 			      pwm2 = (uint8_t)out2;
	 			  }
	 		  }
	 	   	  else
	 	   	  {
	 			  direc[1] = 's';
	 			  pwm2 = 0;

	 	   	  }
	 if(velocity_ref3 == 0 && velocity_ref4 == 0 && velocity_ref2 ==0)
	 {
		 flag = arm_is_down;
	 }

	// saturation limits
	if(pwm2>100)
		pwm2=100;
	else if(pwm2<15 && pwm2>2 && direc[1] == 'b')//up
		pwm2=15;
	else if(pwm2<15 && pwm2>2 && direc[1] == 'f')// down
		pwm2=5;
	else if(pwm2 <= 2) {
		direc[1] = 's';
		pwm2=0;
	}

	if(pwm3>9 && direc[2] == 'f'){
		pwm3 = 9;
	}
	else if(pwm3>50 && direc[2] == 'b')
	{
		pwm3 = 50;
	}
	else if(pwm3<6 && pwm3>3 && direc[2] == 'f')
	{
		pwm3=6;
	}
	else if(pwm3<15 && pwm3>3 && direc[2] == 'b')
	{
		pwm3=15;
	}
	else if(pwm3 <= 3) {
		direc[2] = 's';
		pwm3=0;
	}

	if(pwm4>30 && direc[3] == 'b') // max speed up
		pwm4=30;
	if(pwm4>8 && direc[3] == 'f')// max speed down
		pwm4=8;
	else if(pwm4<25 && pwm4>3 && direc[3] == 'b')// min  speed up
		pwm4=25;
	else if(pwm4<5 && pwm4>3 && direc[3] == 'f')// min speed down
		pwm4=5;
	else if(pwm4 <= 3)
	{
		direc[3] = 's';
		pwm4=0;
	}
}
void rot_base(float teta)
{
	error1 = teta - theta1;
	velocity_ref1=P(error1,kp11);
	if(velocity_ref1 != 0)
	{
	      out1 = PI(velocity_ref1 - velocity1, kp1, ki1, Ts);

	      if(out1 > 0)
	      {
	    	  direc[0] = 'b';
	    	  pwm1 = (uint8_t)out1;
	      }
	      else
	      {
	    	  direc[0] = 'f';
	    	  pwm1 = (uint8_t)(-out1);
	      }

	}
	else
	{
		  direc[0] = 's';
		  pwm1 = 0;
		  base_position_now = teta;
	}


	// Saturation Limits...
	  if(pwm1>100)
		  pwm1=100;
	  else if(pwm1<15 && pwm1>1)
		  pwm1 = 12;
	  else if(pwm1 <= 1)
	  {
		  direc[0] = 's';
		  pwm1 = 0;
		  base_position_now = (uint8_t)teta;
	  }
}

void arm_down2(void){
	error4 = theta4_down - theta4 ;
	velocity_ref4 = P(error4, kp14);
	if(velocity_ref4 != 0)
		 {
			  out4 = PI(velocity_ref4 - velocity4, kp4, ki4, Ts);
			  if(out4 < 0)
			  {
				  direc[3] = 'f';
				  pwm4 = (uint8_t)(-out4);
			  }
			  else
			  {
				  direc[3] = 'b';
			      pwm4 = (uint8_t)out4;
			  }
		 }
		 else  // velocity_ref4 = 0 (motor4 off)
		 {
			  direc[3] = 's';
			  pwm4 = 0;
			  error2 = theta2_down - theta2;
			  	      velocity_ref2 = P(error2,kp12);
			  	   	  if(velocity_ref2 != 0)
			  		  {
			  			  out2 = PI(velocity_ref2 - velocity2, kp2, ki2, Ts);

			  			  if(out2 < 0)
			  			  {
			  			      direc[1] = 'f';
			  			      pwm2 = (uint8_t)(-out2);
			  			  }
			  			  else
			  			  {
			  			      direc[1] = 'b';
			  			      pwm2 = (uint8_t)out2;
			  			  }
			  		  }
			  	   	  else
			  	   	  {
			  			  direc[1] = 's';
			  			  pwm2 = 0;
			  			  flag = arm_is_down;
			  	   	  }
		 }
	//saturation limits
	if(pwm2>100)
		pwm2=100;
	else if(pwm2<15 && pwm2>2 && direc[1] == 'b')//up
		pwm2=15;
	else if(pwm2<15 && pwm2>2 && direc[1] == 'f')// down
		pwm2=5;
	else if(pwm2 <= 2) {
		direc[1] = 's';
		pwm2=0;
	}
	if(pwm4>30 && direc[3] == 'b') // max speed up
			pwm4=30;
		if(pwm4>8 && direc[3] == 'f')// max speed down
			pwm4=8;
		else if(pwm4<18 && pwm4>3 && direc[3] == 'b')// min  speed up
			pwm4=18;
		else if(pwm4<5 && pwm4>3 && direc[3] == 'f')// min speed down
			pwm4=5;
		else if(pwm4 <= 3)
		{
			direc[3] = 's';
			pwm4=0;
		}

}

void arm_up2(void)
{
	error2 = theta2_up - theta2;
	velocity_ref2 = P(error2,kp12);
	if(velocity_ref2 != 0)
	{
		out2 = PI(velocity_ref2 - velocity2, kp2, ki2, Ts);

	      if(out2 < 0)
	      {
	    	  direc[1] = 'f';
	    	  pwm2 = (uint8_t)(-out2);
	      }
	      else
	      {
	    	  direc[1] = 'b';
	    	  pwm2 = (uint8_t)out2;
	      }
	}
	else // velocity_ref2 = 0  (motor2 off)
	{
		//motor2 off
		direc[1] = 's';
		pwm2 = 0;


		error4 = theta4_up - theta4;
		velocity_ref4 = P(error4, kp14);

		if(velocity_ref4 != 0)
		{
			 out4 = PI(velocity_ref4 - velocity4, kp4, ki4, Ts);
			  if(out4 < 0)
			  {
			      direc[3] = 'f';
			      pwm4 = (uint8_t)(-out4);
			  }
			  else
			  {
			      direc[3] = 'b';
			      pwm4 = (uint8_t)out4;
			  }
		}
		else // velocity_ref4 = 0 (motor4 off)
		{
			direc[3] = 's';
			pwm4 = 0;
			flag = arm_is_up;
		}
	}
		// saturation limits
		if(pwm2>100)
			pwm2=100;
		else if(pwm2<15 && pwm2>2 && direc[1] == 'b')//up
			pwm2=15;
		else if(pwm2<15 && pwm2>2 && direc[1] == 'f')// down
			pwm2=5;
		else if(pwm2 <= 2) {
			direc[1] = 's';
			pwm2=0;
		}


		if(pwm4>40 && direc[3] == 'b') // max speed up
			pwm4=40;
		if(pwm4>8 && direc[3] == 'f')// max speed down
			pwm4=8;
		else if(pwm4<18 && pwm4>3 && direc[3] == 'b')// min  speed up
			pwm4=18;
		else if(pwm4<5 && pwm4>3 && direc[3] == 'f')// min speed down
			pwm4=5;
		else if(pwm4 <= 3)
		{
			direc[3] = 's';
			pwm4=0;
		}
}


void arm_down44(void)
{
	error3 = theta3_down - theta3; //     ADC
	error4 = theta4_down - theta4 ;
	velocity_ref3 = P(error3, kp13);
	velocity_ref4 = P(error4, kp14);
	if(velocity_ref3 != 0)
	{
	    out3 = PI(velocity_ref3 - velocity3, kp3, ki3, Ts);
	      if(out3 < 0)
	      {
	          direc[2] = 'f';
	          pwm3 = (uint8_t)(-out3);
	      }
	      else
	      {
	    	  direc[2] = 'b';
	    	  pwm3 = (uint8_t)out3;
	      }

	 }
	 else // velocity_ref3 = 0 (motor3 off)
	 {
		  direc[2] = 's';
		  pwm3 = 0;
	 }

	 if(velocity_ref4 != 0)
	 {
		  out4 = PI(velocity_ref4 - velocity4, kp4, ki4, Ts);
		  if(out4 < 0)
		  {
			  direc[3] = 'f';
			  pwm4 = (uint8_t)(-out4);
		  }
		  else
		  {
			  direc[3] = 'b';
		      pwm4 = (uint8_t)out4;
		  }
	 }
	 else  // velocity_ref4 = 0 (motor4 off)
	 {
		  direc[3] = 's';
		  pwm4 = 0;
	 }
	 error2 = theta2_down2 - theta2;
	 	      velocity_ref2 = P(error2,kp12);
	 	   	  if(velocity_ref2 != 0)
	 		  {
	 			  out2 = PI(velocity_ref2 - velocity2, kp2, ki2, Ts);

	 			  if(out2 < 0)
	 			  {
	 			      direc[1] = 'f';
	 			      pwm2 = (uint8_t)(-out2);
	 			  }
	 			  else
	 			  {
	 			      direc[1] = 'b';
	 			      pwm2 = (uint8_t)out2;
	 			  }
	 		  }
	 	   	  else
	 	   	  {
	 			  direc[1] = 's';
	 			  pwm2 = 0;

	 	   	  }
	 if(velocity_ref3 == 0 && velocity_ref4 == 0 && velocity_ref2 ==0)
	 {
		 flag = arm_is_down;
	 }

	// saturation limits
	if(pwm2>100)
		pwm2=100;
	else if(pwm2<15 && pwm2>2 && direc[1] == 'b')//up
		pwm2=15;
	else if(pwm2<15 && pwm2>2 && direc[1] == 'f')// down
		pwm2=5;
	else if(pwm2 <= 2) {
		direc[1] = 's';
		pwm2=0;
	}

	if(pwm3>9 && direc[2] == 'f'){
		pwm3 = 9;
	}
	else if(pwm3>50 && direc[2] == 'b')
	{
		pwm3 = 50;
	}
	else if(pwm3<6 && pwm3>3 && direc[2] == 'f')
	{
		pwm3=6;
	}
	else if(pwm3<15 && pwm3>3 && direc[2] == 'b')
	{
		pwm3=15;
	}
	else if(pwm3 <= 3) {
		direc[2] = 's';
		pwm3=0;
	}

	if(pwm4>30 && direc[3] == 'b') // max speed up
		pwm4=30;
	if(pwm4>8 && direc[3] == 'f')// max speed down
		pwm4=8;
	else if(pwm4<25 && pwm4>3 && direc[3] == 'b')// min  speed up
		pwm4=25;
	else if(pwm4<5 && pwm4>3 && direc[3] == 'f')// min speed down
		pwm4=5;
	else if(pwm4 <= 3)
	{
		direc[3] = 's';
		pwm4=0;
	}
}

void arm_up44(void)
{
	error2 = theta2_up - theta2;
	velocity_ref2 = P(error2,kp12);
	if(velocity_ref2 != 0)
	{
		out2 = PI(velocity_ref2 - velocity2, kp2, ki2, Ts);

	      if(out2 < 0)
	      {
	    	  direc[1] = 'f';
	    	  pwm2 = (uint8_t)(-out2);
	      }
	      else
	      {
	    	  direc[1] = 'b';
	    	  pwm2 = (uint8_t)out2;
	      }
	}
	else // velocity_ref2 = 0  (motor2 off)
	{
		//motor2 off
		direc[1] = 's';
		pwm2 = 0;


	}
	error3 = theta3_up - theta3;
			error4 = theta4_up2 - theta4;
			velocity_ref3 = P(error3, kp13);
			velocity_ref4 = P(error4, kp14);
			if(velocity_ref3 != 0)
			{
				out3 = PI(velocity_ref3 - velocity3, kp3, ki3, Ts);
			      if(out3 < 0)
			      {
			    	  direc[2] = 'f';
			    	  pwm3 = (uint8_t)(-out3);
			      }
			      else
			      {
			    	  direc[2] = 'b';
			    	  pwm3 = (uint8_t)out3;
			      }

			}
			else // velocity_ref3 = 0 (motor3 off)
			{
				direc[2] = 's';
				pwm3 = 0;
			}

			if(velocity_ref4 != 0)
			{
				 out4 = PI(velocity_ref4 - velocity4, kp4, ki4, Ts);
				  if(out4 < 0)
				  {
				      direc[3] = 'f';
				      pwm4 = (uint8_t)(-out4);
				  }
				  else
				  {
				      direc[3] = 'b';
				      pwm4 = (uint8_t)out4;
				  }
			}
			else // velocity_ref4 = 0 (motor4 off)
			{
				direc[3] = 's';
				pwm4 = 0;
			}

			if(velocity_ref3 == 0 && velocity_ref4 == 0 && velocity_ref2 == 0)
			{
				flag = arm_is_up;
			}



	// saturation limits
	if(pwm2>100)
		pwm2=100;
	else if(pwm2<15 && pwm2>2 && direc[1] == 'b')//up
		pwm2=15;
	else if(pwm2<10 && pwm2>2 && direc[1] == 'f')// down
		pwm2=5;
	else if(pwm2 <= 2) {
		direc[1] = 's';
		pwm2=0;
	}

	if(pwm3>50 && direc[2] == 'b'){
		pwm3=50;
	}
	else if(pwm3 > 15 && direc[2] == 'f'){
		pwm3=5;
	}
	else if(pwm3<10 && pwm3>2 && direc[2] == 'f')
	{
		pwm3=5;
	}
	else if(pwm3<20 && pwm3>2 && direc[2] == 'b')
	{
		pwm3=20;
	}
	else if(pwm3 <= 2) {
		direc[2] = 's';
		pwm3=0;
	}

	if(pwm4>50 && direc[3] == 'b') // max speed up
		pwm4=50;
	if(pwm4>8 && direc[3] == 'f')// max speed down
		pwm4=8;
	else if(pwm4<28 && pwm4>3 && direc[3] == 'b')// min  speed up
		pwm4=28;
	else if(pwm4<5 && pwm4>3 && direc[3] == 'f')// min speed down
		pwm4=5;
	else if(pwm4 <= 3)
	{
		direc[3] = 's';
		pwm4=0;
	}

}
/* USER CODE END 0 */

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

  /* USER CODE END 1 */

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

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

  /* USER CODE BEGIN Init */
  conveyor[0]='n';
  /* 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_ADC1_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_ADCEx_Calibration_Start(&hadc1);


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	    /* USER CODE END WHILE */
//
          old1 = theta1;
          old2 = theta2;
          old3 = theta3;
          old4 = theta4;
          AD1=0;
          AD2=0;
          AD3=0;
          AD4=0;

          for(j=0;j<100;j++)
          {
        	  for(i=0; i<4; i++)
        	  	      {

        	  	      HAL_ADC_Start(&hadc1); // Start ADC Conversion
        	  	      HAL_ADC_PollForConversion(&hadc1, 1); // Poll ADC1 Peripheral & TimeOut = 1mSec
        	  	      AD_RES = HAL_ADC_GetValue(&hadc1); // Read ADC Conversion Result
        	  	      switch(i)
        	  	      {
        	  	        case 0:
        	  	          AD1 += AD_RES>>3; // Map The ADC_RES To PWM DutyCycle
        	  	          break;
        	  	        case 1:
        	  	          AD2 += AD_RES>>3; // Map The ADC_RES To PWM DutyCycle
        	  	          break;
        	  	        case 2:
        	  	          AD3 += AD_RES>>3; // Map The ADC_RES To PWM DutyCycle
        	  	          break;
        	  	        case 3:
        	  	          AD4 += AD_RES>>3; // Map The ADC_RES To PWM DutyCycle
        	  	          break;
        	  	       }
        	        }
          }

	      theta1=((AD1/155.555)-87)*(pi/180.0);   //  AD/100 (100 number of reads) degree into rad (need to shift 3 bits to left )
	      theta2=((AD2/155.555)-87)*(pi/180.0);
	      theta3=((AD3/155.555)-87)*(pi/180.0);
	      theta4=((AD4/155.555)-87)*(pi/180.0);
//
	      time_previous = time_now;
	      time_now = HAL_GetTick();
	      Ts = (time_now-time_previous)/1000.0;
	      velocity1=(theta1-old1)/Ts;
	      velocity2=(theta2-old2)/Ts;
	      velocity3=(theta3-old3)/Ts;
	      velocity4=(theta4-old4)/Ts;

//          arm_down2();

	      if(series == 10 )
	      {

	    	  conveyor[0] = 'n';
		      if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15)==1)// B15 inductive Proximity Sensor
		      {

		    	  material_type = metal;

		      }
		      if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)==1)// A8 capacity proximity sensor
		      {
		    	  conveyor[0] = 's';  // Stop Conveyor belt
		    	  if(material_type != metal)
		    	  {
		    		  material_type = not_metal;
		    	  }
		    	  series = 1;  // next step

		      }


	      }
	      else if(series == 1)
	      {
	    	  arm_up();
	    	  if(flag == arm_is_up)
	    	  {
	    		   series = 2;
	    	  }


	      }
	      else if(series == 2 )
	      {
	    	  rot_base(pi/2);
	    	  if(base_position_now == (uint8_t)(pi/2))
	    	  {
	    		  series = 3;
	    	  }

	      }


	      else if( series == 3 )
	      {
	    	  arm_down();
	    	  if(flag == arm_is_down)
	    	  {
	    	  	   end_effector[0]='c';
	    	  	   x += 1;
	    	  }
	    	  if(x == 100)
	    	  {
	    		  series = 4;
	    		  x = 0;
	    	  }

	      }
	      else if(series == 4)
	      {
	    	  arm_up44();
	    	  if(flag == arm_is_up)
	    	  {
	    		  series = 5;
	    	  }

	      }
	      else if(series == 5)
	      {
	    	  if(material_type == metal)
	    	  {
	    		  rot_base(pi);
	    		  if(base_position_now == (uint8_t)(pi))
	    		  {
	    			  series = 6;
	    		  }

	    	  }
	    	  else if(material_type == not_metal)
	    	  {
	    		  rot_base(0.0);
	    		  if(base_position_now == (uint8_t)(0.0))
	    		  {
	    			  series = 6;
	    		  }
	           }
	      }
	      else if(series == 6)
	      {
	    	  arm_down44();
	    	  if(flag == arm_is_down)
	    	  {
	    		  series = 7;
	    	  }
	      }
	      else if(series == 7)
	      {
	    	  end_effector[0] = 'o';
	    	  x += 1;                // as a timer
	    	  if(x == 100)
	    	  {
	    		  x = 0;
	    		  series = 10;
	    		  material_type = 0;
	    	  }
	      }





	      memcpy(&AD[0],&pwm1,1);
	      memcpy(&AD[1],&pwm2,1);
	      memcpy(&AD[2],&pwm3,1);
	      memcpy(&AD[3],&pwm4,1);
	      HAL_UART_Transmit(&huart2, end_effector, 1, 100);
	      HAL_UART_Transmit(&huart2, conveyor, 1, 100);
	      HAL_UART_Transmit(&huart2, direc, 4, 100);
	      HAL_UART_Transmit(&huart2, AD, 4, 100);

	      HAL_Delay(15);

...

This file has been truncated, please download it to see its full contents.

Variables and constants

C/C++
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __ROBOT_H
#define __ROBOT_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stm32g0xx_hal.h"


#define metal                                       1 // The material is metal
#define not_metal                                   2 // The material is not metal

#define pi                                       3.14
#define theta1_0                                   0 // 0 degree for base
#define theta1_90                                1.57 // 90 degree for base
#define theta1_180                               3.14 // 180 degree for base
#define theta2_down                              1.48 // down for shoulder (pi/2)
#define theta2_up                                2.155 // up for shoulder  (3pi/4)
#define theta3_down                              1.80 // down for shoulder
#define theta3_up                                2.20  // up for shoulder
#define theta4_down                              2.0  // down for shoulder
#define theta4_up                                1.40  // up for shoulder
#define theta2_down2                             1.15 // down for shoulder (pi/2)
#define theta4_up2                               1.25  // up for shoulder

#define min_velocity_1                              7 //  7 % PWM
#define min_velocity_2_up                          10 // 10 % PWM
#define min_velocity_2_down                         6 //  6 % PWM
#define min_velocity_3_up                          10 // 10 % PWM
#define min_velocity_3_down                         5 //  5 % PWM
#define min_velocity_4_up                           6 //  6 % PWM
#define min_velocity_4_down                         6 //  6 % PWM

#define done_classification                         0 // fished the operation
#define arm_is_down                                 1 // Arm is down
#define arm_is_up                                   2 // Arm is down
#define catch                                       3 // end_effector is closed (catch)



#define Kp1                                        4.0  // Kp for P controller
#define Kp                                         20.0 // Kp for PI controller
#define Ki                                         5.0  // Ki for PI controller



// parameter for P controller
#define kp11                                        6.0 // kp for P controller motor1
#define kp12                                        6.0 // kp for P controller motor2
#define kp13                                        6.5 // kp for P controller motor3
#define kp14                                        6.0 // kp for P controller motor4

// parameter for PI controller

#define kp1                                        17.0 // kp for PI controller motor1
#define kp2                                        15.0 // kp for PI controller motor2
#define kp3                                        15.0 // kp for PI controller motor3
#define kp4                                        10.0 // kp for PI controller motor4

#define ki1                                        10.0 // ki for PI controller motor1
#define ki2                                        5.0 // ki for PI controller motor2
#define ki3                                        5.0 // ki for PI controller motor3
#define ki4                                        20.0 // ki for PI controller motor4  //25






float PI_one(float error, float Ts);
float P(float error ,float KP);
float PI(float error, float KP, float KI, float Ts);













#ifdef __cplusplus
}
#endif

#endif /* ROBOT_H */

pi and p function

C/C++
#include "robot.h"

// must define Kp,Ki in "robot.h"
float PI_one(float error,float Ts)
{
	 static float error_previous, sum;
//	 static uint8_t x;
	 float  out_PI;
//	 x += 1;
//	 if(x == 5)
//	 {
//		 sum=0;
//	 }
	 sum += error;
	 out_PI = Kp*error + Ki*(error+error_previous)*Ts;
	 error_previous = error;
	 if(out_PI > 100.0)
		 out_PI = 100.0;
	 else if(out_PI < -100.0)
		 out_PI = -100.0;


	 return out_PI;

}

float P(float error , float KP)
{

	 float out_P;
	 out_P = KP*error ;
	 if(out_P > pi/2)   // Max speed = pi/2 (rad/s)
		 out_P = pi/2;
	 else if(out_P < -pi/2)
		 out_P = -pi/2;

	 if(error < 0.05 && error > -0.05)
		 out_P = 0.0;


	 return out_P;
}


float PI(float error, float KP, float KI, float Ts)
{
	 static float error_previous,sum ;
	 float probortional, integral, out_PI ;

//	 if(x == 5)//////////////////////////
//		 sum = 0;
//	 sum += error;
	 integral = KI*(error+error_previous)*Ts;
	 if(integral > 5.0)
		 integral = 5.0;
	 else if(integral < -5.0)
		 integral = -5.0;
	 probortional = KP*error;
	 out_PI = probortional + integral;
	 error_previous = error;
	 if(out_PI > 100.0)
		 out_PI = 100.0;
	 else if(out_PI < -100.0)
		 out_PI = -100.0;

	 return out_PI;
}

Dual H-Bridg Motor Driver (H18R1x) firmware

Credits

Ahmad-Almadloosh
1 project • 1 follower
Contact
Haseeb AbdulRahman
1 project • 1 follower
Contact
Ahmad TASKIA
11 projects • 11 followers
MPhil. Bsc. ELECTRONICS Engineering
Contact
Ahmed Abdulhai
3 projects • 3 followers
Contact

Comments

Please log in or sign up to comment.