public:watches:watchwinder_python_code
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
public:watches:watchwinder_python_code [24/05/22 07:14 BST] – gm4slv | public:watches:watchwinder_python_code [Unknown date] (current) – removed - external edit (Unknown date) 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | < | ||
- | |||
- | |||
- | ====== Watchwinder | ||
- | |||
- | === Home Brew Winder === | ||
- | |||
- | I built a simple watch-winder to keep automatic watches fully wound when not being worn. Mainly as a small project to play with a pyBoard and a servo motor. | ||
- | |||
- | A short piece of microPython makes the servo turn, first one direction, then then other, then a pause, at a speed that makes sure a watch is fully wound overnight. The speed depends on the required number of turns to achieve full-wind, which depends on the watch movement, and whether the movement winds in one or other, or both, rotational directions. | ||
- | |||
- | The watch is placed in a plastic box attached to the servo motor and the motor is simple clamped in a '' | ||
- | |||
- | ==== Photos ==== | ||
- | |||
- | {{: | ||
- | |||
- | {{: | ||
- | |||
- | {{: | ||
- | |||
- | {{: | ||
- | |||
- | |||
- | === more to come === | ||
- | |||
- | < | ||
- | |||
- | |||
- | === Code === | ||
- | |||
- | microPython | ||
- | |||
- | <code python> | ||
- | |||
- | # main.py -- put your code here! | ||
- | |||
- | |||
- | import pyb | ||
- | |||
- | servo1 = pyb.Servo(1) | ||
- | |||
- | # LED colours | ||
- | # red flash = motor stopped | ||
- | # green on = manual stop for 120 seconds | ||
- | # yellow on/flash = motor running | ||
- | # blue flash = 5 seconds before a change of state | ||
- | |||
- | ledr = pyb.LED(1) | ||
- | ledg = pyb.LED(2) | ||
- | ledy = pyb.LED(3) | ||
- | ledb = pyb.LED(4) | ||
- | |||
- | # servo speeds to achieve approx 6 rpm in either direction. | ||
- | ccw = 14 | ||
- | cw = -7 | ||
- | stop = 0 | ||
- | |||
- | |||
- | # 12 minute cycle : | ||
- | # observed turns complete per stage: | ||
- | # 2 min CW = ~11 turns | ||
- | # 4 min stop | ||
- | # 2 min CCW = ~ 12 turns | ||
- | # 4 min stop | ||
- | # 23 turns / 12 min = 115 turns / hour | ||
- | # ETA 2836-2 requires 650 turns / day for full winding | ||
- | # this would take 5.6 hours on winder per day to guarantee full wind. | ||
- | |||
- | period = 120 # seconds | ||
- | |||
- | # turn LEDs off (unneccesary? | ||
- | ledr.off() | ||
- | ledg.off() | ||
- | ledy.off() | ||
- | ledb.off() | ||
- | |||
- | # interrupt function to allow changing/ | ||
- | def stop_servo(): | ||
- | |||
- | # red LED on at start of interruption | ||
- | ledr.on() | ||
- | ledy.off() | ||
- | |||
- | # turn off any flashing LEDs during interruption | ||
- | tim4.callback(None) | ||
- | |||
- | # flash blue LED to signal stop imminent | ||
- | flash_blue() | ||
- | |||
- | # stop servo | ||
- | servo1.speed(0) | ||
- | |||
- | # red LED off and green LED on to indicate "safe to proceed" | ||
- | ledr.off() | ||
- | ledg.on() | ||
- | |||
- | # pause for 2 minute | ||
- | pyb.delay(120 * 1000) | ||
- | |||
- | # flash blue LED to signal re-start imminent | ||
- | flash_blue() | ||
- | |||
- | # green LED off to indicate end of interruption. | ||
- | ledg.off() | ||
- | |||
- | pyb.hard_reset() | ||
- | |||
- | # after resumption from interrupt the next stage will usually be a | ||
- | # " | ||
- | # perhaps need to look at the best way of resuming? or even quit() | ||
- | # at the end of the stop_servo() interrupt and then manually reset via the | ||
- | # RST button? | ||
- | |||
- | # main programme resumes where it left off.... | ||
- | return | ||
- | |||
- | def cycle_led(): | ||
- | |||
- | ledb.on() | ||
- | pyb.delay(500) | ||
- | ledy.on() | ||
- | pyb.delay(500) | ||
- | ledg.on() | ||
- | pyb.delay(500) | ||
- | ledr.on() | ||
- | pyb.delay(500) | ||
- | ledb.off() | ||
- | ledy.off() | ||
- | ledg.off() | ||
- | ledr.off() | ||
- | |||
- | return | ||
- | |||
- | def flash_blue(): | ||
- | |||
- | t = 0 | ||
- | while t < 10: | ||
- | |||
- | ledb.toggle() | ||
- | pyb.delay(500) | ||
- | t += 1 | ||
- | return | ||
- | |||
- | def rotate_cw(p): | ||
- | |||
- | # solid yellow LED when going CW | ||
- | ledy.on() | ||
- | servo1.speed(cw, | ||
- | pyb.delay(p * 1000) | ||
- | flash_blue() | ||
- | ledy.off() | ||
- | |||
- | return | ||
- | |||
- | |||
- | def rotate_ccw(p): | ||
- | |||
- | # flash yellow LED when going CCW | ||
- | tim4.callback(lambda t: ledy.toggle()) | ||
- | servo1.speed(ccw, | ||
- | pyb.delay(p * 1000) | ||
- | flash_blue() | ||
- | tim4.callback(None) | ||
- | ledy.off() | ||
- | |||
- | |||
- | return | ||
- | |||
- | |||
- | def pause(p): | ||
- | |||
- | # flash red LED during motor pause period | ||
- | tim4.callback(lambda t: ledr.toggle()) | ||
- | servo1.speed(stop, | ||
- | pyb.delay(p * 1000) | ||
- | flash_blue() | ||
- | tim4.callback(None) | ||
- | ledr.off() | ||
- | |||
- | return | ||
- | |||
- | |||
- | # USR on-board switch used to pause running to allow | ||
- | # watch to be removed / changed | ||
- | sw = pyb.Switch() | ||
- | |||
- | # callback to run the function that pauses the operation | ||
- | sw.callback(stop_servo) | ||
- | |||
- | #timer to flash LEDs | ||
- | tim4 = pyb.Timer(4, | ||
- | |||
- | cycle_led() | ||
- | |||
- | # the main loop | ||
- | while True: | ||
- | |||
- | rotate_cw(period) | ||
- | |||
- | pause(2 * period) | ||
- | |||
- | rotate_ccw(period) | ||
- | |||
- | pause(2 * period) | ||
- | |||
- | |||
- | </ | ||
- | |||
- | |||
- | ==== Page Info ==== | ||
- | |||
- | Page created Sun May 22 00:52:45 2022 by John Pumford-Green | ||
- | |||
- | Page last updated: ~~LASTMOD~~ | ||
- | |||
- | ==== tags ==== | ||
- | |||
- | {{tag> | ||
- | |||
public/watches/watchwinder_python_code.1653372850.txt.gz · Last modified: (external edit)