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

Рекомендованные сообщения

Здравствуйте!

Из за короткого имени сети wifi (из двух символов) возникает ошибка "Некорректный SSID домашней сети"

Подскажите пожалуйста как решить данную проблему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@pvspec доброе время суток.

В файле index.htm найдите строку

function checkSSID(ssid) { return ssid.match(/^[a-z0-9_. -]{3,30}$/i); }

замените её на

function checkSSID(ssid) { return ssid.match(/^[a-z0-9_. -]{2,30}$/i); }

 

  • Thanks 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый день, возможно как-то хранить данные графика во SPIFFS чтобы после перезагрузки модуля они не исчезали? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Сергій Артеменко доброе время суток.

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

Из минусов можно отметить следующее:

  1. При перезагрузке точки на графике могут сдвинуться на время равное тому интервалу времени пока контроллер был выключен. Чем дольше не было питания, тем больше будет рассогласование. Это связано с тем, что контроллер не хранит отметки времени для точек на графике, отсчет идет от последней сохраненной точки с известными интервалами времени опираясь на время устройства с которого просматривается график. Это сделано для того, чтобы отказаться от учета реального времени на микроконтроллере.
  2. Любая Flash память имеет ограничение на количество циклов перезаписи, ESP8266 не исключение и число циклов составляет примерно 100000. Если перезаписывать Flash раз в час, то срок жизни будет составлять примерно чуть более 11 лет.
  • Thanks 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Доброго время суток!

Уважаемый Автор, большое спасибо за проект , есть чему поучиться!!!

можно ли написать краткую инструкцию по подключению 2-х ds18b20,  к имеющимся 2 BME280

а то самому что-то только сломать все пока получается :(

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Доброе время суток.

14.01.2019 в 20:33, alex0127 сказал:

можно ли написать краткую инструкцию по подключению 2-х ds18b20,  к имеющимся 2 BME280

Да конечно, но проверить работоспособность Вам придется самостоятельно.

В первую очередь Вам понадобятся следующие библиотеки:

  1. OneWire https://github.com/PaulStoffregen/OneWire
  2. DallasTemperature https://github.com/milesburton/Arduino-Temperature-Control-Library

Скачиваем и добавляем их в Arduino IDE. Первая необходима для реализации обмена данными через шину 1 wire, а вторая представляет из себя всю необходимую реализацию для работы с датчиками серии DS18.

Теперь необходимо определиться с тем, какой порт мы задействуем под шину 1 wire, это важно т.к в проекте уже задействовано много портов, а ESP8266 очень в них ограничена. Из свободных и безопасных остался только GPIO16 (D0 на платах NodeMCU) но с ним могут быть проблемы, в любом случае это стоит проверить. Если вдруг не получится, то придется задействовать один из портов, используемых для управления нагрузкой, например, GPIO14 (D5 на платах NodeNCU). Ранее мы использовали его для управления нагрузкой по разности показаний между двумя датчиками BME280.

ВАЖНО: если с GPIO16 не получится и придется использовать GPIO14, то в основном файле программы закомментируйте вызов функции инициализации данного порта

// gpio_14();

Все необходимое для работы с DS18B20 будем описывать в файле users_bme280_x2.h т.к по всей видимости именно им Вы и пользуетесь в работе с двумя датчиками BME280.

Подключаем дополнительные библиотеки.

#include <OneWire.h>
#include <DallasTemperature.h>

Следом можно объявить все необходимые объекты для работы с шиной и датчиками. Я сразу укажу варианты для разных портов.

DallasTemperature ds18b20(new OneWire(16)); // GPIO16 (D0)
// DallasTemperature ds18b20(new OneWire(14)); // GPIO14 (D5)

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

void sensors_config() {
  /* тут описан код других датчиков */

  ds18b20.begin();  
  cron.add(cron::time_5s, [&](){ ds18b20.requestTemperatures(); }, true);
  sensors.add(T, device::in, "ds18b20_s0", [&](){ return ds18b20.getTempCByIndex(0); });
  sensors.add(T, device::in, "ds18b20_s1", [&](){ return ds18b20.getTempCByIndex(1); });
}

Пару слов о том, что мы добавили в эту функцию.

Инициализация шины 1 wire

ds18b20.begin();

Добавляем в планировщик новое задание которое будет отвечать за рассылку телеграммы по шине с целью запроса температуры у всех имеющихся датчиков. Последний параметр (true) заставит задачу отработать сразу при добавлении в планировщик.

cron.add(cron::time_5s, [&](){ ds18b20.requestTemperatures(); }, true);

Далее описываем каким способом собирать данные с датчиков

sensors.add(T, device::in, "ds18b20_s0", [&](){ return ds18b20.getTempCByIndex(0); });
sensors.add(T, device::in, "ds18b20_s1", [&](){ return ds18b20.getTempCByIndex(1); });

В данном представлении датчики объявлены как внутренние - device::in (можете объявить их как внешние device::out), и имеют идентификаторы в системе ds18b20_sX, где X это индекс датчика найденного библиотекой DallasTemperature. Эта информация будет полезна если появится необходимость вывода данных с этих датчиков на общий график.

В теории все должно заработать. Отпишитесь пожалуйста о своих результатах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
6 hours ago, Kitsum said:

Да конечно, но проверить работоспособность Вам придется самостоятельно

Все работает!!! и как верно предположили заработало только на  GPIO14 (D5 на платах NodeNCU).

Но вроде как есть же еще свободные пины GPIO  1,2,3,9,10, tx rx на внешнем питании уже не нужен по идее.

Кстати сделал одну интересную ошибку когда заливал прошивку удаленно, забыл указать параметр Tools->Flash size-3m (стоял 1m)

и ESP не увидела SPIFFS  вообще , соотв  зайти в нее не удалось, пришлось снимать и идти прошивать на ББ.

Большое спасибо за поддержку!!!

PS. Ошибки идут иногда с DS18, с BME ни разу не замечал, а с DS18 раз в 5 мин проскакивает значение -127, хотя все соединения хорошие и кабель родной короткий прямо в ESP вставлен...

Изменено пользователем alex0127

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
16.01.2019 в 21:23, alex0127 сказал:

Ошибки идут иногда с DS18, с BME ни разу не замечал, а с DS18 раз в 5 мин проскакивает значение -127, хотя все соединения хорошие и кабель родной короткий прямо в ESP вставлен...

  • Попробуйте провести эксперимент используя только один из двух датчиков по очереди чтобы попытаться исключить неисправность датчиков. Или временно замените датчики на другие.
  • Убедитесь, что сама линия имеет надежные контактные соединения с контроллером и датчиками.
  • Проверьте исправность подтягивающего резистора на шине 1 wire.
  • Попробуйте подключать датчики без использования паразитного питания если конечно последнее используется.
  • Воспользуйтесь одним из стандартных примеров библиотеки DallasTemperature для 10-15 минутного теста.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Все разобрал, тщательно собрал, по статистике с MQTT одна две ошибки с каждого датчика в сутки, раньше было 1 ошибка в полчаса, наверное это уже приемлимый результат. с BME ошибок нет совсем!!! наверное OneWire менее помехозащищенный протокол чем I2C.

render.png.5507a435f6be6ebb1e07f295bbb3b99d.png

Изменено пользователем alex0127
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый день.

Поделитесь прошивкой на несколько DS18B20 ,  мне нужно что бы обращение к датчику происходило по серийному номеру (если какой нибудь датчик отсоединить то нумерация списка датчиков не менялась).  

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
24.01.2019 в 15:54, olegkaras сказал:

Добрый день.

Поделитесь прошивкой на несколько DS18B20 ,  мне нужно что бы обращение к датчику происходило по серийному номеру (если какой нибудь датчик отсоединить то нумерация списка датчиков не менялась).  

У меня работает на десяток датчиков DS и 2 BME все передается по MQTT каждые 5с на домашнюю SCADA на ней же работает и брокер. Есть иногда провалы по связи с DS в этом проекте не отрабатываются ошибки связи с DS в другом проекте (не закончил до конца) написан обработчик ошибок.

Для настройки датчиков DS создана спец страница t.htm автоматически генерируемая, которая позволяет настроить (правда в программе руками) адреса DS отслеживает отказы и т.д. страничка генерируется через файловую систему ESP (см скетч сейчас уже не помню что там рисовал). 

Уже пол года все работает. давно не заглядывал - смотрите как там написано.

Еще реализованы (как всегда не до конца но работают). на основании исходника метеостанции: Счетчики воды, Меркурий 230 по 485 связи, сейчас делается email нотификатор читающий из MQTT данные и генерирующий email сообщения с предупреждениями - потом он будет расширен GSM модулем с SMS нотификатором с функцией управления.

ESP8266_WS_V2.0_BETA13.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
24.01.2019 в 15:54, olegkaras сказал:

Поделитесь прошивкой на несколько DS18B20 ,  мне нужно что бы обращение к датчику происходило по серийному номеру (если какой нибудь датчик отсоединить то нумерация списка датчиков не менялась).  

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

Замените запрос температуры по индексному номеру датчика

sensors.add(T, device::in, "ds18b20_s0", [&](){ return ds18b20.getTempCByIndex(0); });

на запрос по уникальному серийному номеру

sensors.add(T, device::in, "ds18b20_s0", [&](){ return ds18b20.getTempC({ 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 }); });

После этих изменений датчику c идентификатором ds18b20_s0 будет соответствовать DS18B20 с адресом 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый день! Очень интересная метеостанция. Жалко, что дальше не развивается. Недавно получил ESP, теперь понятно на каком уровне можно с ней работать. Побольше бы таких проектов.

А теперь о работе программы. Почему на телефоне нет иконки статистики за 24 часа? Отдельные графики работают. CCS811 несовсем корректно обрабатывается. У меня после проветривания комнаты резко растут показания и  плавно снижаются. 

Скрытый текст

m.thumb.jpg.5534f77912da7ab9f5d7353ba21eebc0.jpg

В библиотеке CCS811 есть пример возможности корректировки датчика по температуре и влажности. Подскажите как подправить  код.,

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Доброе время суток.

9 часов назад, IvAn сказал:

Очень интересная метеостанция. Жалко, что дальше не развивается.

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

9 часов назад, IvAn сказал:

Почему на телефоне нет иконки статистики за 24 часа?

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

Но если хочется её вернуть, то в файле index.htm найдите следующий фрагмент css кода.

@media screen and (max-width:610px) {
    #graph { display: none; }
    div.copyright { position: unset; }
}

И удалите из него строку

#graph { display: none; }

Не забудьте запаковать файл обратно в .gz формат

9 часов назад, IvAn сказал:

CCS811 несовсем корректно обрабатывается. У меня после проветривания комнаты резко растут показания и  плавно снижаются.

Это зависит от самого датчика. В проекте данные проходят только через медианный фильтр, класс medianFilter_t в файле tools.h. По сути, это просто накопительный буфер для сглаживания случайных пиков. Больше информации можно посмотреть тут https://ru.wikipedia.org/wiki/Медианный_фильтр

9 часов назад, IvAn сказал:

В библиотеке CCS811 есть пример возможности корректировки датчика по температуре и влажности. Подскажите как подправить  код.,

В ранних версиях используемой библиотеки это не было реализовано. Интересно посмотреть, как это повлияет на показания.

В файле users_auto.h есть пример кода для работы с датчиком

#if SENSOR_CCS811
  sensors.add(C, device::out, 0x5A, "out_co2", [&](){ 
    ccs811.begin(); 
    ccs811.start(CCS811_MODE_1SEC); 
  }, [&](){ 
    uint16_t eco2, etvoc, errstat, raw;    
    ccs811.read(&eco2, &etvoc, &errstat, &raw); 
    return eco2; 
  }, true);
#endif

Замените его на этот

#if SENSOR_CCS811
  sensors.add(C, device::out, 0x5A, "out_co2", [&](){ 
    ccs811.begin(); 
    ccs811.start(CCS811_MODE_1SEC); 
  }, [&](){ 
    uint16_t eco2, etvoc, errstat, raw;
    ccs811.set_envdata(sensors.get("out_temperature"), sensors.get("out_humidity"));
    ccs811.read(&eco2, &etvoc, &errstat, &raw); 
    return eco2; 
  }, true);
#endif

Разница всего в одной строке

ccs811.set_envdata(sensors.get("out_temperature"), sensors.get("out_humidity"));

Где out_temperature и out_humidity, это имена объявленных Вами сенсоров температуры и влажности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Простое добавление строчки для корректировки сенсора ccs811 не подходит. Все датчики перестают отвечать примерно через час. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
2 часа назад, IvAn сказал:

Простое добавление строчки для корректировки сенсора ccs811 не подходит. Все датчики перестают отвечать примерно через час. 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, Kitsum сказал:

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

Только это не пробовал. Завтра попробую. Без корректировки работает. С корректировкой четыре раза отключались датчики. Убрал корректировку,  опять заработало. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый день! вопрос к автору: пожалуйста, посоветуйте как лучше реализовать подключение к данному проекту HX711 c тензодатчиками , из указанных здесь сенсоров хочу использовать только BME280.  заранее огромное спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Доброе время суток.

16 часов назад, evgenyD сказал:

посоветуйте как лучше реализовать подключение к данному проекту HX711 c тензодатчиками

Электронных компонентов для проверки у меня нет, но я постараюсь помочь, опираясь на код библиотеки. Все фактические проверки Вам придется произвести самостоятельно. Я буду использовать эту библиотеку https://github.com/bogde/HX711, Вы можете использовать любую другую, просто действуйте по аналогии.

В первую очередь необходимо определиться с используемыми портами микроконтроллера. Предлагаю задействовать 12 и 13 порты, но т.к они уже были использованы ранее, то в основном файле проекта необходимо закомментировать вызов функции gpio_12_13(). Я выбрал эти порты для примера, возможно Вы задействуете какие ни-ть другие.

/* Инициализация GPIO для управления внешней нагрузкой */
//gpio_12_13(); // Простое превышение температуры или влажности (выставляется в WEB интерфейсе)

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

Я предположу, что для описания сенсоров Вы используете один из пользовательских файлов имена которых начинаются с users_.

В начале файла подключаем выбранную библиотеку.

#include "HX711.h"

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

HX711 scale(12, 13);

Создадим описание для системы визуализации (плагин Knob).

knob_t *W = new knob_t(-100, 10000, "1", "Вес", "Гр");

Мне не известно какой датчик Вы будите использовать, поэтому значения я выбрал на свое усмотрение. Минимальный вес равен -100 грамм, максимальный 10000 грамм, шаг шкалы 1, описание сенсора "Вес", ну и "Гр" в качестве единиц измерения. Минимальный вес в -100 грамм взят не случайно, так Вам будет проще найти калибровочный коэффициент.

Теперь модифицируем функцию sensors_config() и объявим новый сенсор.

/* Добавление датчиков в систему */
void sensors_config() {
  /* Тут описан код других датчиков */
  
  scale.set_scale(3); // калибровочный коэффициент
  scale.tare(); // тарирование

  sensors.add(W, device::in, "in_weight", [&](){
    return scale.get_units() * 0.035274; // перевод в граммы
  });
}

В теории, этого должно быть достаточно.

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

scale.set_scale(3);

Также обратите внимание, что при запуске микроконтроллера происходит тарирование весов.

scale.tare();

Отпишитесь о результатах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый день! Для начала хочу поблагодарить Вас за отличный проект! Хотелось бы добавить в сборку анемометр, об этом уже был разговор в теме. Можно использовать кулер процессора на примере вот этого проекта: http://kiteforum.org.ua/index.php?topic=7613.0.  Если Вам не сложно, помогите добавить код для считывания показаний и передачей по MQTT в сборку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
08.10.2018 в 12:04, Kitsum сказал:

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

Добрый день! За прошедшее время освоил передачу данных через NRF24 с датчиков , подключенных к ProMini . И прием данных на Мегу с выводом на экран . Теперь в раздумье, как забрать ESPшкой с Меги (или Нано) полученные данные датчиков. Как Вы уже рекомендовали, хочу подключить Ардуину как slave к ESP по I2C. Нашел библиотеку iarduino_I2C_connect для этих целей. Думаю, должно получиться. А вот как потом эти данные переварить в ESP и отправить в локальный web-сервер и (или) народный монитор? Подскажите, пожалуйста, куда копать, а то несколько дней никак не могу сообразить, с чего начать.

PS: пробывал перепаивать на ESP 64Mbit и 128Mbit флеш , программировал как Generic ESP8266 module в формате 8(7SPIFFS) и 16(15SPIFFS). Ваша метеостанция работает, в веб-интерфейсе корректно отображается размер установленной памяти. Так что запас для модификации веб-интерфейса есть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Доброе время суток.

23.02.2019 в 19:28, Дмитрий сказал:

Хотелось бы добавить в сборку анемометр, об этом уже был разговор в теме.

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

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

В первую очередь необходимо определиться, какой порт микроконтроллера будем задействовать. Я возьму за основу порт 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

  • Thanks 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пожалуйста, войдите для комментирования

Вы сможете оставить комментарий после входа



Войти сейчас

  • Похожие публикации

    • Автор: Kitsum
      Хотите помочь проекту или спонсировать новый?
      Yandex.Money PayPal.me Тема проекта
      Arduino IDE + Project + Libraries + tools: https://yadi.sk/d/jseefFB50NMhAg
    • Автор: Kitsum
      Просмотреть файл [esp8266] Библиотека CMD, реализует настройку микроконтроллера и управление вашей программой через терминал.
      Основная задача библиотеки, это прием пользовательских команд через UART интерфейс, их обработка и выполнение пользовательского кода, связанного с той или иной командой.
      Данная библиотека позволяет реализовать:
      Управление микроконтроллером Любую настройку, будь то WiFi, другие библиотеки или часть Вашей программы Вызывать Ваши задачи (функции) из терминала по команде и передавать им требуемые параметры Использовать контроллер в качестве шлюза между датчиками и программами на PC Внимание: любая команда, передаваемая в терминал обязана заканчиваться символом перевода строки "\n".
      Подключение библиотеки
      #include <cmd.h> Инициализация объекта, к которому мы будем обращаться для добавления команд. В качестве параметра объекту необходимо передать указатель на объект Serial или любой другой схожий по типу интерфейс.
      cmd command(&Serial); В функции Setup описываем какие команды требуется обрабатывать. Например, по команде "test" вызывать пользовательскую функцию с именем "myFunctionName". Имя пользовательской функции может быть абсолютно любым.
      void Setup() { Serial.begin(115200); command.add("test", myFunctionName); } Пользовательская функция будет вызываться каждый раз, когда по интерфейсу Serial поступит команда "test". Если команда будет передана с параметрами, то эти параметры будут переданы в качестве аргументов пользовательской функции.
      В функции loop должна находится команда вызова обработчика.
      void loop() { command.handleEvents(); } Пользовательская функция обязана соответствовать ряду требований:
      Не возвращать никакого результата (быть объявленной с типом void) Принимать в качестве первого аргумента переменную с типом byte в которой будет храниться число равное количеству переданных параметров Принимать в качестве второго параметра переменную с типом char** в которой будет храниться указатель на массив со всеми указателями (char*) на переданные параметры void myFunctionName(byte argc, char** argv) { /* ... */ } Функция всегда должна иметь такой вид, даже если не подразумевается, что ей будут передаваться какие-либо параметры.
      Чтобы перебрать все переданные параметры и вывести их в консоль, можно воспользоваться следующим примером
      void myFunctionName(byte argc, char** argv) { if (0 < argc) { for (uint8_t i = 0; i < argc; i++) { Serial.printf("%i. %s\n", i, argv[i]); } } } Пример вызова пользовательской функции без параметров и с ними
      # test No parameter was passed # test p1 p2 p3 p4 p5 0. p1 1. p2 2. p3 3. p4 4. p5 Помните, что параметры представлены в виде указателей и работать с ними нужно как с обычными переменными не получится т.к указатель содержит не значение переменной (переданный параметр), а указатель на ту область памяти микроконтроллера в которой это значение находится.
      Чтобы сравнить два значения, например, параметр под индексом 0 (идет первым в списке) с каким-либо значением в программе, воспользуйтесь функцией strcmp, которая возвращает целочисленное значение, указывающее на лексическое расхождение строк. Если строки равны, то возвращаемое значение равно 0.
      if (!strcmp(argv[0], "wifi")) { Serial.println(F("Первый аргумент WiFi")); } else { Serial.println(F("Первый аргумент НЕ WiFi!!!")); } Для копирования значения указателя в другую переменную с типом char можно воспользоваться функцией strcpy
      char myVar[20]; strcpy(myVar, argv[0]); if (myVar == "123456") { Serial.prinln(F("ok")); } Также можно обернуть указатель объектом String и получить весь функционал этого объекта, который будет содержать значение параметра
      String param1(argv[0]); // String param1 = argv[0]; Serial.printf("argv[0] length: %i\n", param1.length()); Serial.printf("argv[0] is integer?: %s\n", param1.toInt() ? "YES" : "NO"); if (param1 == "qwerty") { Serial.println(F("Hello QWERTY!")); } С библиотекой идут несколько примеров, в том числе и пример конфигурации WiFi в режиме STA.
      Автор Kitsum Добавлен 05.12.2018 Категория Библиотеки  
    • Автор: Kitsum
      Просмотреть файл [esp8266] Библиотека smartBlink, реализует умное управление штатным светодиодом, что позволяет добавить индикацию состояния вашей программы или микроконтроллера.
      Основная задача библиотеки, это добавление индикации состояния Вашей программы или микроконтроллера. Отображение состояния производится посредством светодиода. Что самое важное, работа библиотеки через прерывание, это позволяет ей поддерживать индикацию даже в то время, когда выполняется длительный код основной программы. Например, Вы можете использовать её для отображения в каком режиме сейчас работает WiFi микроконтроллера, STA или AP и т.д. Или ход выполнения какой-либо операции, например, передача данных на внешний сервер.
      Подключение библиотеки
      #include <smartBlink.h> Чтобы инициализировать управление светодиодом необходимо создать объект, через который мы буем задавать режимы работы индикации.
      smartBlink::smartBlink(byte gpio, bool on = LOW); Объекту необходимо передать два параметра, первый это номер порта, на котором находится светодиод, а второй это уровень логического сигнала, который заставит светодиод работать. Сигнал может быть низким (LOW) или высоким (HIGH), это зависит от схемотехники подключения светодиода.
      Например, штатный светодиод модуля ESP12, использующий GPIO2 (порт 2) можно объявить следующим образом.
      #define led2_pin 2 #define led2_on_signal LOW smartBlink led2(led2_pin, led2_on_signal); Теперь можно в основной программе использовать метод устанавливающий какой режим индикации использовать.
      smartBlink::setMode(mode_t mode); Например, зададим режим светодиода led2 в котором светодиод будет давать одну короткую вспышку раз в секунду.
      led2.setMode(smartBlink::mode_flash1); Режимов работы может быть несколько.
      led2.setMode(smartBlink::mode_off); led2.setMode(smartBlink::mode_flash1); led2.setMode(smartBlink::mode_flash2); led2.setMode(smartBlink::mode_flash3); led2.setMode(smartBlink::mode_flash4); led2.setMode(smartBlink::mode_burn); led2.setMode(smartBlink::mode_inhalf); Чтобы вернуть предыдущий режим индикации для ранее объявленного светодиода led2 используйте следующий метод
      led2.previous(); Благодаря работе библиотеки через прерывания по таймеру, индикация будет работать даже в тех случаях, когда выполняется долгий код.
      С библиотекой идут несколько примеров.
      Автор Kitsum Добавлен 10.12.2018 Категория Библиотеки  
    • Автор: Kitsum
      Основная задача библиотеки, это добавление индикации состояния Вашей программы или микроконтроллера. Отображение состояния производится посредством светодиода. Что самое важное, работа библиотеки через прерывание, это позволяет ей поддерживать индикацию даже в то время, когда выполняется длительный код основной программы. Например, Вы можете использовать её для отображения в каком режиме сейчас работает WiFi микроконтроллера, STA или AP и т.д. Или ход выполнения какой-либо операции, например, передача данных на внешний сервер.
      Подключение библиотеки
      #include <smartBlink.h> Чтобы инициализировать управление светодиодом необходимо создать объект, через который мы буем задавать режимы работы индикации.
      smartBlink::smartBlink(byte gpio, bool on = LOW); Объекту необходимо передать два параметра, первый это номер порта, на котором находится светодиод, а второй это уровень логического сигнала, который заставит светодиод работать. Сигнал может быть низким (LOW) или высоким (HIGH), это зависит от схемотехники подключения светодиода.
      Например, штатный светодиод модуля ESP12, использующий GPIO2 (порт 2) можно объявить следующим образом.
      #define led2_pin 2 #define led2_on_signal LOW smartBlink led2(led2_pin, led2_on_signal); Теперь можно в основной программе использовать метод устанавливающий какой режим индикации использовать.
      smartBlink::setMode(mode_t mode); Например, зададим режим светодиода led2 в котором светодиод будет давать одну короткую вспышку раз в секунду.
      led2.setMode(smartBlink::mode_flash1); Режимов работы может быть несколько.
      led2.setMode(smartBlink::mode_off); led2.setMode(smartBlink::mode_flash1); led2.setMode(smartBlink::mode_flash2); led2.setMode(smartBlink::mode_flash3); led2.setMode(smartBlink::mode_flash4); led2.setMode(smartBlink::mode_burn); led2.setMode(smartBlink::mode_inhalf); Чтобы вернуть предыдущий режим индикации для ранее объявленного светодиода led2 используйте следующий метод
      led2.previous(); Благодаря работе библиотеки через прерывания по таймеру, индикация будет работать даже в тех случаях, когда выполняется долгий код.
      С библиотекой идут несколько примеров.
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.

×
×
  • Создать...