Watch Winder MK2:
Main Features:
OLED Display with TPD (Turns Per Day)
Rotary Encoder with Push Button for selecting TPD setting
Upgraded to NEMA stepper motor
Cooling Fan
Spring loaded bearings
TMC2208 Stepper Motor Driver
Optical Switch for Homing
Electronic Components:
Watch Winder 3D-Printed Parts:
Chassis Design:
Spring Loaded Bearing
693ZZ Bearing 3x8x4 mm
Watch Winder MK2:
The first Watch Winder I designed was 4 years ago when I was 20-21. I have been thinking about improving the design for a very, very long time. Now that I have 4-5 years more experience with building and electronics, I felt confident that I could design and create an even better Watch Winder.
MK2 aims to add more features to the original watch winder while being better designed, but still maintaining the beautiful aesthetics of the 1st version.
The important thing to keep in mind is wiring the coils correctly. They need to match each other. The example Stepper Motor Driver is an A4988. (How To Mechatronics - Stepper Motors and Arduino - The Ultimate Guide)
TMC2208 Stepper Motor Driver:
I decided to use the TMC2208 Stepper Motor Driver for this project as it is very quiet - much quieter than the A4988 and DRV8825 - and has the option for microstepping - not that it was used!
GND - Ground
VIO - Logic Supply Voltage
M2B Motor Coil 2
M2A Motor Coil 2
M1A Motor Coil 1
M1B Motor Coil 1
VM - Motor Supply Voltage
DIR - Direction Signal Input
STEP - Step Signal Input
CLK - Clock Input
PDN - UART and Auto Power Down Control: GND = On, VIO = Off
MS2 = Step Configuration
MS1 = Step Configuration
EN = Enable Motor Outputs: GND = On (0V), VIO = Off (5V)
TMC2208 Specs and Important Information: (from fysetc website)
Logic Input Voltage (VIO): 3 - 5V
Motor supply Input Voltage (VM): 5.5 - 36V
Potentiometer is for adjusting motor current input (adjusts the resistance):
Max Continuous Motor Current Output: 1.4A, Peak Current: 2A. Reference Voltage should not exceed 1V.
Measure the voltage on the Vref pin (0 - 2.5V). Maximum settable motor current is 1.77A RMS. SilentStepSticks can only go up to 1.2A RMS
Definitions:
Irms: Root Mean Square current per phase (lrms = Imax/1.41)
Imax: Maximum current per phase (Imax = lrms*1.41)
Vref: Voltage on the Vref pin
Equations:
Irms = (Vref*1.77A)/2.5V = Vref*0.71
Vref = (Irms*2.5V)/1.77A = Irms*1.41 = Imax
Note: IMPORTANT
Vref measures Gnd and the voltage at the middle of the potentiometer.
Do not connect the motor when measuring the voltage, otherwise it is easy to burn the driver.
Power should be connected when measuring voltage, do not just connect USB power supply.
0.91 " I2C OLED Display (128x32):
It only made sense for me to have a display of this resolution due to the size limitations of the Watch Winder Chassis. Initially, I tried modeling the 0.91" OLED display into the original front cover of the 4" MK1 chassis, but the OLED display did look right with how small the front cover bezel already was. Additionally, I realized I would need more real estate in the Chassis anyway for all the other components and wiring I was trying to implement.
Rotary Encoder:
From the MK1, I had already purchased the Rotary Encoders 5 years ago exactly for this project. However, I did not have the knowledge or skills to implement all of the components I used in my MK2 Watch Winder. Fast forward 5 years ahead and I was able to find the Rotary Encoders. Once again, the main limitation was size. The Rotary Encoders I purchased were soldered to PCBs, but these PCBs were much to big for the Chassis. I had to desolder the Rotary Encoders from their PCBS in order to fit them into the Chassis. Ironically, they seemed to work even better after I directly soldered them to the Arduino Nano.
Rotary Encoder:
From the MK1, I had already purchased the Rotary Encoders 5 years ago exactly for this project. However, I did not have the knowledge or skills to implement all of the components I used in my MK2 Watch Winder. Fast forward 5 years ahead and I was able to find the Rotary Encoders. Once again, the main limitation was size. The Rotary Encoders I purchased were soldered to PCBs, but these PCBs were much to big for the Chassis. I had to desolder the Rotary Encoders from their PCBS in order to fit them into the Chassis. Ironically, they seemed to work even better after I directly soldered them to the Arduino Nano.
Optical Switch:
The road to the Optical Switch implementation was a long and windy one. Initially, I was dead-set on using silent limit switches. I was extremely interested and lured in by the idea of tiny silent clicky mouse buttons, but after implementing the switch I realized that my design simply didn't work. Originally, I designed the Wheel to have a small notch at the top so that during a homing sequence, the Wheel would spin around till the notch would press the limit switch button located at the 12 o'clock position on the Chassis. However, this did not work for 2 reasons: 1. Gravity weighs down on the Wheel and the notch was either weidghed down by its own weight or did not have enough force to push the limit switch all the way in. 2. My spring loaded bearing design is based on springs and even if the notch interacts with the limit switch, the spring loaded bearings would allow enough play where the notch could ride over the limit switch button without even depressing it due to the springs giving way for the wheel to move downwards.
The optical switch was always the logical option for this application, but I wanted to try the silent limit switch anyway. Having been defeated by gravity and my own design, I immediately switched back to the optical switch. At first, I was having difficulty physically implementing the optical switch in my CAD design without introducing more complexity more than the design already had. Then I realized I could place the optical switch on the XY-plane instead of the Z axis and this was the breakthrough approach I needed to achieve a beautifully simple, yet reliable design. KISS!! (Keep it simple, stupid). The beautifully simple solution was to have a slot at the bottom of the wheel where the optical sensor could sit in. A small cutout on the bottom of the wheel allows the light to passthrough to connect to the other side of the optical switch, completing the loop and triggering the optical switch.
Rated for 20 million clicks.
Max use case: 1000 TPD.
20,000,000/1000 = 20,000 days
20,000/365 = 54.8 years
No specific spec for lifetime of photoelectric light used in the switch.
Code:
Things I learned about code: ISRs: interrupts, why you shouldn't have Serial.print in ISRs, why you shouldn't have dynamic memory usage in ISRs
Problem Statement 1: What is an Interrupt?
I was having trouble getting the rotary encoder to work with the serial monitor while the stepper motor was running. When I commented out the code for the motor, the rotary encoder worked. When I commented out the code for the rotary encoder, the motor worked, but I could mot get them working together.
Solution:
I coded in interrupts for the rotary encoder on the DT pin.
Solution explanation:
The Arduino nano's loop function executes 100k to 130k times a second. When I would try to spin the rotary encoder, the serial monitor would never display anything for 2 main reasons. First, the code I wrote for the motor is blocking. This means that the motor code would have to complete before anything could be sent to the serial monitor. Second, the polling rate is so fast when running the loop function that the rotary encoder signal would never have been detected in the loop since it would either always be running the motor code or reading through the rotary encoder code. I would've had to rotate the rotary encoder in the 1Hz that the loop function was being re-executed which would be impossible for a human. Why does an interrupt work? This takes the rotary encoder code out of the loop function. Now, there is explicit code that will be executed when an interrupt signal is detected. This means that my rotary encoder signal will never be lost in the loop function.
Problem Statement 2: Why shouldn't I use Serial.print or call functions in ISRs?
Problem Statement 3: Why can't I use arduino's dynamic memory in ISRs?
Problem Statement 4:
Resources:
The Machine Shop - Website
https://themachineshop.uk/how-to-drive-a-nema17-stepper-motor-with-a-tmc2208-v3-and-an-arduino-uno/
Motor Wiring is incorrect - I followed HowToMechatronics to get the Stepper Motor wired correctly. It would still be useful to use a multimeter to figure out the coils.
Used their code for Stepper Motor movement
How To Mechatronics - YouTube
https://www.youtube.com/watch?v=7spK_BkMJys&t=1073s
Used the A4988 Wiring Diagram in the video
TMC2208 Pinout Diagram
https://wiki.fysetc.com/docs/TMC2208
Diagram of TMC2208 Stepper Motor Driver Pinout. Good information about the TMC2208
Bas on Tech - YouTube
https://www.youtube.com/watch?v=gPLpPFmv-Zc
Video on attachInterrupt for Rotary Encoder
Limit Switch -> Optical Switch