This project implements a robotic hand capable of performing "rock, paper, scissors" gestures. The hand is controlled by an STM32L476xx microcontroller, which drives servo motors to articulate the fingers. User input for selecting gestures is provided through push buttons.
The primary goals of this project are:
- To create a functional robotic hand that demonstrates basic animatronic principles.
- To provide a hands-on learning experience with embedded systems programming, including GPIO, PWM, and interrupt handling on an STM32 microcontroller.
- To serve as a reproducible example of a mechatronics project, with clear documentation for building both the hardware and software components.
The mechanical design of the hand is based on the InMoov open-source 3D-printable robot hand. This project focuses on the control system and basic gesture implementation.
The following components are necessary to build the robotic hand:
Mechanical Components:
- 1x 3D Printed Hand, Wrist, and Forearm (InMoov design)
- Lube (for joints)
- Copper pieces (details should be in project reports or InMoov documentation)
- 200 lb Fish Braid (for tendons)
- Super Glue
- Drill bits: 2mm, 2.5mm, 3mm, 3.2/3.5mm, 8mm
- 1x 8mm x 8cm bolt (wristlarge to wristsmall)
- 1x 8mm x 4cm bolt (wriarge to thumbbottom) - Note: "wriarge" might be a typo in Supplies.txt, should likely be "wristlarge"
- 1x 8mm x 6cm bolt (wriarge to robpart1) - Note: "wriarge" might be a typo in Supplies.txt, should likely be "wristlarge"
- 16x 3mm x 2cm bolts (for finger hinges, may need cutting to size)
Electronic Components:
- 1x STM32L476xx Microcontroller (e.g., a development board like the NUCLEO-L476RG)
- 6x Servo Motors (e.g., MG996R or similar)
- 3x Push Buttons (for Rock, Paper, Scissors input)
- Breadboard and Jumper Wires
- Batteries and Battery Holders (to power the servos and microcontroller)
- Antistatic Foam (optional, for safe handling of components)
EMG Additions (Optional, not implemented in current firmware):
- 1x MyoWare Muscle Sensor
- 3x Electrode Pads
Camera Additions (Optional, not implemented in current firmware):
- 1x Camera
Tools:
- Soldering iron and solder (may be required depending on component choices)
- Screwdrivers and Allen keys (for assembly)
- Wire strippers/cutters
- 3D Printer (or access to a printing service)
To compile and flash the firmware for the robotic hand, you will need a development environment for STM32 microcontrollers.
1. Toolchain:
- STM32CubeIDE: This is STMicroelectronics' official integrated development environment (IDE) and includes the necessary compiler (GCC for Arm) and debugging tools. It's available for Windows, macOS, and Linux.
- Keil MDK / IAR Embedded Workbench: These are commercial IDEs popular for Arm Cortex-M development.
- Makefile with GCC: For a more command-line-oriented approach, you can use a
make
based build system with thearm-none-eabi-gcc
compiler. The providedstartup_stm32l476xx.s
suggests a GCC-based toolchain might have been used.
2. STM32CubeMX (Optional but Recommended):
- STM32CubeMX is a graphical tool to configure STM32 microcontrollers and generate initialization C code. While this project provides pre-written initialization code, CubeMX can be helpful for understanding pin configurations or modifying the project for different hardware.
3. ST-LINK Utility / STM32CubeProgrammer:
- You will need software to flash the compiled firmware (
.bin
or.hex
file) to the STM32 microcontroller. ST-LINK Utility (older) or STM32CubeProgrammer (newer) are official tools from STMicroelectronics for this purpose. Most STM32 development boards (like Nucleo or Discovery boards) have an integrated ST-LINK debugger/programmer.
General Steps:
- Install your chosen IDE/Toolchain: Download and install the software package (e.g., STM32CubeIDE).
- Set up a Project:
- If using an IDE like STM32CubeIDE, you can typically import the existing
src
files into a new STM32 project. You'll need to select the correct target microcontroller (STM32L476xx). - If using a Makefile, you'll need to configure it for the source files and the target MCU.
- If using an IDE like STM32CubeIDE, you can typically import the existing
- Configure Include Paths: Ensure the compiler can find the header files (
ServoMotor.h
,interrupts.h
,stm32l476xx.h
). In most IDEs, this is handled automatically or through project settings. - Build the Project: Compile the source code to generate the firmware binary.
- Flash the Firmware:
- Connect the STM32 microcontroller to your computer (usually via USB, through an ST-LINK debugger).
- Use your chosen programming tool (STM32CubeProgrammer or the IDE's built-in flashing capability) to upload the generated
.hex
or.bin
file to the microcontroller's flash memory.
Note on existing code:
The project includes startup_stm32l476xx.s
, which is a startup file typically used with GCC-based toolchains. The stm32l476xx.h
is a device header file providing register definitions for the specific microcontroller. The C files (main.c
, ServoMotor.c
, interrupts.c
) contain the application logic.
The mechanical structure of this robotic hand, including the fingers, palm, wrist, and forearm components, requires 3D printing. As listed in the Supplies.txt
file and the "Hardware Requirements" section, these parts are based on the InMoov open-source humanoid robot project.
Obtaining STL Files:
- Official InMoov Project: The most reliable source for the STL files is the official InMoov website or repositories. Search for "InMoov hand" or "InMoov arm" to find the relevant files.
- Project-Specific Files (If any): The
Final Project Report.pdf
orECE3710_Final Project Proposal.pdf
associated with this repository may contain direct links to the specific versions of STL files used, or modifications made. Please consult these documents if available. (As an AI assistant, I do not have access to these PDF files).
Printing Recommendations:
- Material: PLA or PETG are common choices for their ease of printing and strength. ABS can also be used for greater durability but is more challenging to print.
- Printer Settings: Refer to the InMoov project documentation for recommended slicer settings (layer height, infill, supports, etc.). These parts often require careful orientation and support generation for successful printing.
- Quantity: Ensure you print all necessary components as per the InMoov hand assembly guides.
Supplies.txt
mentions "1x 3D Printed Hand, Wrist, and Forearm".
Important Considerations:
- The InMoov project is extensive. You will need to identify the specific parts relevant to the hand and forearm assembly used in this particular project.
- Post-processing of 3D printed parts (removing supports, sanding, drilling holes to the correct size) is often necessary. The drill bit sizes mentioned in
Supplies.txt
are relevant here.
Assembling the robotic hand requires careful mechanical work and connection of the electronic components.
Mechanical Assembly:
- Prepare 3D Printed Parts: Ensure all 3D printed parts are cleaned, supports removed, and any necessary holes are drilled to the correct sizes as specified in
Supplies.txt
(e.g., for finger hinges, wrist connections). - Follow InMoov Guides: The assembly process for the InMoov hand is detailed in the official InMoov project documentation (website, forums, community resources). These guides typically provide visual step-by-step instructions. It is crucial to refer to these, as the assembly can be intricate.
- Use Specified Hardware:
- Refer to
Supplies.txt
for the list of bolts and their designated locations (e.g., "1x8mmx8cm bolt to attach wristlarge to wristsmall"). - Use lube for joints to ensure smooth movement.
- The "200 lb Fish Braid" is used for the tendons that actuate the fingers. The InMoov guides will show how to route these.
- Refer to
- Servo Motor Installation: Securely mount the servo motors in their designated slots within the forearm structure. Ensure the servo horns can be attached and will properly pull the tendons.
Electronic Assembly:
- Microcontroller Setup: Place the STM32L476xx microcontroller on a breadboard or prepare it for connections if it's a development board.
- Servo Connections:
- Connect each servo motor to the STM32 microcontroller. Each servo has three wires:
- PWM Signal: Connect to the GPIO pins configured for PWM output in
ServoMotor.c
(PA0, PA1, PA5, PB10, PB11 - though note thatServoMotor.c
seems to configure 5 PWM outputs for TIM2, CH1-4, with PA0/PA5 potentially sharing a channel or one being a typo. The code comments suggest PA0, PA1, PB10, PB11, PA5 are used for Thumb, Index, Middle, Ring, Pinky respectively. This needs careful wiring based onServoMotor.c
's GPIO and TIM2 channel configurations). - Power (VCC): Connect to a suitable power supply (e.g., 5V or 6V, depending on the servo specifications). This should typically be a separate power supply from the microcontroller for higher current demand.
- Ground (GND): Connect to the ground of both the servo power supply and the microcontroller.
- PWM Signal: Connect to the GPIO pins configured for PWM output in
- Connect each servo motor to the STM32 microcontroller. Each servo has three wires:
- Button Connections:
- Connect the three push buttons to the GPIO pins configured for external interrupts in
interrupts.c
(PC0, PC1, PC4). - Each button should be wired with a pull-down resistor (as configured in
interrupts.c
) or ensure the internal pull-downs are effective, with one terminal of the button connected to 3.3V (from the MCU) and the other to the GPIO pin.
- Connect the three push buttons to the GPIO pins configured for external interrupts in
- Power Supply:
- The microcontroller (e.g., NUCLEO board) is typically powered via USB or an external power supply.
- The servo motors require a separate, more robust power supply capable of delivering the necessary current (potentially several amps if all servos move simultaneously). Ensure a common ground between the servo power supply and the microcontroller.
Important Notes:
- The project's PDF reports (
Final Project Report.pdf
,ECE3710_Final Project Proposal.pdf
) may contain specific assembly diagrams, photos, or instructions tailored to this version of the project. Please consult these if available. - Take care with wiring to avoid short circuits or damage to components. Double-check connections before applying power.
- The mapping of servos to specific fingers and their corresponding PWM channels on the STM32 is critical. Refer to the comments in
ServoMotor.c
for the intended connections:- Thumb: PA0 (TIM2_CH1)
- Index Finger: PA1 (TIM2_CH2)
- Middle Finger: PB10 (TIM2_CH3) Note:
ServoMotor.c
comments sayPB10->CH3
,Servo_Init
configuresTIM2->CCMR2
for CH3 which would be PA2 or PB10 if remapped. The GPIO init sets PB10 to AF1 (TIM2_CH3). This seems correct. - Ring Finger: PB11 (TIM2_CH4) Note:
ServoMotor.c
comments sayPB11->CH4
,Servo_Init
configuresTIM2->CCMR2
for CH4 which would be PA3 or PB11 if remapped. The GPIO init sets PB11 to AF1 (TIM2_CH4). This seems correct. - Pinky: PA5 (TIM2_CH1) Note:
ServoMotor.c
comments sayPA5->CH1
. This means the Pinky and Thumb share TIM2_CH1 (PA0). This is unusual. It could be that one of these is meant to be on a different timer or channel, or there's a simplification in the code where two fingers are controlled by the same signal. Therock/paper/scissors
functions setTIM2->CCR1
once, implying one signal for both. This needs careful verification by the user during assembly.
This section will require careful cross-referencing with ServoMotor.c
by the end-user.
Once the robotic hand is assembled and the firmware is flashed to the STM32 microcontroller, it can be operated using the connected push buttons.
Powering On:
- Ensure both the microcontroller and the servo motors are properly powered according to the "Assembly" section. Typically, you might power the microcontroller first via USB or its dedicated supply. Then, enable the power supply for the servo motors.
- On startup, the
main()
function initializes the button interrupts, SysTick timer, PWM, and servo motors. The hand should be in a default state (likely corresponding to the initial PWM duty cycles set, or a neutral position if implemented).
Controlling Gestures:
The project uses three push buttons to trigger different hand gestures:
- Red Button (Connected to PC0): Pressing this button triggers the
rock()
function. The hand will close into a fist (all fingers, including the thumb, move to the 'closed' or 180-degree servo position). - Yellow Button (Connected to PC1): Pressing this button triggers the
paper()
function. The hand will open flat (all fingers, including the thumb, move to the 'open' or 0-degree servo position). - Green Button (Connected to PC4): Pressing this button triggers the
scissors()
function. The hand will form a 'scissors' gesture:- Thumb: Closed (180-degree servo position)
- Index Finger: Open (0-degree servo position)
- Middle Finger: Open (0-degree servo position)
- Ring Finger: Closed (180-degree servo position)
- Pinky: Closed (180-degree servo position)
Behavior Notes:
- As defined in
interrupts.c
, after each button press and corresponding gesture function call, there is adelay_ms(200)
(200 millisecond delay). This is likely to debounce the button or allow the servos time to reach their positions. - The servo movement speed and precision depend on the servo quality, power supply, and mechanical construction.
- The
SysTick_Handler()
is defined but empty ininterrupts.c
, so no periodic tasks are currently running from SysTick interrupts apart from its use for thedelay_ms
function (if it uses SysTick, which is not explicitly shown but common). Thesystick_init(4000)
inmain.c
initializes it, likely for a 1ms tick if the system clock is 4MHz, as suggested by comments inServoMotor.c
.
Refer to the ServoMotor.c
and interrupts.c
files for the exact implementation details of the gestures and button handling.
The firmware for the robotic hand is written in C and organized into several files within the src/
directory.
-
main.c
:- This is the entry point of the application.
- It initializes the necessary hardware components by calling functions from other modules:
Interrupt_Init()
: Configures GPIOs for button inputs and enables external interrupts.systick_init()
: Initializes the SysTick timer, likely used for creating delays.PWM_Init()
: Configures GPIO pins for PWM output to control the servo motors and initializes Timer 2 (TIM2) for PWM generation.Servo_Init()
: Further configures TIM2 channels for PWM output to the servos and enables the timer.
- After initialization, it enters an infinite loop (
while(1);
), as the core logic is event-driven (interrupt-based).
-
ServoMotor.h
:- Header file for
ServoMotor.c
. - Declares functions for PWM initialization (
PWM_Init
), servo timer configuration (Servo_Init
), gesture control (rock
,paper
,scissors
), and a delay function (delay_ms
). - Defines constants related to PWM duty cycles for different servo positions (0, 90, 180 degrees).
- Header file for
-
ServoMotor.c
:- Contains the implementation for controlling the servo motors.
PWM_Init()
: Sets up GPIO pins (PA0, PA1, PA5, PB10, PB11) to their alternate function mode for TIM2 PWM outputs. Configures system clock (MSI).Servo_Init()
: Configures TIM2 parameters (prescaler, auto-reload value) to achieve a 50Hz PWM period. Sets up TIM2 Channels 1, 2, 3, and 4 for PWM mode and enables them.rock()
,paper()
,scissors()
: These functions set the Capture Compare Registers (CCR) of TIM2 channels to specific values, corresponding to the duty cycles defined inServoMotor.h
, to move the servos to the desired positions for each gesture.delay_ms()
: A simple software delay loop.- Includes detailed comments explaining PWM calculations and register configurations.
-
interrupts.h
:- Header file for
interrupts.c
. - Declares functions for interrupt initialization (
Interrupt_Init
) and SysTick initialization (systick_init
). - It also implicitly declares the interrupt handler function prototypes (e.g.,
EXTI0_IRQHandler
) by nature of them being standard CMSIS names, though they are not explicitly in the header.
- Header file for
-
interrupts.c
:- Manages button inputs and SysTick interrupts.
Interrupt_Init()
: Configures GPIO pins PC0, PC1, and PC4 as inputs with pull-down resistors. Sets up the EXTI (External Interrupt) lines and enables their corresponding IRQs in the NVIC (Nested Vectored Interrupt Controller) for these pins.EXTI0_IRQHandler()
,EXTI1_IRQHandler()
,EXTI4_IRQHandler()
: These are the interrupt service routines (ISRs) for the Red, Yellow, and Green buttons, respectively. When a button is pressed (rising edge detected), the corresponding ISR calls the appropriate gesture function (rock()
,paper()
, orscissors()
) and then introduces a short delay.systick_init()
: Initializes the SysTick peripheral for generating periodic interrupts (though the handler is empty).SysTick_Handler()
: The ISR for SysTick interrupts. Currently, it's empty and does not perform any actions.
-
stm32l476xx.h
:- This is a device-specific header file provided by STMicroelectronics (or a similar vendor).
- It contains definitions for all peripheral registers, bit masks, and memory addresses for the STM32L476xx microcontroller. This allows the C code to interact with hardware registers using symbolic names (e.g.,
RCC->AHB2ENR
,TIM2->CCR1
).
-
startup_stm32l476xx.s
:- This is an assembly language startup file, typically used with GCC-based toolchains.
- It contains the initial code that runs after the microcontroller resets, including:
- Setting up the initial stack pointer.
- Defining the vector table (which holds addresses of interrupt handlers and the reset handler).
- Initializing the
.data
and.bss
sections of memory. - Branching to the
main()
function in C.
This structure separates concerns: main.c
for initialization and the main loop, ServoMotor.c
for output (servo control), and interrupts.c
for input (button handling).