Магнитная левитация на Arduino Nano: детали, схема и код (PID и без)
Компоненты и материалы
| Компонент | Количество | Примечание |
|---|---|---|
| Arduino Nano R3 | 1 | Можно любой Arduino, но шилд рассчитан под Nano |
| Электромагнит 12В, диаметр 25 мм | 1 | |
| Линейный датчик Холла 49E | 1 | Не используйте ключевой датчик Холла (switch) — только линейный! |
| Дарлингтонский мощный транзистор TIP120 | 1 | Для управления электромагнитом |
| Резистор 1 кОм | 1 | База транзистора |
| Диод 1N4007 (высоковольтный, импульсный) | 1 | Защита от обратного ЭДС электромагнита |
| Блок питания 12В 1А | 1 | Для электромагнита |
| Бредборд | 1 | |
| Таковые кнопки 12 мм | 2 | Регулировка точки левитации (+/-) |
| Перемышки (набор) | 1 |
Программное обеспечение
- Arduino IDE
О проекте
Устройство для магнитной левитации на базе Arduino. Корпус можно напечатать на 3D-принтере или собрать без него.
3D-модели:
- Корпус левитатора (легко печатается, крепится на клей, без винтов): Thingiverse 1392023
- Шилд для Arduino Nano: Thingiverse 1392530 или заказать готовый: OSH Park


Важные моменты
- Датчик Холла устанавливается в нижнюю часть наконечника (файл top_sensor.stl) — см. фото.
- Расстояние от датчика Холла до электромагнита — минимум 5 мм.
- Можно использовать другие линейные датчики Холла (не ключевые!).
- Обязательно неодимовые постоянные магниты (обычные ферритовые — не сработают).
- Тяжелые объекты левитируют стабильнее.

Подробности и советы в моих «Makes» на Thingiverse:
- Левитатор 3D-печатный: make:201394
- Шилд для Arduino Nano: make:201420
Код
Две версии прошивки: простая (без PID) и с PID-регулятором для более стабильной левитации.
Levitator.ino — простая версия (без PID)
//=========================================================|
// Ekobots Innovation Ltda - www.ekobots.com.br |
// Juan Sirgado y Antico - www.jsya.com.br |
//---------------------------------------------------------|
// Program Magnetic Levitator - 2016/02/06 |
// All rights reserved 2016 |
//=========================================================|
int anaPin = 1; // Аналоговый вход A1 (датчик Холла)
int digPin = 5; // Цифровой выход D5 (управление транзистором)
int subPin = 7; // Кнопка «-» (понижение точки левитации)
int addPin = 8; // Кнопка «+» (повышение точки левитации)
int anaVal = 0; // Значение с датчика Холла
boolean digVal = 0; // Состояние электромагнита
int levVal = 228; // Точка левитации (подбирается экспериментально)
int dlyVal = 250; // Задержка мкс между циклами
void setup() {
Serial.begin(57600);
Serial.println("Levitator by JSyA");
Serial.println("Starting...");
pinMode(digPin, OUTPUT);
pinMode(subPin, INPUT_PULLUP);
pinMode(addPin, INPUT_PULLUP);
Serial.println("Started.");
}
void loop() {
anaVal = analogRead(anaPin); // Чтение магнитного поля
// Регулировка точки левитации кнопками
if (digitalRead(addPin) == LOW) {
levVal++;
value_log();
delay(250);
}
if (digitalRead(subPin) == LOW) {
levVal--;
value_log();
delay(250);
}
// Простейшее управление: если поле ниже точки — включаем магнит, иначе выключаем
if (anaVal < levVal) digVal = LOW;
else digVal = HIGH;
digitalWrite(digPin, digVal);
delayMicroseconds(dlyVal);
}
void value_log() {
Serial.print("anaVal=["); Serial.print(anaVal); Serial.print("]-");
Serial.print("digVal=["); Serial.print(digVal); Serial.print("]-");
Serial.print("levVal=["); Serial.print(levVal); Serial.println("];");
}
//=========================================================|
Levitator_PID.ino — версия с PID-регулятором
//=========================================================|
// Ekobots Innovation Ltda - www.ekobots.com.br |
// Juan Sirgado y Antico - www.jsya.com.br |
//---------------------------------------------------------|
// Program Magnetic Levitator PID - 2016/10/06 |
// All rights reserved 2016 |
//=========================================================|
int anaPin = 1;
int digPin = 5;
int subPin = 7;
int addPin = 8;
int anaVal = 0;
int digVal = 0;
int levVal = 262;
int dlyVal = 10;
float timVal = 0;
// PID параметры
float setpoint = 0;
float measured_value = 0;
float output = 0;
float integral = 0;
float derivative = 0;
float error = 0;
float previous_error = 0;
float dt = 0.1;
float Kp = 1.0;
float Ki = 0.1;
float Kd = 0.01;
void setup() {
Serial.begin(57600);
Serial.println("Levitator by JSyA");
Serial.println("Starting...");
pinMode(digPin, OUTPUT);
pinMode(addPin, INPUT_PULLUP);
pinMode(subPin, INPUT_PULLUP);
setpoint = levVal;
Serial.println("Started.");
}
void loop() {
anaVal = analogRead(anaPin);
// PID расчет
measured_value = anaVal;
error = setpoint - measured_value;
integral = integral + error * dt;
derivative = (error - previous_error) / dt;
output = (-Kp * error) + (-Ki * integral) + (-Kd * derivative);
previous_error = error;
// Преобразование выхода PID в ШИМ (0-255)
digVal += output;
if (digVal < 0) digVal = 0;
if (digVal > 255) digVal = 255;
analogWrite(digPin, digVal);
// Лог каждые 500 мс (раскомментируйте при необходимости)
// if ((millis() - timVal) > 500) { value_log(); timVal = millis(); }
// Регулировка точки уставки кнопками
if (digitalRead(addPin) == LOW) {
setpoint++;
value_log();
delay(250);
}
if (digitalRead(subPin) == LOW) {
setpoint--;
value_log();
delay(250);
}
delayMicroseconds(dlyVal);
}
void value_log() {
Serial.print("anaVal=["); Serial.print(anaVal); Serial.print("]-");
Serial.print("digVal=["); Serial.print(digVal); Serial.print("]-");
Serial.print("setpoint=["); Serial.print(setpoint); Serial.println("];");
}
//=========================================================|
Схемы (Fritzing)

Производственный процесс
- Ретро-часы на индикаторах Numitron с Arduino: просто, надёжно, экономно
- Датчик CO2 K30: мониторинг качества воздуха в реальном времени на Arduino
- Устройство для общения глухосліпых людей с помощью 1Sheeld и Arduino
- Умная копилка: управление монетоприёмником на Arduino Nano
- Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
- Интеграция ёмкостного сканера отпечатков DFRobot с Arduino или ESP8266
- Интерактивный HMI-проект на Nextion с Arduino Mega и датчиками
- Роботизированная рука 6 степеней свободы на Arduino Mega с управлением через Nunchuk
- Магнитная левитация на отталкивании с Arduino: Простая схема и DIY-руководство
- Измерение солнечной радиации на Arduino UNO с Ethernet Shield