4.final project sorter
Sorter¶
Overview¶
This is the final version of the sorter within the FabAcademy period👍
Created a circuit design and programming part in week10
You can see it at 0:13 - 0:56 in the following video.
Design with Fusion360¶
Created shafts (φ8 mm x 800 mm)
Create linear bushing and thread it through the shaft
Linear bush and Timing belt can be attached to the back of the base.
Attached the base.
Attached the stepper motor and the rotary shaft screw
Created the case for the stepper motor and the rotary shaft screw
When the base passes directly over the part with the ultrasonic sensor, the sensor reacts and the lid of the box it passes through opens.
For this reason, I thought of adding a rack and pinion gear in the part where the trash is dropped into the box
Keep the sorter and the boxes a short distance apart, and after the base is in front of the target box, the rack brings the base forward and causes it to react to the ultrasonic sensor.
Create gears to be attached to a stepping motor to operate the rack and pinion.
Each gear has the following parameters.
The left side is the gear attached to the tip of the stepping motor, and the right side is the other larger gear.
The base of the sorter was created as follows
Attach the gears as follows
Next, create the rack and pinion
The pinion gear was created with the following parameters
Referred to How to make rack gear【歯車マスターの道】Fusion360でラックギアを作る方法
The rack gear was created with the following parameters
Duplicate the tooth using the rectangle pattern.
Sketch a rectangle under the teeth
Created a base on which to place the tilting mechanism of the sorter as shown below.
I have made the rack and pinion engage in parallel as they operate.
Create a mechanism to tilt the base on which the object is placed.
I use servo motor to tilt the gears.
The two gears use the same size and the parameters are as follows
Attach the case as follows
put it on the base as follows
Create a case for the servo motor as shown below.
Create a base to put things on.
The base is made of MDF 2.5mm.
A case that allows mounting of the electronic base is attached to the base of the sorter.
Also drilled a hole for the timing belt.
I have covered the top with acrylic to protect the board.
Attach to the guide as follows
Design electric circuit with Kicad¶
Designed the following
Wired as follows
The electronic parts are as follows
The board is as follows
The wiring is as follows
These are the control pins which are used to control the where EN, SLP and RST control the power states and DIR and STEP control the input.
SLP and RST are shorted because they are not used in this project.
M0, M1, and M2 are pins for use when using microstep, but are not used this time
VMOT, GND: This is the stepper motor power supply pins. Connect 8.2-45V external power supply with VMOT and common ground.
Programming¶
#include <WiFi.h>
#include <WebServer.h>
#include <ESP32Servo.h>
#include <AccelStepper.h>
#define SSID "ENV_WIFI"
#define PASS "ENV_PASS"
Servo myservo1;
int pos = 80;
#define motorInterfaceType 1
const int dirPin1 = 22;
const int stepPin1 = 23;
const int stepSpeed = 1700;
const int stepsPerRevolution = 200;
AccelStepper myStepper1(motorInterfaceType, stepPin1, dirPin1);
const int dirPin2 = 19;
const int stepPin2 = 21;
AccelStepper myStepper2(motorInterfaceType, stepPin2, dirPin2);
int minUs = 500;
int maxUs = 2400;
WebServer server(80);
void setup()
{
Serial.begin(115200);
myservo1.setPeriodHertz(50);
myservo1.attach(5, minUs, maxUs);
myservo1.write(80);
pinMode(stepPin1, OUTPUT);
pinMode(dirPin1, OUTPUT);
pinMode(stepPin2, OUTPUT);
pinMode(dirPin2, OUTPUT);
connectWiFi();
server.on("/", handleRoot);
server.on("/nothing", nothing);
server.on("/charcol", charcol);
server.on("/notcharcol", notcharcol);
server.on("/plastic", plastic);
server.begin();
Serial.println("HTTP server started");
}
void loop()
{
server.handleClient();
}
void connectWiFi()
{
WiFi.begin(SSID, PASS);
Serial.println();
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
}
void handleRoot()
{
server.send(200, "text/plain", "Hello");
}
void nothing()
{
server.send(200, "text/plain", "nothing");
}
void charcol()
{
Serial.println("charcol");
myStepper1.setMaxSpeed(1000);
myStepper1.setAcceleration(50);
myStepper1.setSpeed(200);
myStepper1.moveTo(2500);
myStepper1.runToPosition();
myStepper2.setMaxSpeed(1000);
myStepper2.setAcceleration(50);
myStepper2.setSpeed(200);
myStepper2.moveTo(-150);
myStepper2.runToPosition();
delay(500);
for (pos = 80; pos < 140; pos += 1)
{
myservo1.write(pos);
delay(50);
}
for (pos = 140; pos >= 80; pos -= 1)
{
myservo1.write(pos);
delay(50);
}
myStepper2.setMaxSpeed(1000);
myStepper2.setAcceleration(50);
myStepper2.setSpeed(200);
myStepper2.moveTo(10);
myStepper2.runToPosition();
myStepper1.setMaxSpeed(1000);
myStepper1.setAcceleration(50);
myStepper1.setSpeed(200);
myStepper1.moveTo(0);
myStepper1.runToPosition();
server.send(200, "text/plain", "charcol");
}
void notcharcol()
{
Serial.println("notcharcol");
myStepper1.setMaxSpeed(1000);
myStepper1.setAcceleration(50);
myStepper1.setSpeed(200);
myStepper1.moveTo(1700);
myStepper1.runToPosition();
myStepper2.setMaxSpeed(1000);
myStepper2.setAcceleration(50);
myStepper2.setSpeed(200);
myStepper2.moveTo(-150);
myStepper2.runToPosition();
for (pos = 80; pos < 140; pos += 1)
{
myservo1.write(pos);
delay(50);
}
for (pos = 140; pos >= 80; pos -= 1)
{
myservo1.write(pos);
delay(50);
}
delay(500);
myStepper2.setMaxSpeed(1000);
myStepper2.setAcceleration(50);
myStepper2.setSpeed(200);
myStepper2.moveTo(10);
myStepper2.runToPosition();
myStepper1.setMaxSpeed(1000);
myStepper1.setAcceleration(50);
myStepper1.setSpeed(200);
myStepper1.moveTo(0);
myStepper1.runToPosition();
server.send(200, "text/plain", "notcharcol");
}
void plastic()
{
Serial.println("plastic");
myStepper1.setMaxSpeed(1000);
myStepper1.setAcceleration(50);
myStepper1.setSpeed(200);
myStepper1.moveTo(500);
myStepper1.runToPosition();
myStepper2.setMaxSpeed(1000);
myStepper2.setAcceleration(50);
myStepper2.setSpeed(200);
myStepper2.moveTo(-150);
myStepper2.runToPosition();
delay(500);
for (pos = 80; pos < 140; pos += 1)
{
myservo1.write(pos);
delay(50);
}
for (pos = 140; pos >= 80; pos -= 1)
{
myservo1.write(pos);
delay(50);
}
myStepper2.setMaxSpeed(1000);
myStepper2.setAcceleration(50);
myStepper2.setSpeed(200);
myStepper2.moveTo(10);
myStepper2.runToPosition();
myStepper1.setMaxSpeed(1000);
myStepper1.setAcceleration(50);
myStepper1.setSpeed(200);
myStepper1.moveTo(0);
myStepper1.runToPosition();
server.send(200, "text/plain", "plastic");
}
Explanation of Codes¶
Library for using wifi
#include <WiFi.h>
Library for use as a web server
#include <WebServer.h>
Library for using servo
#include <ESP32Servo.h>
Library for using stepper
#include <AccelStepper.h>
Define SSID and password
#define SSID "ENV_WIFI"
#define PASS "ENV_PASS"
Create an instance for servo motor
Servo myservo1;
Published values for SG90 servo
int minUs = 500;
int maxUs = 2400;
Define pins to which DRV8825’s STEP & DIR pins are connected.
const int dirPin = 22;
const int stepPin = 23;
const int dirPin2 = 16;
const int stepPin2 = 17;
Set motorInterfaceType to 1. (1 means an external stepper driver with Step and Direction pins)
#define motorInterfaceType 1
Create an instance for each stepper motor
AccelStepper myStepper(motorInterfaceType, stepPin, dirPin);
AccelStepper myStepper2(motorInterfaceType, stepPin2, dirPin2);
Create an instance of the web server to process the web server with the name server. The port number is set to the common port 80
WebServer server(80);
The data transfer rate for serial communication was specified at 115200 bps(baud)
Serial.begin(115200);
Use 50hz servo
servo.attach(pin, min, max)
-
pin: the number of the pin that the servo is attached to
-
min (optional): the pulse width, in microseconds, corresponding to the minimum (0-degree) angle on the servo (defaults to 544)
-
max (optional): the pulse width, in microseconds, corresponding to the maximum (180-degree) angle on the servo (defaults to 2400)
myservo1.setPeriodHertz(50);
myservo.attach(4, minUs, maxUs);
Configures stepper pins to behave as an output
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(stepPin2, OUTPUT);
pinMode(dirPin2, OUTPUT);
Connect WiFi
connectWiFi();
When starting the web server, define a function for each address.
server.on("/", handleRoot);
server.on("/nothing", nothing);
server.on("/charcol", charcol);
server.on("/notcharcol", notcharcol);
server.on("/plastic", plastic);
server.begin();
Serial.println("HTTP server started");
In void loop(), only “WebServer.handleClient()” is called, and the processing is described in the each function
void loop() {
server.handleClient();
}
Configure Wifi Connect settings
void connectWiFi(){
WiFi.begin(SSID, PASS);
Serial.println();
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
}
WiFi.begin() to connect to a network
WiFi.begin(SSID, PASS);
Connecting to a Wi-Fi network can take a while, so we usually add a while loop that keeps checking if the connection was already established by using WiFi.status(). When the connection is successfully established, it returns WL_CONNECTED
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
void handleRoot(){
server.send(200, "text/plain", "OK");
}
Return value to client
HTTP 200 OK is the response code returned if the request is successful
server.send(200, "text/plain", "OK");
The main part is writen in the following three functions.
The contents of the following functions are almost the same, the only difference is that they control the moving position of the stepper motors and the different servo motors.
// Flow for trash that can be turned into charcoal
void charcoal(){}
// Flow for trash that cannot be turned into charcoal
void notcharcol(){}
// Flow for plastic
void plastic(){}
Here is an example of charcol() code
void charcol(){
Serial.println("charcol");
myStepper1.setMaxSpeed(1000);
myStepper1.setAcceleration(50);
myStepper1.setSpeed(200);
myStepper1.moveTo(2500);
myStepper1.runToPosition();
myStepper2.setMaxSpeed(1000);
myStepper2.setAcceleration(50);
myStepper2.setSpeed(200);
myStepper2.moveTo(-150);
myStepper2.runToPosition();
delay(500);
for (pos = 80; pos < 140; pos += 1)
{
myservo1.write(pos);
delay(50);
}
for (pos = 140; pos >= 80; pos -= 1)
{
myservo1.write(pos);
delay(50);
}
myStepper2.setMaxSpeed(1000);
myStepper2.setAcceleration(50);
myStepper2.setSpeed(200);
myStepper2.moveTo(10);
myStepper2.runToPosition();
myStepper1.setMaxSpeed(1000);
myStepper1.setAcceleration(50);
myStepper1.setSpeed(200);
myStepper1.moveTo(0);
myStepper1.runToPosition();
server.send(200, "text/plain", "charcol");
}
Sets the maximum permitted speed. The run() function will accelerate up to the speed set by this function. Caution: the maximum speed achievable depends on your processor and clock speed. The default maxSpeed is 1.0 steps per second.
myStepper.setMaxSpeed(1000);
Sets the acceleration/deceleration rate.
Parameters [in] acceleration The desired acceleration in steps per second per second. Must be > 0.0. This is an expensive call since it requires a square root to be calculated. Dont call more ofthen than needed
myStepper.setAcceleration(50);
Sets the desired constant speed
myStepper.setSpeed(200);
Set the target position. The run() function will try to move the motor (at most one step per call) from the current position to the target position set by the most recent call to this function. Caution: moveTo() also recalculates the speed for the next step. If you are trying to use constant speed movements, you should call setSpeed() after calling moveTo().
myStepper.moveTo(2500);
Moves the motor (with acceleration/deceleration) to the target position and blocks until it is at position. Dont use this in event loops, since it blocks.
myStepper.runToPosition();
Rotate the servo motor from 80 to 140 degrees, and after that, Rotate it from 140 to 80 degrees, rotating 1 degree every 50 ms.
for (pos = 80; pos < 140; pos += 1)
{
myservo1.write(pos);
delay(50);
}
for (pos = 140; pos >= 80; pos -= 1)
{
myservo1.write(pos);
delay(50);
}
Packaging¶
A stepper motor moves the base to the left and right in the x-axis direction.
The timing belt at the base where the things are placed is passed through as follows.
Pull in the direction of the arrow to apply the belt tightly.
The wiring for the stepping motor is hidden by a black tube as shown below.
The servo motor wiring is also hidden with black tubing as shown below.
I installed a Drag Chain I use to hide the wiring of the stepper motor to hide the wiring for the stepper motor.
The drag chain was created by ModelStation
Drag chain is fixed to the acrylic cover of the electrical board
Drag chain is attached to the kerf bending columns as follows.