Реклама ⓘ
Главная » Arduino
Призовой фонд
на май 2024 г.
1. 1000 руб
Сайт Паяльник

Реклама ⓘ

Использование HMI TFT-дисплея STONE и ESP32 для управления массажным креслом

В данной статье, мы рассмотрим создание приложение для домашнего массажного кресла на основе TFT-дисплея STONE и платы ESP32. Идея следующая. При включении на дисплее появится некоторый стартовый интерфейс. После непродолжительного времени, дисплей автоматически перейдет в режим, предназначенный для установки текущего времени, для этого появится виртуальная клавиатура. После установки текущего времени, нажимается «OK», чтобы войти в интерфейс выбора режима массажа. Программа предполагает вам три варианта массажа:

  • массаж головы,
  • массаж спины,
  • комплексный массаж (массаж головы и спины).

В данном режиме вы можете также регулировать интенсивность массажа, выбирая высокую, среднюю или низкую интенсивность. Светодиодный индикатор будет подсвечивать выбранный вами режим массажа. Кроме того, вы можете установить таймер по продолжительности массажа, по истечении которого, кресло автоматически остановится.

Передача всех параметров работы осуществляется через последовательный порт TFT-дисплея STONE. А это следующие функции:

  • Функция кнопочного переключения
  • Функция автоматического перехода в специальное меню при запуске
  • Реализация установки времени
  • Реализация приема и распределения данных
  • Реализация последовательного интерфейса для связи
  • Функция выбора строки меню

Модули, необходимые для проекта:

  • LCD TFT-дисплей STONE STVC101WT-01
  • Отладочная плата ESP32
  • Модули драйверы для шаговых двигателей
  • Шаговые двигатели
  • Модуль индикатора на 8 светодиодов

Блок схема устройства:

Характеристики используемого TFT-дисплея:

  • Диагональ: 10.1 дюйма (размер области самого экрана: 222.7х125.3 мм)
  • Разрешение: 1024x600
  • Яркость: 300 кд / м2, светодиодная подсветка
  • Цвет RGB: 65К
  • Срок службы: 20000 часов
  • 32-битный процессор Cortex-M4 200 МГц
  • Flash-память: 128 МБ (или 1 ГБ)
  • Интерфейс UART: RS232 / RS485 / TTL / USB
  • Программное обеспечение Toolbox для проектирования графического интерфейса (GUI)

Используемый TFT-дисплей STVC101WT-01 связывается с ESP32 через последовательный порт, для передачи управляющих команд. Отображаемый интерфейс создается на компьютере в специальной среде STONE Tool 2019. При разработке интерфейса можно добавлять различные кнопки, текстовые поля, а также фоновые изображения. После необходимо сгенерировать файл конфигурации и загрузить его в память дисплея. Различные инструкции по работе с экраном можно скачать на официальном сайте: https://www.stoneitech.com/support/download

Подобные дисплеи, являются аналогами дисплеев Nextion, о которых уже выходило несколько статей: https://cxem.net/guard/3-90.php и https://cxem.net/comp/comp221.php Это довольно удобные дисплеи, упрощающие разработку, но при этом имеющие высокую цену.

Светодиодный модуль, представляет собой индикаторный модуль на 8 светодиодов. Пример такого модуля. Диоды подключены по схеме общий анод, включение светодиода осуществляется низким уровнем сигнала. На модуле так же размещены токоограничивающие резисторы на каждый светодиод. Напряжение питания может составлять от 3 до 5.5 В

  • Рабочее напряжение: 3-5.5 В
  • Рабочий ток: 24 мА (максимум)
  • Уровень включения: низкий уровень
  • Количество светодиодов: 8
  • Цвет дисплея: красный (D1 / D2 / D3 / D4 / D5 / D6 / D7 / D8)

ESP32 – это система на кристалле, с Wi-Fi 2.4 ГГц и двухрежимным Bluetooth на борту, разработанная по ультрамалопотребляющей технологии TSMC 40 нм. Они отличаются стабильностью, универсальностью и надежностью, а также обладают несколькими режимами энергосбережения, что позволяет использовать их в широком спектре устройств. Пример такой платы

Возможности Wi-Fi

  • 802.11 b/g/n
  • 802.11 n (2.4 ГГц), up to 150 Мбит/с
  • WMM-PS, UAPSD
  • Агрегация A-MPDU и A-MSDU
  • Block ACK
  • Фрагментация и дефрагментация данных
  • Автоматический мониторинг сигнала Beacon
  • функции безопасности 802.11 i: пред-аутентификация и TSN
  • Защищенный доступ Wi-Fi через протоколы (WPA)/WPA2/WPA2-Enterprise/Wi-Fi Protected Setup (WPS)

Bluetooth

  • Совместимость со спецификациями Bluetooth v4.2 BR/EDR и BLE
  • Мощность передатчика в соответствии с Class-1, class-2 и class-3 без внешнего усилителя
  • Улучшенный контроль излучаемой мощности
  • Максимальная мощность передатчика +12 дБм
  • Чувствительность -94 дБм
  • Адаптивная скачкообразная перестройка частоты (AFH)
  • Стандартный уровень HCI на базе SDIO/SPI/UART
  • Высокоскоростной HCI через UART: до 4 Мбит/с

Модуль драйвера для шагового двигателя основан на микросхеме ULN2003. ULN2003 – это массив из семи транзисторов Дарлингтона для коммутации нагрузок до 50 В и 500 мА. Каждый вход микросхемы подтянут к питанию через резистор номиналом 4,7 кОм. При рабочем напряжении 5 В он может быть напрямую подключен к цепям ТТЛ и КМОП. Здесь используется корпус DIP-16, 4-фазный 5-проводный шаговый двигатель 5 В. Пример такого модуля сразу с двигателем

  

Разработка

Разработку кода для ESP32 выполним в среде Arduino IDE. Скачиваем Arduino IDE с официального сайта: https://www.arduino.cc/en/Main/Software

Пишем код, для удобства исходный код я выложил в конце статьи. Далее компилируем код и прошиваем ESP32.

Создание интерфейса для дисплея

С официального сайта скачиваем приложение STONE Tool 2019 https://www.stoneitech.com/support/download/software и распаковываем. Из папки с программой запускаем TOOL 2019.exe и создаем новый проект.

В окне создания нового проекта можно выставить разрешение экрана, имя и путь хранения.

Далее настраиваем загрузочную страницу и заголовок для пакетов связи.

По умолчанию фон дисплея залит изображением синего цвета.

 

Чтобы удалить фоновое изображение, щелкаем правой кнопкой мыши на «0.jpg» и выбираем «Удалить». Таким же образом выбираем «Добавить», чтобы добавить изображение, необходимое для проекта.

Для реализации установки времени, добавляем элемент настройки часов (RTC).

  

Для создания виртуальной клавиатуры нам необходимо создать массив кнопок и прописать им соответствующие значения.

Далее создаем элементы меню, прописываем параметры и добавляем иконки.

Таким образом вы можете установить кнопки для переключения между страницами интерфейса.

Для каждой кнопки задается соответствующее действие, для этого прописываем следующие настройки в коде:

//Передняя часть
uint8_t   HeadGearHigh[9]     = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0E, 0x01, 0x00, 0x03};
//HeadGearHigh используется для установки высокой интенсивности массажа головы
uint8_t   HeadGearMiddle[9]   = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0E, 0x01, 0x00, 0x02};
//HeadGearMiddle используется для установки средней интенсивности массажа головы
uint8_t   HeadGearLow[9]      = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0E, 0x01, 0x00, 0x01};
//HeadGearLow используется для установки низкой интенсивности массажа головы

uint8_t   HeadTiming[9]       = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x11, 0x01, 0x00, 0x09};
//HeadTiming используется для получения времени таймера для массажа головы

uint8_t   HeadModeStart[9]    = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x19, 0x01, 0x41, 0x61};
//HeadModeStart используется для запуска массажа головы
uint8_t   HeadModeStop[9]     = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x24, 0x01, 0x46, 0x66};
//HeadModeStop используется для остановки массажа головы

//Задняя часть
uint8_t   BackGearHigh[9]     = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x1A, 0x01, 0x00, 0x01};
//BackGearHigh используется для установки высокой интенсивности массажа задней части
uint8_t   BackGearMiddle[9]   = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x1A, 0x01, 0x00, 0x02};
//BackGearHigh используется для установки средней интенсивности массажа задней части
uint8_t   BackGearLow[9]      = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x1A, 0x01, 0x00, 0x03};
//BackGearLow используется для установки низкой интенсивности массажа задней части

uint8_t   BackModeStart[9]    = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0C, 0x01, 0x42, 0x62};
//BackModeStart используется для запуска массажа задней части
uint8_t   BackModeStop[9]     = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0D, 0x01, 0x43, 0x63};
//BackModeStop используется для остановки массажа задней части

//Комплексный режим
uint8_t   IntegratedModeStart[9]= {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0F, 0x01, 0x44, 0x64};
//IntegratedModeStart используется для запуска комплексного массажа
uint8_t   IntegratedModeStop[9] = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x1F, 0x01, 0x45, 0x65};
//IntegratedModeStop используется для остановки комплексного массажа

Теперь соединяем все вместе.

 

 

Исходный код для ESP32

/*Управление шаговым двигателем – один цикл
Эта программа может управлять униполярным или биполярным шаговым двигателем.
Мотор подключен к 8 и 11 выходам Arduino.
Двигатель должен сделать один оборот в одном направлении, затем один оборот в другом направлении.

Разработано 11.03.2007
Модифицировано 30.11.2009
Автор: Tom Igoe
Перевод: Науменко Андрей 
Последние правки с переводом 02.10.2020*/

#include "stdlib.h"
#include <AccelStepper.h>

const float STEPCYCLE = 2050;
const float TheMaxSpeed = 1000.0; //количество шагов на один оборот, необходимо подстроить под ваш двигатель
const float headspeed_str[4] = {0, TheMaxSpeed/4, TheMaxSpeed/2, TheMaxSpeed};
const float backspeed_str[4] = {0, TheMaxSpeed, TheMaxSpeed/2, TheMaxSpeed/4};

//инициализация шаговых двигателей
AccelStepper HeadStepper(AccelStepper::FULL4WIRE, 15, 0, 2, 4);
AccelStepper BackStepper(AccelStepper::FULL4WIRE, 16, 5, 17, 18);

const int ledPin_1 = 14; // номер ножки, подключенной к светодиоду
const int ledPin_2 = 27; // номер ножки, подключенной к светодиоду
const int ledPin_3 = 26; // номер ножки, подключенной к светодиоду
const int ledPin_4 = 25; // номер ножки, подключенной к светодиоду
const int ledPin_5 = 33; // номер ножки, подключенной к светодиоду
const int ledPin_6 = 21; // номер ножки, подключенной к светодиоду
const int ledPin_7 = 22; // номер ножки, подключенной к светодиоду
const int ledPin_8 = 23; // номер ножки, подключенной к светодиоду

//буфер
uint8_t cout_i = 0;
uint8_t RecievedTemp[9] = {0};
float settingbuf[2] = {TheMaxSpeed, 0};
float MorenCycle = 100;

//Передняя часть
uint8_t   HeadGearHigh[9]     = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0E, 0x01, 0x00, 0x03};
//HeadGearHigh используется для установки высокой интенсивности массажа головы
uint8_t   HeadGearMiddle[9]   = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0E, 0x01, 0x00, 0x02};
//HeadGearMiddle используется для установки средней интенсивности массажа головы
uint8_t   HeadGearLow[9]      = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0E, 0x01, 0x00, 0x01};
//HeadGearLow используется для установки низкой интенсивности массажа головы

uint8_t   HeadTiming[9]       = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x11, 0x01, 0x00, 0x09};
//HeadTiming используется для получения времени таймера для массажа головы

uint8_t   HeadModeStart[9]    = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x19, 0x01, 0x41, 0x61};
//HeadModeStart используется для запуска массажа головы
uint8_t   HeadModeStop[9]     = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x24, 0x01, 0x46, 0x66};
//HeadModeStop используется для остановки массажа головы

//Задняя часть
uint8_t   BackGearHigh[9]     = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x1A, 0x01, 0x00, 0x01};
//BackGearHigh используется для установки высокой интенсивности массажа задней части
uint8_t   BackGearMiddle[9]   = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x1A, 0x01, 0x00, 0x02};
//BackGearHigh используется для установки средней интенсивности массажа задней части
uint8_t   BackGearLow[9]      = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x1A, 0x01, 0x00, 0x03};
//BackGearLow используется для установки низкой интенсивности массажа задней части

uint8_t   BackModeStart[9]    = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0C, 0x01, 0x42, 0x62};
//BackModeStart используется для запуска массажа задней части
uint8_t   BackModeStop[9]     = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0D, 0x01, 0x43, 0x63};
//BackModeStop используется для остановки массажа задней части

//Комплексный режим
uint8_t   IntegratedModeStart[9]= {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x0F, 0x01, 0x44, 0x64};
//IntegratedModeStart используется для запуска комплексного массажа
uint8_t   IntegratedModeStop[9] = {0xA5, 0x5A, 0x06, 0x83, 0x00, 0x1F, 0x01, 0x45, 0x65};
//IntegratedModeStop используется для остановки комплексного массажа

void setup()
{
    //инициализация UART для связи с TFT-дисплеем
    Serial.begin(115200);

    //инициализация пинов подключенных к светодиодам на вывод
    pinMode(ledPin_1, OUTPUT);
    pinMode(ledPin_2, OUTPUT);
    pinMode(ledPin_3, OUTPUT);
    pinMode(ledPin_4, OUTPUT);
    pinMode(ledPin_5, OUTPUT);
    pinMode(ledPin_6, OUTPUT);
    pinMode(ledPin_7, OUTPUT);
    pinMode(ledPin_8, OUTPUT);

    digitalWrite(ledPin_1, HIGH); //зажигаем светодиод
    digitalWrite(ledPin_2, HIGH); //зажигаем светодиод
    digitalWrite(ledPin_3, HIGH); //зажигаем светодиод
    digitalWrite(ledPin_4, HIGH); //зажигаем светодиод
    digitalWrite(ledPin_5, HIGH); //зажигаем светодиод
    digitalWrite(ledPin_6, HIGH); //зажигаем светодиод
    digitalWrite(ledPin_7, HIGH); //зажигаем светодиод
    digitalWrite(ledPin_8, HIGH); //зажигаем светодиод
}

void loop()
{
    if(Serial.available() != 0)
    {
        for(cout_i = 0; cout_i < 9; cout_i ++)
        {
            RecievedTemp[cout_i] = Serial.read();
        }

        switch(RecievedTemp[5])
        {

        case 0x0E://двигатель передней части
            if(HeadStepper.isRunning() == true)
            {
                HeadStepper.stop();
            }
            settingbuf[0] = headspeed_str[RecievedTemp[8];
            if(RecievedTemp[8] == 1)
            {
                digitalWrite(ledPin_1, LOW); 
                digitalWrite(ledPin_2, LOW); 
                digitalWrite(ledPin_3, LOW); 
                digitalWrite(ledPin_4, HIGH); 
                digitalWrite(ledPin_5, HIGH); 
                digitalWrite(ledPin_6, HIGH); 
                digitalWrite(ledPin_7, HIGH); 
                digitalWrite(ledPin_8, HIGH);
            }
            else if(RecievedTemp[8] == 2)
            {
                digitalWrite(ledPin_1, LOW);
                digitalWrite(ledPin_2, LOW);
                digitalWrite(ledPin_3, LOW);
                digitalWrite(ledPin_4, LOW);
                digitalWrite(ledPin_5, LOW);
                digitalWrite(ledPin_6, LOW);
                digitalWrite(ledPin_7, HIGH); 
                digitalWrite(ledPin_8, HIGH); 
            }
            else
            {
                digitalWrite(ledPin_1, LOW);
                digitalWrite(ledPin_2, LOW);
                digitalWrite(ledPin_3, LOW);
                digitalWrite(ledPin_4, LOW);
                digitalWrite(ledPin_5, LOW);
                digitalWrite(ledPin_6, LOW);
                digitalWrite(ledPin_7, LOW);
                digitalWrite(ledPin_8, LOW);
            }
        
            break;
        case 0x11://таймер
            if(HeadStepper.isRunning() == true)
            {
                  HeadStepper.stop();
            }
            settingbuf[1] = RecievedTemp[8];
            break;
        
        case 0x19://старт передней части
            if(settingbuf[1] == 0)
            {
                settingbuf[1] = 5;
            }
            break;
        
        case 0x24://стоп передней части
            if(HeadStepper.isRunning() == true)
            {
                HeadStepper.stop();
            }
            break;
        
        case 0x1A://двигатель задней части
            if(BackStepper.isRunning() == true)
            {
                BackStepper.stop();
            }
            settingbuf[0] = backspeed_str[RecievedTemp[8]];
            if(RecievedTemp[8] == 3)
            {
                digitalWrite(ledPin_1, LOW); 
                digitalWrite(ledPin_2, LOW);
                digitalWrite(ledPin_3, LOW);
                digitalWrite(ledPin_4, HIGH);
                digitalWrite(ledPin_5, HIGH);
                digitalWrite(ledPin_6, HIGH);
                digitalWrite(ledPin_7, HIGH);
                digitalWrite(ledPin_8, HIGH);
            }
            else if(RecievedTemp[8] == 2)
            {
                digitalWrite(ledPin_1, LOW);
                digitalWrite(ledPin_2, LOW);
                digitalWrite(ledPin_3, LOW);
                digitalWrite(ledPin_4, LOW);
                digitalWrite(ledPin_5, LOW);
                digitalWrite(ledPin_6, LOW);
                digitalWrite(ledPin_7, HIGH);
                digitalWrite(ledPin_8, HIGH);
            }
            else
            {
                digitalWrite(ledPin_1, LOW);
                digitalWrite(ledPin_2, LOW);
                digitalWrite(ledPin_3, LOW);
                digitalWrite(ledPin_4, LOW);
                digitalWrite(ledPin_5, LOW);
                digitalWrite(ledPin_6, LOW);
                digitalWrite(ledPin_7, LOW);
                digitalWrite(ledPin_8, LOW);
            }
            break;
        
        case 0x0C://старт задней части
            BackStepper_Setting_Run(settingbuf[0], MorenCycle);
            break;
        
        case 0x0D://стоп задней части
            if(BackStepper.isRunning() == true)
            {
                BackStepper.stop();
            }
            break;
        
        case 0x0F://старт комплексного режима
            if(HeadStepper.isRunning() == true)
            {
                HeadStepper.stop();
            }
            if(BackStepper.isRunning() == true)
            {
                BackStepper.stop();
            }
            break;
        
        case 0x1F://остановка комплексного режима
            if(HeadStepper.isRunning() == true)
            {
                HeadStepper.stop();
            }
            if(BackStepper.isRunning() == true)
            {
                BackStepper.stop();
            }
            break;
        
        default:
            break;
        }
    }
}

 

Теги:

Опубликована: 0 2
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (1) | Я собрал (0) | Подписаться

0
Публикатор #
На форуме автоматически создана тема для обсуждения статьи.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Arduino UNO
Arduino UNO
Печатная плата для усилителя "LM3886 + AD825" Ветрогенератор
вверх