Skip to content

12. Mechanical Design

group assignment: • design a machine that includes mechanism+actuation+automation+function+user interface • build the mechanical parts and operate it manually • document the group project and your individual contribution Group Assignment Was not sure about what to build, and decided to build a Hello-Hello machine, that we use to communicate accross our hubs.

I started with an idea to build a machine that cn be used at falab winam as, a small conveyer for microfactory processing.

And as a group we decided to make machines that can communicate together, my machine is able to send a message to Skylab from winam kisumu....

Designing

Ideation using card board alt text alt text

I watched rack and pinion from youtube rack and pinion then modified it to fit our machine.

alt textalt textalt text

copy gear to use the bottom one to get the rack.

alt text alt text

used rectanlur pattern to come up with many teeth i used 21,

alt text After that you mark lines from one end to another then you draw a rectangle and extrude to object selcet one side of the object to be the object. then you get this

alt text

alt text

Now its time to draw the base; alt text alt text

I xtended rhe base, then added two small rectangles one i use as bucket and the other for picking zone, and a rectangular part for my motor

alt text alt text here i extruded the teeth to get the rack

3D printing

alt text

Assembly Using servo motor,

The SG90 servo operates on PWM control, typically rotating within 0°–180°, with a speed of about 0.1–0.12 seconds per 60° (≈500–600° per second under no load). In practice, the servo showed jittering, inconsistent startup positions, and sudden high torque at startup, leading to abrupt and uncontrolled motion. It also failed to achieve precise positioning under load (rack and pinion), highlighting its limited torque, poor accuracy, and sensitivity to power and signal stability.

Step Motor alt text alt text

Detailed Summary of Stepper Motor Setup

A 28BYJ-48 5V stepper motor with a ULN2003 driver was used to achieve controlled motion through sequential coil activation.

Connections:

  • IN1 → D0
  • IN2 → D1
  • IN3 → D5
  • IN4 → D6
  • LIMIT1 → D7 (INPUT_PULLUP)
  • LIMIT2 → D3 (INPUT_PULLUP)
  • BUZZER → D4
  • ULN2003 powered with 5V and shared GND with ESP32

limit swithces alt text

The motor was driven using a step sequence, allowing precise forward and reverse motion. Limit switches were used to change direction, and the buzzer provided feedback.

This setup worked better than the servo because the stepper follows direct step commands, giving stable and predictable motion without needing PWM control.

alt text

MQTT

We had a succeful communication between Ethiopia and Kenya since we were in diffrent labs, and my fellow from etipian managed to control my machine

alt text

Code

Worked with mqttt,skylab

#include <WiFi.h>
#include <PubSubClient.h>

// ---------------- WIFI ----------------
const char* ssid = "MT";
const char* password = "#@Innovate";

// ---------------- MQTT ----------------
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);

const char* controlTopic = "esp32/skylab/control";

// ---------------- PINS (YOUR WORKING SETUP) ----------------
#define IN1 D0
#define IN2 D1
#define IN3 D5
#define IN4 D6

const int LIMIT1 = D7;
const int LIMIT2 = D3;
const int BUZZER  = D4;

// ---------------- MOTOR ----------------
int direction = 0;   // NOW MQTT CONTROLLED
int stepIndex = 0;

// step sequence
int steps[8][4] = {
  {1,0,0,0},
  {1,1,0,0},
  {0,1,0,0},
  {0,1,1,0},
  {0,0,1,0},
  {0,0,1,1},
  {0,0,0,1},
  {1,0,0,1}
};

unsigned long lastStepTime = 0;
int stepDelay = 3;

// ---------------- BUZZER ----------------
unsigned long buzzerStart = 0;
bool buzzerOn = false;
int buzzerDuration = 0;

void startBuzzer(int duration) {
  digitalWrite(BUZZER, HIGH);
  buzzerStart = millis();
  buzzerDuration = duration;
  buzzerOn = true;
}

void updateBuzzer() {
  if (buzzerOn && millis() - buzzerStart > buzzerDuration) {
    digitalWrite(BUZZER, LOW);
    buzzerOn = false;
  }
}

// ---------------- MOTOR STEP ----------------
void applyStep(int i) {
  digitalWrite(IN1, steps[i][0]);
  digitalWrite(IN2, steps[i][1]);
  digitalWrite(IN3, steps[i][2]);
  digitalWrite(IN4, steps[i][3]);
}

// ---------------- MQTT CALLBACK ----------------
void callback(char* topic, byte* payload, unsigned int length) {

  String msg = "";
  for (int i = 0; i < length; i++) msg += (char)payload[i];

  msg.trim();

  Serial.print("📩 MQTT Command: ");
  Serial.println(msg);

  if (msg == "HELLO") {
    direction = 1;
  }

  else if (msg == "BYE") {
    direction = -1;
  }

  else if (msg == "STOP") {
    direction = 0;
  }
}

// ---------------- WIFI ----------------
void setup_wifi() {
  Serial.print("🔌 Connecting WiFi...");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\n✅ WiFi connected");
  Serial.println(WiFi.localIP());
}

// ---------------- MQTT RECONNECT ----------------
void reconnect() {
  while (!client.connected()) {
    Serial.println("🔄 Connecting MQTT...");

    if (client.connect("ESP32_Skylab")) {
      Serial.println("✅ MQTT connected");
      client.subscribe(controlTopic);
    } else {
      Serial.print("❌ MQTT failed: ");
      Serial.println(client.state());
      delay(1000);
    }
  }
}

// ---------------- SETUP ----------------
void setup() {

  Serial.begin(115200);
  Serial.println("\n🚀 SYSTEM STARTING...");

  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

  pinMode(LIMIT1, INPUT_PULLUP);
  pinMode(LIMIT2, INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);

  setup_wifi();

  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

// ---------------- LOOP ----------------
void loop() {

  if (!client.connected()) reconnect();
  client.loop();

  bool limit1 = (digitalRead(LIMIT1) == LOW);
  bool limit2 = (digitalRead(LIMIT2) == LOW);

  // 🚨 LIMIT SAFETY (kept from your working system
  if (limit1) {
    direction = -1;
    startBuzzer(120);
  }

  if (limit2) {
    direction = 1;
    startBuzzer(120);
  }

  // ⚡ MOTOR STEPPING
  if (direction != 0 && millis() - lastStepTime >= stepDelay) {
    lastStepTime = millis();

    stepIndex += direction;

    if (stepIndex > 7) stepIndex = 0;
    if (stepIndex < 0) stepIndex = 7;

    applyStep(stepIndex);
  }

  updateBuzzer();
}

3d file