Мой первый мобильный робот на базе контроллера ESP32
Содержание:
- Вхождение в тему
- Немного о ESP32
- Особенности сборки робота на ESP32
- Программируем в Arduino IDE (ESP32 и Arduino IDE)
- Добавляем поддержку контроллера ESP32 в Arduino IDE
- Особенности программирования мобильного робота на шаговых моторах и ESP32
- Ссылка на листинги и материалы
Вхождение в тему
Вот и добрался я до нового китайского контроллера ESP32, и традиционно я решил воплотить на нем мобильного робота.
От прошлого проекта балансирующего робота на шаговых моторах мне остались 4 маломощных шаговика, которые я не смог использовать в балансирующем роботе из за недостаточной мощности.
Честно говоря, я бы еще долго раскачивался и примерялся к данному контроллеру, если бы не ребята из БХВ-Петербург, предложившие мне его освоить, вернее им импанировали контроллеры на базе ESP8266, но я уже пробовал с ним работать и выявил один непоправимый дефект, а именно ESP8266 имеет крайне мало свободных GPIO (или контактов ввода/вывода). вернее на плату разведено их достаточное количество, но когда начинаешь их использовать, выясняется, что большинство из них уже задействовано под внутренние цели контроллера и применение их не возможно или сильно ограничено.
Немного о ESP32
Микроконтроллер и управление
• Tensilica Xtensa LX6 двухъядерный (или одноядерный) 32-разрядный процессор, с тактовой частотой 160 или 240 МГц и производительностью до 600 DMIPS
• Сопроцессор с ультранизким энергопотреблением
Память: 520 КБ памяти SRAM
Беспроводная связь:
1. Wi-Fi: 802.11 b/g/N
2. Bluetooth: v4.2 BR/EDR and BLE
Периферийные интерфейсы:
• 12-разрядный АЦП до 18 каналов
• 2 × 8 бит ЦАПа
• Датчик температуры
• 4 × SPI
• 2 × I²S для интерфейсов
• 2 × I²C интерфейса
• 3 × UART
• SD / SDIO / CE-ATA / MMC / eMMC хост-контроллер
• SDIO / SPI слейв контроллер
• Ethernet MAC interface с выделенным DMA и IEEE 1588 Precision Time Protocol support
• CAN bus 2.0
• ИК дистанционное управление (передатчик / приемник, до 8 каналов)
• Возможность подключения двигателей и светодиодов через ШИМ выход
• Датчик Холла
• Аналоговый предусилитель ультра низкой мощности
Основным недостатком контроллера ESP8266 (предшественника ESP32), является урезанное до критического минимума количество выводов (9+1 аналоговый), которые можно использовать для нужд прикладной программы. Даже маленький и безобидный контроллер Arduino NANO имеет 21 двоичный порт ввода/вывода (правда два из них работают только на вход A6 и A7).
Таким образом, полноценное управление мобильным роботом с ESP8266 сильно затруднено и возможно только при добавлении некоторых костылей: раширителей портов, подчиненных контроллеров и пр.
ESP32 уже довольно хорош по части GPIO, количество общедоступных выводов достаточно для мобильного робота с системой датчиков. Появилось также множество аналоговых входов (осеня халасо). Полностью свободными и доступными для использования можно назвать 13 выводов:
GPIO 2, 4, 12, 14, 13, 15, 16, 17, 25, 25, 27, 32, 33.
Дополнительно для ввода данных можно использовать еще 4 GPIO:
GPIO 34, 35, 36, 39.
GPIO задействованные шинам SPI, i2c и т.д.:
1, 3, 5, 18, 19, 21, 22, 23
Особенностью как ESP8266 так и ESP32 является реализация аналогового ввода, в отличии от 5 вольтовых контроллеров Arduino, к которым я привык, на аналоговые входы следует подавать напряжение не выше 1 вольта. Таким образом, если от датчиков вашего робота приходит аналоговый сигнал значением от 0 до 5 вольт, он предварительно должен быть подвержен пропорциональному делению, например при помощи резистивного делителя.
Экспериментально доказано, что написанное выше для ESP32 не верно. Измерения аналоговых сигналов идут от напряжения питания и до нуля, т.е. от 3.3v до 0. Соответсвенно и пропорциональное деление рекомендуется приводить к значениям, максимум которых не будет превышать 3.3v.
Контроллер ESP32 на плате можно приобрести на известной китайской торговой площадке за 300-700 рублей (в зависимости от наличия дополнительной функциональности).
Я же заказал себе наиболее простой модуль Lolin32 lite (т.е. легкую версию). Она реализована на текстолите не очень хорошего качества, он тонкий и его слегка повело, но меня почему то это не смутило. Единственное, что мне не понравилось, это отсутствие GPIO21 но попробую обойтись и без него :-).
Особенности сборки робота на ESP32
Шаговые моторы, как я уже писал, достались мне от другого проекта вот ссылка на них моторы имеют резистивное сопротивление 26 Ом, держат шаг при токе 0.6А, стандартный шаг 0.9 градусов.
В качестве драйверов я использовал drv8825 , деление шага выставил в 4, это означает, что стандартный шаг в 0.9 градусов еще делится на 4 при помощи функций драйвера drv8825, для этого вывод драйвера (MS2) подтянут к питанию (3.3V взято от ESP32). Вывод драйвера EN можно и не подключать к контроллеру, но при этом через шаговый мотор всегда будет идти ток, что приведет к неэффективному расходыванию заряда аккумуляторов и нагреву моторов и драйверов, а так при неактивности робота моторы можно обесточивать и значительно экономить на заряде.
Контакты драйвера RESET и SLEEP нужно подтянуть к питанию контроллера. Остальное показано на схеме.
Статья находится в режиме редактирования...
Теперь по электропитанию, чтобы добиться приемлемого тока через шаговые моторы, мне пришлось использовать связку из 4-х последовательно соединенных литиевых аккумуляторов 18650, что дало напряжение около 15V, теперь моторы смогут получить ток до 0.6 А, а точнее 0.58А.
Контроллер ESP32 потребляет также не слабый ток при включенных WIFI - BT это 0.17А, поэтому использовать понижающий стабилизатор вроде KPEH5 я не стал, чтобы не переводить заряд аккумуляторов на нагрев, а поставил импульсный понижающий стабилизатор с регулировкой выхода, стабилизировав его выход на 5V. Импульсные стабилизаторы хороши тем, что имеют высокий коэффициент полезного действия до 98%. В цепь питания шаговых моторов я дополнительно установил конденсатор емкостью 1000мкФ, рассчитанный на 35V напряжения. Установка конденсатора с напряжением в 10V может привести к взрыву данного кондесатора!
Можно сэкономить и установить более простой стабилизатор например этот см.ссылку.
Корпус робота был фрезерован из 3мм фанеры на ЧПУ. Т.к. лазерный резак я еще недособрал.
Программируем в Arduino IDE (ESP32 и Arduino IDE)
Теперь перейдем к программе. Что мне понавилось в ESP32, так это удобство использования, пока я запрограммировал робота используя Arduino IDE, но можно пользоваться другими языками, например LUA.
Добавляем поддержку контроллера ESP32 в Arduino IDE
Для того, чтобы ESP32 стал доступен в Arduino IDE нужно выполнить следующие действия:
- Скачать архив по ссылке на GitHub.
- Распаковать архив в папку ....Documents/Arduino/hardware/espressif/esp32
Далее переходим в папку tools и запускаем на выполнение программу get.exe. Ждем, скачивания дополнений, если антивирус спросил предоставить ли программе досуп? предоставляем и запускаем ее снова.
в папке tools/dist должные появиться 3 файла.
Особенности программирования мобильного робота на шаговых моторах и ESP32
Теперь особенности. За основу для своей программы я взял два примера:
- RepeatTimer, откуда взял основы по работе с таймерами (требовались для генерации шагов).
- SerialToSerialBT, это пример подключения BT модуля (требуется для управления роботом).
Если я не ошибаюсь, то таймеры 64 разрядные, точнее можно узнать в документации, она доступна по ссылке с листингами. Таймеров общего назначения 4-е, ими можно пользоваться без ограничений, для генерации ШИМ на GPIO используются другие ресурсы. Тактируются таймеры частотой 80Мгц, а не частотой ядра. Таким образом если задать делитель 80, timer = timerBegin(0, 80, true), то максимальная частота срабатывания таймера будет 1Мгц (1 раз в микросекунду). timerAttachInterrupt(timer, &onTimer, true), задается функция, которая будет вызываться при срабатывании таймера, здесь ее имя onTimer. timerAlarmWrite(timer, 1000000, true), задается количество тиков таймера до срабатывания прерывания, здесь это число 1000000. timerAlarmEnable(timer), запускает таймер. timerAlarmDisable(timer) - отключает таймер.
По поводу Bluetooth все еще проще.
#include bluetoothserial.h - подключаем библиотеку работы с BT.
BluetoothSerial SerialBT; - создаем экземпляр класса BluetoothSerial.
SerialBT.begin("MONSTERESP32"); - запускаем Bluetooth и даем имя нашему устройству, у меня это MONSTERESP32.
Ниже приведен пример чтения данных с BT порта:
while (SerialBT.available())
{
bt_input = (char)SerialBT.read();
flagDataBT = true;
}
Более подробно программу я рассмотрел в ролике: