Skip to content

MagnetoShield

erik1392 edited this page Nov 12, 2023 · 101 revisions

Contents

Introduction
Application programming interface
   Initialization and calibration
   Input
   Output
   Auxiliary functions
Examples
   Feedback control
   System identification
Detailed hardware description
   Circuit design
   Parts
   PCB
About
  Authors

Legacy documentation

Release 1: (MagnetoShield R1)
Release 2: (MagnetoShield R2)

Introduction

The MagnetoShield belongs to the family of control engineering education devices for Arduino that form a part of the AutomationShield project and presents a low-cost miniature magnetic levitation experiment. The device uses a solenoid electromagnet to generate a magnetic force which lifts up the permanent magnet. The goal is to control the position of the levitating magnet indirectly measured by a Hall effect sensor, which creates a simple single-input single-output (SISO) feedback loop. Due to its complexity and fast dynamics, MagnetoShield is great tool for learning and implementation of feedback control algorithms. The hardware is low-cost and small, making it ideal for take-home experiments or long-term student projects.

MagnetoShield

Application programming interface

The basic application programming interface (API) serving the device is written in C/C++ and is integrated into the open-source AutomationShield Arduino library. This library contains hardware drivers and sample exercises for control systems engineering education. All functionality associated with the MagnetoShield is included in the MagnetoShield.h header, which contains the MagnetoClass class that is constructed by default as the MagnetoShield object. The functions specific to this shield mostly perform input/output peripheral communication.

The summary of basic functions and the illustration below should get you started quickly:

  • Output (sensor): MagnetoShield.sensorRead();
  • Output (auxiliary sensor): MagnetoShield.auxReadCurrent();
  • Input (actuator): MagnetoShield.actuatorWrite();

magneto_actsens

Initialization and calibration

The following subsections describe the methods used to access the input and output of the MagnetoShield. Note that before you begin an experiment you must initialize the hardware by calling the

MagnetoShield.begin();

method, which sets the analog reference to external. This way the 3.3V rail connected to the reference pin acts as the maximum for the 10-bit built-in ADC ensuring compatibility with non-AVR boards. In addition to this, the method calls the Wire library for the I2C bus functionality required for the DAC chip.

It is recommended to start the applications by selfcalibrating the device, by calling the

MagnetoShield.calibration();

method, which measures the output of the Hall effect sensor with the magnet off and on full power. The calibrated ADC levels can be accessed by the getMinCalibrated() and getMaxCalibrated() methods. Direct distance measurement is not available on this device and it is not even needed for simple feedback control, but first-principle models require a distance signal. The distance of the permanent magnet from the solenoid is known at the two extremes; e.g. when it rests on the surface of the PCB directly over the sensor and when it hits the roof of the enclosure. Let us assume that there is a power relationship between the magnetic flux measured on the Hall sensor and the distance at time , so that

The calibration routine thus performs a two-point calibration searching for constants and based on this idea. In case you don't run the calibration routine, default values are given as well.

Input

For general feedback control experiments, it does not actually matter what units we used to power the solenoid: it may be percentage of full power, voltage, current, etc. However, if we wish to use first-principle models or model-based control, the input to the solenoid shall be

MagnetoShield.actuatorWrite(u);

which applies the input voltage ranging from 0 to 12V at the given sample.
The method uses the results of an offline multi-point calibration procedure described in this paper. Alternatively, input to the solenoid can be also sent by employing the actuatorWritePercents() method.

Output

The distance of the permanent magnet from the solenoid can be determined by calling

y=MagnetoShield.sensorRead()

method that returns the distance in millimeters as a floating point number. The method reads the ADC levels from the Hall sensor and calls adcToGauss(), converting the levels to voltage related to the 3.3V reference, removing the 2.5V bias for zero magnetic flux and multiplying by the manufacturer given sensitivity of 1.3mV/G. The magnetic flux is then recalculated by the above-mentioned two-point calibration implemented in the gaussToDistance() method. Sensor readings can be acquired in percents, by employing the sensorReadPercents() methods as well.

Auxiliary functions

In addition, there are some non-essential auxiliary functions provided in the device API. First of these is the method reading the current sensor that is useful when one considers a first-principle model of the process. The current sensor is accessed by

i=MagnetoShield.auxReadCurrent();

which returns the current reading in milliamperes. The method polls for ADC levels, which are converted to voltage and this in turn to current by a proportional gain defined by the current sensor chip.

The external reference potentiometer is read by

r=MagnetoShield.referenceRead();

which returns a floating point number in the range of 0–100 (%).
Finally, calling

vin=MagnetoShield.auxReadVoltage();

will return the supply voltage of the 12V rail, being mainly useful for self-diagnostics.

Examples

Feedback control

For a start you may want to experiment with a closed-loop control of the levitating ball's position by the proportional–integral–derivative controller (PID) algorithm.

The implementation of PID control in C/C++ is demonstrated by a worked example, which makes use of the interrupt-driven sampling subsystem of the AutomationShield library, and also its built-in input-saturated absolute-form PID method with integral windup handling by clamping. You may select wheter the reference is given by the potentiometer or you want to test a predetermined reference trajectory. The progress of the experiments can be followed in real time through the Serial Plotter of the Arduino IDE or logged in MATLAB.

magneto_pid

The above figure shows a typical and robustly repeatable closed-loop experiment. At the beginning of the experiment, the permanent magnet laying at rest is quickly pulled up close to the level of the solenoid, then settles on the first reference level r=14mm with some overshoot (upper graph). Other reference levels are followed closely. The levitation including the reference changes are obvious and visually engaging. The lower graph shows the corresponding input signal. The nonlinear nature of its closed-loop dynamics can be hypothetically further improved by better—possibly natively nonlinear—control methods.

Model predictive control

Worked examples for MPC on the MagnetoShield provided with the AutomationShield library make use of two distinct development lines of the same control concept: processor-intensive implicit optimization performed online and memory-critical explicit MPC (EMPC). The µAO-MPC package for implicit MPC and the Multi-Parametric Toolbox for explicit MPC were used.

In order to minimize the computational burden, MPC examples are formulated with input-only constraints (0–10 V) and do not contain a stabilizing terminal set.

The above figure demonstrates the EMPC tracking of a reference distance, implemented in Simulink and deployed on the Arduino Due.

System identification

Input-output experiments for data gathering can be easily launched, displayed and logged using the Arduino IDE. The system is open-loop unstable, therefore experimental data have to be obtained in a closed loop using a feedback controller. A worked C/C++ example initializes the sampling and PID control subsystems from the AutomationShield library. A pre-tuned PID controller is used to follow a reference output sequence, each setpoint for a thousand samples. In order to create a rich probe signal, the inputs computed by the controller are superimposed by a 1.5V pseudorandom signal generated in the device. The resulting input and corresponding output are logged.

After you gather enough data sufficient for system identification, you may try to fit a model to the experimental response. A comprehensive background on mathematical modeling of the magnetic levitation experiment based on mechanical and electrical first principles can be found in our paper.
A worked MATLAB example takes the experimental data and searches for the unknown parameters of the system's transfer function. First, an initial guess of the model is built based on laboratory measurements. This initial model is then fitted to the experimental data using the MATLAB’s System Identification Toolbox. After several iterations the identification procedure converges reliably to a solution. As shown below, the resulting transfer function provides a decent 83.3% match to the measured input-output data.

magneto_ident

Accuracy of the identified model can be verified in a closed-loop simulation of the model response in the time domain. As it is evident, the linear model over-values the random noise in the probe signal, which in reality is much less stated.

magneto_ident2

Another worked MATLAB example in turn assumes a linearized state-space model parametrized with five unknown parameters, initialized same as in the previous example. The only difference here is, that the current sensor is used to gather dynamic current measurements at each sample, as current represents one of three dynamic states of the system.
The following figure shows the comparison of the model outputs with experimental measurements in the frequency-domain. The model fit to measurement is 82% for the position measurement and 87% for the current signal, suggesting an adequate model that is suited for simulation, estimator and observer design, and model-based control.

magneto_freq

More details on the identification procedure can be found here.

Detailed hardware description

The MagnetoShield is an open hardware product, you are free to make your own device. If you come up with improvements, please let us know so we can improve our design as well. The discussion below should help you to improvise a similar setup for experimentation on a breadboard or perforation board. You may even order a professionally made PCB by a PCB fabrication service.

The schematic representation of the MagnetoShield is shown in the figure below. The position of a disc-shaped levitating permanent magnet (a) is sensed indirectly by a Hall effect sensor (b). The analog voltage signal from the sensor is passed through an analog-to-digital converter (ADC) (c) to the microcontroller (d). Inputs computed in the microcontroller are turned to an analog voltage signal through a digital-to-analog converter (DAC) (e) then passed to an amplification circuit (f) to the solenoid (g). A current sensor (h) is employed to gain extra insight to dynamic processes, mainly for system identification purposes.

magneto_scheme

Circuit design

The circuit schematics were designed in the Freeware version of the DIPTrace CAD software. You may download the circuit schematics for the MagnetoShield from here.

magneto_circuit

Let us start with the input signal path. The microcontroller (U1)—for example, an atMega 328P in case of an Arduino Uno—is connected to an NXP Semiconductors PCF8591T external 8-bit DAC chip (U3) via the I2C bus, pulled up to 5V (R1,R2). The voltage output of the DAC is then boosted by a rail-to-rail operational amplifier (U5.1) connected to 12 V via the VIN pin. This means that an external power supply connected to the barrel- jack on the prototyping board is required to run the device. The operational amplifier is connected in a non-inverting configuration such, that the feedback loop follows the voltage passing through the electromagnet (L1), while its gain may be calibrated by the surface-mounted trimmer in the feedback branch (R10) and a fixed resistor in the grounding branch (R3). The trimmer shall be calibrated to provide 10.0 V through the electromagnet at DAC saturation, which may be achieved with a simple multi-meter or an oscilloscope. This hardware design assumption is later utilized in the software interface. A transistor ( Q1) powered from the high-side 12 V rail is driven through the output of the op-amp, ultimately supplying the electromagnet (b). A generic protection diode (D1) is connected anti-parallel to the electromagnet in order to prevent possible damage from back electromotive force (EMF) during transients. The electromagnet leads are connected to the underlying PCB via a corresponding pair of two-pin male and female headers.

Let us continue with the output path. MagnetoShield utilizes indirect distance sensing by an Allegro MicroSystems A1302KUA linear Hall effect sensor (U2). Since the magnetic levitation experiment is designed to be compatible with ARM Cortex M-series boards as well, a 3.3V Zener diode is used to protect analog inputs from overvoltage. The hall sensor is bipolar and is supplied from the 5V rail, therefore an incidental swap of the magnet polarities could result in an overvoltage on these devices. Other sensing circuits use the same type of Zener clippers (D3D5) as well. The output of the Hall sensor is connected directly to the Arduino, which contains built-in ADC peripheries.
Although a non-essential functionality, sensing the current passing through the electromagnet may aid mathematical modeling of the system, providing data for estimation and system identification tasks. The electromagnet is powered through a precise shunt resistor with a known resistance (R8). This differential input signal is then amplified using a Texas Instruments INA169 high-side measurement current shunt monitor (U4) with a gain configured by a precise resistor (R9). The output of this amplifier is then fed to the ADC of the Arduino, which is also protected by the aforementioned Zener clamp.

Note that there are also simple auxiliary circuits extending the functionality of the MagnetoShield. A potentiometer (POT1) can be programmed to perform a number of roles, most notably it may supply a manually adjusted reference trajectory for position. There is a voltage divider circuit (R6,R7) that monitors supply voltage, and finally, a LED signals power to the board (D6).

Parts

To make a MagnetoShield either on a PCB or on a breadboard you will need the following parts or their similar equivalents:

Part Name Type/Value/Note PCS
3D Print 5.7g Ø1.75mm PETG filament, bright green, at 240°C (90°C bed) 1
C1,C3 Capacitor 0805, ceramic, 0.1µF 2
(h),C2 Capacitor 0805, tantalum, 10µF 1
Enclosure top clear acrylic; e.g. h=2 mm, stamped to the outer diameter of the tube 1
(m),U4 Current sensor INA149 1
(b),U3 DAC PCF8591T 1
(i),D1 Diode DO214AC 1
(j),U2 Hall sensor A1302KUA 1
Header 6×1, female, 2.54mm pitch 1
Header 8×1, female, 2.54 mm pitch 2
Header 10×1, female, 2.54mm pitch 1
(q),D2 LED 0805, red 1
Magnet NdFeB, disc, Ø8mm, h=2mm, N38 1
(e),Q2 MOSFET IRF520 1
PCB 2 layer, FR4, 1.6mm thick 1
(o),POT1 Potentiometer 10kΩ 1
(c),(f),R1,R2,R4 Resistor 10kΩ, 0805 3
(n),(p),R6,R9 Resistor 3kΩ, 0805, 0.1% 2
(p),R7 Resistor 1kΩ, 0805, 0.1% 1
(f),R3 Resistor 220Ω, 0805 1
O-Ring rubber, M12, h=1mm, e.g. Ø18mm (outer) 1
Screws polyamid, M3×8 2
Shaft ACP CA9MA9005 1
(l),R8 Shunt 10Ω, 0805, 0.1% 1
(g),L1 Solenoid 220Ω, 0805 1
Enclosure tube clear, Plexiglas XT, h=8mm, Ø10mm (inner), φ12mm (outer) 1
(k),D3–D5 Zener diode 3.3V, SOD323 3

Note that the total cost of the above components and thus of the entire MagnetoShield is no more than $9 excluding labor and postage.

The structure for holding the solenoid was designed in Autodesk Fusion 360 and printed by a Prusa I2 MK3/S 3D printer using PETG filament in 80 minutes time.

PCB

The printed circuit board has been designed in the Freeware version of the DIPTrace CAD software. The PCB is two-layer and fits within the customary 100 x 100 mm limit of most board manufacturers. The DIPTrace PCB layout and circuit schematics can be downloaded here and here, respectively, while the ready-to-manufacture Gerber files with the NC drilling instructions are available from here.

magneto_pcb magneto_pcb2

About

This shield was designed and created within a Bachelor's thesis at the Institute of Automation, Measurement and Applied Informatics (IAMAI) in 2017/2018. The Institute belongs to the Faculty of Mechanical Engineering, Slovak University of Technology in Bratislava. The thesis is available here.

Authors

  • Hardware design: Erik Mikuláš, Gergely Takács, Jakub Mihalík
  • Software design: Gergely Takács, Jakub Mihalík
  • Wiki: Martin Gulan, Erik Mikuláš, Anna Vargová and Gergely Takács