To help the technicians solve the problems of sorting out numerous & various electronic components, We designed a new SMD component counter.
Bowl feeders are commonly used in industrial automation to handle a large number of parts, such as nuts and bolts, and deliver them to a process one at a time. Often, these feeders include orientation steps to ensure that all the parts are aligned in the correct position for the process. We used these mechanisms to design small machines that count SMD electronic parts.
The project is also about designing a real product by yourself, this product is similar to another on the market as the search engines showed. It’s easy and economic to DIY this device.
In this tutorial, We will take you through the steps that we followed to make this awesome project. We hope you will like it.
Steps 📝🛠️1) Design and 3D print the project enclosure and mechanical parts:
The basic form of the machine has a weighted base and an upper bowl on three angled springs. while the lower base is fixed the upper ones hang using something like a suspension system and in the center of the upper base we put a vibratory motor that will provide the right vibration to make the part move. All part drawings using SOLID-WORKS then printed 🖨️🪛🔧⚙️
2)Plan the array and assemble the hardware:
The motor needed to be driven with a Hexabitz SPST MOSFET Switch Module(H0FR7) which controls the speed of the motor and then the speed of parts motion. Then we used IR Infrared sensor to count the pieces after they arrived at the hole in the upper base [1].
We also used 6 Digit Seven Segment Module(H3BR6x) to show the number of SMD pieces and we put a group of push buttons to set the number of pieces we wanted [2].
and 3.3V/1A DC-DC Power Supply Module(H03R0x) to provide a 3.3v to run all module used in these project by 12v external power supply [3].
We prepare the project components and plan our array design by aligning modules side-by-side. Then we solder the modules together using Hexabitz Fixture.
We used a 100-mil PTH Proto Board (H00R4x) to build slot optocoupler sensor module circuit [4].
The circuit of optocoupler sensor module is very simple and easy to build with very few components. As you can see in the circuit diagram.
And H40Rx is a programmer module which contains STLINK-V3MODS stand-alone debugging and programming mini probe for STM32 microcontrollers (Hexabitz modules and other MCUs) [5].
3) Writing codes with STM32CubeIDE software:
Check out this article for writing code with STM32CubeIDE.
Let's first create the topology for the three modules (H0FR7, H3BR6) and set their configurations, then add the same topology for all modules.
/*
BitzOS (BOS) V0.2.9 - Copyright (C) 2017-20232 Hexabitz
All rights reserved
File Name : topology.h
Description : Array topology definition.
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __topology_H
#define __topology_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32g0xx_hal.h"
#define __N 2 // Number of array modules
// Array modules
#define _mod1 1<<3
#define _mod2 2<<3
// Topology
static uint16_t array[__N ][7] ={
{_H0FR7 , _mod2 | P3, 0, 0, 0, 0, 0}, // Module 1
{_H3BR6, 0, 0,_mod1 | P1, 0, 0, 0}, // Module 2
};
// Configurations for duplex serial ports
#if ( _module == 1 )
#define H0FR7 1
#define _P1pol_normal 1
#define _P2pol_normal 1
#define _P3pol_normal 1
#define _P4pol_normal 1
#define _P5pol_normal 1
#define _P6pol_normal 1
#endif
#if ( _module == 2 )
#define H3BR6 1
#define _P1pol_normal 1
#define _P2pol_normal 1
#define _P3pol_reversed 1
#define _P4pol_normal 1
#define _P5pol_normal 1
#define _P6pol_normal 1
#endif
#ifdef __cplusplus
}
#endif
#endif /*__ topology_H */
/************************ (C) COPYRIGHT HEXABITZ *****END OF FILE****/
Now, let's enable the topology by un-comment its #include directive in project.h file inside all modules.
#include "topology.h"
- H0FR7 Firmware main.c code:
/*
BitzOS (BOS) V0.2.9 - Copyright (C) 2017-2023 Hexabitz
All rights reserved
File Name : main.c
Description : Main program body.
*/
/* Includes ------------------------------------------------------------------*/
#include "BOS.h"
#include <stdio.h>
#include <string.h>
/* Private variables ---------------------------------------------------------*/
bool INC,DEC,Callback,SENS=0,work_sens=1;
bool SENSER_INT=0,stoooop=0;
bool flag_hold=0,flag_press=0,a=0;
uint32_t counter_Callback=0;
uint32_t startTime=0,startTimee=0;
uint16_t D_CNT=0,C_CNT=0;
int parameter=0;
int pwm=30;//dutyCycle mosfet --> 3.7v
int NumberOfCounter=0;
int NumberOfPieces=0;
int distance=0;
int Out_thePieces=0;
bool reset_Number_operations=0;
int currentNumber = 0; // Variable to keep track of the current number being set
uint32_t Steps;
uint16_t time=500;
char idDisplay;
int Latch_ON=0;
bool start=0;
uint32_t Number_of_operations=0;
uint32_t Tickstart1=0,Timeout1=8;
uint8_t testmodbus[5];
HAL_StatusTypeDef statuse=0;
/* Private function prototypes -----------------------------------------------*/
void INC_function()
{
INC = HAL_GPIO_ReadPin(Count_inc_GPIO_Port, Count_inc_Pin);
if(!INC&&flag_hold==1)
{
D_CNT=D_CNT+1;
if(parameter==1)
{
NumberOfCounter=D_CNT;
memcpy(&messageParams[0],&NumberOfCounter, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='n';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
if( parameter==2)
{
NumberOfPieces=D_CNT;
memcpy(&messageParams[0],&NumberOfPieces, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='C';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
if(parameter==3)
{
distance=D_CNT;
memcpy(&messageParams[0],&distance, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='d';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
if(parameter==4)
{
Out_thePieces=D_CNT;
memcpy(&messageParams[0],&Out_thePieces, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='g';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
if(parameter==5)
{
reset_Number_operations=D_CNT;
memcpy(&messageParams[0],&reset_Number_operations, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='R';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
}
}
void DEC_function()
{
DEC = HAL_GPIO_ReadPin(Count_dec_GPIO_Port, Count_dec_Pin);
if(!DEC&&(D_CNT>0)&&flag_hold==1)
{
D_CNT--;
if(parameter==1)
{
NumberOfCounter=D_CNT;
memcpy(&messageParams[0],&NumberOfCounter, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='n';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
if(parameter==2)
{
NumberOfPieces=D_CNT;
memcpy(&messageParams[0],&NumberOfPieces, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='C';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
if(parameter==3)
{
distance=D_CNT;
memcpy(&messageParams[0],&distance, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='d';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
if(parameter==4)
{
Out_thePieces=D_CNT;
memcpy(&messageParams[0],&Out_thePieces, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='g';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
if(parameter==5)
{
reset_Number_operations=D_CNT;
memcpy(&messageParams[0],&reset_Number_operations, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='R';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
}
}
void display_parameter()
{
if( parameter==1&¤tNumber==0)
{
Delay_ms(800);
memcpy(&messageParams[0],&NumberOfCounter, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
idDisplay='n';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
currentNumber++;
}
else if( parameter==2&¤tNumber==1)
{
memcpy(&messageParams[0],&NumberOfPieces, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
idDisplay='C';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
currentNumber++;
}
else if( parameter==3&¤tNumber==2)
{
memcpy(&messageParams[0],&distance, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber,5);
idDisplay='d';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
currentNumber++;
}
else if( parameter==4&¤tNumber==3)
{
memcpy(&messageParams[0],&Out_thePieces, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
idDisplay='g';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
currentNumber++;
}
else if( parameter==5&¤tNumber==4)
{
memcpy(&messageParams[0],&reset_Number_operations, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
idDisplay='R';
messageParams[0]=idDisplay;
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
currentNumber++;
}
else if( parameter==6)
{
SendMessageToModule(2, CODE_H3BR6_SevenDisplayOff, 0);
messageParams[0]=5;
messageParams[1]=0;
memcpy(&messageParams[2], &"REAdy",5);
SendMessageToModule(2, CODE_H3BR6_SevenDisplaySentence, 7);
memcpy(&messageParams[0], &Steps, 4);
messageParams[4]=2;
memcpy(&messageParams[5], &time, 2);
SendMessageToModule(4, CODE_H18R1_Stepper_Bipoler_EighthStep_IT,7);
Delay_ms(500);
currentNumber=0;
parameter=0;
flag_hold=0;
start=1;
}
}
void Stop_the_engines()
{
Output_PWM(0);
}
void Sensor()
{
if(Latch_ON==1&&NumberOfPieces!=0&&start==1)//&&SENS==1
{
memcpy(&messageParams[0], &C_CNT, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
messageParams[0]='C';
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
if(stoooop==1)
{
Number_of_operations=Number_of_operations+C_CNT;
if(Number_of_operations>=9900)
{
Number_of_operations=C_CNT;
}
Output_PWM(0);
Latch_ON=0;
stoooop=0;
C_CNT=0;
Delay_ms(200);
memcpy(&messageParams[0], &Number_of_operations, 4);
messageParams[4]=0;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayNumber, 5);
messageParams[0]=6;
messageParams[1]=0;
messageParams[0]='T';
messageParams[1]=5;
SendMessageToModule(2, CODE_H3BR6_SevenDisplayLetter,2);
}
}
}
/* Main function ------------------------------------------------------------*/
int main(void){
Module_Init(); //Initialize Module & BitzOS
//Don't place your code here.
for(;;){
}
}
/*-----------------------------------------------------------*/
/* User Task */
void UserTask(void *argument)
{
Tickstart1 = HAL_GetTick();
SendMessageToModule(2, CODE_H3BR6_SevenDisplayOff, 0);
Delay_ms(100);
messageParams[0]=6;
messageParams[1]=0;
memcpy(&messageParams[2], &"HELLO",5);
SendMessageToModule(2, CODE_H3BR6_SevenDisplaySentence, 7);
Stop_the_engines();
while(1)
{
INC = HAL_GPIO_ReadPin(Count_inc_GPIO_Port, Count_inc_Pin);//on-->1
DEC = HAL_GPIO_ReadPin(Count_dec_GPIO_Port, Count_dec_Pin);//on-->1
SENS = HAL_GPIO_ReadPin(Count_SENS_GPIO_Port, Count_SENS_Pin);//on-->0
Sensor();
if (flag_hold==1)//parameter change
{
INC_function();
DEC_function();
display_parameter();
if(parameter==5&&reset_Number_operations==1)
{
Number_of_operations=0;
}
}
if (flag_press==1&& start==1)
{
if (NumberOfPieces==0)
{
Output_PWM(0);
SendMessageToModule(2, CODE_H3BR6_SevenDisplayOff, 0);
messageParams[0]=6;
messageParams[1]=0;
memcpy(&messageParams[2], &"ERROR",5);
SendMessageToModule(2, CODE_H3BR6_SevenDisplaySentence, 7);
Latch_ON=0;
}
else
{
Output_PWM(pwm);
Latch_ON=1;
flag_press=0;
a=0;
C_CNT=0;
SENSER_INT=1;
}
}
}
}
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
Callback=HAL_GPIO_ReadPin(Count_Start_GPIO_Port, Count_Start_Pin);
if (GPIO_Pin == GPIO_PIN_5 && Callback==0)
{
startTime = HAL_GetTick();
a=1;
if(flag_hold==1 && parameter>0)
{
parameter++;
D_CNT=0;
}
if (parameter>6)
{
parameter=0;
}
}
}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
SENS = HAL_GPIO_ReadPin(Count_SENS_GPIO_Port, Count_SENS_Pin);//on--> 1
if (GPIO_Pin == GPIO_PIN_4 &&start==1&&SENSER_INT==1&&SENS==1)
{
if ((HAL_GetTick() - Tickstart1) > Timeout1)
{
Tickstart1 = HAL_GetTick();
C_CNT++;
if(C_CNT==NumberOfPieces)
{
Output_PWM(0);
stoooop=1;
SENSER_INT=0;
}
}
}
Callback=HAL_GPIO_ReadPin(Count_Start_GPIO_Port, Count_Start_Pin);
if (GPIO_Pin == GPIO_PIN_5 && a==1 && Callback==1)
{
startTimee=HAL_GetTick();
if((startTimee - startTime) >= 3000)
{
Latch_ON=0;
flag_hold=1;
parameter=1;
start=0;
Output_PWM(0);
SendMessageToModule(2, CODE_H3BR6_SevenDisplayOff, 0);
messageParams[0]=6;
messageParams[1]=0;
memcpy(&messageParams[2], &"CHAngE",6);
SendMessageToModule(2, CODE_H3BR6_SevenDisplaySentence, 8);
currentNumber=0;
}
else if((startTimee - startTime) < 1500&&start==1)
{
flag_press=1;
}
else if((startTimee - startTime) < 3000)
{
startTimee=0;
startTime=0;
}
}
}
/*-----------------------------------------------------------*/
Control PWM signal with % dutycycle (0-100):
Display an integer value on the display:
Display a character on the display:
4)Assembly of mechanical and electronic components:
At the final stage, we combine all the parts to get the final project.
Please feel free to leave a comment here if you have any questions or concerns regarding this project 😃💡
References:
[1] https://hexabitz.com/product/spst_mosfet_switch_h0fr7/
[2] https://hexabitz.com/product/6-digit-seven-segment-h3br6x/
[3] https://hexabitz.com/product/3-3v-1a-dc-dc-power-supply-h03r0x/
[4] https://hexabitz.com/product/100-mil-pth-proto-board-h00r4x/
[5]STLINK-V3MODS Programmer (H40Rx) – Hexabitz
[6]https://www.agriexpo.online/prod/wintersteiger-seedmech-gmbh/product-175745-20769.html
[7] https://hexabitz.com/modules/
Comments
Please log in or sign up to comment.