Перейти к публикации
iT4iT.CLUB

Таблица лидеров


Популярные публикации

Отображаются публикации с наибольшей репутацией на 25.02.2019 во всех областях

  1. 1 балл
    Доброе время суток. @Дмитрий Давайте попробуем, но я заранее предупреждаю, что Вам придется самостоятельно проводить все испытания. Я лишь постараюсь помочь с рекомендациями относительно данного проекта. И так. На сколько я понял, общая идея заключается в подсчете импульсов чашечного анемометра. Самый верный путь, это регистрировать импульсы по прерыванию т.к это не тратит драгоценное время ЦП. Далее, опираясь на частоту импульсов вычислять расстояние, которое прошел анемометр как будто это колесо автомобиля, а уже из этих данных выводить скорость. Стоит учитывать, что при расчете частоты нужно брать время между предыдущим и текущим расчетом скорости ветра, а не фиксированный интервал т.к есть и другие задачи время выполнения которых может меняться, а микроконтроллер выполняет код в реальном времени без распараллеливания задач. В первую очередь необходимо определиться, какой порт микроконтроллера будем задействовать. Я возьму за основу порт GPIO14. Он уже был задействован в проекте, поэтому в основном файле необходимо закомментировать вызов функции, которая его занимает. //gpio_14(); // Расхождение расчетной абсолютной влажности между показаниями с двух датчиков, например, BME280 Теперь порт свободен и можно преступать к коду анемометра. Мне не известно какие датчики Вы еще используете поэтому всё дальнейшее описание я буду делать так, как будто у меня только один этот датчик, так будет более понятно. Выберите пользовательский файл в котором будите работать, это любой .h файл начинающийся с префикса users_ или создайте новый файл со своим уникальным именем, например users_wspeed.h. Выбранный Вами файл должен быть подключен через оператор include в основном файле программы, другие пользовательские файлы должны быть закомментированы. Для себя я выбрал вариант с новым файлом users_wspeed.h //#include "users_auto.h"; // Пользовательская конфигурация датчиков, именно тут описывается с какими датчиками работать //#include "users_bme280_x2.h"; // Пример для двух датчиков BME280 (несовместим с users_auto.h) //#include "users_multiple_ds18b20.h"; #include "users_wspeed.h"; Весь код в этом файле должен быть заключен в конструкцию такого вида #ifndef USERS_H #define USERS_H /* Весь код описанный ниже располагается тут */ #endif Это указания для компилятора, на тот случай если в коде окажутся подключены два пользовательских файла. Теперь добавим описание для плагина Knob который отобразит наш сенсор в web интерфейсе. Установим приделы шкалы от 0 до 40 метров в секунду с шагом в одну десятую и соответствующим описанием. /* Параметры индикаторов web интерфейса для плагина Knob Мин Макс Шаг Заголовок Ед. измер. |---------------------|----|------|------|--------------|---------| */ knob_t *S = new knob_t(0, 40, ".1", "Скорость в.", "м/c"); Теперь объявим все необходимые константы. Обязательно укажите значения, подходящие для Вашего датчика. Учтите количество импульсов на один полный оборот, радиус анемометра и коэффициент для калибровки датчика. По сути этот коэффициент равен расхождению в скорости (м/c) между показаниями Вашего датчика и какого ни-ть эталонного, например другого анемометра. Можно собрать анемометр, покататься с ним на машине и сравнить показания, только помним о переводе км/ч в м/c. Я надеюсь, что зависимость линейная и все будет в порядке. /* Параметры конфигурации для расчета скорости ветра */ #define windSpeed_Pin 14 // GPIO микроконтроллера к которому подключен чашечный анемометр #define windSpeed_Pulses 1 // Количество импульсов на один оборот чашечного анемометра #define windSpeed_Correction 0 // Коэффициент поправки. Разница в скорости м/с между измеренным и фактическим значением полученная при калибровки #define windSpeed_Radius 100 // Радиус чашечного анемометра от центра до середины чашечки в милиметрах Объявим переменные для хранения показаний частоты и расчетной скорости. uint32_t windSpeed_Hz = 0; // Тут будет зафиксирована частота за ПЛАВАЮЩИЙ интервал времени float windSpeed = 0; // Тут будет зафиксирована скорость ветра Далее опишем функцию, которая будет вызываться по прерыванию и изменять показания частоты /* Функция, регистрирующая импульсы с чашечного анемометра */ void pulseDetected() { ++windSpeed_Hz; } Переходим к основной функции, отвечающей за расчет скорости ветра. Обязательно все за мной перепроверяйте т.к я мог ошибиться в расчетах или что-то сделать не так. На время расчетов мы выключаем регистрацию новых импульсов. За время мы возьмем интервал между предыдущим вызовом этой функции и текущим. Рассчитаем длину окружности и общий пройденный путь. Полученный результат запишем в одну из объявленных ранее глобальных переменных. /* Функция, производящая расчет скорости ветра */ void pulseCounter() { detachInterrupt(windSpeed_Pin); // Отключаем регистрацию импульсов на время расчета /* Расчет скорости ветра */ if (windSpeed_Hz) { float time = cron.lastRun("Wind Speed Calculation") / 1000; // Время прошедшее с последнего расчета скорости ветра в секундах float circumference = 3.14 * 2 * windSpeed_Radius; // Длинна окружности анемометра в милиметрах float distance = (windSpeed_Hz / windSpeed_Pulses) * circumference; // Пройденое растояние в милиметрах float speed = distance / time / 1000; // Скорость в метрах в секунду (грязная) windSpeed = speed + windSpeed_Correction; // Скорость ветра с учетом коректировки } else windSpeed = 0; /* Сброс частоты */ windSpeed_Hz = 0; attachInterrupt(windSpeed_Pin, pulseDetected, FALLING); // Возобновляем регистрацию импульсов } Опишем функцию возвращающую расчетный результат скорости. /* Функция, возвращающая последнее расчетное значение скорости ветра */ float getWindSpeed() { return windSpeed; } Ну и осталось самое главное, это функция описывающая наши сенсоры. void sensors_config() { pinMode(windSpeed_Pin, INPUT_PULLUP); // Конфигурируем порт микроконтроллера как вход с активным встроенным подтягивающим резистором attachInterrupt(windSpeed_Pin, pulseDetected, FALLING); // Регистрация импульсов с чашечного анемометра по прерыванию на землю cron.add(cron::time_10s, pulseCounter, "Wind Speed Calculation"); // Задача в планировщике для расчета скорости ветра sensors.add(S, device::out, "windSpeed", getWindSpeed); // Добавляем сенсор скорости ветра в web интерфейс } Как мы видим, тут происходит инициализация порта микроконтроллера на вход с подтяжкой к питанию. Объявление прерывания. А также добавление задачи по расчету скорости в планировщик и добавление нашего сенсора. Еще раз напоминаю, что я не могу гарантировать работоспособность данного решения, у меня нет возможности это проверить. Внимательно все просмотрите, я постарался везде указать комментарии. Помните, что импульсы считаются по прерыванию на землю, Вы должны гарантировать, что схема датчика будет их генерировать. На всякий случай прикрепляю готовый файл. users_wspeed.zip
×
×
  • Создать...