Учебный стенд LESO6 и LabVIEW. Часть 2

Шауэрман Александр А., shamrel@yandex.ru
       Борисов Александр В.

Работа над ошибками и новая библиотека

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

1. Подприборы FTDI в большинстве своем не позволяют установить зависимость данных для четкого порядка выполнения, в результате приходится использовать Flat Sequence Structure, что загромождает диаграмму, уменьшает наглядность и ограничивает гибкость программирования. Самый простой способ создать зависимость – это в каждом приборе, помимо входа handle, добавить такой же выход, тогда приборы можно будет соединять последовательно.

2. Программа не имеет системы обработки ошибок. Пока в примере нет сложного алгоритма, а вся программа состоит из небольшого числа подприборов, ошибку обнаружить легко. Но когда будут реализованы алгоритмы пакетного обмена данными и управления, а глубина иерархии станет значительной, определить, почему не работает система, станет сложно. Потому следует в подприборах организовать поток кластера ошибок. Кроме того, обработка ошибок – еще одно средство (помимо handle) создания зависимости данных, определяющее порядок выполнения. И не следует забывать, что обработка ошибок – это признак хорошего стиля программирования!

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

4. Все модули для работы с FTDI выглядят одинаково и для того чтобы на блок-диаграмме их можно было различать, приходится активировать Label – текстовую метку, что загромождает диаграмму. Если же сделать изображение на иконке "говорящим", то наглядность программы возрастет.

Ниже на рисунках показаны блок-диаграммы виртуальных приборов (ВП) leso6_demo2.vi и leso6_demo1.vi (из предыдущей статьи). ВП выполняют одинаковыю функцию.

 

FTDI Open Device By Description
Рисунок 1 – Блок-диаграмма leso6_demo1.vi (так было)

 

FTDI Open Device By Description
Рисунок 2 – Блок-диаграмма leso6_demo2.vi (так стало)

Второй ВП создан с помощью новой библиотеки LESO, где учтены все замечания. Библиотека (формально это не библиотека, а просто набор отдельных ВП) содержит несколько модулей: LESO OPEN (файл LESO_open.vi), LESO CLOSE (файл LESO_close.vi), LESO WRITE (файл LESO_write.vi), LESO READ (файл LESO_read.vi), LESO QUEUE (файл LESO_queue_status.vi) и LESO ERR (файл LESO_error.vi). Подробное описание модулей и ссылка для скачивания в конце статьи.

Логику работы последнего ВП проследить просто. Первым делом стенд LESO открывается в модуле с иконкой LESO OPEN, в том же модуле происходит инициализация последовательного порта. Далее стенду отправляются данные Write Data количеством Bytes To Write, очевидно, что это действие выполняет модуль с иконкой LESO WRITE. Затем модуль с иконкой LESO QUEUE по истечении 50 мс передает модулю LESO READ количество байт для приема. После приема дескрипторы устройства закрываются модулем LESO CLOSE. Все модули последовательно соединены между собой дескриптором handle и кластером ошибок. Завершает блок-диаграмму Simple Error Handler – обработчик ошибок, который в случае ошибки выдаст диалоговое окно с описанием ошибки и ее источником.

Цифровой термометр

Для примера использования модулей "LESO" создадим простой практический пример: систему мониторинга температуры. На стенде LESO6LESO1) установлен цифровой датчик температуры DS18B20. Датчик подключен к микроконтроллеру по последовательному однопроводному интерфейсу 1-Wire. Наша программа на LabVIEW будет запрашивать значение температуры с устройства и выводить на экран с помощью специального индикатора Thermometer. Так как устройство будет выполнять всего одну функцию (измерение температуры), то протокол взаимодействия упростим до одной команды: запрос температуры. Команду можно выполнить, послав один байт, при этом, так как стенд выполняет всего лишь одно действие, особого значения не имеет, какой именно будет этот байт. Для простоты положим так: стенд в ответ на любой байт должен слать значение температуры.

Интерфейс 1-Wire довольно сложен для реализации, однако можно воспользоваться готовым драйвером из демонстрационного проекта. Файл исходного кода программы, драйвера и makefile можно скачать с репозитория. Ниже приведен основной исходный код.

#include <avr/io.h>
#include "uart.h"
#include "ds18b20.h"
 
int main()
{
    uart_init();                        // Инициализируем UART.
    // Структура для чтения температуры.
    ds18b20_memory_t ds18b20_memory = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
    for(;;)                                // Бесконечный цикл.
    {
        ds18b20_convert();                // Запускаем преобразование температуры.
        // Ждем команды.
        uart_getchar(NULL);
        ds18b20_read(&ds18b20_memory);    // Читаем температуру.
 
        // Проверяем контрольную сумму считанных из датчика данных.
        if(!ds18b20_crc8((uint8_t *)&ds18b20_memory, sizeof(ds18b20_memory)))
        {    // Если сошлось, то отправляем значение температуры:
            // Передаем целую часть значения температуры.
            uart_putchar(ds18b20_memory.temper_MSB, NULL);
            // Передаем дробную часть значения температуры.
            uart_putchar(ds18b20_memory.temper_LSB, NULL);
        }
    }
    return 0;
}

Для использования функций драйвера UART и датчика температуры DS18B20 подключены соответствующие заголовочные файлы "uart.h" и "ds18b20.h". В основной функции main происходит инициализация UART (115200 бит/с, 8-битный режим, 1 STOP-bit), далее объявляется и инициализируется структура ds18b20_memory, которая послужит контейнером для принятых от датчика данных. В бесконечном цикле, созданном с помощью пустого оператора for(;;) запускается процесс измерения температуры – функция ds18b20_convert(). Далее программа ожидает прихода по последовательному порту байта данных – функция uart_getchar(NULL). Принятый байт никуда не записывается и никак не обрабатывается: значение его не важно, важен сам факт прихода. После приема байта функция ds18b20_read() читает данные с датчика. В качестве параметра функции указывается адрес структуры ds18b20_memory. Затем полученная структура проходит проверку на контрольную сумму, и если ошибок не обнаружено, то по UART отправляется два байта значения температуры, а программа переходит к следующей итерации цикла.

Front Panel  DS18B20 LabVIEW

С программой на LabVIEW дело обстоит еще проще. Модифицируем предыдущий пример следующим образом: заключим подприборы записи (LESO WRITE) и чтения (LESO READ) в цикл while. Условие завершения цикла – нажатие кнопки STOP или ошибка выполнения. Массив Write Data содержит лишь один байт, Bytes To Write установим тоже в единицу. После отправки команды ждем 20мс (параметр у подприбора LESO QUEUE) и читаем полученные данные. Если мы получили два байта, а именно столько мы отправляли из микроконтроллера, то преобразуем данные и выводим на индикатор. Светодиод Valid горит зеленым, если мы приняли два байта, следовательно значения актуальны, в противном случае – красным. Между итерациями цикла установим задержку 750мс, столько времени нужно датчику, согласно документации, для гарантированного выполнения преобразования температуры в код. Следует заметить, что если установить меньшее значение, либо вообще обойтись без задержки, то работоспособность системы не нарушится, стенд будет исправно возвращать на каждый запрос данные, однако реально меняться они будут все также раз в 750мс. Поэтому, для того чтобы разгрузить процессор искусственно введена эта задержка.

 

Atmega DS18B20 LabVIEW
Рисунок 3 – Блок-диаграмма термометра

Если все сделано правильно: стенд подключен к компьютеру, прошивка загружена, программа на LabVIEW запущена, то индикатор "Термометр" будет в реальном времени показывать температуру на стенде. Можно попробовать прикоснуться пальцем к микросхеме датчика (микросхема подписана на плате как D4) и значение индикатора изменится. Если что-то пойдет не так, то читайте и анализируйте сообщения об ошибках.

Почитать по теме:

Учебный стенд LESO6 и LabVIEW. Часть1. На примерах демонстрируется возможность использование среды LabVIEW для работы с учебным стендом LESO6.

Настройка IDE Eclipse для работы с микроконтроллерами AVR. Статья посвящена установке и настройке интегрированной среды разработки (IDE) Eclipse для работы с микроконтроллерами семейства AVR. Установка в Windows и Linux.

Создание проекта в Eclipse для микроконтроллеров AVR. Описан процесс создания и настройки проекта в среде Eclipse с использованием плагина AVR-Eclipse и экспорт проекта с готовым Makefile.

Настройка Eclipse для работы с программатором avrdude. Рассмотрены способы загрузки hex-файла в память программ стенда с помощью программатора avrdude, показаны методы интеграции avrdude и Eclipse.

На GitHub самая новая версия.  Исходные коды прошивки микроконтроллера стенда LESO6, написаны на Си, демонстрирует работу микропроцессора с периферией. В том числе и рассмотренный в статье пример. Там же найдете модули LabVIEW LESO и программу термометра.

 

Справочник по модулям LabVIEW LESO

LESO OPEN

LESO_open.vi.

Открывает соединение с устройством LESO. Настраивает параметры обмена по последовательному порту. Возвращает дескриптор соединения handle. Этот дескриптор должен быть использован для последующей работы с устройством.

Используется драйвер D2XX (динамическая библиотека ftd2xx.dll).

LESO_open.vi

cstr
LESO Name. Имя лабораторного стенда. По этому имени произойдет поиск в системе и открытие устройста. Прошито в память FTDI, для стендов это "LESO6", "LESO1.1" и т.д.
cnclst
Serial Config. Структура с параметрами последовательного порта.
cu32
Baudrate. Скорость передачи данных. Бит/с.
cu8
Word Length. 8-ми или 7-ми битовая передача данных.
cu8
Stop Bits. Количество STOP-бит при передаче байта информации.
cu8
Parity. Контроль четности. 9-ый бит.
istr
Serial Number. Серийный номер стенда. Содержит префикс с описанием типа устройства и порядковый номер в партии.
iu32
Handle. Дескриптор устройства.
cerrcodeclst
error in. Входной терминал кластера ошибки.
cbool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ci32
code. Код ошибки.
cstr
source. Описание происхождения ошибки или предупреждения.
ierrcodeclst
error out. Выходной терминал кластера ошибки.
ibool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ii32
code. Код ошибки.
istr
source. Описание происхождения ошибки или предупреждения.


LESO CLOSE

LESO_close.vi.

Закрывает устройство. Освобождает Handle.

LESO_close.vi

cu32
Handle in. Дескриптор устройства. Вход.
iu32
FT_Status. Состояние устройства после выполнения операции.
cerrcodeclst
error in. Входной терминал кластера ошибки.
cbool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ci32
code. Код ошибки.
cstr
source. Описание происхождения ошибки или предупреждения.
ierrcodeclst
error out. Выходной терминал кластера ошибки.
ibool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ii32
code. Код ошибки.
istr
source. Описание происхождения ошибки или предупреждения.


LESO WRITE

LESO_write.vi.

Передает массив данных устройству.

LESO_write.vi

cu32
Handle in. Дескриптор устройства. Вход.
iu32
Handle out. Дескриптор устройства. Выход.
iu32
FT_Status. Состояние устройства после выполнения операции.
c1du8
Buffer. Массив данных для передачи устройству.
cu32
Bytes To Write. Количество байт, которое должно быть передано устройству.
iu32
Bytes Written. Количество байт, которое было реально передано устройству.
cerrcodeclst
error in. Входной терминал кластера ошибки.
cbool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ci32
code. Код ошибки.
cstr
source. Описание происхождения ошибки или предупреждения.
ierrcodeclst
error out. Выходной терминал кластера ошибки.
ibool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ii32
code. Код ошибки.
istr
source. Описание происхождения ошибки или предупреждения.


LESO READ

LESO_read.vi

Принимает массив данных с устройства.

LESO_read.vi

cu32
Handle in. Дескриптор устройства. Вход.
iu32
Handle out. Дескриптор устройства. Выход.
iu32
FT_Status. Состояние устройства после выполнения операции.
cu32
Bytes To Read. Количество байт, которое должно быть принято от устройства.
i1du8
Read Data. Принятый массив данных.
iu32
Bytes Read. Количество принятых байт.
cerrcodeclst
error in. Входной терминал кластера ошибки.
cbool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ci32
code. Код ошибки.
cstr
source. Описание происхождения ошибки или предупреждения.
ierrcodeclst
error out. Выходной терминал кластера ошибки.
ibool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ii32
code. Код ошибки.
istr
source. Описание происхождения ошибки или предупреждения.


LESO QUEUE

LESO_queue_status.vi

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

LESO_queue_status.vi

cu32
Handle in. Дескриптор устройства. Вход.
iu32
Handle out. Дескриптор устройства. Выход.
iu32
FT_Status. Состояние устройства после выполнения операции.
cu32
milliseconds to wait. Ожидание перед запросом статуса (мс). Установите 0, если требуется вернуть статус мгновенно.
iu32
Bytes Waiting. Количество байт доступных в буфере приема для чтения.
cerrcodeclst
error in. Входной терминал кластера ошибки.
cbool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ci32
code. Код ошибки.
cstr
source. Описание происхождения ошибки или предупреждения.
ierrcodeclst
error out. Выходной терминал кластера ошибки.
ibool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ii32
code. Код ошибки.
istr
source. Описание происхождения ошибки или предупреждения.

LESO_ERR

LESO_error.vi

Преобразует FT_Status в ошибку. Если FT_Status не равен FT_OK, то добавляет ошибку в кластер ошибок. В описании ошибки будет имя текущего ВП и FT_Status.

LESO_error.vi

cu32
FT_Status. Состояние устройства после выполнения операции.
cerrcodeclst
error in. Входной терминал кластера ошибки.
cbool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ci32
code. Код ошибки.
cstr
source. Описание происхождения ошибки или предупреждения.
ierrcodeclst
error out. Выходной терминал кластера ошибки.
ibool
status содержит TRUE (X), если ошибка произошла, если ошибки нет, то содержит FALSE (галочка).
ii32
code. Код ошибки.
istr
source. Описание происхождения ошибки или предупреждения.
12 мая 2015

Комментарии:



Аватар пользователя Лолипоп

Доброго дня. На рисунке 3 в кейсе стоит элемент в виде параллелепипеда, выходящего в трубу, к нему еще ноль подключен сверху. Что это? И зачем к нему подключен ноль? Затем результат еще делится на 16 (!?) Зачем?

Орфографическая ошибка в тексте:
Чтобы сообщить об ошибке автору, нажмите кнопку "Отправить сообщение об ошибке". Вы также можете отправить свой комментарий.