Floating and Spinning Earth Globe

by herwig9820 in Circuits > Arduino

50325 Views, 236 Favorites, 0 Comments

Floating and Spinning Earth Globe

picture 0.jpg

The objectives of this project were (1) to make an object float, by means of magnetic levitation and controlled by an Arduino Nano and (2) documenting the whole process allowing other people to build one on their own.

There were some requirements, too. First, I wanted an object of a certain size and weight, floating in a very stable way (no jitter, no oscillations,...). Additionally, safety was a concern (the main magnet has a 24 Volt and 25 Watts rating, producing quite some heat).

And last but not least: the end result had to be 'nice', earning its place in my living room !

I finally came up with an 11 cm (4.3") magnetically levitated earth globe, not only floating but rotating at a fixed pace as well, illuminated by two digitally controlled led strips and nicely fitted inside a wooden lantern.

The movie below explains it better than a thousand words ... check it out !

Supplies

This is a list of the most important components I used

  • a wooden lantern (of course). Internal dimensions: 180 x 180 x 300 mm minimum
  • wooden laths and planks
  • spacers, nuts and bolts
  • plexiglass 3 mm (you will have to cut it yourself)
  • heatsink 1.85°C/W, 100 x 88 x 35mm
  • electromagnet ITS-MS-7040-24VDC: this is a fairly strong electromagnet weighing 800 grams, and rated at 1200 Newton holding force, 24 V DC, 24 Watt
  • 3D printed 'globe rotation hall sensor assembly' (link to STL file provided in this instructable)
  • 3D printed spider to hold the six rotation coils (link to STL file provided in this instructable)
  • Empty plastic spools to create coils
  • Block Enamel-coated copper wire 0.28 mm
  • Adafruit RGB ledstrip APA102 60 led 1 meter
  • Honeywell hall effect position sensor SS495AAnalog Devices
  • temperature sensor TMP36Neodymium magnet circular 10 mm height 5 mm
  • Neodymium magnet cube 20 x 20 x 20 mm
  • DC to DC (step down) convertor Velleman VMA404
  • Arduino Nano R3PCB designed with Autodesk Fusion 360 (Schematic and Gerber files attached to this instructable)
  • a lot of electrical components (PCB BOM attached to this instructable)
  • Wall power supply 24 Volt 36 Watt DC plug 2.1 x 5.5x 11 mm

Software, tools and online services

  • Autodesk Fusion 360: PCB design. Autodesk has a free version of their software, and it's working great
  • Seeed studio Fusion PCB manufacturing. You will need to upload the Gerber files (zip file attached) when placing your order. PCB will be delivered, ready for assembly.
  • Highly recommended: oscilloscope, e.g. Tektronix TBS1052B
  • 3D printer
  • soldering station
  • The usual tools like tweezers, pliers, multimeter ...

Understanding Magnetic Levitation

One way to achieve magnetic levitation is to position an electromagnet above an object—in this case, an earth globe—which contains a very strong magnet. By constantly measuring the vertical position of the object, we can vary the magnetic force exerted by the electromagnet on the object's magnet to keep the object in place.

This happens much in the same way as driving a car on the highway. By constantly measuring whether the car drifts to the left or to the right, the driver can stay in his/her lane by applying small corrections only. This mechanism is called a "control system" or "feedback system."

This magnetic levitation control system is not a "linear" system at all. For instance, the relationship between current applied to the electromagnet and force exerted (on the globe's magnet) is quadratic. Moreover, this force varies with the distance between electromagnet and magnet—which seems logical. But this relationship also is quadratic! That means that the "parameters" (we'll talk about that in a moment) used to keep the globe's position stable are critical.

Any change to the globe's weight, the magnet, the electromagnet or the position of the sensor will probably result in a highly unstable globe, and you will have a hard time finding the correct parameters (which will be trial and error, I'm afraid) to obtain stable operation again. Indeed, this non-linearity also makes it difficult to apply mathematical methods to calculate these parameters.

Globe Lifting Control System: How Does It Work ?

Picture 1.jpg
Picture 2.jpg

So, how does it work? Well, I'll try to explain it in an easy way. And, in the meantime, please keep an eye on the figures. First, we need to determine the globe's vertical position. This position is measured by a Hall effect sensor, a tiny device that measures the strength of the magnetic field (produced by the magnet mounted inside the globe), converting it to an electrical voltage. If the globe comes closer to the sensor, the magnetic field strength will increase and the output voltage will change. In our case, because of the way the magnet's north and south poles and the Hall effect sensor are positioned, this voltage will decrease. Voltage will increase again if the globe moves further away from the sensor. So, the sensor effectively converts a position to a voltage!

This (small) voltage (typically between 100mV and 300mV at the operating point, depending on settings) is amplified before it is converted to a 10-bit number by the Arduino ADC (analog-to-digital converter). Welcome to the digital world! This amplification is a necessary step, considering the very small voltage variations to be captured (less than a millivolt at the Hall detector output) and the 10-bit Arduino ADC resolution. Note that, from a control systems perspective, the ADC conversion can be considered a second "amplification" step. The ADC scales an input voltage to a number from 0 to 1,023. It is perfectly fine to consider this number as the digital representation of a (scaled) voltage. Or you can use "ADC steps" as a unit. Doesn’t matter, as long as you are consistent.

As a next step, the program will subtract this number (representing a position but expressed in millivolts—or ADC steps if you prefer) from the desired position (called "setpoint"), which should also be expressed in millivolts—or ADC units—and appropriately scaled. We can only subtract values expressed in same units. The subtraction gives us the deviation from the desired globe position. We call it "error signal," because it is zero when there is no deviation. This deviation is (again) expressed in millivolts.

Forgetting for a while about the "integrator" and "differentiator" boxes in the figure (I'll come to that in a moment), we have a third amplification step that is performed digitally this time. The amplification factor ("gain") is stored as a constant in the Arduino program. Note that the total gain delivered by these three amplification steps is simply the product of the three individual gains. Whether these steps happen in the analog or digital world is not relevant at all! And this total gain is important, because a higher gain makes that a same (small) controller input (here: deviation in position) produces a higher output (here: a pulse with a higher duty cycle—we'll come to that).

Imagine if this total gain would be very small. Not a lot would happen, right? More in general, with the gain too low or too high, the system risks to become highly unstable, so we need to choose it carefully.

Anyway, the amplified error signal is then fed to 16-bit Arduino Nano Timer 1 to generate a pulse with a specific duty cycle (PWM—pulse width modulation). If it's zero, then the duty cycle will be zero as well. If it's 999, the duty cycle will be 100%. The pulse duration is fixed at exactly one millisecond. This can be seen in the oscilloscope screen capture in the figure. The pulse produced will determine the "ON" time of the electromagnet (using power transistor Q1—we're back in the analog world now) within that single millisecond. This will increase or decrease the "average" force exerted by the electromagnet on the globe's magnet within that millisecond and as a result the globe's position will change.

As you might have guessed, this whole process is repeated every millisecond (interrupt driven). Every cycle is started by reading the ADC output to obtain the hall sensor voltage. If the globe is in a stable, floating position, this voltage will be close to the setpoint voltage (in this example: around 1000 millivolts, which is 10 times the hall-effect sensor output). As with any control system, this voltage will fluctuate a little: if it wouldn't, we wouldn't need a controller. Think about that!

Check out the oscilloscope screen capture (yellow channel) and verify that every millisecond the globe is falling to the ground for approximately 500 microseconds and then moving upwards again towards the electromagnet ('up' is actually 'down' on the oscilloscope and vice versa. Sorry for that).

And what about these integrator and differentiator boxes ? Well...

Differentiating the error signal with respect to time and adding this term to the error signal provides a faster reaction to quickly changing globe positions (the effect of this term will be smaller for slower changing globe positions). The differentiator time constant Τd (which is also a parameter in the Arduino program) controls the weight of this term. It is the most critical of all parameters: it must be carefully chosen to obtain stability !

And why do we integrate the error signal (with respect to time) ? Well, imagine the system is in rest and the actual globe position corresponds to the setpoint: this reduces the error signal to zero, as well as the PWM output (pulse with zero duty cycle) and the electromagnet's force exerted on the globe. But this situation is impossible: because of the globe's weight, it needs a counterforce. So, the globe's position in rest will be a little lower than indicated by the setpoint (which leaves us with a non-zero error signal and, consequently, a non-zero PWM signal and a counterforce). This is called 'static error'. Now, if we integrate the remaining error signal, the controller (PWM) output will slowly increase, the globe position will approach the desired position, the error signal will become zero and integration will stop... exactly when the globe is where we want it to be. The integrator time constant Τi is, as you will have guessed, another parameter in the Arduino program. It is less critical than Τd.

Conclusion: 4 parameters are important here. Setpoint, gain, integration time constant and differentiation time constant. You'll find these constants defined in the Arduino program.

And why is the sampling time 1 millisecond ? Why not 10 milliseconds ? In free fall, an object initially at rest will fall about 5 micrometers in 1 millisecond. In 10 milliseconds, this increases to 0.5 millimeter (x 100). Not exactly a stable situation as perceived by the human eye and probably a lot more difficult to keep the system stable from a control system perspective. That answers it !

Electromagnet Assembly

picture 3.jpg
picture 3a.png

This assembly contains everything we need, except for the coils used for globe rotation and the led strips.

The electromagnet is quite powerful and produces a fair amount of heat. To keep everything safe, a quite large heatsink is placed on top of it. Additionally, a temperature sensor is fixed to the heatsink. It will be used to continuously control temperature.

Above the heatsink comes a wooden plank (used to 'hang' the assembly in the wooden lantern without the need for any nuts or bolts). Just underneath, notice an aluminum corner profile to keep the plank in position. Threaded spacers connect the plank with the base of the heatsink.

Underneath the heatsink, using the same holes (which you will have to drill, of course) we have another set of threaded spacers arriving at a plexiglass plate, holding the sensor we use for vertical position measuring (hall-effect sensor).

The plexiglass measures 90 x 105 mm. The back edge extends 67 mm from the hall-effect sensor (electromagnet center) position. Note that this last dimension is important as this is where the 3D assembly holding the globe rotation hall-effect sensor will be attached to the plexiglass. We'll discuss this later.

Also, you will have to cut the plexiglass plate and drill holes in it. Carefully measuring and making a few sketches first, will prove to be a big help !

Important: make sure that the spacers (and the bolts underneath the plexiglass) are not magnetic.

Lifting Hall-effect Sensor

picture 4.jpg
picture 4b.png

Several ways exist to accurately measure the distance between globe and electromagnet - more correctly, to measure the deviation between desired position ('set point') and actual position. A common method is to use a light source at one side of the globe and a light detector at the other side. But in our case, as said, we use a hall-effect sensor measuring the strength of a magnetic field (which depends on the globe position) and converting this to an electrical voltage.

Actually, this sensor will not control the position of the globe with reference to the electromagnet, but with reference to the sensor itself. But because this sensor is fixed in position, this will ultimately determine the setpoint: the position of the globe with reference to the electromagnet.

As said before, the vertical distance between electromagnet and sensor (or plexiglass plate) is critical.

With the electromagnet I used (height 40 mm), the plexiglass plate is 58 mm away from the heatsink (which can be obtained by stacking 15 mm and 40 mm threaded spacers, adding a nut in the middle). This gives a 'gap' of 18 mm between electromagnet and hall sensor.

A question you might ask: doesn't the magnetic field of the electromagnet influence the sensor reading ? Well, yes... but this is not a problem, because while we read out the sensor value (every millisecond), the electromagnet is always in the same ('ON') condition (you can verify this by looking at the scope screenshot, above). So, it's attribution is constant and can be discarded.

This hall-effect sensor needs to be placed exactly beneath the center point of the magnet. If not, you will introduce oscillations in the system and your globe will start to 'swing' in a horizontal direction, which is something the electromagnet cannot control. You will have to figure out how to determine that position. When doing it visually, take into account a thing called 'parallax'. Suggestion: once you have determined that spot, put a small dot on the bottom side of the plexiglass. This will then help you position the hall sensor.

The hall-effect sensor is placed into a receptacle with precision contacts, glued to the plexiglass plate (I used Loctite superglue). This allows for easy fine tuning the sensor position because the sensor leads are not soldered. Assuming we're using an SS 495A sensor, the stamped side must be facing down (the Arduino program assumes it).

When gluing the receptacle, make sure the plexiglass plate is clean and dry. We'll deal with the PCB connection later.

Temperature Sensor

picture 5.jpg

The temperature sensor continuously measures the heatsink temperature: when it passes a set threshold, magnet and coils will be shut off.

You will need to mount the sensor in such a way that it makes good mechanical contact with the heatsink. How to do that will largely depend on the heatsink used.

We'll deal with the PCB connection later.

The Globe

picture 6.jpg

I was able to find a globe for use as piggy bank. This has the advantage that there's a big opening at the bottom (and the disadvantage there's a slot for throwing in money, too). In this case we'll use this opening to position a strong permanent magnet (Neodymium, 20 x 20 x 20 mm) inside, near the globe's geographic North Pole. I used double-sided adhesive tape to do the trick. You'll need some chirurgical skills and good thinking to finish the job without having to open (and possibly damage) the globe, but... it's possible.

Make sure you position the magnet with its north pole facing upwards (a cube has six sides, so you will have to do some experimenting). Be careful not to make a mistake here: if you place the magnet upside down, you will not be able to make it work! Best is to use a compass to determine the magnet's north pole: a magnet's north pole attracts a compass needle's south pole: this is the needle pointing in the direction of the earth's geographic South (this looks strange, but the earth's magnetic North is located close to the earth's geographical South and vice versa).

Later on, you will have to reverse the electromagnet wires if the force exerted on the globe's magnet proves to be repelling instead of attracting. But don't worry about that for now.

But we also want the globe to rotate, right ? This will require placement of two additional (smaller) magnets inside the globe. Also these are of the Neodymium type. And again, I was lucky... the globe I use, is made of two plastic halves with an inside border (in red) used to glue them together (I guess). This border is the ideal place to position these two magnets: one at the Greenwich meridian, and the other... at the opposite side, of course (the anti-meridian). Note that I used double-sided adhesive tape.

Important: position the magnet at the Greenwich meridian with its north pole facing up, the other one with its north pole facing down. The magnets will generate a (very small) torque, keeping the globe rotating - but that comes later.

Globe Rotation Coils

Picture 7.jpg
Picture 9.jpg
picture 8b.png

To create a globe rotation torque, we need a rotating magnetic field. The six coils placed below the globe will serve that purpose.

You will have to make these coils yourself, out of empty spools (I found these on the internet) and 500 turns of enamel-coated copper wire (0.28 mm diameter). Supposing the coils you use will be similar to mine, this will produce a coil resistance around 20 Ohm, which is just fine.

The coils are held in place by a 3D-printed spider with six knobs, providing a tight fit with the center holes in the spools. The spider itself is fixed to a plexiglass plate by two screws.

The spider STL file (needed for 3D printing one yourself) is available for 3D viewing and downloading through this link: Sketchfab spider 3D model (you will need to create a free account first).

A two-pin header is soldered to each coil, these headers are all connected to a larger 15-pin receptacle (with 3 unused pins) glued to the spider, right in the middle.

The coils are numbered from 1 to 6 (check out pictures) and coil terminals are labeled A and B.

If, looking down at a coil from the top, the winding direction (from first to last turn) is clockwise, we define terminal A as the start of the first turn of the copper winding (close to the center of the spool) and terminal B as the end of the last turn of the copper winding.

If the winding direction is counterclockwise, then we designate the start of the first turn as terminal B and the end of the last turn as terminal A.

The coils will work together in 3 pairs: coil 1 and 4, 2 and 5, 3 and 6. Therefore, we will connect the 2-pin headers (coil terminals) to the receptacle (as shown in the pictures). As you can see, the coils 'B' terminals are simply interconnected for each coil pair. The Receptacle pins for the coils 'A' terminals are soldered to the flat cable (6 wires).

At the other end of the flat cable, we will solder a receptacle later. Foresee ample cable length for the time being.

The plexiglass plate, of course, will have to be cut to the desired dimensions, depending on the lantern you use.

If everything is correctly connected, at any given moment the vertical magnetic field orientation of three adjacent coils will be opposite to the magnetic field of the other three coils. At regular intervals, this field will rotate by 60 degrees, counterclockwise (looking at the coils from the top). This will create a torque on the globe's two side magnets. Moreover, this rotation will be in phase with what the Arduino program expects. So, it's very important to follow the connection instructions carefully.

To obtain a nicer visual effect, the coils are positioned some 130 cm under the two globe rotation magnets. As we don't need much torque, even with this distance we will be able to keep the globe rotating.

Globe Rotation Sensor Assembly

picture 10b.png
picture 10c.png
picture 10d.png

This assembly consists of six 3D-printed parts. Its purpose is to position the globe rotation hall-effect sensor in such a way that it can pick up the passage of the 2 globe rotation magnets mounted inside the globe. Therefore, it allows the hall sensor to be moved horizontally (by moving the 'vertical connector' part forward or backward) and vertically (by sliding the 'hall-sensor housing' up or down in its slot). Once in position, two nuts keep the hall-effect sensor firmly in place.

The hall sensor itself is placed inside the small tube at the lower end of the 'hall-sensor housing'. A precision-contact receptacle is glued to the back side of it (I used Loctite superglue) to receive the three hall sensor leads.

This allows for easy fine tuning the sensor position because the sensor leads are not soldered. Assuming we're using an SS 495A sensor, the stamped side must be facing up (the Arduino program assumes it).

Mounting the hall-effect sensor is a simple task: just bend the 3 leads in a 90° position, slide the sensor inside the small tube (from back to front) and, using tweezers, place the 3 sensor leads in the receptacles with precision-contacts.

The globe rotation sensor assembly STL file (needed for 3D printing one yourself) is available for 3D viewing and downloading through this link: Sketchfab globe rotation assembly 3D model (you will need to create a free account first).

Globe Rotation Control System

Picture 11.jpg

As explained already, the rotation coils beneath the globe will exert a tiny torque on the globe (because of the two small magnets mounted inside the globe). This torque is so small, that it will only keep the globe's rotation synced with ('locked to') the rotating magnetic field (caused by the six coils) if the two speeds (of magnetic field and globe) are not too far apart.

As a side note, it is certainly not helping that we also have the earth magnetic field trying to turn the globe into a compass: indeed, if the coils are switched off, the globe will always position itself with its two magnets pointing to the earth's magnetic North and South Pole. The fact that the rotation magnets are positioned with their poles facing up and down does not prevent that, because the earth magnetic field lines do not run horizontally - in most geographical areas, they have a vertical component !

Anyway - we need some type of control system - but nothing like the lifting control system described earlier (which is based on pure control theory).

First thing is, the controller needs to have knowledge about the globe's rotation speed. We won't measure this speed directly (although methods exist to do that) but we will measure the time of each globe rotation. As you will have guessed, the rotation hall sensor provides this input. It only detects passage of the 'Greenwich anti-meridian' magnet - the other rotation magnet (at the Greenwich meridian) passes quietly.

The circuit around opamps IC8A and IC8D takes the rotation hall sensor as input (oscilloscope screenshot - blue channel) and provides a pulse (yellow channel) which is then further shaped by a Schmitt trigger (IC8C). The Schmitt trigger output (not shown) is sampled by the Arduino Nano and used as controller input.

If the globe rotation speed is currently too low (lower than the desired speed), the rotating magnetic field speed will be set to a speed slightly higher than the current globe rotation speed (and vice versa). This process is repeated at each full turn of the globe, until the globe rotation speed reaches a small band around the desired rotation speed. Within that band, the control system is switched off and the rotating magnetic field speed is fixed to the desired rotation speed, for once and for all. Globe rotation is now 'locked to' or 'synced with' the rotating magnetic field.

The control system described here will only work if the phase of the rotating magnetic field is set correctly (with reference to the rotating globe). The program takes care of that, but this requires correct wiring of the coils and correct relative positioning of the coils in the horizontal plane with respect to placement of the hall sensor (see the corresponding picture).

Led Strips

Picture 12.jpg
picture 19.jpg

Because a globe floating and spinning in the dark is not much of an attraction, two digital led strips are added as a final touch. Each RGB led is individually controllable and only four wires are needed: ground, 5 Volt, data and clock.

These led strips are sold 'by the meter' and you can easily cut them to the desired length. In this case, each led strip contains 8 LEDs. The type I used also has a very convenient adhesive tape at the back side, making it quite easy to position the led strips and fix them in place (probably you'll need a few small wooden rails as well).

The clock lines will be tied together later, and the data lines as well (we will send the same data to the two led strips). For now, just solder a 4-wire flatcable of sufficient length to the input side of each led strip (the data flow is clearly indicated by arrows, as you can see in the picture). As a strain relief and to keep the flatcables in place, easiest is to glue them to the lantern. We'll deal with the other end of these two flatcables later.

Important: to keep current consumption low, only 8 of the 16 LEDs will be used and even not at full power. This is quite sufficient to obtain nice visual effects. If each RGB led (rated at 60 mA) would be switched on simultaneously and at full power, this would draw almost 1 Ampere. We will use a fraction of that.

Note: the l293D half bridge providing power to the led strips has a maximum rating of 600 mA.

Arduino Nano Code

The program is fairly well documented so I will not elaborate too much on it. See the .ino file attached.

The program has been designed for speed. Especially, the interrupt service routines (ISRs) do not make use of floating-point numbers. This means that, for instance, the lifting controller calculations are done with (long) integers, increasing accuracy by adding extra 'binary fraction' digits and removing them at the end of the calculation (shifting values left or right by a number of bits).

// define binary fraction digits to add for increased accuracy

constexpr int PIDcalculation_BinaryFractionDigits{ 14 };  // PID controller calculations

constexpr int gain_BinaryFractionDigits{ 8 };             // gain

constexpr int TTTintFactor_BinaryFractionDigits{ 18 };    // integration factor

constexpr int TTTdifFactor_BinaryFractionDigits{ 3 };     // differentiation factor

constexpr int PIDcalc_preliminaryDivisionDigits{ 4 };     // multiplications

Note: because of this, care must be taken, if specific constants are changed, that no under- or overflow situations occur.

Also, because divisions take much longer than multiplications (no processor instruction for division), there are none in the ISRs. Example: dividing a value by a constant '5' can be performed by multiplying that value with an integer constant '51' (51 = 1/5 * 2^8) and then shifting right 8 bits. If more accuracy is needed, use more bits.

This results in an average processor load of about 20%, which is measured by the program and can be verified with the Serial Monitor.

Program Main Loop

The main loop is short (everything happens in a number of dedicated procedures) but clearly shows the general structure.

  • If an event or user command is available, it will be processed. If not, the program moves on. Events are generated by Interrupt Service Routines. User commands are assembled from the Serial Interface or the (optional) hardware buttons.
  • Switch states (read and debounced within the ISR) are used to adapt settings if needed.
  • Data (if any) is sent to the serial interface and to the optional LCD.
  • If led strip brightness needs to change (indicated by the occurrence of a specific 'led strip' event), serial data will be sent to the led strip.
  • As long as there's nothing to do, control will stay in the idle loop. If there are still events to process (event queue not empty), the key buffer is not empty or an interrupt occurred ('Timer 1 overflow' or 'ADC complete interrupt') the idle loop will exit.
void loop()

{

    getEventOrUserCommand();   // get ONE event or assembled user command if available

    processEvent();            // process event, if available

    processCommand();          // process command, if available

    checkSwitches();           // if SW3 to SW0 to be interpreted as switches only

    writeStatus();             // print status to Serial (and LCD if connected)

    writeParamLabelAndValue(); // print label and value to Serial (and LCD)

    writeLedStrip();           // write ledstrip data

    myEvents.removeOldestChunk(ISRevent != eNoEvent);    // remove event from queue

    wdt_reset();               // reset watchdog timer

    resetHWwatchDog = true;    // allow ISR to reset hardware watchdog

    idleLoop();                // return if still something to do or ISR occurred

}

Note: as a general principle, all data transferred to / from hardware over the Arduino Nano Port D 'data bus' (see section 'PCB hardware') is written or read from within the ISRs, because this goes fast anyway, but with two exceptions:

1. Led strip data is sent serially over the same Port D data bus, which takes a few milliseconds (400 bits sent each time the led strip needs to be refreshed) - this would stall the ISR execution. Therefore, the main program loop takes care of sending led strip data. The program ensures there are no 'collisions' when sending led strip data is interrupted by an ISR sending or receiving data using the same data bus.

2. The optional LCD also uses the same data bus, and is also written to from within the main program loop because the standard LiquidCrystal library is used, which has no knowledge of the hardware address decoding logic used on the PCB.

Interrupts

Timer 1 interrupt

Timer 1 is a 16-bit timer. It executes every millisecond and performs the following tasks

  • provides time base (timer 0 is not used by the program, but it is not disabled)
  • resets hardware watchdog
  • initiates lifting hall-sensor ADC conversion and enables 'ADC complete' interrupt
  • polls globe rotation hall-effect sensor
  • reads and debounces switches / buttons and produces keycodes for pressed / released buttons (if connected)
  • most important of all: it provides the PWM (Pulse Width Modulation) signal controlling the lifting magnet

ADC complete interrupt

  • sometimes executed twice every millisecond: at completion of lifting hall-sensor ADC conversion (every millisecond) and et completion of temperature sensor ADC conversion (every 128 milliseconds)
  • reads converted ADC value. If this was a lifting hall-sensor value, proceeds. If it was a temperature sensor conversion, stores the temperature and exits
  • performs calculations related to lifting control, rotation control, safety
  • sets timer 1 register controlling pulse duty cycle for electromagnet (PWM)
  • outputs data for the coils, the LEDs etc.
  • calculates led strip brightness levels. Note that serial data will be sent to the led strips in the main program loop (because time consuming)
  • sends information to the main loop by using 'events': data is stored in dynamic memory, indicating the nature of the event (e.g. the globe's rotation speed has now obtained the set value) along with some extra information. The main loop will process events and remove them again from dynamic memory (see class 'MyEvents')
  • every 128 milliseconds: initiates a temperature ADC conversion (which will trigger a second, but very short, occurrence of this ISR)

Schematic and PCB

Picture 13.jpg

A two-layer PCB (schematic attached) hosts all electronics, except the sensors, the electromagnet, the coils and the led strips. The PCB has been designed with great care, trying to observe good practices like making adequate use of power planes and separating as much as possible analog and digital component areas (minimize noise introduced by digital logic presented to the analog circuits - especially the stability of the floating globe will depend on signal variations of less than 0.5 millivolts).

The board contains a number of extra connectors, making available most of the Arduino Nano pins as well as a few other signals. This facilitates using the board for prototyping activities beyond the scope of this project.

The files ('Gerber files') you will need to order this PCB are attached as well (file 'globe PCB V1 rev B-CAMOutputs.rar').

What follows is not a complete explanation of the PCB schematic. It is merely meant to give you some insight in the way the board works.

  • The board uses Arduino Nano port D (6 bits wide) as a data bus. It provides the data for the coils, the LEDs, the led strip, the optional LCD,... and reads the switch and button states.
  • IC10 decodes a 3-bit address (provided by Arduino port B bits 0, 4 and 5) into 8 I/O selection lines. Four of these selection lines will select either IC2 flip flops to write data to (to control coils), IC3 flip flops (to control leds etc.), IC4 buffers (to read switches and buttons) or the led strip. Unused selection lines are wired to an expansion connector (SV5). Note that the (optional) LCD chip select is directly wired to an Arduino Nano pin (check the code), because it is accessed via the LiquidCrystal library which does, of course, not use a decoder chip to select the LCD.
  • IC5 and IC6 each contain 4 half-bridges, which are typically used to control motors etc. We use IC5 and half of IC6 to drive the six coils. The two remaining half bridges of IC6 are used to supply voltage to the led strips (these are not directly connected to Vcc) and let the software control the red led.
  • Opamps IC9A and IC9D form some kind of a 'hardware watchdog'. If the software fails to regularly switch the signal at its input from high to low and vice versa, its output will come low, signaling an error condition, effectively shutting down electromagnet, coils and led strip and switching on the red led.
  • Opamp IC8B amplifies the lifting hall sensor by a factor 10. Important: by changing the values of resistors R10 and R12 from 100K to 150K, you can increase the amplification to 15 (which provides a greater ADC accuracy). If you do so, you must change the corresponding #define statement in the Arduino program accordingly. This signals the program that a few constants need to be adapted (the digital gain, for instance).
#define highAnalogGain 1  // 0: analog gain 10, 1: analog gain 15 (defined by resistors R9 to R12)

· Opamps IC8A, C and D are used to shape the signal coming from the rotation hall sensor.

· Opamp IC9B is used as an inverter and IC9C is not used at all.

Component Placement

Picture 14.jpg
Picture 15.jpg
Picture 8.jpg

The PCB contains quite a lot of components: you'll find a complete list (bill of material) in the file attached
(file '5__2021-globe PCB V1 rev B-BOM').

Parts are clearly indicated on the schematic drawing, the PCB silk screen and in the photograph of the components. I used IC sockets for all chips (female headers for the Arduino Nano) potentially saving me a lot of trouble in case a chip must be replaced. I used 74HCT logic chips because of the low power consumption, but 74LS chips will work as well (IC1 to 4, IC10).

The VMA404 step down converter is mounted vertically, components facing outward (see figure). The terminals are clearly labelled on the main board and on the stepdown converter board.

Before connecting terminal Out+, the converter's trimpot must be adjusted to obtain an output voltage of 7V—temporarily plugging in the external 24V wall power supply. This voltage setting will guarantee proper functioning of the board without dissipating excess power. When terminal Out+ is connected but before placing the actual chips in their sockets, it is good to use a multimeter or oscilloscope to run a few tests verifying that 5V is obtained where expected across the board.

We will need a connection to the three sensors (temperature and two Hall effect sensors), the electromagnet, the coils and the LED strip—and we'll need power, of course. Power is supplied by an external 24V wall power adapter, plugged into the PCB DC connector. It's a good idea to check the polarity first: 24V(+) is to be delivered to the center pin.

The polarity of the two wires to the electromagnet will be determined later (during testing). If the force exerted will be repelling rather than attracting—the wires need to be switched.

Sensor connectors (J3, J4 and J5 on the schematic) each expect 5V, sensor signal output and GND wires to be connected to the same respective connector pin. So, if a sensor is connected to a wrong connector, nothing will breakdown—although the board won't function, of course.

For the lifting Hall effect sensor (connector J3) I did not use a connector at all but soldered the wires directly to the board, not making them longer than needed, because the voltage variations measured are small (less than 0.5mV).

For connection to the rotation coils (10-pin header—only 6 pins used), corresponding signal names are clearly indicated on the two figures indicating globe rotation coils connections and corresponding PCB connections.

The PCB LED strip connector has 5 pins. The pin closest to the DC power jack, pin 1, delivers 5V. Pin 2 and pin 3 are data lines for lower and upper LED strip (currently supplying the same data). Pin 4 delivers the clock signal and pin 5 is GND.

Testing and Tuning

Picture 16.jpg
picture 18.jpg

Of course, I can only give you some general guidelines, but I would suggest using this roadmap for testing:

Test 1: verify communication (over USB) with the serial monitor on your PC. Make sure all DIP switches are in the OFF position and verify that the serial monitor's baud rate corresponds to the baud rate set by the Arduino program (standard 1000000 baud - preferably do not change it). Plug in the USB cable (you don't need to power on the PCB board yet and you don't need to make any other connections for now) and verify that the Arduino responds with a message starting with "Type + or - to change parameter shown, E to edit value,..." after reset.

Setup: in the serial monitor, type 'A' + ENTER. Arduino will respond with a list of parameters and values (see figure). Check that the rotation time set ('rot time') is 12 seconds and the vertical globe position ('vert pos') is set to 1000 millivolts (or 1500 millivolts, if you changed the analog gain to 15 - see section 'PCB'). If it's not, refer to section 'Serial communication' to set these values.

Test 2: for this test, forget about globe rotation and led strips for a while. Just connect the temperature sensor (if you don't, the board will detect a 'high temperature' and will not allow powering the electromagnet). Connect the lifting hall sensor and the electromagnet wires as well. Power on. You should see the green PCB led flashing. Wait 5 seconds. The blue PCB led should start blinking (a complete explanation about led colors and meaning is given further on). Now, move the globe (with the big lifting magnet) slowly upward, in the direction of the lifting hall sensor (and the electromagnet) until it touches the plexiglass plate. Then move it away from the sensor, in a downward direction. This enables the electromagnet and the lifting control system. Bringing the globe closer to the magnet again, you should now observe an attracting force between electromagnet and lifting magnet. If you observe a repelling force, the two electromagnet's wires need to be switched.

Test 3: try 'hanging' the globe into position (procedure explained in next section).

Test 4: power off, connect the rotation hall-effect sensor as well and power on. Hang the globe into position again and give it a slight turn (counterclockwise).

  • Connect an oscilloscope to IC8A pin 9 (Schmitt trigger input) and verify that the waveform you see looks like the yellow waveform in the figure showing Greenwich magnet passage pulse shaping in step 'Globe rotation control system'. If it's not, then try to obtain this waveform by adjusting the horizontal and vertical position of the rotation hall sensor (loosening the two nuts - see section 'Rotation sensor assembly assembly).
  • Tune Schmitt trigger output: connect oscilloscope channel 2 to IC8C pin 8 (Schmitt trigger output). By adjusting trimpot R8, set the input threshold voltage (scope channel 1) to 0.8 Volt (more or less). Supposing you gave the globe a rotation speed between somewhere between 10 and 15 seconds, this should produce a pulse between 0.5 and 1 second, each time the 180° meridian passes the rotation hall sensor.

Test 5: power off, connect the coils as well and power on. Hang the globe into position again and give it a slight turn (counterclockwise). The rotation control system should now kick in. After some 30 seconds, the PCB led should go out, indicating that the set rotation speed is obtained.

Test 6: now, connect the led strips. Then, use serial monitor commands (explained in a next section) to set led strip cycle 5 (cycle through all colors) and led strip timing 1 (fastest). Verify that the led strips function properly (remember that not all LEDs are used).

Positioning the Globe and Status Leds

When you power up the system, you can immediately 'hang' the globe in position (some 35 mm below the electromagnet, or approximately 15 mm below the plexiglass plate holding the lifting hall-sensor): just watch the RGB status led mounted on the PCB. If it lights up steady green, you're at the correct height. If it blinks (green), you're either too high or too low. it needs some practice (not too much, though) but it should be fairly easy.

Once the globe floats, give it a slight turn (counterclockwise) and wait... depending on the initial rotation speed you gave it (which is not critical), after some time, the globe will attain its set rotation time (standard 12 seconds).

The RGB status led has a few other functions too:

Led is off : the globe is floating and globe rotation is locked (synced with the rotating magnetic field created by the coils).

Led is ON or flashes (green or blue):

  • green led flashes approx. 4 times a second: globe is not within a narrow 'floating' range. While positioning the globe, use this to guide you to the correct distance between globe and electromagnet.
  • green led is on continuously: globe is floating but no Greenwich position sync (passage of Greenwich anti-meridian magnet) detected yet. Rotation coils switched off.
  • green led is flashing rapidly (approx. 16 times per second): globe is floating; a first rotation time measurement is underway. Rotation coils switched off.
  • blue led is on continuously, but with brighter (green) flashes: globe is floating but globe rotation is not yet locked. A (brighter) blue flash indicates the direction of the rotating magnetic field is changing. A green flash indicates the Greenwich magnet is currently passing the rotation hall sensor.

Led is blinking slowly (blue): lifting magnet and coils are currently switched off because of an error condition. The number of consecutive 1-second blinks (followed by a pause) indicates what caused the error condition:

  • 1 blink: dropped globe for more than 5 seconds (globe probably fell down or was taken away, or no globe detected yet after power on).
  • 2 blinks: sticky globe: globe position too high for more than 5 seconds (globe was probably sticking to the plexiglass plate).
  • 3 blinks: average lifting magnet duty cycle was higher than 80% for the last few minutes (a situation that is highly unlikely to occur, but as this concerns safety...).
  • 4 blinks: smoothed temperature reading is higher than 65° Celsius.

To enable the system again, bring the globe close to the plexiglass plate holding the lifting sensor (in an upward movement), then move it away from the plexiglass plate again (downward movement). The led will now turn green again and you'll have (again) 5 seconds to bring the globe back into its floating position.

Led is red: If, because of a malfunction or program error, the program stops producing pulses on the input of the circuit around Opamps IC9A and IC9D (acting as a hardware watchdog), lifting magnet and coils will be disabled and the led will turn red.

Controlling the Spinning Globe Via USB

picture 16b.png

By using the Arduino serial monitor (or other properly configured 'terminal' software) via USB, you can print certain information and change a few settings.

The following information ('parameters') can be printed:

  • Currently selected rotation time (setting)
  • Actual rotation time
  • Rotation time sync error: the accumulated globe rotation time error (when locked)
  • 'Globe rotation locked' time. Reset when globe rotation is not locked
  • 'Globe is floating' time. Reset when globe is not floating
  • Temperature (degrees Celsius)
  • Lifting magnet average duty cycle (%)
  • Globe vertical position: reference (setpoint) in millivolts (setting).Note that setpoint values refer to values as read by the ADC, so they are scaled to 10 (or 15 - see PCB section) times the hall-sensor output for the set vertical position
  • Smoothed average of the absolute value of the globe vertical position error in millivolts as read by the ADC
  • Current value of the integration term, calculated by the globe lifting controller
  • Average phase between rotating magnetic field and rotating globe (when locked). Can be used to calibrate the phase between rotating magnetic field and globe, set by the globe rotation controller before locking is obtained
  • Average duration of the 'ADC conversion complete' ISR routine in microseconds (smoothed)
  • Average processor load (smoothed)

In addition, each status change will be printed (e.g. the selected rotation time is reached).

Use the following commands to print parameters and their values or change settings (sending a 'Carriage Return' is not needed, although you might have to press Enter to send your command to the Arduino, depending on the terminal software you use).

  • '+' or '-' : print next or previous parameter. When in edit mode: select next or previous parameter value from list.
  • 'E': edit current parameter. When in edit mode: end editing and save currently selected parameter value in EEPROM memory. Only available for changing rotation time and fine-tuning globe vertical position, no function for other parameters.
  • C': cancel editing without saving. No function when not in editing mode.
  • 'S' to start or stop showing live values. This will start or stop printing the actual value of the currently selected parameter regularly to the serial monitor (for instance the time it took to complete the last globe rotation). Does not apply to settings.
  • 'A': print all parameters at once, as well as current led strip settings.

Additional commands:

  • ?': print available commands (help).
  • 'T': print time stamp (time in milliseconds since last reset - a real time clock is not available).
  • 'LC0' to 'LC5': select a led strip cycle. 0 = Off, 1 = constant brightness white, 2 = constant brightness magenta, 3 = constant brightness blue, 4 = fade between white and blue, 5 = smoothly cycle between all colors (from blue to cyan, green, yellow, red, magenta, and blue again,...). Selection is stored in EEPROM memory.
  • 'LT1' to 'LT4': change led strip cycle time. 1 = fastest (minutes), 4 = slowest (hours). Note that the timing is not relevant for all led strip cycle types. Selection is stored in EEPROM memory.
  • 'R0' and 'R1': apply an optional step to the globe position reference allowing to capture the response. See next section.

Measuring Step Response

Picture 17.jpg

Serial monitor commands 'R0' and 'R1' let you apply an optional step ('R1') or no step ('R0') to the globe vertical position reference (setpoint) and then sends the measured response (actual globe vertical position) and controller output (PWM duty cycle) to the serial monitor where it can be logged for evaluation in excel etc.

The step applied ('R1' command only) increases the vertical position setpoint with 100 ADC steps. Expressed in millivolts at the hall sensor output: 100 ADC steps * (5000 millivolts / 1023 ADC steps) / 10 = 49 millivolts (if the analog gain is set to 10 - see section 'PCB').

The Arduino starts sending data to the serial monitor, 1 second before the step is applied ('R1' command) and continues sending data for 20 seconds.Every millisecond, a line containing three values is sent, the values being separated by a semicolon. Value 1: millisecond (1 to 20000)Value 2: lifting hall-effect sensor value read (in ADC steps)Value 3: controller output (PWM duty cycle as a value from 0 to 999 = 100%). See the excel step response chart attached as picture.

A few notes on the use of the 'R0' and 'R1' commands:

  • The 'Rn' command requires a high baud rate: the baud rate set by the program is 1000000, so this shouldn't e a problem.
  • The value of the integration term (see section 'Globe lifting control system') including extra accuracy digits (see section ('Arduino Nano code') at the start of the 'Rn' output (first millisecond) is printed to the serial monitor as well. This allows 'replaying' controller calculations in excel based on logged hall-effect sensor values (in ADC steps), verifying that the calculated controller output in excel is identical to the logged controller output.
  • When sending step response data has ended, the globe vertical position is gently brought back to its original setting.
  • Do not use this command while you are showing Live values (see 'S' command)

Using Hardware Buttons and LCD

picture 17b.png

It is possible to connect 4 buttons ('+', '-', 'E' and 'C') directly to the Spinning Globe board PCB, as well as a 16 x 2 character, Arduino compatible LCD display. This allows you to review the same live values and change the same settings as by using the serial monitor.

The LCD displays status information on the top line (e.g. "E! dropped globe") and the currently selected parameter (see section "Serial communication") on the bottom line.

Note that led strip settings cannot be changed using the hardware buttons. They are not displayed on the LCD either.

Connecting ('make' contact) buttons: use connector SV2.

  • '-' button: connect one pin to signal 'SW0' (SV2 pin 2), other pin to GND
  • '+' button: connect one pin to signal 'SW1' (SV2 pin 4), other pin to GND
  • 'E' button: connect one pin to signal 'SW2' (SV2 pin 6), other pin to GND
  • 'C' button: connect one pin to signal 'SW3' (SV2 pin 8), other pin to GND

Pressing these buttons will have the same effect as sending the equivalent commands using the serial monitor (or other terminal software).

Important: make sure DIP switches 2 to 5 are all in the OFF position. These switches are connected to signals 'SW3' to 'SW0', respectively, in parallel with these 4 buttons. Setting a switch in the ON position will tie the corresponding signal to GND, making the corresponding button inoperable. Moreover, if one of these switches is in the ON position right after reset or power on, the system enters programming mode (see further).

Connecting an LCD: use general-purpose connector SV5 to connect an optional 2 x 16 character LCD based on the Hitachi LCD controller. Data is sent to the LCD using a 4-bit bus and the LCD is working in write-only mode: wire the LCD Read/Write pin to ground.

  • Connect LCD data bits 4 to 7 pins to signals 'D4(PD4)' to 'D7(PD7)' (Arduino port D bits 4 to 7, see schematic)
  • Connect the LCD RS (register select) pin to signal 'D3(PD3)' (port D bit 3)
  • Connect the LCD enable pin to signal 'PB2' (Arduino port B bit 2)
  • Properly connect power, LCD contrast and backlight LED pins (using resistors as specified in the LCD datasheet - resistors not provided on the PCB)

Using the DIP Switches to Change Settings (program Mode)

It is possible to set globe rotation time, fine-tune globe vertical position setpoint, or set led strip cycle and timing without using the serial monitor or buttons / LCD.

Procedure to enter and exit program mode:

1. while power is OFF, indicate which setting you want to change with DIP switches 2 to 5 (signals 'SW3' to 'SW0'), as outlined below. Do not use any other switch setting. Note that DIP switch 1 (signal 'SW4') is not currently used.

ON ON ON ON: change led strip settings

ON ON ON OFF: set rotation time

ON ON OFF ON: fine-tune globe vertical position reference

2. Power ON. Then, while power is ON, set the DIP switches as indicated below.

=> If initial switch setting isON ON ON ON: set a ledstrip cycle and timing, as follows:

ON ON ON ON: switch off led strip

ON ON ON OFF: constant brightness white

ON ON OFF ON: constant brightness magenta

ON ON OFF OFF: constant brightness blue

ON OFF (T1) (T0): fade between white and blue

OF ON (T1) (T0): cycle between all colors (blue, cyan, green, yellow, red, magenta, blue,...)

other switch settings do not affect the last set led strip cycle and timing

(T1) (T0) sets led strip timing:

ON ON: timing 1 (fastest)

ON OFF: timing 2

OFF ON: timing 3

OFF OFF: timing 4 (slowest)

=> If initial switch setting is ON ON ON OFF: set a globe rotation time, as follows:

ON ON ON ON: globe rotation OFF ('compass' behavior)

ON ON ON OFF: 12 seconds

ON ON OFF ON: 9 seconds

ON ON OFF OFF: 7.5 seconds

ON OFF ON ON: 6 seconds

ON OFF ON OFF: 4.5 seconds

ON OFF OFF ON: 3 seconds

ON OFF OFF OFF: 2.4 seconds

other switch settings: globe rotation OFF

=> If initial switch setting is ON ON OFF ON: fine-tune globe vertical position setpoint (in millivolt units), as follows:

ON ON ON ON: 1000 millivolts

ON ON ON OFF: 1200 millivolts

ON ON OFF ON: 1400 millivolts

ON ON OFF OFF: 1600 millivolts

ON OFF ON ON: 1800 millivolts

other switch settings: 1000 millivolts

Note that setpoint values refer to values as read by the ADC, scaled to 10 times the hall-sensor output for the set vertical position. In case you changed the analog gain to 15 (see section 'PCB'), the values set will be 1500, 1800, 2100, 2400 and 2700 millivolts, respectively.

3. Power OFF. Then, while power is OFF, set switches 2 to 5 to 'OFF' again. The desired setting has already been stored (in EEPROM memory).

4. Power ON again.

That's All, Folks

I have tried to give you an insight into the project that consumed most of my free time during the last year. During this endeavor, I had to answer a lot of design questions that popped up, one by one. But it paid off and I’m really happy with the result.

I tried to make the instructions as detailed as possible. However, I realize that completeness is something that is very hard, if not impossible, to achieve.

I hope that this project will be a learning opportunity for some and be a lot of fun for others.

Anyway, I would encourage you to build a floating and spinning globe of your own!