ESP8266 стал воистину «народным» в мире дешевых интернет вещей. Встречайте ему достойную замену ESP32.
Краткое описание, программирование в Ardiono IDE, примеры читайте в этом обзоре
Начну пожалуй с характеристик ESP32, взятых из официального даташита:
Память и ЦПУ
- Двухядерный 32-битный микропроцессор Xtensa LX6 160-240МГц
- ОЗУ — 520Кб
- ПЗУ — 448Кб
- Дополнительно RTC таймер с 16Кб ОЗУ
- Внешняя флэш память 4-16Мб
- Питание 2.2 — 3.6В
WiFi и Bluetooth
- WiFi 802.11n 2.4Гц с максимальной скоростью 150Мбит/сек
- WPA)/WPA2/WPA2-Enterprise/Wi-Fi Protected Setup (WPS
- Bluetooth v4.2 BR/EDR and BLE
Периферия
- 12- битная АЦП на 18 портах
- 8-битная ЦАП на 2 портах
- 10-портов в режиме сенсорных кнопок
- Встроенный температурный датчик
- 4 x SPI
- 2 x IS1
- 2 x I2C
- 3 x UART
- 1 host (SD/eMMC/SDIO)
- 1 slave (SDIO/SPI)
- Ethernet MAC interface with dedicated DMA and IEEE 1588 support
- CAN 2.0
- IR (TX/RX)
- Motor PWM
- LED PWM up to 16 channels
- Hall sensor
- Ultra-low-noise analog pre-amplifier
Защита
- IEEE 802.11 standard security features all supported, including WFA, WPA/WPA2 and WAPI
- Secure boot
- Flash encryption
- 1024-bit OTP, up to 768-bit for customers
- Cryptographic hardware acceleration:
– AES
– HASH (SHA-2) library
– RSA
– ECC
– Random Number Generator (RNG)
Энергопотребление
- Максимальный ток при передаче WiFi — 160-260мА
- Потребление без включенного WiFi и Bluetooth — 20мА
- LightSleep — 0.8мА
- DeepSleep — до 10мкА
- Режим гибернизации с активным RTC — 5мкА
Я заказал отладочную плату на ESP-WROOM-32 с 16Мб флэша, USB/UART на CP2102 и прошитым загрузчиком. (Даташит на нее) за $8.22. Цена на сам модуль начинается от $5. Еще за $0.5 можно купить терминальную платку, а за $4 отдельно отладочную плату без модуля
Назначение выводов отладочной платы можно посмотреть здесь
Все для программирование есть у производителя, в его разделе на GITHUB
Там же есть ESP32 CORE для Arduino IDE
Установка под Windows очень проста:
— Устанавливаем Arduino IDE (если еще не установлена)
— Скачиваем архив с последней версий Core ESP32
— Распаковываем архив в папку:
C:/Users/[YOUR_USER_NAME]/Documents/Arduino/hardware/espressif/esp32
После это в Board Manadger появляется поддержка ESP32
Инструкции по установке в LINUX и MAC OS лежат на страничке проекта
Подключаем отладочную плату с ESP32 к USB и, если установлен драйвер на CP2102, то видим отладочный COM порт в системе. Если нет, ставим драйвер, как например это описано здесь
Запустив монитор порта на 115200 видим загрузку системы
Библиотек портировано еще очень мало
В каталогах example лежат примеры. Давайте займемся программированием.
Подключение к WiFi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include <WiFi.h> #include <WiFiClient.h> const char* ssid = "DIR-320"; const char* password = "-----------"; void setup(void) { Serial.begin(115200); // Connect to WiFi network WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop(void){;} |
С запуском веб-сервера из примера тоже проблем не составила. Правда удобных классов для HTTP-сервера в библиотеках нет, и весь HTTP-протокол реализуется вручную на лету. Но перенос библиотек ESP8266 дело времени. Да и самому можно заняться на досуге.
Сенсорные кнопки
Давайте посмотрим как работают TOUCH сенсоры.
Подключаем пару проводков с площадками к выводам T1 и T2
После этого функции touchRead(T1) и touchRead(T2) возвращают значение больше 25, если прикоснуться к площадкам и 0-2 если не прикасаться.
Как работать с кнопками я подробно описывал
Программа работы с двумя сенсорными кнопками и подавлением дребезга
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
bool button_state1 = false; uint32_t ms_button1 = 0, ms_button2 = 0; void setup() { Serial.begin(115200); Serial.println("Test button ..."); } void loop(){ uint32_t ms = millis(); // Фиксируем нажатие кнопки if( touchRead(T1) > 20 && ( ms - ms_button1 ) > 100 ){ ms_button1 = ms; Serial.println("Press key B1"); } if( touchRead(T2) > 20 && ( ms - ms_button2 ) > 100 ){ ms_button2 = ms; Serial.println("Press key B2"); } } |
Работа со встроенными датчиками температуры и Холла
Кто то считает Arduino IDE огрызком нормальной системы разработки. Позвольте не согласится. Arduino IDE это довольно примитивный редактор + среда G++ для микроконтроллеров. А CORE ESP32 содержит версию SDK и никто не мешает пользоваться им напрямую.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
extern "C" { uint8_t temprature_sens_read(); uint32_t hall_sens_read(); } void setup(void){ Serial.begin(115200); } void loop(void){ uint8_t tf = temprature_sens_read(); float tc = ( tf - 32 )/1.8; Serial.printf("Temp=%dC hal=%d\n",(int)tc,hall_sens_read()); delay(1000); } |
Температура ядра выдается в фаренгейтах и ее не сложно перевести в градусы цельсия, а вот что показывает датчик холла и есть ли он на самом деле я не разобрался. По крайней мере, на магнит выдача значений никак не реагировала.
Подключение OLED дисплея по I2C
По настоящему сильная сторона Arduino это гигантское количеством готовых библиотек. Нормально заработали библиотеки SSD1306 и GFX от Adafruit для OLED дисплея I2C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include <Wire.h> #include "GFX.h" #include "SSD1306.h" Adafruit_SSD1306 display(-1); void setup(void){ Serial.begin(115200); Serial.println("Start..."); Wire.begin(); // Сканируем I2C шину for(int i = 1; i < 127; i++ ) { Wire.beginTransmission(i); if( Wire.endTransmission() == 0 ){ Serial.printf("Found I2C device 0x%x\n",i); } } // Инициализация дисплея display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(0,0); display.println("ESP32"); display.setCursor(0,32); display.println("TEST"); display.display(); delay(2000); } void loop(void){;} } |
Код также содержит I2C сканер, определяющий все устройства на шине.
NTP часы на дисплее TM1637
Попробуем написать какую нибудь законченную программу для ESP32. Пусть это будут часы с синхронизацией времени в интернете по NTP, которую я уже описывал для ESP8266
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
/* * This sketch sends a message to a TCP server * */ #include <WiFi.h> #include <WiFiUdp.h> #include <WiFiMulti.h> #include "TM1637.h" #define TM1637_CLK 22 #define TM1637_DIO 23 IPAddress timeServerIP; const char* ntpServerName = "time.nist.gov"; int TIMEZONE=5; const int NTP_PACKET_SIZE = 48; byte packetBuffer[ NTP_PACKET_SIZE]; WiFiUDP udp; TM1637 tm1637(TM1637_CLK,TM1637_DIO); WiFiMulti WiFiMulti; unsigned int localPort = 2390; // local port to listen for UDP packets unsigned long ntp_time = 0; long t_correct = 0; unsigned long cur_ms = 0; unsigned long ms1 = 0; unsigned long ms2 = 10000000UL; unsigned long t_cur = 0; bool points = true; unsigned int err_count = 0; uint16_t vdd = 0; void setup() { Serial.begin(115200); delay(10); // Инициализация дисплея tm1637.init(); // Установка яркости дисплея tm1637.set(2); tm1637.point(false); tm1637.display(0,'-'); tm1637.display(1,'-'); tm1637.display(2,'-'); tm1637.display(3,'-'); delay(3000); // We start by connecting to a WiFi network WiFiMulti.addAP("DIR-320", "------------"); Serial.println(); Serial.println(); Serial.print("Wait for WiFi... "); while(WiFiMulti.run() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); delay(500); } void loop() { cur_ms = millis(); t_cur = cur_ms/1000; // Каждые 60 секунд считываем время в интернете if( cur_ms < ms2 || (cur_ms - ms2) > 60000 ){ err_count++; // Делаем три попытки синхронизации с интернетом if( GetNTP() ){ ms2 = cur_ms; err_count = 0; t_correct = ntp_time - t_cur; } } // Каждые 0.5 секунды выдаем время if( cur_ms < ms1 || (cur_ms - ms1) > 500 ){ ms1 = cur_ms; ntp_time = t_cur + t_correct; DisplayTime(); points = !points; } // Если нет соединения с интернетом, перезагружаемся if( err_count > 10 ){ Serial.println("NTP connect false"); Serial.println("Reset ESP32 ..."); // ESP.reset(); } delay(100); } /** * Выдача текущего времени на индикатор */ void DisplayTime(void){ uint16_t m = ( ntp_time/60 )%60; uint16_t h = ( ntp_time/3600 )%24; Serial.print("Time: "); Serial.print(h); Serial.print(":"); Serial.println(m); tm1637.point(points); tm1637.display(0,h/10); tm1637.display(1,h%10); tm1637.display(2,m/10); tm1637.display(3,m%10); } /** * Посылаем и парсим запрос к NTP серверу */ bool GetNTP(void) { WiFi.hostByName(ntpServerName, timeServerIP); sendNTPpacket(timeServerIP); delay(1000); int cb = udp.parsePacket(); if (!cb) { Serial.println("No packet yet"); return false; } else { Serial.print("packet received, length="); Serial.println(cb); // Читаем пакет в буфер udp.read(packetBuffer, NTP_PACKET_SIZE); // 4 байта начиная с 40-го сождержат таймстамп времени - число секунд // от 01.01.1900 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); // Конвертируем два слова в переменную long unsigned long secsSince1900 = highWord << 16 | lowWord; // Конвертируем в UNIX-таймстамп (число секунд от 01.01.1970 const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears; // Делаем поправку на местную тайм-зону ntp_time = epoch + TIMEZONE*3600; Serial.print("Unix time = "); Serial.println(ntp_time); } return true; } /** * Посылаем запрос NTP серверу на заданный адрес */ unsigned long sendNTPpacket(IPAddress& address) { Serial.println("sending NTP packet..."); // Очистка буфера в 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // Формируем строку зыпроса NTP сервера packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[1] = 0; // Stratum, or type of clock packetBuffer[2] = 6; // Polling Interval packetBuffer[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // Посылаем запрос на NTP сервер (123 порт) udp.beginPacket(address, 123); udp.write(packetBuffer, NTP_PACKET_SIZE); udp.endPacket(); } |
Подключаем индикатор к GPIO22 и GPIO23, ESP32 соединяется с интернетом и на дисплее получаем точное время для Перми
Выводы
Жаль что в этом обзоре нельзя обьять все. За кадром остались и работа с Bluetooth и обновление прошивки по воздуху и работа с аналоговыми выходами и многое другое.
Но ведь это только начало!
Безусловно, ESP32 несмотря на свою не дозревшую программную часть, железка очень интересная. Да и по деньгам она уже не слишком кусается. Лично я буду ее пробовать использовать в различных проектах. А значит, будут и новые обзоры.
Хороший обзор.Спасибо. А работу с BLE пробывали? У меня что то не взлетело.
Нет пока. Ищу с чем бы применить
Датчик хола работает.
Вот данные с serial монитора:
Temp=50C hal=1
Temp=50C hal=9
Temp=50C hal=4
Temp=51C hal=0
Temp=50C hal=2
Temp=51C hal=65530
Temp=50C hal=65535
Temp=51C hal=0
Temp=50C hal=5
Temp=50C hal=3
Реагирует на магнит/удар пальцем по крышке гр..чипа…)))
Но мой модуль жутко греется =(
Приобрел esp32. Но к сожалению не могу запустить…
Возникла ошибка при загрузке http://arduino.esp8266.com/package_esp8266com_index.json
exit status -1
Ошибка компиляции для платы ESP32 Dev Module.
Возможно где то ошибка у разработчиков в автоматической установке пакета
Попробуйте его вручную поставить, как я в статье описывал
У меня не находит файл в папке \espressif\esp32\tools\esptool.exe
У Вас ест такой?
Заработало. Больше вопросов нет. Спасибо!
народ, а для чего этот микро контроллер, в чего можно применить, что сделать никто ничего не показывает
Хочу собрать контроллер (термостат) в дом. Только вот нужно будет прицепить 7 температурных датчиков и 6 нагрузок (исполнительные механизмы) с возможностью расширения до 10 датчиков и 10 нагрузок.
Возможно ли все это повесить на ESP32? Везде описаны примеры и конструкции с 1 или 4 датчиками. Поэтому такой вопрос возник.
Возможно, но ESP32 избыточно. Там и обычной ардуины/ESP8266 за глаза
DS18B20 возможно на одной шине 10 датчиков. У них адреса уникальные
Доброго времени суток. А не пробовали с модуля данные в uart отправлять? Нигде не могу примеров найти обмена данными по uart, где только уже не искал. Задумка такая: на RS-485 висит пара десятков AVR, у каждого «свои» символы, на которые он «отзывается. Хотелось бы всем этим безобразием со смартфона управлять…
Конкретно в этом проекте нет. А так ничего сложного не вижу. Только нужно прошивки с двух сторон реализовывать с протоколом обмена
Ага, вот, интерпретатор накопал наконец-то тут… https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_ru. Пытаюсь разобраться)…
Я считаю, что интерпретатор в микроконтроллерах — зло
Си++ не намного сложнее Lua, а функциональность совсем другая
Куда подключать батарейку для rtc? Сколько не гляжу пина VBAT не вижу.
Вопрос по подключению периферии — не могу найти либы для шаговика.
Добрый день. Кто может помочь мне с разработкой простого софта для esp32? Естественно не бесплатно. Тут уж как договоримся. Или может посоветуете куда обратиться
Вкусное на потом оставляет?
Здравствуйте. Не могу свою ESP32 подключить к wifi как описано в этой статье…
Заливал wifi сканер точку видит… делаю вывод что модуль wifi работает.
Что может быть?
Трудно сказать. Ошибка в названии точки доступа (большие/маленькие буквы проверьте), неисправность ESP32, несовместимость ESP и роутера (к сожалению, встречал и такое, правда на WSP8266)