How to read this notebook
The logs build on each other like the chapters of a textbook. Definitions come first, then results that follow from them, each with a proof and a worked example using this rig's numbers. Every log carries a tag that says how sure we are.
- Measured:
- done and recorded, with the data linked.
- Not yet calibrated:
- measured in raw sensor units, so the size in grams isn't pinned down yet.
- Our theory:
- our electromagnetic force equations and our rig constants \(K\) and \(K'\). These are predictions, not results.
- Claude AI derived · unverified:
- the physical mechanics of the rotor's motion and of the setup: how the rotor moves, and how that motion changes the average force. We worked this out with help from Claude AI. So far it has been checked only within Korent, by our founder, an undergraduate physics student, and not yet by an expert in mechanics. It always sits in a white box. If you spot a problem, please get in touch.
- Open question:
- something we don't know yet.
- Planned:
- the next tests, in order.
- Idea:
- untested designs.
Box colours
Equations are numbered so later logs can point back to them. If we get something wrong, we'll correct it here in the open and say what changed.
The question, stated precisely
Before this project we built the LeviPen, a pen that holds a small ball magnet in the air. Getting it to work meant fighting magnets that did things we didn't expect, and that led us to a sharper question: what does a magnet feel when the magnet next to it is spinning?
Other people have shown that a magnet spinning fast enough can hold a second magnet floating below it.[3][4][5] In those experiments the floating magnet is free to move and turn. Here the second magnet is clamped to a scale, so the force on it can be measured directly.
Making "no matter which way it faces" precise
"Polarity-free" sounds clear but isn't something you can measure until it is pinned down. The definitions below turn it into a measurable quantity.
Definition 1.1 (the measured force). Let \(P(\mathbf m_t,\omega)\) be the time-averaged force along the spin axis on a clamped test magnet with dipole moment \(\mathbf m_t\), when the rotor spins at angular speed \(\omega\). Positive \(P\) means the test magnet is pushed away from the rotor.
Definition 1.2 (even and odd parts). Flipping the test magnet end for end sends \(\mathbf m_t \to -\mathbf m_t\). Define
$$E(\omega)=\tfrac12\big[P(\mathbf m_t,\omega)+P(-\mathbf m_t,\omega)\big],\qquad O(\omega)=\tfrac12\big[P(\mathbf m_t,\omega)-P(-\mathbf m_t,\omega)\big]. \tag{1.1}$$Then \(P = E + O\). \(E\) is unchanged by the flip and \(O\) changes sign.
Any function can be split uniquely into a part that is symmetric under a flip and a part that is antisymmetric. Splitting this way turns "doesn't care about polarity" into one number, \(E\), and "ordinary magnet force" into another, \(O\).
Proposition 1.3. Every static force between two rigid magnets in fixed positions belongs entirely to \(O\).
This is the key logical step. A nonzero \(E\) cannot come from ordinary magnet-on-magnet forces. It needs a mechanism that is quadratic in \(\mathbf m_t\), for example motion of the rotor caused by the force itself (Log 4), or something non-magnetic such as air flow or vibration, which the controls in Log 6 are there to catch.
Definition 1.4 (polarity-free repulsion). A polarity-free force is present if \(E(\omega)\neq 0\) after subtracting what a non-magnetic dummy rotor produces under identical conditions. It is a repulsion if that remainder is positive.
Research question. For a clamped test magnet, is \(E(\omega)\neq 0\)? If so, how big is it and how does it scale with \(\omega\)?
Apparatus and notation
A motor spins one magnet (the rotor). A second magnet (the test magnet) is clamped on the spin axis and mounted on a load cell, a strain-gauge sensor that weighs small forces. A Hall sensor and a pickup coil measure the spin speed.
| Part | Role | Where to buy |
|---|---|---|
| Rotor magnet: ½ in × ½ in N52 cylinder, diametric | Magnetized across its spin axis, so its moment sweeps around the axis. | Search |
| Test magnet: ½ in × ½ in N52 cylinder, axial | Magnetized along the axis; clamped 1.12 in (28.4 mm) face to face from the rotor. | K&J D88-N52 |
| DC motor and speed controller, on their own power supply | Spin the rotor at 65 and 85 rev/s (3,900 and 5,100 rpm) under PWM speed control. | Your existing motor |
| Straight-bar load cell (10 kg, about 1 mV/V) | Bends very slightly under the axial force on the test magnet. | Search |
| HX711 24-bit load-cell amplifier | Turns the load cell's microvolt signal into counts. | SparkFun HX711 guide · Search |
| Seeed XIAO ESP32-C3 microcontroller | Runs the firmware: sets speed, reads sensors, streams data. | Search |
| A3144 Hall switch | One pulse per magnet pass, for speed and rotor angle. | Search |
| Pickup coil | A second, independent speed reading from the rotor's changing field. | Hand-wound, or search |
| SS49E linear Hall sensor (planned) | Reads field strength; for a later check of the rotor magnet's tilt. | Search |
| ADXL375 ±200 g accelerometer (planned) | Measures how much the rotor shakes; for a later direct check of \(K\). | Adafruit ADXL375 |
| Capacitors, 10 kΩ and 100 kΩ resistors | Supply filtering and signal conditioning (see the capacitor table below). | Ceramic kit · 1000 µF · Resistors |
| 3D-printed frame, twisted-pair wire | Holds the parts in line; twisted pairs reject pickup of motor noise. | Printed in-house |
Wiring the apparatus
There are two separate circuits: a power side (motor supply, controller, motor) that switches amps of current, and a signal side (ESP32, HX711, sensors) that measures microvolts. Most of the wiring rules exist to keep the first from leaking into the second. That leak is exactly what corrupted the early readings (Log 5).
| From | To | Why |
|---|---|---|
| Motor supply + and − | Speed controller power input | The motor gets its own supply, so its current surges don't pull down the logic voltage. |
| Speed controller output | Motor | Keep these two wires short and twisted together, so the loop that carries the switched current is small and radiates less. |
| ESP32 PWM pin | Speed controller signal input | Sets the motor drive (the "power %" in Log 7). |
| Motor supply − (ground) | ESP32 GND, joined at one point next to the controller's signal input | The PWM signal needs a shared reference. Joining grounds at a single point (a star ground) stops motor current from flowing back through the sensor ground wires. |
| Load cell red, black | HX711 E+, E− | Excitation: the HX711 powers the strain-gauge bridge. |
| Load cell green, white | HX711 A+, A− | The bridge output, a few microvolts per gram. Twist all four wires and route them away from the motor leads, crossing at right angles if they must cross. Wire colours vary by maker; check yours. |
| HX711 VCC, GND | ESP32 3.3 V, GND | Powering the amplifier from the clean logic supply keeps motor noise out of the measurement. |
| HX711 DT (data), SCK (clock) | Two ESP32 digital pins | The digital readout. Keep these wires short. On boards with a RATE pin, set it high for 80 readings per second. |
| A3144 pin 1 (VCC), pin 2 (GND) | 5 V and GND | The A3144 is specified for 4.5–24 V, so 3.3 V is below its rating. |
| A3144 pin 3 (OUT) | ESP32 interrupt pin, with a 10 kΩ pull-up to 3.3 V | The output is open-collector: it only pulls low. The pull-up supplies the high level, and pulling up to 3.3 V instead of 5 V protects the ESP32 pin. |
| Pickup coil, one end | Mid-supply bias: two 100 kΩ resistors from 3.3 V and GND | The coil's signal swings above and below zero. The ESP32 analog input can't read negative voltages, so the signal is centred at 1.65 V. |
| Pickup coil, other end | ESP32 analog pin, through a 1 kΩ resistor | The series resistor limits current into the pin if the coil produces a spike. |
Capacitors: where they go and why
A capacitor stores a small amount of charge right next to a part. When the part suddenly needs current, or when noise arrives on a wire, the capacitor supplies or soaks it up locally instead of letting it travel through the wiring. Small ceramic capacitors (100 nF) handle fast spikes; large electrolytic ones (µF and up) handle slower dips. Place every capacitor as close as possible to the pins it protects, because extra wire length adds inductance and undoes the benefit.
| Capacitor | Where it goes | How to connect | Why |
|---|---|---|---|
| 470–1000 µF electrolytic, rated at least 1.5× the motor supply voltage | Across the speed controller's power input | Positive lead to +, striped (negative) lead to −. Polarity matters: reversed, it can fail violently. | The motor draws current in PWM pulses. Without a local reservoir, the supply wires ring with every pulse and radiate noise into the sensors. |
| 100 nF ceramic | Directly across the motor terminals (brushed DC motors only) | Either way round; solder at the motor. | Brushes spark as they switch, which creates very fast spikes. This shorts them out right where they start. |
| 100 nF ceramic + 10 µF | HX711 VCC to GND, at the board | Ceramic either way round; for an electrolytic or tantalum 10 µF, + goes to VCC. | The HX711 resolves microvolts, so any ripple on its supply shows up as counts. Many boards already have some; extra at the pins does no harm. |
| 100 nF ceramic | A3144 VCC to GND, at the sensor | Either way round. | Keeps supply spikes from causing false triggers. |
| 1 nF ceramic (optional) | A3144 OUT to GND | Either way round. | With the 10 kΩ pull-up it filters spikes faster than 10 µs (10 kΩ × 1 nF). That is far shorter than one revolution (11.8 ms at 85 rev/s), so real pulses pass. |
| 1 µF ceramic | Coil bias midpoint to GND | Either way round. | Holds the 1.65 V bias steady so the coil signal rides on a quiet reference. |
| 100 nF ceramic | ADXL375 VCC to GND (planned) | Either way round. | Standard supply decoupling for a sensor that samples thousands of times per second. The Adafruit board already includes it. |
Safety: unplug both supplies before changing wiring. An electrolytic capacitor holds charge after power is removed; touch its leads with a resistor before handling it.
Notation
| Symbol | Meaning | Value here |
|---|---|---|
| \(z\) | Spin axis, pointing from the rotor to the test magnet | |
| \(\omega = 2\pi f\) | Rotor angular speed; \(f\) in rev/s | \(\omega_A = 408.4\), \(\omega_B = 534.1\ \text{rad/s}\) |
| \(m\) | Dipole moment of each magnet | \(1.856\ \text{A}\cdot\text{m}^2\) |
| \(\mu_0\) | Permeability of free space | \(4\pi\times10^{-7}\ \text{T}\cdot\text{m/A}\) |
| \(C=\mu_0 m^2/4\pi\) | Dipole strength constant | \(3.446\times10^{-7}\ \text{N}\cdot\text{m}^4\) |
| \(D\) | Centre-to-centre distance | \(1.62\ \text{in} = 0.04115\ \text{m}\) |
| \(P\) | Time-averaged axial force on the test magnet | measured |
| \(r\) | Load-cell reading | counts |
Two numbers worked out
Example 2.1 (dipole moment). A uniformly magnetized cylinder has \(m = (B_r/\mu_0)\,V\), where \(B_r\) is the remanence. For N52, \(B_r \approx 1.45\ \text{T}\). The volume of a ½ in × ½ in cylinder (radius 6.35 mm, height 12.7 mm) is
$$V=\pi r^2 h=\pi(6.35\times10^{-3})^2(12.7\times10^{-3}) = 1.609\times10^{-6}\ \text{m}^3, \tag{2.1}$$ $$m=\frac{1.45}{4\pi\times10^{-7}}\,(1.609\times10^{-6}) = 1.856\ \text{A}\cdot\text{m}^2. \tag{2.2}$$Example 2.2 (why \(D\) is not the gap). Dipole formulas measure distance between the magnets' centres, not their faces. Each magnet's centre sits half its height (0.25 in) behind its face, so
$$D = \text{gap} + 2\times 0.25\ \text{in} = 1.12 + 0.50 = 1.62\ \text{in} = 0.04115\ \text{m}. \tag{2.3}$$Using the gap instead overstates every force that scales like \(1/D^4\) by \((1.62/1.12)^4\approx 4.4\) times.
Static forces and why they hide the signal
Before looking for a small effect, you need to know the size of the big, ordinary forces it sits on. This log computes them from the standard dipole–dipole force law, found in any electromagnetism textbook.
Proposition 3.1 (force between two dipoles). For dipoles \(\mathbf m_1\) at the origin and \(\mathbf m_2\) at position \(\mathbf r = r\hat{\mathbf r}\), the force on \(\mathbf m_2\) is
$$\mathbf F=\frac{3\mu_0}{4\pi r^4}\Big[(\mathbf m_1\!\cdot\hat{\mathbf r})\,\mathbf m_2+(\mathbf m_2\!\cdot\hat{\mathbf r})\,\mathbf m_1+(\mathbf m_1\!\cdot\mathbf m_2)\,\hat{\mathbf r}-5(\mathbf m_1\!\cdot\hat{\mathbf r})(\mathbf m_2\!\cdot\hat{\mathbf r})\,\hat{\mathbf r}\Big]. \tag{3.1}$$This is the force between two point magnets. At \(D = 1.62\) in, the magnets are about 3 diameters apart, close enough to the point limit for estimates. Finite-size integration agrees at this distance.
Case (a) (the actual setup: rotor moment across the axis). Put \(\hat{\mathbf r}=\hat{\mathbf z}\), \(\mathbf m_1 = m(\cos\omega t,\sin\omega t,0)\), \(\mathbf m_2 = m\hat{\mathbf z}\). Then \(\mathbf m_1\!\cdot\hat{\mathbf r}=0\) and \(\mathbf m_1\!\cdot\mathbf m_2=0\), so only the second term of (3.1) survives:
$$\mathbf F(t)=\frac{3\mu_0 m^2}{4\pi D^4}\,(\cos\omega t,\ \sin\omega t,\ 0)=A\,(\cos\omega t,\ \sin\omega t,\ 0),\qquad A=\frac{3C}{D^4}. \tag{3.2}$$ $$A=\frac{3(3.446\times10^{-7})}{(0.04115)^4}=0.361\ \text{N}\ \ (36.8\ \text{gf}). \tag{3.3}$$On the axis, the spinning rotor exerts no axial force on the test magnet. It exerts a 36.8 gf sideways force that rotates with the rotor. By Newton's third law the rotor feels the same rotating force in reverse, and that shakes it. This is the starting point of Log 4.
Case (b) (both moments along the axis). With \(\mathbf m_1 = \pm m\hat{\mathbf z}\) and \(\mathbf m_2 = m\hat{\mathbf z}\), every term of (3.1) points along \(\hat{\mathbf z}\):
$$F_z=\frac{3\mu_0}{4\pi D^4}(\pm m^2)(1+1+1-5)=\mp\frac{6C}{D^4}=\mp 0.721\ \text{N}\ \ (73.5\ \text{gf}). \tag{3.4}$$Remark 3.2 (a tilted rotor magnet). If the rotor magnet sits tilted by an angle \(\gamma\) out of the plane, its moment has an axial part \(m\sin\gamma\) that does not rotate. By (3.4) that part gives a steady axial force
$$\bar F_z=\frac{6C\sin\gamma}{D^4}\approx 1.28\ \text{gf per degree of tilt}, \tag{3.5}$$which is linear in \(\mathbf m_t\), so it belongs to \(O\) (Proposition 1.3).
Compare the scales. A 1° mounting error gives about 1.3 gf. The effect predicted in Log 4 is around 0.05 gf. The small signal is buried under ordinary forces 25 times larger from a barely visible tilt. That is why the measurement in Log 6 compares two speeds (static forces cancel) and flips the test magnet (odd forces cancel).
The model under test
Our theory is that the rotating force in (3.2) shakes the rotor on its mount, and that the rotor mount can be described by two constants: its mobility \(K\) (how easily it shakes) and its stiffness \(K'\). The rotor's small orbit is correlated with the force itself, so averaging over a turn leaves a steady force on the test magnet, set by \(K\) and \(K'\). This is a prediction, not a result. Logs 7 and 8 test it.
The step-by-step mechanics of the rotor in the white box below were derived with Claude AI and haven't been independently checked. The mathematics is the same type as Kapitza's pendulum and the effective potential for motion in a rapidly oscillating field.[1][2]
Rotor mechanics and dynamics: how the rotor moves on its mount, and how that motion averages into a force. Treat everything in this box as a draft until it is checked.
Assumptions
- Small motion: the rotor's displacement \(\mathbf u\) satisfies \(|\mathbf u|\ll D\).
- Prescribed orientations: the rotor's angle is \(\omega t\) and the test magnet does not turn, so the force comes from a potential: \(\mathbf F=-\nabla U\).
- The rotor mount behaves like a linear spring in each sideways direction: effective mass \(M\), stiffness \(K'\), damping \(c\). Define the mobility \(K = 1/M\).
- The test magnet is held rigidly. The load cell barely moves.
- Steady state: start-up transients have died out.
Step 1: how the rotor moves
Write the force on the test magnet as a steady part plus harmonics of the spin frequency:
$$F_j(t)=\bar F_j+\sum_{h\ge1}\operatorname{Re}\!\left[f_{h,j}\,e^{ih\omega t}\right],\qquad j=x,y. \tag{4.1}$$The rotor feels \(-\mathbf F\) (Newton's third law). Each sideways direction is a driven, damped oscillator:
$$M\ddot u_j+c\,\dot u_j+K'u_j=-F_j(t). \tag{4.2}$$Try \(u_j=\sum_h \operatorname{Re}[u_{h,j}e^{ih\omega t}]\). Substituting gives \((K'-Mh^2\omega^2+ich\omega)\,u_{h,j}=-f_{h,j}\), so
$$u_{h,j}=-\chi_h f_{h,j},\qquad \chi_h=\frac{1}{K'-Mh^2\omega^2+ic\,h\omega}. \tag{4.3}$$\(\chi_h\) is the mount's response: how far it moves per newton at frequency \(h\omega\). Above the mount's resonance, \(h\omega > \sqrt{K'/M}\), inertia dominates and the rotor moves opposite to the force on it. Below resonance the spring dominates and it moves with the force. That sign change matters in the result.
Step 2: averaging the force
Proposition 4.1 (averaged force). Under assumptions 1–5, the time-averaged axial force on the test magnet is \(P=\bar F_z+\sum_h \Delta P_h\), with
$$\Delta P_h=G_h\,\operatorname{Re}\!\left[\frac{1}{Mh^2\omega^2-K'-ic\,h\omega}\right]\ \xrightarrow{\;c\,\to\,0\;}\ \frac{G_h}{h^2\omega^2/K-K'}, \tag{4.4}$$ $$G_h=-\frac14\frac{\partial S_h}{\partial D},\qquad S_h=\sum_{j=x,y}|f_{h,j}|^2. \tag{4.5}$$(i) Expand. When the rotor moves by \(\mathbf u\), the test magnet's position relative to the rotor shifts by \(-\mathbf u\). To first order in \(\mathbf u\) (assumption 1), $$F_z(\mathbf R_0-\mathbf u,t)=F_z(\mathbf R_0,t)-u_j\,\partial_jF_z+O(u^2).$$
(ii) Use symmetry. By assumption 2, \(\partial_jF_z=-\partial_j\partial_zU=\partial_zF_j\): mixed partial derivatives of a potential commute. So \(\langle F_z\rangle=\bar F_z-\langle u_j\,\partial_zF_j\rangle\).
(iii) Average products. For two signals at the same frequency, \(\langle\operatorname{Re}(a e^{i\theta})\operatorname{Re}(b e^{i\theta})\rangle=\tfrac12\operatorname{Re}(ab^*)\), and different harmonics average to zero. With (4.3), $$\langle u_j\,\partial_zF_j\rangle=\tfrac12\sum_h\operatorname{Re}\!\left[u_{h,j}\,\partial_zf^*_{h,j}\right]=-\tfrac12\sum_h\operatorname{Re}\!\left[\chi_h\,f_{h,j}\,\partial_zf^*_{h,j}\right].$$
(iv) Simplify. On the axis, each \(f_h\) has a phase that does not change with distance (its size does), so \(f\,\partial_zf^*=\tfrac12\partial_z|f|^2\). Also \(\partial_z=\partial/\partial D\). Therefore $$\langle F_z\rangle=\bar F_z+\tfrac14\sum_h\operatorname{Re}(\chi_h)\,\frac{\partial S_h}{\partial D}=\bar F_z-\sum_h\operatorname{Re}(\chi_h)\,G_h,$$ and \(-\chi_h = 1/(Mh^2\omega^2-K'-ich\omega)\) gives (4.4).
∎Corollary 4.2 (the model's force is polarity-free). \(\Delta P_h\) is even in \(\mathbf m_t\), so in an ideal flip test \(E=\sum_h\Delta P_h\) and \(O=\bar F_z\).
Remark 4.3 (what the formula says).
- Above the mount's resonance (\(h^2\omega^2/K > K'\)), \(\Delta P > 0\): a repulsion. Far above resonance it falls off as \(1/\omega^2\).
- Below resonance, \(\Delta P < 0\): an attraction. The sign depends on the mount, not on the magnets.
- Check: for a free rotor (\(K'=0\), \(c=0\)), (4.4) is \(\Delta P=-\partial U_{\text{eff}}/\partial D\) with \(U_{\text{eff}}=S/(4M\omega^2)\). That is the textbook effective potential for a particle in a rapidly oscillating force.[2]
- A direct step-by-step simulation of a rotor on a spring, also run with Claude AI, agreed with (4.4) to within about 2%, including the sign change below resonance.
Step 3: this rig's numbers
Example 4.4 (gradient coefficient). From (3.2), \(\mathbf f_1=A(1,-i,0)\): the rotating force is a single harmonic, so \(S_1=2A^2\) and every \(h\ge2\) term vanishes. Since \(A\propto D^{-4}\),
$$\begin{aligned}G_1&=-\frac14\frac{\partial(2A^2)}{\partial D}=-A\frac{\partial A}{\partial D}=\frac{4A^2}{D}=\frac{36C^2}{D^9}\\[4pt]&=\frac{4(0.361)^2}{0.04115}=12.64\ \text{N}^2/\text{m}.\end{aligned} \tag{4.6}$$Example 4.5 (the chop signal). Log 6 measures the difference between two speeds. With \(K'\) small compared with \(\omega^2/K\),
$$\mathrm dP=\Delta P(\omega_A)-\Delta P(\omega_B)=K\,G_1\left(\frac{1}{\omega_A^2}-\frac{1}{\omega_B^2}\right). \tag{4.7}$$ $$\begin{aligned}\frac{1}{408.4^2}-\frac{1}{534.1^2}&=2.489\times10^{-6}\ \text{s}^2,\\[4pt]\frac{\mathrm dP}{K}=12.64\times2.489\times10^{-6}&=3.15\times10^{-5}\ \text{N}\cdot\text{kg}=3.21\times10^{-3}\ \text{gf}\cdot\text{kg}.\end{aligned} \tag{4.8}$$\(K\) has not been measured yet (Log 9). For illustration only: if the rotor assembly shakes like 67 g of mass (\(K = 15\ \text{kg}^{-1}\)), then \(\mathrm dP \approx +0.048\ \text{gf}\).
Rotor orbit for the same illustration: from (4.3) with \(K'\approx 0\), the rotor orbits with radius \(|\mathbf u| = KA/\omega^2 \approx 32\ \mu\text{m}\) at 65 rev/s. That is far smaller than \(D\), so assumption 1 holds.
Example 4.6 (a test that needs no knowledge of \(K\)). With \(K'\approx0\), (4.7) predicts a ratio between two different chops that depends only on the speeds:
$$\frac{\mathrm dP(65/85)}{\mathrm dP(75/85)}=\frac{65^{-2}-85^{-2}}{75^{-2}-85^{-2}}=2.50. \tag{4.9}$$Measuring a different ratio would mean either \(K'\) matters or the model is wrong.
The instrument and its problems
The model's signal is a few hundredths of a gram-force. This log covers how the rig turns force into numbers, how small a change it can resolve, and what went wrong on the way.
The reading model
The amplifier outputs integer counts. Over the small range used here the load cell is linear:
$$r = s\,P + b + n(t), \tag{5.1}$$where \(s\) is the scale in counts per gram-force (unknown until calibration, Log 9), \(b\) is an offset that includes the large static magnet force, and \(n(t)\) is noise. Results are reported in counts until \(s\) is measured.
Noise and averaging
With the motor off, the reading wanders by about 4 counts over 10 seconds. If readings within a block are independent with standard deviation \(\sigma\), the mean of \(N\) of them has standard error
$$\sigma_{\bar r}=\frac{\sigma}{\sqrt N}. \tag{5.2}$$Long blocks (many readings at each speed) shrink the error. Quadrupling the block length halves it. Blocks are summarized by their median rather than their mean, because a single bad reading can't drag a median far.
Speed
The Hall sensor gives \(n_p\) pulses per revolution. Counting \(N_p\) pulses in a time \(\Delta t\) gives
$$f=\frac{N_p}{n_p\,\Delta t},\qquad \omega=2\pi f. \tag{5.3}$$Problem 1: the motor was corrupting the readings
Electrical noise from the motor drive got into the HX711. That showed up as three fault types: readings at about half value (the amplifier's gain switching), the same value repeated (frozen output), and timeouts. After several fixes, about 1% of readings are still rejected.
Problem 2: the firmware only ran while reset was held
The board only ran while its reset button was held down. The firmware now starts on power-up and runs continuously, which made long automatic test sequences possible.
Problem 3: the rule for discarding readings
Definition 5.1 (fault-only rejection). A reading is discarded only if the instrument failed: a timeout, an exact repeat of a frozen value, or a gain glitch. It is never discarded because of its size.
Remark 5.2 (why not clip outliers?). Suppose you expect \(\mu_0\), the true mean is \(\mu\neq\mu_0\), and you keep only readings inside \([\mu_0-k,\ \mu_0+k]\). The kept readings are cut off more on the side away from \(\mu_0\), so their mean moves toward \(\mu_0\). The filter manufactures agreement with the expectation. Rejecting only on instrument faults avoids this, because the decision never looks at the value.
Earlier sessions (Oct 11–15)
- Noise floor. With the motor off, single readings scatter by about 25 counts. A 10 s average has a standard error of about 3 counts, and the reading drifts by about 2–3 counts per minute.
- Speed sensor. A pickup coil sees the rotor clearly: its signal has one strong line at the spin frequency. That is the speed used from Oct 12 on.
- At a 2.5 in gap. No speed dependence within about ±40 counts. That is expected: the model predicts a far smaller effect there.
- At a 0.8 in gap. Attempts were stopped: the motor mount broke at full power, the motor overheated, and the rotor stalled against the test magnet's pull.
- New motor and interference fixes (Oct 15). Before the fixes, the amplifier gave about 2 good readings per second with the motor on. After them, about 10.
Method: speed chop and flip test
Log 3 showed that the static forces are hundreds of times larger than the signal. Log 5 showed the reading drifts. This method removes both, using differences that are proved below to cancel them.
Definition 6.1 (chop estimators). Let \(\bar r_{A_1},\bar r_B,\bar r_{A_2}\) be block medians at speeds \(\omega_A,\omega_B,\omega_A\), centred at times \(t_0-T,\ t_0,\ t_0+T\). Define
$$\mathrm dP_{\text{plain}}=\bar r_{A_1}-\bar r_B,\qquad \mathrm dP_{ABA}=\tfrac12\big(\bar r_{A_1}+\bar r_{A_2}\big)-\bar r_B. \tag{6.1}$$Proposition 6.2 (A–B–A cancels linear drift). If the reading is \(r(t)=sP(\omega(t))+b+c_1t+c_2t^2+n(t)\), then, ignoring noise,
$$\begin{aligned}\mathrm dP_{ABA}&=s\big[P(\omega_A)-P(\omega_B)\big]+c_2T^2,\\ \mathrm dP_{\text{plain}}&=s\big[P(\omega_A)-P(\omega_B)\big]-c_1T+c_2(T^2-2t_0T).\end{aligned} \tag{6.2}$$Linear drift, such as a sensor slowly warming up, disappears exactly from A–B–A but stays in the plain difference. In our data the two estimators differ by up to 17 counts (Log 7), which shows the drift is real. A–B–A is the main statistic from now on.
Proposition 6.3 (what the chop keeps). The chop removes every force that does not depend on speed. What remains is
$$\begin{aligned}\frac{\mathrm dP_{ABA}}{s}=\ &\big[\Delta P(\omega_A)-\Delta P(\omega_B)\big]\\&+\big[\bar F_z(\omega_A)-\bar F_z(\omega_B)\big]\\&+\big[N(\omega_A)-N(\omega_B)\big],\end{aligned} \tag{6.3}$$where \(N\) collects non-magnetic speed-dependent effects (air, vibration, heat, eddy currents).
The static magnet force of Log 3 drops out only if it doesn't change with speed. If the rotor magnet tilts a little more at higher speed, (3.5) leaks into the result. That is why the chop alone isn't enough, and the flip test and controls exist.
Separating the three terms in (6.3)
- Flip test. Run with the north face toward the rotor, then the south face. By Corollary 4.2 and Proposition 1.3, \(\tfrac12(\mathrm dP_N+\mathrm dP_S)\) keeps \(\Delta P\) and \(N\), and \(\tfrac12(\mathrm dP_N-\mathrm dP_S)\) keeps \(\bar F_z\).
- Dummy rotor (planned). A non-magnetic copy of the rotor magnet measures \(N\) alone.
- Motor-only control. The rotor magnet is removed. This measures the motor's own contribution to \(N\).
(6.4) holds only if the north, south and dummy runs are identical apart from the change being tested: same speeds, same motor power, same temperature. Interleaving them cycle by cycle in one session is how that will be enforced (Log 9).
First results (Oct 15): the signal flips with the magnet
These were the first runs, on October 15, before pre-registration, so their numbers are exploratory: the analysis rules were applied afterwards. At a 1.12 in gap, the 65/85 rev/s chop gave about +22 counts with the north face toward the rotor and about −97 counts with the south face. The sign reverses, so most of the measured signal is odd in \(\mathbf m_t\). By Proposition 1.3, that is an ordinary magnetic effect, not the polarity-free force. All values are raw counts because \(s\) in (5.1) has not been measured. Every run is listed.
| Run | Setup | \(\mathrm dP_{ABA}\) (counts) | \(\mathrm dP_{\text{plain}}\) (counts) | Notes |
|---|---|---|---|---|
| Measurement 1 | North face toward rotor | −82.2 | −98.2 | Before the rotor magnet was refitted |
| Measurement 2 | North face toward rotor | +23.2 | +29.3 | |
| Measurement 3 | North face toward rotor | +21.2 | +38.2 | |
| Flipped 1 | South face toward rotor | −101.3 | −101.4 | |
| Flipped 2 | South face toward rotor | −91.8 | −87.5 | |
| Control 1 | Rotor magnet removed | −68.2 | −63.9 | First control run; noisy |
| Control 2 | Rotor magnet removed | +1.3 | +3.0 | |
| Control 3 | Rotor magnet removed | −3.2 | −2.5 | |
| Control 4 | Rotor magnet removed | −11.3 | −7.9 |
In short: spinning the rotor faster changes the force on the test magnet, but flipping the test magnet flips that change. So these first runs mostly show an ordinary magnet force from how the rotor magnet sits. Log 8 repeats the test properly.
Applying (6.4) to these runs
Average the two runs taken after the refit in each orientation:
$$\overline{\mathrm dP}_N=\tfrac12(23.2+21.2)=22.2,\qquad \overline{\mathrm dP}_S=\tfrac12(-101.3-91.8)=-96.6\ \text{counts}. \tag{7.1}$$ $$\hat E=\tfrac12(22.2-96.6)=-37.2\ \text{counts},\qquad \hat O=\tfrac12(22.2+96.6)=+59.4\ \text{counts}. \tag{7.2}$$There is no dummy run yet, so \(\hat E\) here still contains \(N\).
What is established
A speed-dependent force exists. With both magnets in place, \(|\mathrm dP|\) is 21 to 101 counts. With the rotor magnet removed, it is 1 to 11 counts in three of the four controls. The first control, at −68.2, is flagged as noisy and still listed.
It is mostly odd in \(\mathbf m_t\). \(|\hat O|\approx 59\) counts, compared with \(|\hat E|\approx 37\).
It depends on how the rotor magnet sits. Refitting the rotor magnet moved the north-facing result from −82.2 to about +22 counts. That fits a mounting-dependent odd term such as the tilt in (3.5).
The motor load depends on polarity. At 85 rev/s the motor needed 81–82% drive with the north face toward it and 53–55% with the south face. At 65 rev/s it was 58–60% versus 45% or less.
What is not established
\(\hat E\) is not yet a valid estimate of \(\Delta P\). The motor ran at different power in the two orientations, which breaks the condition under (6.4) that the runs be identical apart from the flip. The scale \(s\), its sign, and \(N\) are all unmeasured. So there is no claim yet about a polarity-free force, its size in grams, or its direction.
Pre-registered flip runs (Oct 18–19): the speed effect is real and repeatable
Over one night we ran eight speed chops at a 1.12 in gap: four with the test magnet's south face toward the rotor, then four with the north face. The rules for every run were written to a file before it started: 65/85 rev/s, 15 s halves, the first 7 s of each half discarded, 5 cycles, alternating A–B and B–A order, and a 10-minute motor cool-down between runs. Readings were rejected only for instrument faults, and no model corrections were applied. All values are raw load-cell counts. The scale \(s\) is still not calibrated.
| Run | Face toward rotor | Started | Low speed | High speed | \(\mathrm dP_{ABA}\) (counts) | Recheck |
|---|---|---|---|---|---|---|
| S1 | South | Oct 18, 21:36 | 67.5 rev/s, 46% | 86.5 rev/s | −95.5 ± 5.6 | −99.1 |
| S2 | South | Oct 18, 21:49 | 68.5 rev/s, 45% | 88.2 rev/s | −104.1 ± 10.6 | −106.0 |
| S3 | South | Oct 18, 22:02 | 67.3 rev/s, 45% | 87.2 rev/s | −106.6 ± 8.8 | −106.9 |
| S4 | South | Oct 19, 00:29 | 65.1 rev/s, 45% | 89.2 rev/s | −85.8 ± 4.4 | −88.4 |
| N1 | North | Oct 19, 00:43 | 63.0 rev/s, 56% | 84.9 rev/s | +91.9 ± 5.3 | +95.2 |
| N2 | North | Oct 19, 00:56 | 61.7 rev/s, 55% | 83.5 rev/s | +57.2 ± 13.2 | +50.9 |
| N3 | North | Oct 19, 01:09 | 60.6 rev/s, 55% | 85.6 rev/s | +101.6 ± 4.6 | +104.6 |
| N4 | North | Oct 19, 01:23 | 61.6 rev/s, 53% | 85.9 rev/s | +119.6 ± 4.8 | +121.8 |
Splitting the result with (6.4)
Average the four runs of each face. The error is the scatter between runs divided by \(\sqrt4\):
$$\overline{\mathrm dP}_S=-98.0\pm4.7,\qquad \overline{\mathrm dP}_N=+92.5\pm13.1\ \text{counts}. \tag{8.1}$$ $$\hat E=\tfrac12\big(\overline{\mathrm dP}_N+\overline{\mathrm dP}_S\big)=-2.8\pm7.0,\qquad \hat O=\tfrac12\big(\overline{\mathrm dP}_N-\overline{\mathrm dP}_S\big)=+95.3\pm7.0\ \text{counts}. \tag{8.2}$$The error on a half-sum or half-difference of two independent averages is \(\tfrac12\sqrt{\sigma_N^2+\sigma_S^2}=\tfrac12\sqrt{13.1^2+4.7^2}\approx 7.0\) counts.
In short: the rig measures a real, repeatable change in the force on the test magnet when the rotor speed changes: about 100 counts, the same sign in all four runs of each face, and many times larger than the motor-only controls. Flipping the test magnet flips that change. The part that would push the same way whichever face points at the rotor is zero to within about ±17 counts at this gap.
What is established
The speed-dependent force is real and measurable. All eight pre-registered runs give a change of 57–120 counts between the two speeds. Three of the four motor-only controls in Log 7 give 1–11 counts. The pooled results have errors of 5–13 counts.
It reverses with polarity. South face: −98 ± 5 counts. North face: +93 ± 13 counts. By Proposition 1.3, a force that reverses is an ordinary magnetic force.
No polarity-free part is detected. \(\hat E = -3 \pm 7\) counts, so any speed-dependent push that ignores polarity is smaller than about 17 counts (two error bars) at this gap and speed pair.
The polarity-dependent part changes between days. The north-face result was about +22 counts on Oct 15 and +93 on Oct 18–19. The south-face result stayed near −97. That fits a built-in offset of the rotor magnet that shifts between sessions. Our room temperature swings from hot to near freezing between sessions, which can move printed parts and change both magnets' strength, so it is a likely cause. It wasn't logged, so this is not yet tested.
Our independent recheck agrees. Recomputing every run from the raw log with our own script, using the same instrument-fault rules, gives \(\hat E = -3.5 \pm 7.9\) and \(\hat O = +96.6 \pm 7.9\) counts. That matches the dashboard to within about 1 count.
What is not established
Matched conditions. The low speed wasn't actually held at 65 rev/s: it ran at 65–68 with the south face and 61–63 with the north face, sometimes wandering by 5–11 rev/s within a half. The motor also needed 53–56% drive with the north face and 45–46% with the south face. The faces were run in blocks (all south first, then all north), so anything that drifted through the night lines up with the flip.
Size in grams, and \(K\) and \(K'\). The scale is uncalibrated. The model of Log 4 predicts a polarity-free part of about 5–10 counts for \(K = 15\ \text{kg}^{-1}\). The eddy-current model predicts one of about −7 to −10 counts at the guessed scale, which is also polarity-free and of opposite sign. The current ±7 count error can't separate the two yet.
Videos of every run
Screen recordings of the live dashboard. The top trace is the force and the second is the rotor speed, so you can watch the force move each time the speed switches. The longer videos include the 10-minute cool-down.
Every raw log, event log and run file is in the dataset; its README explains each folder.
Improving the setup: cleaner flip comparisons to find \(K\) and \(K'\)
The pre-registered runs in Log 8 showed the method works and is repeatable, but they still weren't a clean comparison of the two faces. This log is the plan to fix what is left. The setup is changed so that north, south and dummy runs differ only by the flip. The runs are repeated enough times to beat the noise. Then \(K\) and \(K'\) are fitted to the polarity-free part.
What still needs fixing after the October 18–19 runs
- Different motor power. The motor still needs more drive with the north face toward the rotor: 53–56% at the low speed, against 45–46% with the south face. Equation (6.4) needs the runs to be identical apart from the flip.
- Speed not held at the low speed. With the south face toward the rotor the motor sat at its 45% minimum power and ran at 65–68 rev/s instead of 65. With the north face it ran at 61–63. Within a half, the speed sometimes wandered by 5–11 rev/s.
- Room temperature. Our room swings from hot to near freezing between sessions, and temperature was not logged. It can change the load cell, the strength of both magnets, and the fit of the printed parts that set the rotor magnet's offset. The north-face result moved from about +22 counts (Oct 15) to about +93 (Oct 18–19).
- Faces run in blocks, not interleaved. All four south runs came first (21:36–00:33), then all four north runs (00:43–01:26). Anything that drifted through the night, such as room temperature, lines up with the flip.
- Unknown scale. \(s\) in (5.1) hasn't been measured, so counts can't become grams.
Changes to the setup
- Calibrate first: measure \(s\). Hang known masses \(m_i\) on the load cell and record the readings \(r_i\). The least-squares slope of \(r_i = s\,m_i + b\) is $$s=\frac{\sum_i(m_i-\bar m)(r_i-\bar r)}{\sum_i(m_i-\bar m)^2}. \tag{9.1}$$
- A flip holder. A keyed, 3D-printed cup holds the test magnet either way round at exactly the same position, so it can be flipped without unclamping the load cell or touching the rotor. Check the gap with a gauge after every flip. Any change between runs other than the polarity leaks into \(\hat E\).
- Lock the rotor magnet. Fix it so it can't shift in its seat, mark its angle, and never refit it during a series. If it must come out, start a new series. One refit moved the result by about 100 counts, far more than the signal being hunted.
- Hold speed by feedback and log the power. The Hall sensor closes the speed loop, so both orientations run at the same \(\omega\). Drive power is recorded for every block, so a power difference between orientations is shown in the results, not hidden.
- Separate the motor from the load-cell frame. Give the motor its own base, or isolate it with rubber mounts, so vibration can't reach the load cell through a shared frame. This shrinks the non-magnetic term \(N\) in (6.3) instead of only measuring it.
- A dummy rotor. A non-magnetic cylinder with the same size and mass as the rotor magnet (brass, or a printed shell with non-magnetic weight). It reproduces air flow and imbalance vibration but no magnetic force, so it measures \(N\) directly.
- The same warm-up every time. Run the motor for a fixed time before the first block of every session, so heating is the same for every orientation.
- Log the temperature. A small temperature sensor at the load cell, recorded with every reading. Then a day-to-day difference can be checked against temperature instead of guessed.
- Fix the low-speed floor. Lower the motor's minimum power, or raise the low speed, so the speed hold actually holds both faces at the same speed.
- Test the offset directly. Rotate the rotor magnet 180° in its holder and repeat the flip runs. If a built-in offset causes the polarity-dependent part, its sign should reverse.
The run plan
All of this is written into a file before the session starts, and the analysis may only use what is in that file (Log 8).
- Speeds. Three chops share a reference speed: 65/85, 70/85 and 75/85 rev/s. That gives three independent differences for two unknowns, \(K\) and \(K'\), with one left over as a check.
- Order. Within each chop, cycles run as N, S, D, D, S, N, and so on: north, south, dummy, then the mirror image. Each cycle is one A–B–A chop.
- Repeats. \(n = 10\) cycles of each orientation per chop.
- Fixed rules. A 7 s settling discard, fixed block length, the 62% heat stop, and the fault-only filter of Definition 5.1.
Mirroring the order (N S D D S N) cancels slow drift between cycles, by the same argument as Proposition 6.2. A drift that rises steadily through the sequence adds as much to the early cycles of each kind as it does to the late ones, so it drops out of the averages.
How many runs are enough
Log 8 gives a real estimate of the run-to-run scatter. The four south runs have a standard deviation of 9 counts and the four north runs 26 counts, so
$$\sigma_{\text{run}}\approx 15\ \text{counts (between 9 and 26)}. \tag{9.2}$$With \(n\) cycles of each kind, the error on (6.4) is
$$\sigma_{\hat E}=\sigma_{\text{run}}\sqrt{\frac{1}{4n}+\frac{1}{4n}+\frac{1}{n}}=\sigma_{\text{run}}\sqrt{\frac{3}{2n}}. \tag{9.3}$$For \(\sigma_{\text{run}} = 15\) counts and \(n = 10\), \(\sigma_{\hat E}\approx 6\) counts per chop. The illustration in Example 4.5 (\(K = 15\ \text{kg}^{-1}\)) predicts 0.048 gf, which is 5–10 counts for a scale of 100–215 counts/gf: about one to two error bars. Seeing it clearly needs either more runs or less scatter, which is why the temperature log and the speed fix come first.
Our theoryFitting \(K\) and \(K'\)
For each chop \(i\), (4.4) predicts the polarity-free signal in counts:
$$E_i(K,K')=s\,G_1\left[\frac{1}{\omega_{A,i}^2/K-K'}-\frac{1}{\omega_B^2/K-K'}\right]. \tag{9.4}$$Step 1: the simple fit with \(K'=0\). Then \(E_i = K\,x_i\) with \(x_i = s\,G_1\big(1/\omega_{A,i}^2-1/\omega_B^2\big)\), a straight line through zero. The weighted least-squares slope and its error are
$$\hat K=\frac{\sum_i x_i\hat E_i/\sigma_i^2}{\sum_i x_i^2/\sigma_i^2},\qquad \sigma_{\hat K}=\Big(\sum_i x_i^2/\sigma_i^2\Big)^{-1/2}. \tag{9.5}$$| Chop | \(1/\omega_A^2-1/\omega_B^2\) (s²) | \(\mathrm dP/K\) (gf·kg) |
|---|---|---|
| 65/85 rev/s | \(2.489\times10^{-6}\) | \(3.21\times10^{-3}\) |
| 70/85 rev/s | \(1.664\times10^{-6}\) | \(2.14\times10^{-3}\) |
| 75/85 rev/s | \(0.997\times10^{-6}\) | \(1.29\times10^{-3}\) |
Step 2: the full fit. Find the \(K\) and \(K'\) that minimize
$$\chi^2(K,K')=\sum_{i=1}^{3}\frac{\big[\hat E_i-E_i(K,K')\big]^2}{\sigma_i^2}. \tag{9.6}$$Three chops and two unknowns leave one degree of freedom. If the model fits, \(\chi^2\) should come out near 1. A much larger value means the data don't follow (4.4).
Pairing every speed with the same reference (85 rev/s) keeps the three differences independent. With 65/75, 75/85 and 65/85, the third chop is just the sum of the other two, \(\mathrm dP(65/85)=\mathrm dP(65/75)+\mathrm dP(75/85)\), so it adds no new information about \(K\) and \(K'\).
What counts as a result
- A detection: \(\hat E\) is more than 3 error bars from zero, has the same value when the run order is reversed, and the fit in (9.6) passes. Then \(\hat K\) and \(\hat K'\) are reported with their errors.
- No detection: \(\hat E\) is consistent with zero. That is still a result: an upper limit \(K \lt 2\sigma_{\hat E}/x_1\) from the 65/85 chop, which says how stiff the mount would have to be for the effect to hide.
- Either way every cycle is published, including the ones that look wrong.
Join the conversation
We'd rather be corrected early than be wrong in public later. If you see a flaw in a proof, a gap in the method, or know of a related measurement, send it. Students, teachers, engineers and skeptics are all welcome.
Questions we'd like help with
- What is the best way to separate motor vibration from a real magnetic force on a load cell?
- How would you measure a tilt of a fraction of a degree in a magnet spinning at 5,000 rpm?
- Step (iv) of Proposition 4.1 assumes each \(f_h\) has a phase that doesn't change with distance. How far off the axis does that stay true?
- Has anyone measured the force on a clamped magnet next to a spinning one, rather than a floating one?
- What would convince you that a polarity-free force is real and not an artifact?
Message sent. Thank you. If you left an email, we'll reply there.
You can also email Hexapole6@proton.me or Eodymy1@proton.me, or comment on any video on our YouTube channel.