📜 ⬆️ ⬇️

Lego Mindstorms cuckoo clock

Two and a half years ago, I bought a set of Lego Mindstorms EV3 to take my first steps in robotics. Having rolled in an ev3dev assembly to the controller and having played enough with the management of engines and sensors over SSH, I cooled for two years to purchase. The reason was that I lacked imagination in terms of what this could be collected: after several assembled models from Lego Technics (both boxed and self-made), I was already used to wonders like remote-controlled toys, and simple robots like The models from Lego presented at the Krakow exhibition as a person who had worked on the telemechanics system at one time did not cause enough inspiration. I also didn’t really want to repeat the experience of others.

In the end, it dawned on me: a model with a rather complex, interesting, practical and not too hackneyed clock could become a cuckoo clock. Inspired by this idea, I got down to business.

According to my idea, the model was supposed to be not just a toy, but a full-featured device. It was possible to the full: the clock is hanging on my wall and 24/7 displays the current time. I did not set myself the task of reproducing the mechanism of the original in all details - so, my arrows are independent, the sound is reproduced through the speaker of the controller, and the weights and the pendulum serve exclusively for the surroundings. Having thus shifted all the main work to the program part, I assembled the mechanism in the simplest possible version. I have not documented the entire assembly process, so I will not be able to assemble the model again in the same form; nevertheless, the basic principles of coupling software and mechanics are such that the program should work with minimal modifications on other models assembled according to a similar principle.

Watches in various forms are presented in a video that I posted on Youtube:
')

Basic information about the model is presented in the video. Below I will talk in a little more detail about the mechanics, the software, as well as the problems that have arisen during the assembly and operation of this design.

Mechanics


The assembly of the mechanical part took 6 days. Having laid out the boxes with Lego on the table, during the New Year holidays I assembled a mechanism that differs from the final version only in the doors behind which the cuckoo lives (more on this below). I don’t have any special design skills, so the watch is a rectangular box with two hands and a dotted dial on the front side. At the top of the clock is a compartment closed by two doors, in which the cuckoo settled, and at the bottom is a sketchy pendulum and two weights. Details were taken from several Lego sets: one Lego Mindstorms EV3 (31313) , two Volvo graders (42030) , one Mercedes pneumatic boom truck (42043) and one truck crane (42009) . Despite the abundance of sets, a model of this size was barely enough - the watch cover is assembled from strips of different colors, which, however, doesn’t catch the eye, as it is above eye level with wall mounting.

A standard 15-unit Lego Technics bar is used as a minute hand. It is placed on the axis, which rigidly connects it with the engine. Thus, the accuracy of setting the minute hand turned out to be sufficient so that it could be used to determine the time to the minute. Hour hand is shorter and fixed on the swivel mechanism. It is connected with the engine through a few gears, so there is quite a noticeable backlash here - however, it is not so big as to cause problems with determining the time.

The arrows are driven by two large motors (LM). In addition, another one works in conjunction with each of the external hands, the internal one - for the minute hand, it is fixed on the same axis as the first one, and for the clockwork swivel mechanism is duplicated on the inside of the watch. The purpose of the internal arrows is to press the button (Touch sensor) when passing the external arrows through the upper position. Thus, the controller has the ability to determine in which position the arrows are located immediately after switching on, and set them in the correct position based on the system time, saving the user from having to sum up the arrows manually.

Weights are purely decorative function. Initially, I thought to do with one weight, which will slowly descend (as in ordinary hours), and then quickly pull up to the top position (analogous to the manual winding of the pendulum clock). I subsequently refused this option for several reasons. Firstly, the mechanism for switching gear ratios between the engine and the weight introduced extra complexity into the model (and the drive of the pendulum from the same engine only increased it). Secondly, fast liner, whatever one may say, would be a noisy operation, and I wanted the clock to work as quietly as possible. Thirdly, in the usual cuckoo clock there are usually two weights (one ensures the clock’s course, the second - the cuckoo’s work), and placing two changeover wheels for the chain at the bottom of the clock would lead to an even greater increase in the model size.

Proceeding from this, I went in a simpler way: I actually set two weights on the watch, but placed them on a common chain, thrown over the only drive wheel. In this embodiment, the weights are always moving in the opposite directions, dropping in turn. This behavior has little to do with the real pendulum clock, but it looks quite interesting.

The chain is made of ordinary slats of three units each using alternating axes and caps: a slipping cap is a rather rare piece, and I used axes to double the length of the resulting chain. It was not so easy to make a wheel that moves such a chain without slippage and breakdowns, but in the end this was also possible.

As for switching the direction of movement of the weights, my first idea was to make it purely mechanical: when climbing to the bottom wall of the watch case, the wide axis, installed directly above the weight, presses the plate through which the chain is threaded and causes the switching of the direction of rotation of the wheel. The switching element I was going to use is the same as, for example, at the crane 42009 : the driving wheel, moving, engages in the grip then with the right, then with the left neighbor. This idea, however, did not fly: the pressure plate brought the sliding part into a central position, when it was not linked to either the right or left neighbor, the torque ceased to flow to the wheel, and the switch froze in the central position.

To correct this situation, I decided to add to this scheme a moving triangle, the two sides of which would have a fixed length, and the third would be represented by a spring-loaded sliding part used in the suspension of the same truck crane. The meaning of this construction was that the triangle is always on the side of that pressure plate that corresponds to the rising weight: when the weight reaches the top, the panel presses on the triangle, the spring contracts, the triangle passes through the equilibrium position and then "flips" on the other side, releasing spring stored energy. This energy, according to my design, should have shifted the speed switch through the equilibrium position, immediately transferring it to the opposite position.

However, I failed to stabilize this system. By the size of the clock, it can be understood that the miniature mechanisms are not my fad, and as the size of the knot grows, the distortions arising in it lead to friction, eating up most of the switching energy. Having worn out with this mechanism, I finally decided to shift all the dirty work on the microcontroller by installing the touch panels on the button (Touch sensor) instead of complicated mechanics.

A little simple arithmetic. EV3 has four inputs and four outputs. Two entrances and two exits were already occupied by buttons and arrows engines, respectively. Adding to the scheme of the motor, which rotates the wheel of the chain, and two buttons meant that, firstly, I did not have any free ports for connecting the cuckoo position sensor (I thought to use an optical distance meter for this purpose), and secondly - that the remaining nodes (cuckoo and pendulum) have only one engine. I considered the option when both pressure panels above the weights would be connected to a common button, but refused it, because if one of the weights were in the upper position when the clock was turned on, holding the button, the clock would not have enough information to choose the direction of movement of the chain.

Since the pendulum was easier to associate with the mechanism of movement of the chain than with the cuckoo (both in terms of movement and location), I placed another large motor in the lower part of the body, which, first, drives the pendulum back and forth (1 engine turn translates into one complete oscillation of the pendulum), and secondly - through a reduction gear rotates the wheel, which drives the chain. Such a system has the disadvantage that when the direction of movement of the chain is reversed and, consequently, the motor rotates, the pendulum also changes the direction of movement, even if it is in an intermediate position, which may look ugly. However, switching the direction of movement of the weights is a rather rare operation, so I neglected this problem. Another drawback of my assembly is rather replacing the backlash in the drive of the pendulum, because of which, with its slow movement, the pendulum stops at the lowest point for a noticeable eye for a fraction of a second. I was too lazy to fix this problem.

Speaking of the speed of the pendulum. Having experimented with it, I chose a value of 30 degrees for the engine per second. This means that the pendulum makes a full swing in 12 seconds. This is a lot, but as the speed increases, the engine starts to howl, but I’m not at all smiling at the prospect of continuously listening to his song. Again, I was too lazy to sort out the mechanism and introduce a transmission, so I stopped at such a “lunar” format. The gear ratios between the engine and the chain drive wheel are such that the weight goes from the bottom to the top position in 40-50 minutes.

The port of EV3, which remained free after all previous manipulations, was occupied by the middle motor (Medium motor), which drives the cuckoo. The cuckoo itself is assembled from parts of the same Lego technics. In height, the bird reaches 11 units and is placed on a sliding bar (on such in the above-mentioned truck crane there are external stops). A miniature mechanism introduces a transfer between the wings of the bird and its tail, through which I threw a cable fixed inside the watch. The length of the cable was chosen in such a way that the cuckoo would completely leave with the wings lowered and only at the very end of the movement slightly spread them apart. It turned out to be atmospheric - just at the level of mechanization of simple models of watches. The absence of a position sensor is compensated for by the fact that the cuckoo drive is switched on through the slipping gear — it helps not to damage the engine, even if it tries to move the cuckoo beyond the boundary points. The doors are rigidly connected with the lath on which the bird is fixed, and open simultaneously with the departure of the cuckoo itself.

Initially, I used panels 11 by 5 for 1 unit as doors, but this turned out to be a bad idea: their edges were not rounded, and the doors, clinging to adjacent parts, were often blocked, leaving the cuckoo inside. The video shows the second version of the door assembly - the usual strips with rounded edges do not cause such a problem. In addition, the "plank" version of the door opens and closes much quieter.

The clock is mounted on a plank bolted to the wall. The whole structure weighs more than a kilogram.

In this description of the mechanical part, in principle, ends. It remains only to mention that the model is 100% assembled from Lego Mindstorms and Lego Technics, and the only part that does not belong to these sets is the power cord, which I soldered to my EV3, so that I don’t have to change batteries in hours. This wire goes to the power supply included in the outlet.

Program


Build ev3dev provides banding for many programming languages. In order not to have difficulties with the assembly, I decided to limit myself to the Python script. This script is available in the GitLab repository . Below I will briefly go over its functionality.

The code that moves the hands is relatively simple - it recalculates the minutes and hours into the degrees of degrees of rotation of the engines, using data on the number of degrees of the engine per turn of the arrow and the initial displacement of the arrow from the vertical position. All the fun begins when the program tries to get this data.

As I have already said, it was decided to abandon the manual eyeliner. Instead, at start-up, the clock performs calibration, defining the parameters of the geometry. Calibration is performed for both arrows independently of each other.

The calibration algorithm is as follows. First, the engine starts to rotate at a relatively high speed (I use an empirical value of 180 degrees per second) until a confirmation signal comes from the button that fixes the upper position of the arrow. After that, the engine resets the speed to 30 degrees per second and continues to rotate the arrow clockwise (the direction of rotation of the engine is sewn in the program) until it is separated from the point of the last opening of the button by 70 degrees. After that, the arrow passes through the upper position in the opposite direction, fixing the first short circuit and the last opening of the contacts (the button may rattle in the edge positions). Moving away from the last opening by the same 70 degrees, the arrow again changes the direction of movement to a straight line, and the procedure for registering the first closing and the last opening is repeated.

It is considered that the upper position of the arrow corresponds to the arithmetic average between the four values ​​thus obtained. Practice shows that this approximation is quite good - the deviation of the target position of the minute hand from the actual rarely is more than 1 step and almost never exceeds two steps. (The video shows more significant deviations due to the fact that for the purposes of the shooting I transferred the system time, and the hands moved faster than during normal operation, increasing the correction error on each turn, see below.) For an hour hand, the backlash eats accuracy, but the algorithm, of course, uses the same one.

Having calculated the upper position of the arrow and the difference between the first turning on of the sensor and actually the upper position of the arrow (this value is required for correction, see below), the calibration algorithm again increases the engine rotation speed to 180 degrees per second and repeats the procedure for searching the upper position. The difference between two consecutive upper positions determines the length of the full turn of the arrow in units of engine rotation. The procedure for finding the top position is repeated five times, which allows averaging the values ​​obtained and slightly increasing the accuracy.

After the calibration is complete, the hands go to the current time display mode. In this case, on each circle of the arrow, the algorithm fixes the position at which the first circuit breaker closure occurred. The difference between the actual and expected angles of rotation of the engine at this point is the amount of correction; thus, even if the length of the full circle was calculated incorrectly at the calibration stage (the debug output shows that the deviation rarely exceeds 1 degree), the correction on each circle does not allow the needle to shift over time due to the accumulation of error.

Please note that the only information on the relationship of the engine and the arrow that is explicitly wired into the program is the direction of rotation of the engine (direct or reverse), which corresponds to the forward motion of the arrow. Thanks to the position sensors, the need for data on the gear ratio and the initial position of the arrow disappears. Thus, if you collect clocks, in which, besides the hour and minute, the second hand will also be presented, the algorithm will allow you to use it by adding just a few lines, without wasting time on recalculating the teeth.

What the shooter does not have in the movement program is protection against overflow or loss of accuracy. I did not investigate the question of what will happen earlier: the capacity of the angle of rotation of the engine will overflow or the arrows will begin to move in jerks due to the departure of precision to the higher digits of the floating-point number. Nevertheless, practice shows that at times of the order of a few weeks nothing like this happens. If I ever meet this problem, I will most likely just add an engine reset command on each lap, with the appropriate correction of angles in the program.

If the Hand class in my program is responsible for the movement of the arrows, then the LedIndication class lights up, then turns off the LEDs on the front panel of the EV3. I know that the same effect can be achieved with one team, but initially this feature was designed to track program crashes, and then it remained. There is nothing more interesting in this class.

The Pendulum class is responsible for the movement of the weights and the pendulum. The algorithm simply starts the engine in one direction and rotates it at a constant speed until the button corresponding to the full lift of this weight is clamped; after that the direction of the motor is inverted.

In this class, by the way, presents protection from the departure of the program, which is that the engine is turned on for only 2 seconds with a command refresh period of 1 second. If I had turned on the engine in the constant rotation mode, then when we started the weight program, I would push the button and continue to move upwards, which could overload the motor, slip gears, or even damage the mechanism. Protection allows you to prevent this problem.

Finally, the Cuckoo class starts the cuckoo every time the value of 59 minutes is replaced by the value of 0 minutes. First, the cuckoo extends as far as it will go, then kukat once, reproducing the sound through the EV3 speaker, and then hiding again in the watch case. The movement is repeated in accordance with what is now the hour - from 1 to 12 times. The sound was taken from the free library FreeSound and edited to sound better on EV3. (I can’t say that I was pleased with the result, because the bass is almost inaudible when I hit the spring hammer).

The delay between the cuckoo's takeaway team and the sound reproduction team was chosen experimentally so that the sound could be heard around the time the cuckoo reaches its extreme position. With this, however, ev3dev has a small problem: because of the system boot, the sound periodically lags behind, especially if there is an SSH connection to the clock at that moment. The delay can be up to several seconds. I'm not sure if this is a problem with my controller, the build itself, or updates taken from the network (after installing ev3dev, I habitually introduced the apt get upgrade command, although I probably shouldn't have done this), but on average, the cuckoo sounds normal, so debug this question I'm not going.

, , , : , «», «» . , .

, . .

, , . — , , .

, . , , , . , Skype, .

Debian. , , . — EV3 WiFi-. , , , , , .

BSD. , .

Source: https://habr.com/ru/post/417255/


All Articles