Всем привет.
Ссылка на Яндекс Диск со всеми материалами скетчем и библиотеками.
Захотелось мне, и по просьбе трудящихся, добавить в свое зарядное устройство на Ардуино больше возможностей - запись логов на флеш карту, удаленное управление через Wi-Fi, Bluetooth, обновление прошивки по воздуху. И обычная Ардуино Нано тут уже не подходит. Но есть такой замечательный микроконтроллер ESP32.
ESP32 и ESP32-S.
Включают в себя:
Микроконтроллер и управлениеTensilica Xtensa LX6 двухъядерный (или одноядерный) 32-разрядный процессор, с тактовой частотой 160 или 240 МГц и производительностью до 600 DMIPS (Dhrystone MIPS)
Сопроцессор с ультранизким энергопотреблением.
448 КБ ПЗУ для загрузки и основных функций.
520 Кб (8 КБ RTC быстрая память в комплекте) on-chip SRAM для данных и инструкций.
8 КБ SRAM в RTC, который называется RTC быстрой памяти и хранения данных используется для; это для доступа к нему со стороны Главный процессор во время загрузки RTC из режима глубокого сна.
8 КБ SRAM в RTC, который называется медленной памятью RTC и может быть доступен со-процессором во время режима глубокого сна.
1 кбит eFuse, из которых 256 бит используются для системы (MAC-адрес и конфигурация чипа) и остальные 768 бит зарезервированы для клиентских приложений, включая шифрование флэш-памяти и идентификатор чипа.
Беспроводная связь:Wi-Fi: 802.11 b / g / N
Bluetooth: v4.2 BR/EDR and BLE
Периферийные интерфейсы:12-разрядный АЦП до 18 каналов
2 × 8 бит ЦАПа
10 × портов для подключения емкостных датчиков (измеряющие ёмкость GPIO)
4 × SPI мастер-интерфейса (ведущие устройства)
2 × I²S мастер-интерфейса
3 × UART интерфейса
SD/SDIO/CE-ATA/MMC/ eMMC хост-контроллер
SDIO/SPI слейв-контроллеры (ведомые устройства)
Ethernet MAC interface с выделенным DMA и IEEE 1588 Precision Time Protocol support
CAN bus 2.0
Возможность подключения двигателей и светодиодов через ШИМ-выход
Датчик Холла
Аналоговый предусилитель низкого энергопотребления.
Возможности ESP32 позволяют широко развернуться, использовать Wi-Fi и Bluetooth для контроля параметров и управления устройствами.
INA226.
Первое и самое необходимое что должно делать зарядное устройство - это измерять напряжение и ток с хорошей точностью. Для этого идеально подходит специализированная микросхема INA226. Я применяю модуль на ее основе.
Микросхема предназначена для измерения тока, напряжения и мощности в нагрузке постоянного тока. Включает 16 битный АЦП. Общается INA226 с внешним миром по интерфейсу I2C.
Возможности микросхемы:
- измерение постоянного напряжения до 36 вольт;
- измерение тока, протекающего через нагрузку в обоих направлениях. Величина измеряемого тока зависит от сопротивления шунта. На плате установлен резистор номиналом 0,1 Ом что позволяет измерять ток до 0,8 А. Если его заменить на 0,01 Ом то уже можно измерять ток до 8,1 А , 0,005 Ом - 16,2 А и т.д.;
- вычисление мощности;
- отслеживание превышения или снижения заданного параметра (измеряемого напряжения, напряжения шунта, мощности) с выдачей сигнала на вывод Alert;
- 16 программируемых адресов для шины I2C;
- напряжение питания 2,7 – 5 V.
Соединив ESP32 и INA226 по шине I2S и загрузив в ESP32 соответствующее ПО мы получим хороший такой Вольт-Ампер-Ватт метр. А выводить показания можно на дисплей смартфона или экран компьютера. Либо подключить какой либо дисплей к ESP32. Себе я приобрел TFT SPI 3.5 дюйма сенсорный дисплей на контроллере ili9486 и TFT SPI 2,4 дюйма сенсорный дисплей на контроллере ili9341.
Наличие слота под карту памяти позволит записывать измеренные показания на карту памяти. Позже можно сохраненные данные просмотреть на компьютере и вывести графики изменения показаний.
Схема соединения:
На данной схеме отсутствует подключение тачскрина и разъема для SD карты. Это будет в следующей статье.
Для экспериментов можно запитывать схему от USB порта подключенного к ESP32. Либо от источника питания 5 В подключенного к VIN ESP32. Либо от стабильного источника питания 3,3 В.
Измеряемое напряжение подключается к INA226. Желательно не путать полярность подключения. Максимальное напряжение 36 Вольт.
Шунт, для измерения тока, может подключаться как в разрыв минуса так и плюса питания. В данной схеме он подключен в разрыв минуса. INA226 может измерять ток в обоих направлениях. Значение тока может быть положительным и отрицательным.
FreeRTOS.
"Операционные системы реального времени (ОСРВ(RTOS)) предназначены для обеспечения интерфейса к ресурсам критических по времени систем реального времени. Основной задачей в таких системах является своевременность (timeliness) выполнения обработки данных".
"FreeRTOS — многозадачная операционная система реального времени (ОСРВ) для встраиваемых систем. Портирована на несколько микропроцессорных архитектур.
От хабраюзера andrewsh, по поводу лицензии: разрешено не публиковать текст приложения, которое использует FreeRTOS, несмотря на то, что OS линкуется с ним. Исходники самой же RTOS должны всегда прикладываться, изменения, внесённые в неё — тоже.".
ESP32 включает в себя 2 вычислительных ядра. При создании программ в Arduino IDE, ESP32 работает под управлением операционной системы реального времени - FreeRTOS. По умолчанию, сама FreeRTOS работает на первом ядре, а весь пользовательский код на втором ядре. Но это можно изменить используя специальные методы FreeRTOS. Можно создать несколько независимых задач и каждой назначить ядро, на котором задача будет выполняться.
Ядро для ESP32.
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Добавь этот адрес в Arduino IDE: Настройки - Дополнительные ссылки для менеджера плат.
После в Инструменты - Менеджер Плат. Установи ядро для esp32 (Espressif Systems 2.0.5..)
Вольт-Ампер-Ватт метр на ESP32 и INA226.
Собрав все выше описанное воедино, начав изучать FreeRTOS по данной книге и статьям в интернете, я приступил к созданию довольно навороченного измерительного прибора с удаленным доступом и записью логов на карту памяти. В конце он обернется в универсальное зарядное устройство.
Итак приступим. Начну с самого простого и важного - настроить INA226 и считывать с нее показания напряжения, тока и мощности. Для этого я создам отдельную задачу которая будет считывать показания в структуру и записывать их в очередь из 5 элементов. Для общения с INA226 я использую библиотеку от AlexGyver.
INA226 ina(0.01f, 8.0f); // Сопротивление шунта = 0.01 Ом, максимальный ток = 8A.
struct vawStruct { // структура для ina226
float volt;
float amper;
float watt;
};
void setup() {
Serial.begin(115200);
xINA = xQueueCreate(5, sizeof(vawStruct)); // параметры очереди: 5 элементов.
xTaskCreatePinnedToCore(INA226_read, "INA226", 2048, NULL, 2, NULL, 0); // задача для чтения с INA226 в очередь
}
Проводится инициализация INA226. Если если инициализация пошла успешно то в строках применяются параметры работы INA226. Иначе если INA226 не обнаружена то данная задача закрывается.
- ina.setSampleTime(INA226_VBUS, INA226_CONV_4156US); // время выборки напряжения INA226_CONV_2116US INA226_CONV_4156US
- ina.setSampleTime(INA226_VSHUNT, INA226_CONV_8244US); // время выборки тока INA226_CONV_2116US INA226_CONV_8244US
- ina.setAveraging(INA226_AVG_X4); // 4х кратное усреднение, по умолчанию усреднения нет(1, 4, 16, 64, 128, 256, 512, 1024).
Эти три важных параметра отвечают за работу INA226. С какой периодичностью и усреднением результатов будут производиться измерения.
У меня Напряжение считывается 4156 микросекунд. Ток 8244 микросекунды. Производится по 4 таких замера и усредняются. Итого на все тратится 4156 * 4 + 8244 * 4 = 49600 мкс. Почти 50 миллисекунд нужно INA226 на замеры напряжения и тока. Для моих нужд этого вполне достаточно. Так как обновление данных на дисплее происходит с периодичностью 100 мс, а в браузере 200 мс.
Далее задача переходит в бесконечный цикл в котором считывает показания и записывает их в очередь из которой их берут остальные задачи. Данная задача имеет самый высокий приоритет, поэтому очередь ни когда не опустеет. Работает на ядре 0. Когда очередь будет заполнена то задача перейдет в режим ожидания. Как только в очереди появится место задача сразу отработает и заполнит место в очереди.
Код Вольт-Ампер-Ваттметра созданный в Arduino IDE.
Вывод на дисплей.
Для работы с дисплеем TFT SPI 3.5 ili9486 я использую библиотеку TFT_eSPI. Но чтобы библиотека правильно распознала мой дисплей необходимо настроить параметры в файле библиотеки "User_Setup.h". В нем необходимо выбрать тип микроконтроллера (ESP32 в моем случае), тип контроллера дисплея (ili9486 в моем случае) и установить номера контактов к которым подключен дисплей.
Дисплей подключен по шине SPI, разные задачи могут выводить на него свою информацию. Для того чтобы не случилось так что несколько разных задач будут отправлять в дисплей свои данные в один и тот же момент необходимо средствами FreeRTOS разграничить доступ к дисплею во времени, для этого создать семафор:
SemaphoreHandle_t spi_mutex; // мьютекс вывода сообщений на дисплей LCD
void setup() {
spi_mutex = xSemaphoreCreateMutex();
xTaskCreatePinnedToCore(LCD_vaw, "LCD_vaw", 2048, NULL, 1, NULL, 1); // задача чтения из очереди xINA и вывод на дисплей 10 раз в секунду
}
Внутри данной задачи создаем структуру "vawStruct inaVaW"
В цикле считывает в созданную структуру значения из очереди
xStatus = xQueueReceive(xINA, &inaVaW, 0); // считать значение очереди INA226
Если значения считались нормально то выводим на дисплей. Иначе вывести на дисплей "Ошибка INA226". Далее задержка 100 мс, данные на дисплее обновляются 10 раз в секунду.
Перед выводом на дисплей задача проверяет наличие доступа к дисплею и когда он появится то блокирует данный семафор "spi_mutex" и отправляет свои данные на дисплей
xSemaphoreTake(spi_mutex, portMAX_DELAY);
.....
xSemaphoreGive(spi_mutex);
В конце передачи разблокирует семафор.
Для вывода на дисплей аналоговых приборов применяется библиотека TFT_eWidget.
Передача данных через локальную сеть и отображение в браузере компьютера или смартфона.
Благодаря наличию Wi-Fi, ESP32 может отправлять данные замеров куда угодно через интернет. Но сегодня мне просто нужно чтобы ESP32 подключалась к локальной сети и по запросу отсылала данные в браузер компьютера или телефона. Очень удобным средством для этого является GyverPortal - простой конструктор веб интерфейсов для ESP8266 и ESP32.
- Позволяет быстро создать универсальную вебморду для управления и настройки своего девайса;
- Возможность создания многостраничных и динамических веб-интерфейсов в несколько строк кода;
- ... и так далее, почитайте по ссылке выше.
Скачиваю библиотеку и подключаю в свою программу. Создаю задачу в которой будет работать GyverPortal:
#include <GyverPortal.h>
void setup() {
xTaskCreatePinnedToCore(GayverPortal, "GayverPortal", 10240, NULL, 1, NULL, 0); // работа GiverPortal
}
В начале задачи инициализируется Wi-Fi модуль и подключается к вашей Wi-Fi точке доступа через указанные в начале скетча Логин и пароль (AP_SSID, AP_PASS) от вашей Wi-Fi сети:
#define AP_SSID "Login"
#define AP_PASS "Pasword"
Если подключение удалось то запускается работа GayverPortal в бесконечном цикле:
while (portal.tick()); // работает GyverPortal
В монитор порта выводится адрес (мой - 192.168.229.225). Его нужно ввести в строку браузера телефона или компьютера.
Для создания страницы которая будет выводиться в браузере определена функция void build(GyverPortal& portal).
Для автоматического обновления данных на странице создана функция void action(GyverPortal& portal).
Вот так выглядит страница в браузере смартфона
Реализован вывод значений напряжения, тока и мощности. Вывод графиков в реальном времени для напряжения и тока. Время обновления сделано 200 мс - 5 раз в секунду.
Функция void build(GyverPortal& portal) запрашивает данные напряжения, тока и мощности через функцию GP.UPDATE("volt,amper,watt", 200); // список имён компонентов на обновление, время обновления мс
Функция void action(GyverPortal& portal) считывает данные напряжения, тока и мощности из очереди
xStatus = xQueueReceive(xINA, &inaVaWi, 0); // считать значение очереди INA226
и отправляет их на страницу.
Вывод времени работы.
В программе реализована отдельная задача для подсчета и вывода времени работы устройства на LCD дисплей.
void LCD_time(void *pvParameters)
Данная задача рассчитывает время прошедшее с момента запуска данной задачи и выводит его на дисплей 1 раз в секунду. Для разграничения доступа к дисплею используется семафор
xSemaphoreTake(spi_mutex, portMAX_DELAY);
***
Далее мне нужно будет реализовать запись логов времени, напряжения, тока и мощности на SD карту и доступ к файлам записанным на ней из браузера. Это будет в следующей статье.
***
Ссылка на Яндекс Диск со всеми материалами скетчем и библиотеками.
Данный Вольт-Ампер-Ватт метр является учебным, не является законченным устройством пригодным к повседневной эксплуатации. Схема не содержит необходимых защит и развязок.