How to Make Almost Anything

My journey through the MIT course

Week 9: Output Devices

This week's task was to add an output device to a microcontoller board we have designed and program it to do something.

1. Introduction & Overview

This project is an automated vertical linear actuator designed to precisely control the height of an LED grow light panel for an indoor garden system. The primary goal is to maximize the amount of plants that the light handle and optimize light distribution. The system employs a dual NEMA 17 stepper motor configuration, controlled by an ESP32 microcontroller, allowing for an extended range of motion and fine-tuned positioning.

The development followed a spiral methodology, incrementally building and testing functionality from basic motor control to coordinated multi-axis movement.

2. System Design & Components

The actuator is designed with two stepper motors working in tandem along a single vertical axis.

2.1. Mechanical Design

Dual-Stepper Configuration:

Linear Motion: Both motors drive lead screws (e.g., repurposed Prusa MK3 Z-axis TR8*8 lead screws) to convert rotational motion into linear motion. The entire assembly slides along a rigid linear rail to ensure stability and smooth travel.

Payload: A sideways-mounted LED grow light panel.

Cable Management: A critical consideration due to M2 and the LED panel moving with M1. A flexible drag chain or a carefully managed service loop is necessary to protect wiring.

2.2. Electronics Hardware

2.3. Software Design (Control System)

The control software is written in C++ using the Arduino framework for the ESP32.

Development Approach: A spiral development model was used to incrementally build features:

Key Features:

Communication: USB Serial for commands and feedback.

3. Key Software Functionality & Control

The system is controlled via serial commands sent to the ESP32.

3.1. Homing (home 1, home 2, home_all)

A critical function to establish a known reference point (zero position) for each motor.

3.2. Position Control

Direction (dir <motor> <0|1>): Sets the intended physical direction of movement (0 for UP, 1 for DOWN). The software handles any necessary inversion of the DIR pin logic for specific motors.

Relative Moves (steps <motor> <count> <period_us>): Moves the specified motor by a relative number of steps at a given step period.

Continuous Moves (speed <motor> <period_us>): Runs the specified motor continuously at a given step period until a stop command.

Position Querying:

Absolute Panel Positioning (move_panel_to <target_abs_mm>): This command moves the LED panel to a specific absolute vertical height from the base of the system.

The absolute panel position is calculated as: PanelPos_mm = (M1_currentPositionSteps / M1_steps_per_mm) + (M2_currentPositionSteps / M2_steps_per_mm)

The control logic determines the necessary movements for M1 and M2 to achieve this target, respecting individual motor software limits. Motors are moved sequentially.

Panel Position Query (get_panel_pos_mm): (Should be get_panel_pos_mm or similar, if get_pos_mm all doesn't give the combined value). This command would report the calculated absolute height of the LED panel.

3.3. Calibration & Safety

Steps per Millimeter (set_steps_per_mm <motor> <value>): Allows calibration of how many microsteps correspond to 1mm of linear travel for each motor. This is crucial for accurate positioning in real-world units. Depends on lead screw pitch and microstepping settings.

Example Calculation: For a TR8*8 lead screw (8mm travel per revolution) and a 1.8° NEMA 17 motor (200 full steps/revolution) with 1/128 microstepping: Steps_per_mm = (200 full_steps/rev * 128 microsteps/full_step) / 8 mm/rev = 3200 microsteps/mm

Software End-Stops (Iteration 3): Constants like M1_MAX_TRAVEL_MM and M2_MAX_TRAVEL_MM define the maximum permissible travel for each motor from its home position. Movement commands check against these limits (if the motor is homed) to prevent over-travel and potential mechanical damage.

3.4. Motion Smoothing (Iteration 4)

To prevent missed steps, reduce mechanical stress, and achieve smoother operation, especially when moving the significant mass of M2 and the LED panel, acceleration and deceleration (ramping) are implemented. This involves gradually changing the step period at the beginning and end of moves, rather than instantly starting/stopping at full speed.

(Describe your chosen method briefly: e.g., Linear Ramp or AccelStepper library integration).

4. Challenges & Learning

(This is a section for you to personalize heavily! Here are some potential points you might have encountered or learned from):

5. Future Work & Potential Improvements

Advanced Coordinated Motion: Implement more sophisticated algorithms for distributing movement between M1 and M2 when move_panel_to is called (e.g., to minimize wear, maximize speed, or keep M2 in a preferred part of its range). Potentially simultaneous movement of M1 and M2 if using a library like AccelStepper.

6. Code & Visuals

The complete Arduino sketch for the ESP32 controller can be found here: [Link to your Git repository or code file]

(Embed key code snippets here if desired, e.g., the homeMotor function or the move_panel_to logic).

Visuals

Week 9 Image 1 Week 9 Image 2 Week 9 Image 3 Week 9 Image 4 Week 9 Image 5 Week 9 Image 6 Week 9 Image 7 Week 9 Image 8 Week 9 Image 9 Week 9 Image 10 Week 9 Image 11