Sunday, October 03, 2021

An electromagnetic pendulum

 For a future clock project, I would like to construct an electromagnetic pendulum. The pendulum has a magnet at its tip, and base contains a coil of thin wire. We aim to detect when the pendulum is approaching, and then turn on the coil for a short time to add extra energy. This can be done by turning on the coil to attract the magnet before the pendulum reaches the center (vertical), or waiting until it has passed the center and turning on the coil to repel it.

There are many different ways of doing this, and it was used in commercial clocks before electronic movements took over. The German-made Kundo clocks are one example. If you look on the web, you will find many articles about electronic pendulums, whether for clocks or just as toys, with a variety of different circuits. One of the best descriptions is Kundo battery clocks by Rod Elliot, with several possible circuits and a lucid explanation of how they each work. There is a 2 coil, 1 transistor design, used in Clayton Boyer's Toucan clock, and two variants of a 1 coil, 2 transistor design from the Kundo clocks themselves. In another article on the same site, Rod Elliot notes that there is some trial and error in getting these circuits going. After playing around for a few days without getting to anything reliable, I agree. I also found a site with a very similar circuit and a comment thread full on people saying how they never managed to get it to work. I'm not sure why I had so much difficulty. I know that for a few components (capacitors mainly), I didn't have the exact values and had to come up with a substitute. I tried out several different coils that I had around. Some didn't produce enough voltage to turn on the transistors. They would need more turns or more cross-sectional area, both of which affect the induce voltage. Others could clearly turn on the transistors but didn't impart enough energy the the pendulum.

There are other solutions, both analog or digital. One analog option is to replace the transistors with two or more stages of op-amps. You can then tune the sensitivity of the triggering better, and also add some delay before the pulse to the coil happens. Other solutions use a simple microprocessor like a PIC, or a TI chip.

I decided to go with a simple and highly controllable solution. I had some KY003 Hall effect sensor boards in my stock of parts, and so I just connected one to an input pin on an Arduino. The Arduino can't drive the coil directly, so I hooked up an output pin to a transistor, like this:

The transistor is a PN2222, and the Arduino output pin connects to the 22k resistor.

The code is quite simple:
  • wait until the Hall effect sensor turns on.
  • wait a while to allow the pendulum to reach the center.
  • energize the coil for a while.
  • check the Hall effect sensor has turned off (in case we are still within range).
The pendulum itself if a 30cm brass rod. I want a period of about 1 second, so there is a weight around 25cm from the pivot. The magnet is at the end. The delay after detecting the sensor should be long enough for the pendulum to reach or just pass the center. If the angle of the pendulum at its extreme is P, and the angle at which we detect the sensor is S, then the delay should be arccos(S/P)/6.28, to a first approximation. The 6.28 comes from the angular frequency being 6.28 radians/second for a 1 second pendulum. See here. None of this is exactly right, as it assumes a small angle for P, whereas I actually see around 20 degrees in each direction. It also does not allow for extra energy being added to the system. But it will do to get roughly the right values.

This is the prototype working. It needs a small nudge to get going:

Here's the code. Note this is a prototype and might change before the final version.

// Electromagnetic pendulum controller.
// Detect the magnet with hall effect sensor on this pin...
constexpr int hall_sensor = 3;

// ... then wait this many milliseconds ...
constexpr int detect_to_activate_delay = 23;

// ... then energise this output pin ...
constexpr int output = 7;

// ... for this many milliseconds ...
constexpr int activation_duration = 200;

// ... with this much slop in milliseconds when checking the sensor is out of range.
constexpr int sensor_cooldown = 10;

// Use this pin for LED.
constexpr int led = 13;

void setup()
  pinMode(led, OUTPUT);
  pinMode(output, OUTPUT);
  pinMode(hall_sensor, INPUT);
  digitalWrite(led, LOW);
  digitalWrite(output, LOW);

void loop()
  // Sensor reports LOW on detecting a magnetic field.
  if (digitalRead(hall_sensor) == LOW) {
    digitalWrite(output, HIGH);
    digitalWrite(led, HIGH);
    digitalWrite(output, LOW);
    digitalWrite(led, LOW);

    // Wait until the magnet is out of range of the hall effect sensor, and then allow a little longer.
    while (digitalRead(hall_sensor) == LOW) {}

Additional notes

After some experimenting with this form of drive, I think there are some good and bad points.

Good points: it is very easy to build as the circuit is so simple. It's convenient for tuning the timing. You can add a few extra lines to report the time between ticks. Note that the activation delay and duration make very little difference to the timing, so this is about adjusting the position of the bob on the pendulum.

Not so good: getting both the Hall effect sensor and the coil close enough to the magnet is a challenge. I mounted the sensor on top of the coil, but this then requires a large coil to supply enough impulse. The force on the magnet goes down (if I remember correctly) as the square of the distance from the coil. To make life easy, my coil was whatever was left on a 4oz could of 30AWG magnet wire, probably about 300 metres. Anything much less than this didn't work. This could be solved by more careful design, such as mounting the probe embedded in the top of the coil or in the hole in the middle.

No comments: