Hi All,
I'm working on a new educational project that involves two clock hands. The hands are driven by a dual-axis VID28 steppermotor, connected to an EasyDriver wich takes pulse/dir. On startup it will peform a homing routine, set boh hands to 12" and from there move to the actual time. At some point (in educational mode) I want both hands to move to a few new set positions over the shortest path possible. In regular mode it ticks like any other clock (onboard RTC ds3231).
How to calculate the shortest path from timeA to timeB for both hands? (required pulses)
How to determine the direction needed? (direction)
How to keep track of all CW and CCW pulses in order to switch back to RTC after done with educational mode?
to be as short as you and keeping me effort to answer as short as you did
define a zero-point calculate angle on CW rotation
calculate angle on CCW-rotation compare them
the smaller angle is related to the shorter way
Now start coding
best regards Stefan
For the hour hand, start with the time in decimal hours. Let's say the current time (A) is 1:45 (1.75) and the target time (B) is 9:15 (9.25).
Subtract A from B to get 7.5 hours. That is > 6.0 hours so subtract 12 to go the other way. Counterclockwise 4.5 hours * steps per revolution / 12.
Let's try the other direction: A is 9.25 and B is 1.75.
Subtract A from B to get -7.5 hours. That is < -6.0 hours so add 12 to go the other way. Clockwise 4.5 hours * steps per revolution / 12.
Similar for minutes. For 9.25 to 1.75 the minutes go from .25 to .75 and since that is 0.5 hours it doesn't matter which way you go. If the value is between -0.5 and +0.5 you move that direction. If it's above 0.5 or below -0.5 you subtract or add 1.0 and use the new direction.
Can't I just substract hours from hours and minutes from minutes? What's the need to convert to decimals?
Example:
a=hour1 and b=hour2
min(abs(a-b), 12 - abs(a-b)) and do the same for the minutes?
Looks like that should work. Right?
It would be helpful to know the number of pulses per revolution of each hand.
Are both hands controlled by just one motor and some gears, like in a cheap analog wall clock?
Or, is there a separate motor for each hand? That will make a big difference.
There is no need to keep track of all of the individual clockwise and counterclockwise pulses. Instead, keep track of the position of the hands after each pulse. From that you will be able to work out the distance (number of pulses) and direction that you need to move to the target position.
I suggest that, once you have the "educational mode" code working, that you reuse it for normal timekeeping mode. What I mean is that, there is no difference between having the hands point to (for example) 1:50 in "educational mode" and having them point to 1:50 in normal timekeeping mode. Either way, the hands will be pointing to 1:50, so you can use the same code to do both. (I hope I am making myself clear.)
I suppose so, as long as StepsPerHour is a whole number (it might not be; I've seen one clock that used IIRC 512 steps for 12 hours), and as long as 59 * StepsPerHour does not overflow an int.
-Sorry for not responding any faster. Kids & covid says it all.-
Hi,
I'll be using a dual axis stepper motor VID28-05. It does 720 steps/360 deg in full step mode. Here's a video showing how the hands can independently move (not my video). There are two version on sale: one that does non-stop 360 deg and one that does only ~300 deg. I got the 360.
About educational mode: In that mode I want to disconnect the hands from the RTC. They stop moving and wait for instructions where to move to next (shortest path). I'll be making an app wich uses serial communication with the clock over Bluetooth.
In this mode I can teach kids how clock math works.
Example: The boat leaves the harbour at 09:20. It takes 45 minutes to get across the river. What time does the boat arrive? Some examples require the hands to move CCW.
When leaving educational mode, it goes back to the current time RTC. I'm thinking of it in terms of relative and absolute. From absolute (RTC) to relative (educational) is not difficult. But I have to get back to RTC once I leave educational mode. Since its steppers, I have to keep track some how. Or am thinking to difficult?
@johnwasser: you're absolutely right! I wasn't thinking clear (againg).
Another option, base the movement on the question. If the question says the boat arrives at a certain time, and took so many minutes to travel, at what time did it start the journey, then backwards movement would be appropriate.
I don't understand what you mean about "relative" and "absolute". Relative to what?
What is the difference between hands pointing to (for example) 11:18 in educational mode, and 11:18 to show the real time? Why not use the same code for both?
What does your code look like now? Do you have any code written yet? (even if it's only code to display the current time) If you do, please post it so that we can work with what you have.
I can tell you the way I would do it. I would have variables to keep track of the current position of each stepper (int would work fine, I believe). I would also have variables for the target position of the hands. Then, I would do math to see in which (if either) direction to move each hand to get from the current position to the target position, and then I would perform one step for each hand, if necessary.
For example, suppose the hands are showing 2:00, and you want to move them to 11:18.
Your 720 steps for 360 degrees makes the math easy for us: the hour hand moves exactly 1 step per minute (because there are 720 minutes in 12 hours), and the minute hand moves 12 steps per minute. So you have:
hourHandPos = 120; // because 2*60=120
minuteHandPos = 0; // because 0*12=0
hourHandTarget = 678; // because (11*60)+18=678
minuteHandTarget = 216; // because 12*18=216
You subtract hourHandPos from hourHandTarget, and the result is greater than 360 (360 steps is half a turn), so that tells you that the hour hand needs to be moved counterclockwise.
Then, you subtract minuteHandPos from minuteHandTarget, and the result is in the range 1 to 360, which tells you that the minute hand needs to be moved clockwise.
So, you move the hour hand one step counterclockwise, and the minute hand one step clockwise, remembering to update the values of hourHandPos and minuteHandPos accordingly.
Then you repeat this process of computing directions, moving hands, and updating variables until both hands are in the correct positions.
The smart way to implement this would be a layered approach. At the highest API level, deal with only times - hours, minutes, seconds. At the next level convert times to positions of the hands, in steps. In this level pass new target hand positions, in steps, to the lowest level API, which deal exclusively in steps. In that lowest level, determine whether the target hand positions are CW or CCW from the current hand positions, and use that to pass step counts and directions to the stepper drivers. This keeps each of the three API layers very simple, rather than having a single API that must juggle all the different means of book-keeping. This will make the code MUCH simpler to design, code, and debug, and much more reliable once it is fully tested.