Датчик СО2

Использование прочих датчиков и энкодеров и пользовательских блоков к ним
Аватара пользователя
Alias
Лейтенант
Сообщения: 476
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 36
Откуда: Rus44
Имя: Michael
Контактная информация:

Датчик СО2

#41

Сообщение Alias » 26.12.2017{, 17:29}

Попробовал разобраться, как создаются блоки CODE. Взял за основу блок от Anydy и немного переделал секции.
До этого нашел скетч якобы работающего устройства: во вложении.

Решил попробовать покопипастить из него. Там, кстати, есть опечатка ближе к
концу, возможно, непредумышленная. Модифицированный блок во вложении, но он точно так же работает. То есть вывод на экран возможен только в момент опроса СО2, то есть, в данном случае каждые 5 секунд.
Я так понимаю, что это все из-за delay(5000). Если ее удалить вовсе, на
глаз ничего уже и не тормозит, но com-порт при этом заваливает потоком данных с датчика.
В скетче выше задержка реализована через таймер:

Timer t;
t.every(15000, get_co2);

Прошу гуру подсказать, куда и как можно воткнуть его в блоке пользователя,
чтобы он не мешал работе всей программы. Или можно как-то активировать
работу самого блока через вход En по внешнему таймеру? Не знаю, как его,
вход, корректно создать.
С восторгом предаюсь в руки родной милиции, надеюсь на нее и уповаю (с)
Вложения
CO2_1602_I2C.ino
(2.56 КБ) 99 скачиваний
CO2UART_modAlia.ubi
(20.77 КБ) 94 скачивания

pan
Полковник
Сообщения: 2860
Зарегистрирован: 13.04.2017{, 11:57}
Репутация: 204
Имя: noname

Датчик СО2

#42

Сообщение pan » 26.12.2017{, 19:15}

всякие дилэи конечно убирать надо.
Alias писал(а):через вход En
вкладка "входы". добавляете вход, на пример en

СпойлерПоказать
Изображение
 и весь код блока запихиваете в эти скобки.
Alias писал(а):куда и как можно воткнуть его в блоке пользователя
 всё так же как в скетче.


Код: Выделить всё

Timer t;
это в декларе секцию.

Код: Выделить всё

t.every(15000, get_co2);

это в сетап секцию

Аватара пользователя
Alias
Лейтенант
Сообщения: 476
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 36
Откуда: Rus44
Имя: Michael
Контактная информация:

Датчик СО2

#43

Сообщение Alias » 26.12.2017{, 20:01}

Сделал по Вашей подсказке вход En на блоке и управляю им по переднему фронту сигнала с компаратора ежеминутно. И - Бинго! - все работает!
Спасибо! Можно идти дальше.
СпойлерПоказать
Но я, все-таки, не сообразил, как внедрить таймер в сам блок, чтобы он обрел законченный вид. Если поможете, блок можно будет выложить в библиотеку. С меня тестирование и отчет.
Вложения
2713422.png

pan
Полковник
Сообщения: 2860
Зарегистрирован: 13.04.2017{, 11:57}
Репутация: 204
Имя: noname

Датчик СО2

#44

Сообщение pan » 26.12.2017{, 20:47}

Alias писал(а):как внедрить таймер
посмотрите. разберетесь
Вложения
CO2UART-2-CODE-.ubi
(23.1 КБ) 95 скачиваний

Аватара пользователя
Alias
Лейтенант
Сообщения: 476
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 36
Откуда: Rus44
Имя: Michael
Контактная информация:

Датчик СО2

#45

Сообщение Alias » 27.12.2017{, 14:02}

Разобрался. Отлично! Спасибо огромное!
Мало того, написал несколько вариантов реально работающих конкретно у меня блоков. Но!
Полез я в код, стал кое в чем разбираться и обнаружил забавную вещь в блоке из поста выше: тип переменной LastTime объявлен как Long Integer.
Если я правильно понимаю, значение переменной начнет переполняться уже через 24 дня, при этом перестанет соблюдаться тайм-аут на опрос датчика и он будет опрашиваться уже в каждом цикле программы.
Взял на себя смелость объявить ее Unsigned long Integer, пусть она работает вплоть до обнуления самой millis.
Во вложении три блока с индексами 1, 2 и 3. Каждый из них в скетче использует 3668/3678/3718 байт памяти устройства и 324/325/328 байт динамической памяти для глобальных переменных соответственно. Если кому-то критично, могут выбирать.
В примере поставил уровень тревоги на 1200ppm, просто у меня датчик рядом с клавой лежит и я вношу нехилые возмущения в его показания.
Вложения
6030881.jpg
co2-z19.flp
(127.71 КБ) 129 скачиваний
MH-Z19_UART3-CO.ubi
(44.13 КБ) 102 скачивания
MH-Z19_UART2-CO.ubi
(31.02 КБ) 97 скачиваний
MH-Z19_UART1-CO.ubi
(20.78 КБ) 94 скачивания
Последний раз редактировалось Alias 27.12.2017{, 14:04}, всего редактировалось 1 раз.

pan
Полковник
Сообщения: 2860
Зарегистрирован: 13.04.2017{, 11:57}
Репутация: 204
Имя: noname

Датчик СО2

#46

Сообщение pan » 27.12.2017{, 14:32}

буковку пропустил. ulong

Добавлено (27.12.2017, 14:32)
---------------------------------------------
хотя с чего вы взяли что она будет переполняться. это промежуточная переменная для отсчета нужного времени т.е
просто для вычисления разницы..
тем более она периодически через установленный интервал обнуляется.
Последний раз редактировалось pan 27.12.2017{, 14:34}, всего редактировалось 1 раз.

Аватара пользователя
Alias
Лейтенант
Сообщения: 476
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 36
Откуда: Rus44
Имя: Michael
Контактная информация:

Датчик СО2

#47

Сообщение Alias » 27.12.2017{, 14:44}

В смысле, в блоке вместо

unsigned long LastTime=0;

прописать

ulong LastTime=0?

В скетче при компиляции ошиок не выдает и выглядит вот так:



Не знал, исправлю. Спасибо за подсказки!

Почему будет переполняться? Ну, не знаю. Просто если посмотреть код:
СпойлерПоказать
if (millis() - LastTime > interval) // если установленное время прошло
                    {
                        LastTime =0; //сбрасывам запомненное значение
                    }

if( LastTime ==0) {
LastTime = millis(); // запоминаем текущее значение таймера
mySerial.write(cmd, 9);
mySerial.readBytes(response, 9);
unsigned int responseHigh = (unsigned int) response[2];
unsigned int responseLow = (unsigned int) response[3];
ppm = (256*responseHigh) + responseLow;
Serial.println(ppm);
}
LastTime = millis(); // запоминаем текущее значение таймера. И, если мы берем тип Long Integer с предельным значением переменной 2147483647, то в нее просто не впихнуть значение millis при превышении лимита, тк сама millis, как я понимаю, Unsigned long Integer  с пределом до 4294967295.
Но я не настаиваю. В код в принципе я впервые стал влезать со вчерашнего дня и для меня много непонятного. Я в этой чаще и деревьев то не вижу пока что, а только под ноги смотрю.
Вложения
9751968.png

pan
Полковник
Сообщения: 2860
Зарегистрирован: 13.04.2017{, 11:57}
Репутация: 204
Имя: noname

Датчик СО2

#48

Сообщение pan » 27.12.2017{, 14:49}

да без разницы, unsigned long или ulong.
Alias писал(а):ее просто не впихнуть
да нам собственно и не надо. я не пробовал, но по сути там и integer хватит. если компилятор позволит.
нам все равно отслеживать  младшие разряды. при 5 секундах нам главное поймать разницу в 5000.
теоретически старшие разряды пофиг..
Последний раз редактировалось pan 27.12.2017{, 14:50}, всего редактировалось 1 раз.

Аватара пользователя
Alias
Лейтенант
Сообщения: 476
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 36
Откуда: Rus44
Имя: Michael
Контактная информация:

Датчик СО2

#49

Сообщение Alias » 27.12.2017{, 15:14}

Я, когда решил прикинуть, сколько места можно сэкономить в блоке на замене типов переменных, первым делом заменил тип этой переменной на int. И, мониторя com-порт, увидел, какая лавина обрушивается с датчика. Дополнил блок еще одной строкой по примеру предыдущей:
Serial.println(ppm);
Serial.println(LastTime);
и понял, в чем суть. И именно через 32 секунды.
Типу Integer соответствуют целые числа от -32768 до 32767. По программе, мы сравниваем показания таймера системы с нашей переменной. Если разница больше установленного значения, мы присваиваем ей нулевое значение как флаг события и тут же по этому флагу присваиваем переменной текущее значение таймера контроллера.
Сразу после рестарта, значения таймера невелики. Но после 32 секунд, как только его значения переваливают за 32767, мы входим в бесконечный цикл, тк на каждом цикле мы видим, что значения таймера куда больше значения нашей переменной, значит, пора ее обнулять, присваивать ей текущее значение таймера, опрашивать датчик, отправлять в порт.
Присвоить то присвоили. Но не все влезло и далеко не лишнее было отсечено. и на следующем цикле опять мы видим, что разница между текущим значением таймера и переменной куда больше лимита, значит, пора ее обнулять...
Я так думаю (с)

pan
Полковник
Сообщения: 2860
Зарегистрирован: 13.04.2017{, 11:57}
Репутация: 204
Имя: noname

Датчик СО2

#50

Сообщение pan » 27.12.2017{, 15:21}

ну будемс знать что если не влазит то присваивается старшая часть значения

Аватара пользователя
Alias
Лейтенант
Сообщения: 476
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 36
Откуда: Rus44
Имя: Michael
Контактная информация:

Датчик СО2

#51

Сообщение Alias » 27.12.2017{, 15:25}

Выглядит это примерно так:
СпойлерПоказать
Вложения
9716488.gif
Последний раз редактировалось Alias 27.12.2017{, 15:34}, всего редактировалось 1 раз.

Аватара пользователя
Alias
Лейтенант
Сообщения: 476
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 36
Откуда: Rus44
Имя: Michael
Контактная информация:

Датчик СО2

#52

Сообщение Alias » 31.12.2017{, 14:48}

Не дает покоя мне код, вернее, типы переменных в нем.
Штудируя скудную относительно z-19 информацию в сети, вижу, что в русскоязычном секторе все крутится по сути вокруг одной и той же статьи, которую растаскивают на цитаты и принимают за эталон. Однако, встречал несколько раз комментарии, дескать, тип переменных не тот!
Вот кусок "оригинала":
int responseHigh = (int) response[2];
int responseLow = (int) response[3];
Встречается еще одна вариация, тоже активно кочующая по сети:
unsigned int responseHigh = (unsigned int) response[2];
unsigned int responseLow = (unsigned int) response[3];
Бывалые ухмыльнутся: "И что?.."
А мне вот не понятно, зачем байт, получаемый в ответе от датчика, помещать в переменную типа int или unsigned int? Не достаточно ли типа byte?
И еще. Какой же тип необходим и достаточен для переменных responseHigh и responseLow?
Интерес не праздный - хочу сам разобраться, да и блок довести до состояния, достойного помещения в раздел пользовательских блоков.
Понимаю, что и так сойдет, но хочу понять правильный подход.

И, что самое главное, два, казалось бы одинаковых блока выдают разные результаты.
Я поместил датчик в герметичную банку. Мои блоки, что сейчас допиливаю
MH-Z19_UART3_(CODE)
MH-Z19_UART3_2.0_(CODE)
выдают 995ppm, а ранее выкладывавшийся здесь
CO2UART_(CODE)
показывает 740ppm.
При этом датчик физически от питания не отрывался и, соответственно, не калибровался, только обновлялся скетч.
Куда копать? Кому верить?
Может это (unsigned char) / (char) response[9]? Меняю в своем блоке один тип на другой и получаю разные значения, отличающиеся почти в полтора раза.
Решил посмотреть, что присылает в ответе датчик в зависимости от типа переменной response, и оказалось, что типы unsigned char и byte возвращают вполне адекватные значения, а char - абракадабру:
СпойлерПоказать
char.png
При этом тип переменных responseHigh, responseLow и response[2] вообще ни на что не влияют.

Прошу программистов оценить, что здесь не так и как должно быть.
Спасибо!

ROSTISLAVKR
Рядовой
Сообщения: 2
Зарегистрирован: 26.09.2019{, 17:11}
Репутация: 0
Имя: РОСТИСЛАВ

Датчик СО2

#53

Сообщение ROSTISLAVKR » 27.09.2019{, 04:34}

Здраствуйте!
У меня пришла в негодность и отклеилась пластинка заграждающая измерительную камеру в датчике MH-Z14, не могу сообразить чем ее заменить, не могу определить материал этой пластинки. Мне кажется что она воздухонепрозрачная-как тогда происходит измерение?
Материал этой заграждающей пластинки почему-то напоминает фрагмент слоя стеклотекстолита?

Аватара пользователя
Alias
Лейтенант
Сообщения: 476
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 36
Откуда: Rus44
Имя: Michael
Контактная информация:

Датчик СО2

#54

Сообщение Alias » 27.09.2019{, 09:05}

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

ROSTISLAVKR
Рядовой
Сообщения: 2
Зарегистрирован: 26.09.2019{, 17:11}
Репутация: 0
Имя: РОСТИСЛАВ

Датчик СО2

#55

Сообщение ROSTISLAVKR » 27.09.2019{, 11:16}

Благодарен за ответ.
Воспользуюсь советом.

Naladchik
Лейтенант
Сообщения: 675
Зарегистрирован: 04.10.2015{, 19:10}
Репутация: 109
Откуда: Новосибирск
Имя: Павел

Датчик СО2

#56

Сообщение Naladchik » 31.10.2020{, 20:20}

ShishkaRoman писал(а):
31.10.2020{, 14:09}
Захотелось сравнить с показаниями по UART.
для "просто сравнить"
AN157-T6613-Arduino-uart.pdf
(1.18 МБ) 29 скачиваний
AN157-T6613-Arduino-uart.zip
(2.24 КБ) 26 скачиваний
Win7-64. FLProg Portable.
Изображение

Ответить

Вернуться в «Прочие датчики и энкодеры»