Week_12 Assignments
- Group assignment:
This week we have a machine to build ^^. We gathered ideas like air hockey table, cnc foam cutter, pen plotter with colour magazine and more. We selected to make a FarmBot like machine. Our machine can be controilled through a local server GUI running on an Xiao ESP 32 and communicates with serial TX and RX with 3 Arduinos oe for each axis to control. The main board the message will be YF50 or YH or YR70. As the message starts with the axis and then each letter of F, R and H has its meaning as for F that means move forward, R move backwards and for H go home, the number written after the F or the R means the distance in mm. All these letters or command s are the same in all the axis but the Z axis two more letters M for measuring and P for using the pump. The main board should calculate the movement and steps to move for certain positions where the bots are placed.

Group assignment
We divided the work load amongst us and I took the duties of building the Y axis and the frame. We wanted the machine to be 600mm in length and 400mm in width but we were limited by the stock available in our lab so we made it 400 mm in length and 330mm in width as for the working area.
I choose of many mechanisms to move the Y axis a cart with linear guides and smooth rods and all of that driven by a belt. I made the Y axis driven by Two motors separately having one limit switch or end stop.
I fired up Fusion 360 and started designing the Y axis. I downloaded the aluminum profile piece from grabcad also I dwownloaded the corners for the Y axis from grabcad.
I designed the pieces where the Stepper motor (Nema 17) will be fixed and the piece where the other end of the rod will be held. I had a problem with the rods the their lengths are different and varies so I made an extension to solve this problem.
One thing that made designing the Y axis more easy that I mirrored what I did in the right to the left and fixed every component and joint it where it should.

I assembled the machine in fusion after my class mates finished their axes.


Here a video of the final assembly in motion.
After designing the Y axis I 3D printed the parts started with the most time consumming parts like the rod holders, the X axis holder cart.



I printed 8 corners to give more rigidity to the structure and it did.

after printing the corners I started assembling the frame.

After assembling the frame I fixed the rods and the Xaxis holder/cart, tensioned the belt and fixed the motor in one Yaxis.

I tested the movement of that one Yaxis and programmed the arduino to move a certain number of steps and a certain distance calculated like so:
Steps_to_Walk_WantedDistance = (NumverofStepsperRevolution * MicrosteppingFactor * wantedDistance)/(NumberOfTeethOfPulley * beltPitch)
I connected the component (Stepper motor nema 17, stepper driver A4988 with its breakout, limit switch, arduino uno and power adaptor 9V)

For dealing with the A4988 drive I followed this tutorial and learned who to adjust the on board current limit trimmer using a multimeter to measure the voltage between the trimmer top (on board refrenece) and the ground and found the a value of 0.94V works great with my motor.
From here I progressed gradually developing the code. I started with calculating the steps needed for a certain distance entered by the Serial monitor input. I made the code to receive one of the two letters S for Steps and D for distance followed by the number of steps and distance in mm.
Code:
int directionPin = 4;
int stepsPin = 5;
int microStepping = 1;
int betweenStepsDelay = 2000; //in Microsecondes
int steps_fullRevolution = 200;
int gearBeltPitch = 2; //in mm
int wantedDistance;
int wantedSteps;
void setup() {
Serial.begin(9600);
pinMode(directionPin, OUTPUT);
pinMode(stepsPin, OUTPUT);
// put your setup code here, to run once:
}
void loop() {
digitalWrite(directionPin, HIGH);
if (Serial.available()) {
if (Serial.read() == 'D') {
wantedDistance = Serial.parseInt(); // Get Distance in mm to get converted into steps.
wantedSteps = (steps_fullRevolution * microStepping * wantedDistance) / gearBeltPitch;
for (int mystep = 0; mystep <= wantedSteps; mystep++) {
digitalWrite(stepsPin, HIGH);
delayMicroseconds(betweenStepsDelay);
digitalWrite(stepsPin, LOW);
delayMicroseconds(betweenStepsDelay);
}
}
if (Serial.read() == 'S') {
wantedSteps = Serial.parseInt();
for (int mystep = 0; mystep <= wantedSteps; mystep++) {
digitalWrite(stepsPin, HIGH);
delayMicroseconds(betweenStepsDelay);
digitalWrite(stepsPin, LOW);
delayMicroseconds(betweenStepsDelay);
}
}
}
// put your main code here, to run repeatedly:
}
Then I started to add the Yaxis Y letter and the H homing and F for forward and R for backward. I used an interesting function that deals with a String like an array and returns the value of the letter if the array according to the index. the function is .charAt(index).
Code
//Stepper motor 1
int ydirectionPin = 4;
int ystepsPin = 5;
//Stepper motor 2
int ydirectionPin2 = 6;
int ystepsPin2 = 7;
//Steps variables
int microStepping = 1;
int betweenStepsDelay = 1000; // in Microseconds
int steps_fullRevolution = 200;
int gearBeltPitch = 2; // in mm
int numteeth = 20; // pulley teeth number
//Distance
int wantedDistance;
long wantedSteps;
//Serial Command variables
int baudrateSerial = 115200;
char myaxis;
char axis = 'Y';
char mydirection;
char home = 'H';
char forward = 'F';
char Reverse = 'R';
int mydistance;
String mycommand;
//End stop sensor
int sensor = 8;
int sensorval;
int homingOffset = 10; // in mm
int bigdistance = 160;
void backwards ()
{
digitalWrite(ydirectionPin, 0); //SAME DIRECTION
digitalWrite(ydirectionPin2, 1);
}
void forwards ()
{
digitalWrite(ydirectionPin, 1); //SAME DIRECTION
digitalWrite(ydirectionPin2, 0);
}
void setup()
{
Serial.begin(115200);
pinMode(ydirectionPin, OUTPUT);
pinMode(ystepsPin, OUTPUT);
pinMode(ydirectionPin2, OUTPUT);
pinMode(ystepsPin2, OUTPUT);
pinMode(sensor, INPUT);
//Homing Y axis
Serial.println("HOMING !!!");
backwards();
while (digitalRead(sensor))
{
//Serial.println("s");
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
wantedSteps = (steps_fullRevolution * microStepping * homingOffset) / (gearBeltPitch * numteeth);
for (long steps = 0; steps<=wantedSteps; steps++)
{
//Serial.println("E");
forwards();
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
Serial.println("DONE HOMING !");
}
void loop()
{
if (Serial.available())
{
mycommand = Serial.readString();
myaxis = mycommand.charAt(0);
mydirection = mycommand.charAt(1);
mydistance = mycommand.substring(2).toInt();
if (myaxis == axis)
{
if (mydirection == home)
{
Serial.println("HOMINGGGGGGGGGGGGGGGGGGGGGGGGGG !!!");
backwards();
while (digitalRead(sensor))
{
//Serial.println("s");
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
wantedSteps = (steps_fullRevolution * microStepping * homingOffset) / (gearBeltPitch * numteeth);
for (long steps = 0; steps<=wantedSteps; steps++)
{
//Serial.println("E");
forwards();
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
}
else if (mydirection == forward)
{
Serial.print("Moving forwards: ");
Serial.println (mycommand.substring(2).toInt());
wantedDistance = mydistance;
wantedSteps = (steps_fullRevolution * microStepping * wantedDistance) / (gearBeltPitch * numteeth);
for (long mystep = 0; mystep <= wantedSteps; mystep++)
{
forwards();
digitalWrite(ystepsPin, HIGH);
digitalWrite(ystepsPin2, HIGH);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, LOW);
digitalWrite(ystepsPin2, LOW);
delayMicroseconds(betweenStepsDelay);
}
}
else if (mydirection == Reverse)
{
Serial.print("Moving backwards: ");
Serial.println (mycommand.substring(2).toInt());
wantedDistance = mydistance;
wantedSteps = (steps_fullRevolution * microStepping * wantedDistance) / (gearBeltPitch * numteeth);
for (long mystep = 0; mystep <= wantedSteps; mystep++)
{
backwards();
digitalWrite(ystepsPin, HIGH);
digitalWrite(ystepsPin2, HIGH);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, LOW);
digitalWrite(ystepsPin2, LOW);
delayMicroseconds(betweenStepsDelay);
}
}
}
}
}
For the final code I added a software serail to the code to make a didicated channel to communicate with te main board.
Code
#include <SoftwareSerial.h>
SoftwareSerial Channel(9,10); //Rx and TX pins
//Stepper motor 1
int ydirectionPin = 4;
int ystepsPin = 5;
//Stepper motor 2
int ydirectionPin2 = 6;
int ystepsPin2 = 7;
//Steps variables
int microStepping = 1;
int betweenStepsDelay = 1000; // in Microseconds
int steps_fullRevolution = 200;
int gearBeltPitch = 2; // in mm
int numteeth = 20; // pulley teeth number
//Distance
unsigned long wantedDistance;
unsigned long wantedSteps;
//Serial Command variables
int baudrateSerial = 115200;
char myaxis;
char axis = 'Y';
char mydirection;
char home = 'H';
char forward = 'F';
char Reverse = 'R';
int mydistance;
String mycommand;
//End stop sensor
int sensor = 8;
int sensorval;
int homingOffset = 10; // in mm
int bigdistance = 160;
void backwards() {
digitalWrite(ydirectionPin, 0); //SAME DIRECTION
digitalWrite(ydirectionPin2, 1);
}
void forwards() {
digitalWrite(ydirectionPin, 1); //SAME DIRECTION
digitalWrite(ydirectionPin2, 0);
}
void setup() {
Serial.begin(9600);
Channel.begin(9600);
pinMode(ydirectionPin, OUTPUT);
pinMode(ystepsPin, OUTPUT);
pinMode(ydirectionPin2, OUTPUT);
pinMode(ystepsPin2, OUTPUT);
pinMode(sensor, INPUT);
//Homing Y axis
// Serial.println("HOMING !!!");
backwards();
while (digitalRead(sensor)) {
//Serial.println("s");
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
wantedSteps = (steps_fullRevolution * microStepping * homingOffset) / (gearBeltPitch * numteeth);
for (long steps = 0; steps <= wantedSteps; steps++) {
//Serial.println("E");
forwards();
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
Serial.println("DONE HOMING !");
}
void loop() {
if (Channel.available()) {
mycommand = Channel.readString();
Serial.println(mycommand);
myaxis = mycommand.charAt(0);
mydirection = mycommand.charAt(1);
mydistance = mycommand.substring(2).toInt();
if (myaxis == axis) {
if (mydirection == home) {
Serial.println("HOMINGGGGGGGGGGGGGGGGGGGGGGGGGG !!!");
backwards();
while (digitalRead(sensor)) {
//Serial.println("s");
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
wantedSteps = (steps_fullRevolution * microStepping * homingOffset) / (gearBeltPitch * numteeth);
for (long steps = 0; steps <= wantedSteps; steps++) {
//Serial.println("E");
forwards();
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
Channel.println("YH");
} else if (mydirection == forward) {
Serial.print("Moving forwards: ");
Serial.println(mycommand.substring(2).toInt());
wantedDistance = mydistance;
wantedSteps = (steps_fullRevolution * microStepping * wantedDistance) / (gearBeltPitch * numteeth);
for (long mystep = 0; mystep <= wantedSteps; mystep++) {
forwards();
digitalWrite(ystepsPin, HIGH);
digitalWrite(ystepsPin2, HIGH);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, LOW);
digitalWrite(ystepsPin2, LOW);
delayMicroseconds(betweenStepsDelay);
}
}
else if (mydirection == Reverse) {
Serial.print("Moving backwards: ");
Serial.println(mycommand.substring(2).toInt());
wantedDistance = mydistance;
wantedSteps = (steps_fullRevolution * microStepping * wantedDistance) / (gearBeltPitch * numteeth);
for (long mystep = 0; mystep <= wantedSteps; mystep++) {
int SensorRead = digitalRead(sensor);
if (SensorRead == LOW) {
wantedSteps = (steps_fullRevolution * microStepping * homingOffset) / (gearBeltPitch * numteeth);
for (long steps = 0; steps <= wantedSteps; steps++) {
//Serial.println("E");
forwards();
digitalWrite(ystepsPin, 1);
digitalWrite(ystepsPin2, 1);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, 0);
digitalWrite(ystepsPin2, 0);
delayMicroseconds(betweenStepsDelay);
}
break;
} else {
backwards();
digitalWrite(ystepsPin, HIGH);
digitalWrite(ystepsPin2, HIGH);
delayMicroseconds(betweenStepsDelay);
digitalWrite(ystepsPin, LOW);
digitalWrite(ystepsPin2, LOW);
delayMicroseconds(betweenStepsDelay);
}
}
}
}
}
}
You can see the video of the machine in the group assignment.