Skip to content

12. Mechanical Design, Machine Design

So this week for a group work we decided to make a sorter using a steper motor, servo motor and mechanical design. So in the asignment we designed a stand to hold the components

System Workflow

  1. An object is placed on the rotating platform.
  2. The stepper motor rotates the platform to position the object under the camera.
  3. The ESP32 camera captures an image.
  4. A color detection algorithm (tinyML-algorithm) identifies the dominant color.
  5. Based on the color, the servo motor started to act (make a block at degree) pushes the object down from platform.
  6. The process repeats for the next object.

Taken from Omid’s documentation.

The parts used were these:

  1. Microcontroller: ESP32-S3
  2. Optics: Built-in ESP32 camera
  3. Color Detection: Color detection algorithm (tinyML-algorithm)
  4. Control: Arduino IDE
  5. Interface: WiFi web interface for start/stop and monitoring

The work was split 3 ways

  • Documentation - Sam
  • Mechanical Design - Omid
  • Programming - Dinesh

First week only Omid was doing things we were jut waiting for him to finish the mechanical design, the next was Dinesh did the programming and the ai. And last, I was documenting the process for the group.

Link to read more about the 3D modeling alt text alt text

The inside the green circle is our holder for the camera.

In the red hole we have our stepper motor for turning the circular disk on it. alt text Then the blue hole is for our servo which has the arm that pushes the blocks off of the stand. alt text

So those are the models that we created then lets move on to printing it out. alt text

So then we add one servo into the space alt text

Now we add a stepper motor. alt text

Then we add the wheel that we cut with the lazer cutter.

alt text

Putting the chip in place. alt text

alt text

This was the code that Dinesh has made for this week.

#include "esp_camera.h"
#include <WiFi.h>
#include <ESP32Servo.h>

// ===========================
// Camera board configuration
// ===========================
#include "board_config.h"

// ===========================
// WiFi credentials
// ===========================
const char* ssid = "galaxy";
const char* password = "dineshsah";

// ===========================
// SERVO CONFIG
// ===========================
Servo myservo;
const int SERVO_PIN = 2;

// ===========================
// TIMING CONTROL
// ===========================
unsigned long lastCheck = 0;

void startCameraServer();
void setupLedFlash();

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();

  // ===========================
  // CAMERA SETUP (UNCHANGED)
  // ===========================
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.frame_size = FRAMESIZE_UXGA;
  config.pixel_format = PIXFORMAT_JPEG;
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  config.fb_location = CAMERA_FB_IN_PSRAM;
  config.jpeg_quality = 12;
  config.fb_count = 1;

  if (psramFound()) {
    config.jpeg_quality = 10;
    config.fb_count = 2;
    config.grab_mode = CAMERA_GRAB_LATEST;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.fb_location = CAMERA_FB_IN_DRAM;
  }

  // ===========================
  // INIT CAMERA
  // ===========================
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("❌ Camera init failed: 0x%x\n", err);
    return;
  }

  Serial.println("✅ Camera initialized");

  // ===========================
  // SERVO SETUP (FIXED)
  // ===========================
  ESP32PWM::allocateTimer(0);
  ESP32PWM::allocateTimer(1);
  ESP32PWM::allocateTimer(2);

  myservo.setPeriodHertz(50);
  myservo.attach(SERVO_PIN, 1000, 2000);

  Serial.print("✅ Servo attached on GPIO ");
  Serial.println(SERVO_PIN);

  // ===========================
  // WIFI
  // ===========================
  WiFi.begin(ssid, password);
  WiFi.setSleep(false);

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

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

  startCameraServer();

  Serial.print("✅ Camera Ready at http://");
  Serial.println(WiFi.localIP());
}

void loop() {

  // Run detection every 4 seconds (safe)
  if (millis() - lastCheck > 4000) {

    lastCheck = millis();

    Serial.println("\n--- Checking ---");

    camera_fb_t *fb = esp_camera_fb_get();

    if (!fb) {
      Serial.println("⚠️ Camera busy, skipping...");
      return;
    }

    // ===========================
    // BRIGHTNESS DETECTION
    // ===========================
    uint32_t sum = 0;
    int step = 100;

    for (int i = 0; i < fb->len; i += step) {
      sum += fb->buf[i];
    }

    int brightness = sum / (fb->len / step);

    Serial.print("Brightness: ");
    Serial.println(brightness);

    if (brightness < 105) {
  Serial.println("🖤 BLACK detected → Rotate plate");

  myservo.write(180);   // rotate plate
  delay(1000);          // wait for grain movement
  myservo.write(0);     // return to initial

}
else {
  Serial.println("🤍 WHITE detected → Stay idle");

  myservo.write(0);     // keep initial position
}

    esp_camera_fb_return(fb);
  }

  delay(100);
}

The program does 4 main things: 1. Initializes the camera 2. Connects to Wi-Fi 3. Starts a camera web server 4. Detects dark objects and rotates a servo when detected

Now we add a the pcb that was designed and milled you can read here because we used the same pcb as we used in our individual weeks. Design here PCB DESIGN and here you can read about its production PCB PRODUCTION.

For the driver of the steper we used the driver board that Jani made. Yanis pcsb image

What could be improved is the lighting because it will behave diferentrly depending on the light around it. Improved stability. Could add multiple bins. And would be nice to see an automatic feeding system. Videos:

Final video

Design files