Отображение показаний датчика Bluetooth LE на ЖК-экране, подключенном к STM32

Отображение показаний датчика Bluetooth LE на ЖК-экране, подключенном к STM32

18 апреля 2022 г.

Цель этого проекта Bluetooth LE – считывать данные датчика качества воздуха и отображать их на ЖК-дисплее, подключенном к плате STM32. Веб-браузер считывает данные датчика и передает их на плату STM32 с помощью BleuIO.


Вступление


Проект основан на STM32 Nucleo-144, который управляет ЖК-дисплеем с помощью BleuIO.


Для этого проекта нам понадобятся [два USB-ключа BleuIO] (https://www.bleuio.com/), один из которых подключен к плате Nucleo, а другой — к компьютеру, на котором запущен веб-скрипт, и HibouAir — устройство для мониторинга качества воздуха . Когда BleuIO Dongle подключен к USB-порту платы Nucleo, STM32 распознает его и сразу начнет рекламу. Это позволяет ключу на порту компьютера подключаться к веб-скрипту.


С помощью веб-скрипта на компьютере мы можем сканировать и получать данные датчика качества воздуха от HibouAir. Затем мы отправляем эти данные на ЖК-экран, подключенный к STM32 с помощью Bluetooth.


В этом примере мы использовали плату разработки STM32 Nucleo-144 с микроконтроллером STM32H743ZI (STM32H743ZI с поддержкой micro mbed Development Nucleo-144, серия ARM® Cortex®-M7 MCU, 32-разрядная встроенная оценочная плата). Эта плата разработки имеет USB-хост, к которому мы подключаем ключ BleuIO.


Если вы хотите использовать другую настройку, вам нужно убедиться, что она поддерживает USB-хост, и помнить, что настройка GPIO может отличаться и может потребоваться перенастройка в файле .ioc.


О коде


Исходный код проекта доступен на Github.


Либо клонируйте проект, либо загрузите его в виде zip-файла и разархивируйте в рабочую область STM32CubeIDE.


Если вы загружаете проект в виде zip-файла, вам нужно будет переименовать папку проекта с «stm32_bleuio_lcd-master» на «stm32_bleuio_lcd».



Подключите SDA к PF0 на плате Nucleo, а SCL к PF1.


Затем настройте I2C2 в файле ioc STM32Cube следующим образом. (Обязательно измените частоту скорости I2C на 50 кГц в соответствии с требованиями ЖК-дисплея.)





В функции USBH_CDC_ReceiveCallback в USB_HOST\usb_host.c мы копируем CDC_RX_Buffer во внешнюю переменную с именем dongle_response, которая доступна из файла main.c.


```нажмите


недействительным USBH_CDC_ReceiveCallback (USBH_HandleTypeDef * phost)


если (фост == &hUsbHostFS)


// Обрабатывает данные, полученные от хоста USB CDC, здесь просто распечатывает их на UART


rx_size = USBH_CDC_GetLastReceivedDataSize (фост);


HAL_UART_Transmit(&huart3, CDC_RX_Buffer, rx_size, HAL_MAX_DELAY);


// Копируем буфер во внешний буфер dongle_response


strcpy((char )dongle_response, (char )CDC_RX_Buffer);


// Сбросить буфер и перезапустить функцию обратного вызова, чтобы получить больше данных


набор памяти (CDC_RX_Buffer, 0, RX_BUFF_SIZE);


USBH_CDC_Receive(фост, CDC_RX_Buffer, RX_BUFF_SIZE);


возврат;


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


```нажмите


недействительный ключ_интерпретатор (uint8_t * ввод)


если (стрлен ((символ *) ввод)! = 0)


if(strstr((char *)input, "\r
РЕКЛАМА...") != NULL)


реклама = правда;


if(strstr((char *)input, "\r
РЕКЛАМА ПРЕКРАЩЕНА") != NULL)


реклама = ложь;


if(strstr((char *)input, "\r
CONNECTED") != NULL)


Подключен = Истина;


HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);


if(strstr((char *)input, "\r
ОТКЛЮЧЕНО") != NULL)


Подключен = Ложь;


HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);


if(strstr((char *)ввод, "L=0") != NULL)


isLightBulbOn = ложь;


//HAL_GPIO_WritePin(Lightbulb_GPIO_Port, Lightbulb_Pin, GPIO_PIN_RESET);


lcd_clear();


writeToDongle((uint8_t*)DONGLE_SEND_LIGHT_OFF);


uart_buf_len = sprintf(uart_tx_buf, "\r
Очистить экран\r
");


HAL_UART_Transmit(&huart3, (uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);


if(strstr((char *)input, "L=1") != NULL)


isLightBulbOn = истина;


writeToDongle((uint8_t*)DONGLE_SEND_LIGHT_ON);


lcd_clear();


lcd_write (ввод);


memset(&dongle_response, 0, RSP_SIZE);


Мы помещаем функцию интерпретатора в основной цикл.


```нажмите


/ Бесконечный цикл /


/ КОД ПОЛЬЗОВАТЕЛЯ НАЧИНАЕТСЯ, ПОКА /


пока (1)


/ КОД ПОЛЬЗОВАТЕЛЯ КОНЕЦ ПОКА /


MX_USB_HOST_Process();


/ КОД ПОЛЬЗОВАТЕЛЯ НАЧАЛО 3 /


// Простой обработчик ввода uart


обработатьUartInput(uartStatus);


// Интерпретирует данные ключа


dongle_interpreter(dongle_response);


// Начинает рекламу, как только ключ будет готов.


if(!isAdvertising && !isConnected && isBleuIOReady)


HAL_Delay(200);


writeToDongle((uint8_t*)DONGLE_CMD_AT_ADVSTART);


реклама = правда;


/ КОД ПОЛЬЗОВАТЕЛЯ КОНЕЦ 3 /


Использование примера проекта


Что нам понадобится


  • Два [ключа BleuIO] (https://www.bleuio.com/)

  • Плата с микроконтроллером STM32 с портом USB. (Для разработки этого примера использовалась макетная плата Nucleo-144: NUCLEO-H743ZI2. Для подключения ключа к плате Nucleo можно использовать кабель «USB A — Micro USB B» с переходником USB A «мама-мама». использоваться.)


  • [STM32CubeIDE] (https://www.st.com/en/development-tools/stm32cubeide.html)

  • Модуль жидкокристаллического дисплея — [NHD-0420D3Z-NSW-BBW-V3] (https://www.digikey.com/en/products/detail/newhaven-display-intl/NHD-0420D3Z-NSW-BBW-V3/ 2626390?s=N4IgTCBcDaIHIAkAiBaADAFjGpBmAWinAMoDqKAQheQGq4gC6AvkA)

  • [HibouAir] (https://www.hibouair.com/) — устройство для контроля качества воздуха.

Импорт в качестве существующего проекта


В STM32CubeIDE выберите File>Import…



Затем выберите «Общие»> «Существующие проекты» в рабочей области, затем нажмите «Далее >».



Убедитесь, что вы выбрали свое рабочее пространство в «Выбрать корневой каталог:»


Вы должны увидеть проект «stm32_bleuio_SHT85_example», проверьте его и нажмите «Готово».



Запуск примера


Загрузите код в STM32 и запустите пример. USB-ключ, подключенный к STM32, автоматически начнет рекламу.


Отправка данных датчика на ЖК-экран из веб-браузера


Подключите ключ BleuIO к компьютеру. Запустите веб-скрипт для подключения к другому ключу BleuIO на STM32. Теперь вы можете отправлять данные датчика на ЖК-экран.


Для работы этого скрипта нам нужно


  • [USB-ключ BleuIO] (https://www.bleuio.com/), подключенный к компьютеру.

  • [Библиотека javascript BleuIO] (https://www.npmjs.com/package/bleuio)

  • Chrome 78 или более поздней версии, и вам необходимо включить флаг #enable-experimental-web-platform-features в chrome://flags

  • Веб-бандер

Создайте простой HTML-файл с именем index.html, который будет служить интерфейсом скрипта. Этот HTML-файл содержит несколько кнопок, которые помогают подключиться, прочитать рекламные данные с HibouAir, чтобы получить данные датчика качества воздуха и отправить эти данные на ЖК-экран, который подключен к stm32.


```разметка




<голова>


<метакодировка="UTF-8" />




<ссылка


href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"


отн = "таблица стилей"


целостность = "sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"


кроссоригин = "анонимный"


Данные датчика качества воздуха Bluetooth LE на ЖК-экран



<тело класс="мт-5">



<изображение


src="https://www.bleuio.com/blog/wp-content/themes/bleuio/images/logo.png"


Данные датчика качества воздуха Bluetooth LE на ЖК-экран


<дел класс = "строка">










<скрипт src="script.js">




Создайте файл js с именем script.js и включите его в конец файла HTML. Этот файл js использует js-библиотеку BleuIO для написания AT-команд и связи с другим ключом.


```javascript


импортировать * как my_dongle из 'bleuio'


импортировать «регенератор-время выполнения/время выполнения»


const dongleToConnect='[0]40:48:FD:E5:2F:17'


//постоянный идентификатор датчика = '0578E0'


document.getElementById('connect').addEventListener('click', function(){


my_dongle.at_connect()


document.getElementById("clearScreen").disabled=false;


document.getElementById("connect").disabled=true;


document.getElementById("sendDataForm").hidden=false;


document.getElementById ("sendDataForm"). addEventListener ("отправить", функция (событие) {


событие.preventDefault()


const SensorID = document.getElementById('sensorID').значение


getSensorData(идентификатор датчика)


setInterval (функция () {getSensorData (идентификатор датчика)}, 10000);


const getSensorData =((sensorID)=>{


my_dongle.ati().then((данные)=>{


//сделать центральным, если нет


если(JSON.stringify(данные).includes("Периферийные устройства")){


console.log('периферия')


my_dongle.at_dual().then((x)=>{


console.log('теперь центральный')


.тогда(()=>{


// подключаемся к ключу


my_dongle.at_getconn().then((y)=>{


если(JSON.stringify(y).includes(dongleToConnect)){


console.log('уже подключено')


}еще{


my_dongle.at_gapconnect(dongleToConnect).then(()=>{


console.log('подключение успешно')


.затем(асинхронный()=>{


вернуть my_dongle.at_findscandata(sensorID,6).затем((sd)=>{


console.log('сканданные',sd)


пусть advData = sd[sd.length - 1].split(" ").pop()


пусть positionOfID = advData.indexOf (sensorID);


let tempHex = advData.substring(positionOfID+14, positionOfID+18)


let temp = parseInt('0x'+tempHex.match(/../g).reverse().join(''))/10;


пусть co2Hex = advData.substring(positionOfID+38, positionOfID+42)


пусть co2 = parseInt('0x'+co2Hex);


//console.log(temp,co2)


возврат {


«СО2»: СО2,


'Время': temp,


.тог((х)=>{


console.log(x.CO2)


console.log(x.Temp)


var theVal = "L=1 SENSOR ID"+sensorID+"TEMPERATURE" + x.Temp + ' °c CO2 '+ x.CO2+' ppm';


console.log('Сообщение отправлено 1')


// отправить команду для отображения данных


my_dongle.at_spssend(theVal).then(()=>{


console.log('Сообщение отправлено' + theVal)


document.getElementById('clearScreen').addEventListener('щелчок', function(){


my_dongle.ati().then((данные)=>{


//сделать центральным, если нет


если(JSON.stringify(данные).includes("Периферийные устройства")){


console.log('периферия')


my_dongle.at_central().then((x)=>{


console.log('теперь центральный')


.тогда(()=>{


// подключаемся к ключу


my_dongle.at_getconn().then((y)=>{


если(JSON.stringify(y).includes(dongleToConnect)){


console.log('уже подключено')


}еще{


my_dongle.at_gapconnect(dongleToConnect).then(()=>{


console.log('подключение успешно')


.тогда(()=>{


// отправляем команду на очистку экрана


my_dongle.at_spssend('L=0').then(()=>{


console.log('Экран очищен')


В скрипте есть кнопка для подключения к COM-порту на компьютере. Имеется текстовое поле, в котором вы можете написать идентификатор датчика устройства контроля качества воздуха. После подключения скрипт попытается получить объявленные данные от датчика и преобразовать их в значимые данные. После этого он отправит эти данные на плату STM32, которые затем отобразятся на ЖК-экране.


Чтобы подключиться к ключу BleuIO на STM32, убедитесь, что STM32 включен и к нему подключен ключ BleuIO.


Получить MAC-адрес


Следуйте инструкциям, чтобы получить MAC-адрес ключа, подключенного к STM32.


  • Откройте этот сайт https://bleuio.com/web_terminal.html и нажмите «Подключиться к ключу».

  • Выберите соответствующий порт для подключения.

  • Как только он говорит, что подключен, введите ATI. Это покажет информацию о ключе и текущий статус.

  • Если ключ находится в периферийной роли, установите его в центральную, набрав AT+CENTRAL.

  • Теперь выполните сканирование пробелов, набрав AT+GAPSCAN.

  • Как только вы увидите свой ключ в списке, остановите сканирование, нажав Ctrl+C.

  • Скопируйте идентификатор и вставьте его в строку скрипта (script.js) № 4.


Запустить веб-скрипт


Вам понадобится веб-бандер. Вы можете использовать parcel.js


После установки пакета js перейдите в корневой каталог веб-скрипта и введите "parcel index.html". Это запустит вашу среду разработки.



Откройте скрипт в браузере. Для этого примера мы открыли http://localhost:1234.


Вы можете легко подключиться к ключу и увидеть данные о качестве воздуха на ЖК-экране. Ответ отобразится на экране консоли браузера.


Веб-скрипт выглядит так:



Выход


Сообщение отобразится на ЖК-экране.



Также опубликовано [здесь].



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE