STM Урок 128. LAN8742A. LWIP. NETCONN. HTTP. AJAX. Часть 3

 

 

 

В предыдущей части занятия мы продолжили писать функционал нашего клиент-сервера для отправки и приёма данных между собственно сервером и клиентом.

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

Стандартная функция вывода процессов не умеет этого делать, поэтому добавим функцию для сортировки выше нашей функции DynWebPageStr

 

В данной функции мы создали структуру с одним полем — двумерным символьным массивом. Когда такой массив обёрнут в структуру, к нему будет легче прицепиться.

Использовать для сортировки мы будем метод пузырька. Я думаю, многим этот метод известен. Мы сравниваем две соседние строки или величины, и та, которая меньше (если мы, конечно, сортируем наши данные по возрастанию), либо остаётся вверху, либо уходит вверх. Так мы доходим до самого низа и у нас получается то, что самая большая величина у нас находится уже внизу. Затем мы данный процесс повторяем, но до самой нижней строки уже не доходим, а доходим только до предыдущей. И так до тех пор, пока у нас самая меньшая величина не вытеснится вверх, как воздушный пузырь.

Создадим ещё один указатель на строку, которая у нас пришла в качестве аргумента

 

Добавим ещё несколько локальных переменных

 

Создадим указатель на данные типа нашей структуры и привяжем его к глобальному символьному буферу

 

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

 

Далее добавим цикл сортировки строк по алгоритму, который я объяснил выше

 

И затем, наоборот, скопируем наши строки из массива назад в нашу строку, только теперь они будут уже отсортированы в алфавитном порядке

 

По окончании тела функции мы обнулим окончание строки.

Теперь вызовем нашу функцию сортировки строк в функции DynWebPageStr

 

Соберём код, прошьём контроллер, обновим страницу в браузере и нажмём кнопку START

Теперь у нас всё отсортировано, причём процессы, наименование которых с большой буквы, находятся сверху. Даже как-то статично смотрится после того, как прыгали наши строки. Но зато если будет постепенно расти использование стека в какой-то из функции, то мы это увидим без труда.

Пока мы до сих пор передавали с сервера в браузер текстовые данные.

Но есть возможность также передавать данные и других типов.

Зачастую возникает необходимость передать массивы числовых и бинарных данных, которые находятся в памяти не в виде строковых выражений данных величин, а именно в первозданном бинарном виде. Не стоит эти данные сначала преобразовывать в строку, а затем на стороне клиента снова их преобразовывать в числовые. На такие действия уходит очень много ресурсов — как процессорного времени, так и памяти. Если есть возможность обойтись без кодирования-декодирования, то лучше ею пользоваться. Мы так с вами всегда и делаем, когда передаём показания с различных датчиков, а также состояния каких-либо процессов. Поступим так и в нашем случае.

Представим ситуацию, что у нас есть массив каких-то данных, например показаний АЦП за какой-то промежуток времени. И мы этот массив хотим на страничке в браузере клиента показать в виде графика.

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

Для добавления графиков в WEB-страницы существует несколько готовых бесплатных библиотек.

Все они используют JavaScript и найти их несложно.

Вот и мы воспользуемся одной из них — это библиотека Chart.js, которая выпущена под лицензией MIT. Данная лицензия позволяет использовать данную библиотеку бесплатно по любому назначению с одной лишь ремаркой — ссылкой на файл лицензии. Файл лицензии мы также можем разместить в папке со своим проектом, если будем куда-то распространять такой проект. Только делать этого вовсе не нужно, так как мы скачаем с GitHub саму библиотеку в виде файла скрипта JS, а в содержимом данного файла есть ссылка на файл лицензии на Github. Так что, думаю, ничего мы не нарушаем. Поэтому идём на GitHub за библиотекой по ссылке https://github.com/chartjs/Chart.js и спокойно скачиваем скрипт. Он распространён в нескольких версиях, мы возьмём минимизированный, так как наша виртуальная система не любит больших файлов. В минимизированных версиях скриптов убраны все табуляции, пробелы, и даже переводы строк. От этого файл становится порой вдвое меньше, хотя он становится абсолютно нечитабельным, но работоспособность его от этого никак не страдает. Последнюю версию библиотеки мы возьмём по этой ссылке: Chart.js on GitHub.

Перейдём по ссылке и скачаем минимизированную версию

Создадим в папке с нашей главной страницей папку «js» и положим туда данный файл.

Подключим его в нашей главной странице index.php, а заодно добавим заголовок нашей страницы

 

Теперь мы спокойно можем обращаться ко всем функциям данной библиотеки. Рассказывать я про них не буду, так как урок не об этом, мы просто будем ими пользоваться. На официальном сайте всё об этом рассказано.

 

 

В блоке article после нашей информации о процессах, которую мы только что смотрели добавим также блок canvas, так как этого требует библиотека, а также блок с кнопкой START, аналогичной кнопке в предыдущем блоке, которая будет запускать наш график, для чего мы добавим данной кнопке также и функцию

 

Прежде чем добавлять данную функцию, мы в блоки скрипта сначала добавим объект класса нашего графика

 

Затем в функции onload() мы получим ссылку на блок с идентификатором нашего графика и создадим из 512 16-битных чисел

Затем мы создадим объект класса графика, в которой проведём первоначальную инициализацию. Так как метки на каждую точку нам не нужны, то мы их забьём пустыми строками, используя соответствующий массив, затем настроим фон, добавим данные в виде нашего массива с нулями, произведём настройки цветов, фонов и некоторых других опций, с которыми вы также можете ознакомиться на официальном сайте разработчика библиотеки

 

Добавим ещё один таймер, создадим для него сначала идентификатор, добавив ещё одну переменную

 

После функции первого таймера Timer1 добавим функцию для второго таймера

 

В данной функции мы также создали запрос, но с другим типом. Такой тип нам и нужен для оперирования сырыми (бинарными) данными.

Затем мы добавим событие на обработку пришедших данных от сервера, в которой мы считаем наши данные как 16-битные и присвоим их полю данных нашего графика, а затем мы обновим его. Потом отправим запрос серверу и запустим наш таймер

Добавим функцию-обработчик для нашей кнопки в самом низу скрипта

Мы обнулили поле с информацией о процессах, затем кнопку START мы превратили в кнопку STOP, добавив также соответствующую функцию. Ну и, конечно же, не забываем запустить наш таймер, вернее его функцию. Напишем функции для кнопки STOP ниже

 

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

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

Функция startstring()

 

Функция stopstring()

 

Теперь сохраним нашу страницу, сгенерируем файл fsdata.c, обновим дерево нашего проекта и добавим ещё одну функцию формирования документа на запрос клиента после функции DynWebPageStr

 

В данной функции мы пока только добавили некоторые локальные переменные и массив для будущего документа, который мы будем посылать клиенту на его запрос.

Соберём заголовок для пакета HTTP

 

В данном заголовке мы передали длину в байтах, чтобы клиенту легче было работать с нашим пакетом. У нас всего 512 величин по 16 бит, поэтому байтов будет 1024.

Измерим длину заголовка, и в цикле наберём данные, формируя их случайным образом, используя для наш аппаратный генератор, а затем передадим их вместе с заголовком клиенту

 

Добавим также в функции задачи обработки запросов отследим запрос клиента, а в теле условия мы вызовем нашу функцию формирования пакета для ответа клиенту

 

Также не забываем добавить запрос клиента на файл библиотеки для графика

 

Соберём код, прошьём контроллер, обновим страницу в браузере и нажмём кнопку START под полем для графика

У нас прекрасно обновляется информация раз в секунду, я пробовал укорачивать интервал таймера до 40 милисекунд, то есть график обновлялся до 25 кадров в секунду, но иногда были подвисания, особенно в загруженной сети. Напрямую я проводом плату соединять с компьютером не пробовал. Но, я считаю, что и с такой скоростью передача 16-битных данных и отображение на графике такого количества данных динамически — это великое дело.

Думаю, что когда мы будем использовать WebSocket, то процесс пойдёт ещё веселее.

Итак, на данном занятии мы научились передавать данные клиенту по запросу посредством протокола HTTP с использованием некоторых интересных возможностей языка JavaScript без перезагрузки страницы. И не только это, а ещё и передавать данные от клиента серверу также без перезагрузки страницы. Также мы научились передавать пакеты по протоколу HTTP не только строковых, но и бинарных типов.

Всем спасибо за внимание!

 

Предыдущая часть Программирование МК STM32 Следующий урок

Исходный код

 

 

Отладочную плату можно приобрести здесь 32F746G-DISCOVERY

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM LAN8742A. LWIP. NETCONN. HTTP. AJAX

3 комментария на “STM Урок 128. LAN8742A. LWIP. NETCONN. HTTP. AJAX. Часть 3
  1. Peter:

    Hello Narod,

    First, thank you this lots of STM32 article.

    I probaly compile this project, but have some problem.
    First:following lines in error.
    hdma2d.LayerCfg[0].AlphaInverted = DMA2D_REGULAR_ALPHA;
    hdma2d.LayerCfg[0].RedBlueSwap = DMA2D_RB_REGULAR;
    Second: I deleted this lines, and complie is ok.
    Ping ok, but no load the webpage. Why?

    Best regards
    Peter

  2. Peter:

    Other info:
    The TFT display full black and no visible the text.

  3. Peter:

    Hello Narod,

    First, thank you this lots of STM32 article.

    I probaly compile this project, but have some problem.
    First: following lines in error.
    hdma2d.LayerCfg [0] .AlphaInverted = DMA2D_REGULAR_ALPHA;
    hdma2d.LayerCfg [0]. RedBlueSwap = DMA2D_RB_REGULAR;
    Second: I deleted this lines, and complie is ok.
    Ping ok, but no load the webpage. Why?
    The TFT display full black and no visible the text.

    Best regards
    Peter

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*