Замирание всего кода из-за ds18b20
- Войдите на сайт для отправки комментариев
Коллеги, добрый день!
Вероятно данный вопрос поднимался, но через поиск подобной темы я не нашел.
Уровень моих познаний в программировании это "Реле - вкл, подождать 2 сек, реле - выкл, подождать 2 сек" :)
Вопрос заключается в том, что во время считывания показаний с датчиков температуры ds18b20, весь остальной код, как бы, замирает. Всего установлено 6 датчиков. Вообще хотелось бы сделать так, чтобы при вызове функции температура записывалась в переменную (скажем раз в 30 сек).
Использую стандартные библиотеки OneWire и DallasTemperature. Я так понимаю что DallasTemperature использует задержку delay и из-за этого весь код останавливается в момент считывания температуры.
Сделал простенький код, как тестовый, и вместо плавной работы ШИМ по таймеру millis - 30 миллисекунд, происходит какое то импульсное "пускание" ШИМ сигнала.
#include <Wire.h> // Будим интерфейс I2C #include <iarduino_MultiServo.h> // Библиотека на ШИМ модуль PCA9685 iarduino_MultiServo PCA9685; // Объявляем объект PCA9685, для работы с библиотекой #include <OneWire.h> #include <DallasTemperature.h> // Библиотека датчиков ds18b20 ////////////////////////////////////DS18B20////////////////////////////////////////////////// const byte ONE_WIRE_BUS = 0; // Пин D3 к которому подключены все датчики температуры OneWire oneWire(ONE_WIRE_BUS); // Вход датчиков ds18b20 на пине D3 DallasTemperature ds(&oneWire); ///////////////////////////////////////////////////////////////////////////////////////////// int brightness = 0; // уставливаем начально значение яркости int fadeAmount = 128; // шаг приращения/убывания яркости ///////////////////////////////////////////////////////////////////////////////////////////// unsigned long timing; ///////////////////////////////////////////////////////////////////////////////////////////// DeviceAddress Temp1 = {0x28, 0xFF, 0x06, 0x3D, 0x82, 0x16, 0x05, 0x55}; // Адрес датчика температуры Т1 (D3) (1 полоска) (28 FF 6 3D 82 16 5 55) DeviceAddress Temp2 = {0x28, 0xFF, 0x4E, 0x70, 0x84, 0x16, 0x05, 0x2E}; // Адрес датчика температуры Т2 (D3) (2 полоски) (28 FF 4E 70 84 16 5 2E) DeviceAddress Temp3 = {0x28, 0xFF, 0x8A, 0x99, 0x84, 0x16, 0x05, 0xC9}; // Адрес датчика температуры Т3 (D3) (3 полоски) (28 FF 8A 99 84 16 5 C9) DeviceAddress Temp4 = {0x28, 0xFF, 0x72, 0xF0, 0x02, 0x17, 0x03, 0xF8}; // Адрес датчика температуры Т4 (D3) (4 полоски) (28 FF 72 F0 2 17 3 F8) DeviceAddress Temp7 = {0x28, 0xFF, 0x2A, 0x07, 0xC1, 0x16, 0x04, 0x54}; // Адрес датчика температуры Тбак (D3) (5 полосок) (28 FF 2A 7 C1 16 4 54) DeviceAddress Temp13 = {0x28, 0xEE, 0xF7, 0xC7, 0x1D, 0x16, 0x01, 0x2E}; // Адрес датчика температуры Т13 (D3) (6 полосок) (28 EE F7 C7 1D 16 01 2E) float T1; // Датчик температуры Т1 (подача ЦО) float T2; // Датчик температуры Т2 (обратка ЦО) float T3; // Датчик температуры Т3 (подача ЦО ТП) float T4; // Датчик температуры Т4 (обратка ЦО ТП) float T7; // Датчик температуры Т7 (подача ГВС) float T13; // Датчик температуры Т13 (обратка ГВС) void setup() { Wire.begin(); Serial.begin(115200); /////////////////////////////////////////PCA9685/////////////////////////////////////// PCA9685.begin(0x40, 1000); // Инициируем работу с PCA9685. На частоте сигнала ШИМ - 1000 Гц (по умолчанию 50 Гц), можно указать от 1 до 1526 Гц ///////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////DS18B20////////////////////////////////////////////////// ds.begin(); //включаем DS18B20 ///////////////////////////////////////////////////////////////////////////////////////////// } void loop() { ds.requestTemperatures(); // Считываем показания температуры ///////////////////////////////////////////////////////////////////////////////////////////// T1 = ds.getTempC(Temp1); // Датчик температуры Т1 (подача ЦО) T2 = ds.getTempC(Temp2); // Датчик температуры Т2 (обратка ЦО) T3 = ds.getTempC(Temp3); // Датчик температуры Т3 (подача ЦО ТП) T4 = ds.getTempC(Temp4); // Датчик температуры Т4 (обратка ЦО ТП) T7 = ds.getTempC(Temp7); // Датчик температуры Т7 (подача ГВС) T13 = ds.getTempC(Temp13); // Датчик температуры Т13 (обратка ГВС) ///////////////////////////////////////////////////////////////////////////////////////////// Serial.print("brightness = "); Serial.println(brightness); if ( millis() - timing > 30 ){ timing = millis(); PCA9685.analogWrite(15, brightness); // Изменяем яркость подсветки дисплея 1602 brightness = brightness + fadeAmount; if (brightness == 0 || brightness == 4096) { fadeAmount = -fadeAmount ; } } }
И главный вопрос :)
Как сделать так, чтобы температура считывалась тогда, когда её нужно "вызвать" и чтобы при считывании показаний не затормаживался весь код?
Заранее благодарю!
Использую стандартные библиотеки OneWire и DallasTemperature. Я так понимаю что DallasTemperature использует задержку delay и из-за этого весь код останавливается в момент считывания температуры.
Да. Тема настолько баянистая, что начинать обяснять снова - моральное преступление ;) Только в поиск Вам.
Да. Тема настолько баянистая, что начинать обяснять снова - моральное преступление ;) Только в поиск Вам.
Logik да чтож так сразу.
http://arduino.ru/forum/programmirovanie/pochistil-sketch-primera-raboty...
ergeykl почитайте эту тему, я пользуюсь кодом из нее, ничего не тормозит, все прекрасно работает.
Коллеги, добрый день!
Вероятно данный вопрос поднимался, но через поиск подобной темы я не нашел.
То ли не умеете искать. то ли вообще не искали.
Ищите лучше, совсем недавно было обсуждение как раз главного вашего вопроса - "Как сделать так, чтобы задержка при измерении температуры не мешала скетчу"
Как сделать так, чтобы температура считывалась тогда, когда её нужно "вызвать" и чтобы при считывании показаний не затормаживался весь код?
Само по себе считывание требует времени, отсюда и Ваши затыки.
Сделать можно так.
Считываем без блокировки. Для этого
1. заводим переменную для температуры
2 запускаем считывание,
3. не ждём пока считается, а продолжаем заниматься своими делами
4. когда считалось обновляем переменную.
5. продолжаем заниматься своими делами, а через 30 сек. снова исполняем п.2
При таком подходе Вы в любой момент можете взять значение Вашей переменной и знать. что в ней находится темепратура не более, чем 30 секундной давности. Если так устраивает, то делайте.
Ваша библиотека (DallasTemperature) вполне позволяет работать по такому сценарию.
Как сделать так, чтобы температура считывалась тогда, когда её нужно "вызвать" и чтобы при считывании показаний не затормаживался весь код?
Само по себе считывание требует времени, отсюда и Ваши затыки.
Опять с херней влазите. Читайте даташит, считывание как и запуск преобразования пролетают очень быстро, десятки микросекунд. А цикл измерения и преобразования по умолчанию 750мсек. Оно и тормозит, кривая либа просто ждет эти 750мс.
Вы уже один раз облажались, когда утверждали, что от этих 750 мс в этой библиотеке нельзя избавиться, забыли? Опять неймётся в лужу сесть? Отвалите уж ...
А на досуге, откройте таки даташит и изучите матчасть, прежде чем языком молоть:
Склероз с фантазией - жуткая смесь ))) Свал нах! незафлужуй тему.
Большое спасибо!
Большое спасибо!
Конкретно в этой теме вроде не упомянут (может и есть в глубинах темы, не перечитывал) еще один момент, можна уменшить время преобразования настройками ds18b20 до десятков мсек. При этом теряется точность преобразования, но то не всегда важно и учитывая погрешность самого измерения в пол градуса допустимо. Но лучше таки работать с датчиком по феншую, без ожидания в либе.
Большое спасибо!
Не за что. Если потребуется пример неблокирующего вызова, обращайтесь.
ЕвгенийП, я прошу прощения, но пример мне бы не помешал :D
Посмотрел пример кода при использовании только лишь библиотеки OneWire, ничего не выходит. Контроллер у меня esp8266, а пример Почистил скетч примера работы с DS18B20 из библы OneWire.. | Аппаратная платформа Arduino предназначен, вроде как, для ардуино.
Ну, пример вот он. С этой же библиотекой. Не знаю, как на есп - запустите. попробуйте.
Там, главное, основные моменты понять, а писать можно как хотите.
Смотрите на строки 16-18. Это нужно сделать.
А потом смотрите как
1. запустить измерение - в строке 26
2. проверить не готов ли результат - в строке 28
3. получить готовый результат - в строке 29
Контроллер у меня esp8266, а пример предназначен, вроде как, для ардуино.
смотрите код из сообщения #11 той же ветки, он попроще. без прерываний - и должен одинаково работать и на ардуине, и на ЕСП
Сообразил таким образом. Ещё раз большое спасибо всем за помощь!
Вроде работает :)
Сообразил таким образом. Ещё раз большое спасибо всем за помощь!
Вроде работает :)
Как раз в оригинале той функции ваш случай, чтобы сто раз клавиши не стучать, все в массивах и с циклами. Не лень повторять сто раз было?)))))
Вроде работает :)
Чего бы ему не работать. Только вот проверки контрольной суммы не видно. А шина эта часто ошибки кидает. А чтоб ей считать надо не по 2 байта температуры принимать, а все 9 ответа.
Коллеги, если Вас не затруднит, проведите, пожалуйста, свою экспертизу по коду. Как, по Вашему мнению, всё должно работать действительно правильно, с учётом особенностей шины на которую повешены дачики?
Заранее благодарю!
А чего ее проводить? Смысла никакого нет.
Вам уже написали, что CRC вы не проверяете - будете периодически получать недостоверную температуру. Датчики на отрыв/замыкание не проверяете, отрицательные температуры не корректируете.
Коллеги, если Вас не затруднит, проведите, пожалуйста, свою экспертизу по коду. Как, по Вашему мнению, всё должно работать действительно правильно, с учётом особенностей шины на которую повешены дачики?
Заранее благодарю!
Сперва скажите, где это будет работать, а потом уже решать, нужен ли весь этот тюнинг в "Московском зоопарке". Мне пока не понадобился. ИМХО.
Строки 34, 39 закомментируйте, уберите все в массивы и цикл. Если навороты потребуются их без проблем можно добавить.
bwn, данная часть кода будет работать на благо комфортной температуры в загородном доме. Планируется, в будущем, сделать погодозависимый регулятор. В зависимости от температуры наружного воздуха будет производиться воздействия на котельный агрегат (какое воздействие пока что не определился, пока что в планах ШИМ, но там сплошные костыли). Соответственно, в зависимости от показаний датчика температуры наружного воздуха и датчиков температуры в разных участках системы (Т2, Т4, Т13), будет производиться воздействие на котёл.
А что касается кода, не совсем понял. Вы имеете ввиду убрать все глобальные переменные в массивы и цикл?
Все однотипные переменные, относящиеся к датчикам - оформить как массивы. Тогда вместо 4х одинаковых кусков кода для каждого датчика можно будет выполнять один и тот же код в цикле. Общий размер программы уменьшится, конечно не в 4 раза, но в два точно.
Пример
const byte addr[x][8] = {{0x......},{0x.........}....};
float[x]; - это глобально.
флоат не обязателен, тут сами решайте как удобнее.
А кусок с 72 строки заверните в фор, как у меня в функции сделано.
Система подогрева от электронагревателей в овощехранилище у меня четвертый год 365/24 работает без проверок, пока не сбоила. У дальнего датчика электролит (хотя линии короткие).
Делайте пока как есть, а понадобятся проверки, добавить всегда без проблем. ИМХО.
У вас всего 5 датчиков.
Скорее всего они идут в разные стороны, а не вдоль какой-то линии.
Какой смысл подключать их на один пин?
Подключите на 5 разных.
Подпишите клеммник ху-ис-ху.
Отпадёт необходимость считывать и забивать в программе их адреса.
Замена датчиков производится способом их замены.
Без перепрошивки контроллера.
Вы же не макет делаете, а устройство для долгой и надеждой эксплуатации.
При проблеммах с проводами сразу видно где это.
trembo, Вашу мысль понял. Можете разьяснить, если мы вешаем 6 датчиков на клеммник, потом, скажем, 4ый выходит из строя, и я его заменяю. То не собъётся ли номера датчиков? Я имею ввиду что до поломки, например, Т1 был Темп1 Т2 был Темп2 и т.д. а после замены станет Т1 это Темп4. И мне не совсем понятно как ссылаться, например, на значение Т1 в функции ЛУП если оно не прописано глобально, если ипользовать код который предложил b707 в #21 посте?
Не вводятся там номера датчиков от слова совсем.
Работает с любым что воткнули.
Если по коду из 21 поста, то Т объявлен глобально, а адресация T[0], T[1] и т.д. Почитайте про массивы.
Если по коду из 21 поста, то Т объявлен глобально, а адресация T[0], T[1] и т.д. Почитайте про массивы.
bwn, спасибо Вам! Огромное, человеческое спасибо!
Попробуйте мою давнюю заготовку.
Надеюсь все будет понятно.
A1 и A2 - пины датчиков
Чегож только мне, вариант trembo удобен, если есть свободные пины и надо тянуть в разные углы + легкая замена датчиков. В варианте с одной линией, экономим пины, но расплачиваемся длинным общим проводом и невозможностью легкой замены датчика. Как то так.
Попробуйте мою давнюю заготовку.
Надеюсь все будет понятно.
A1 и A2 - пины датчиков
У ТС с проблемы делаев топик начинался, а у Вас она вроде в полный рост?
И то верно. В любом случае буду пробовать все предложенные методы. Ещё раз ВСЕМ огромное спасибо!
У ТС с проблемы делаев топик начинался, а у Вас она вроде в полный рост?
Это проба, я так и написал, работы с двумя датчиками
на разных пинах и без ввода их адресов.
Что-то типа "ДЭМО"
Для понятия идеи.
Дэлэй для того чтобы на мельтешило в сериал мониторе.
Вобще легкая замена возможна и при топологии общей шины. Но надо реализовать поиск датчиков на шине. А адреса в EEPROM хранить. Если при очередном поиске появился новый адрес, а исчез один из старых - значить произошла замена, корректируем адрес в EEPROM. Общая шина позволяет легко добавить новые датчики в сеть, что особо актуально если нет четкого проекта решения и походу вдруг надо мерить еще чтото гдето.
Это проба, я так и написал, работы с двумя датчиками
на разных пинах и без ввода их адресов.
Чего его пробовать, работать без адреса совсем чутчуть проще чем с адресом. подали 0xcc - любой должен выполнить, а 0x55+8 байт адреса - только адресуемый. У ТС кстати тоже есть обращение без адреса - команда на конвертацию.
Но надо реализовать поиск датчиков на шине. А адреса в EEPROM хранить. Если при очередном поиске появился новый адрес, а исчез один из старых - значить произошла замена, корректируем адрес в EEPROM.
Это пока не для ТС задача.((((
Не факт. Самому писать поиск тяжко, но готовую реализацию поиска можна выдрать из чужего кода, из либы например. Както ж ТС адреса своих датчиков получил ;) К тому же разумно поиск делать разово при включении, а там можна и делеев не боятся. А остальное (читать писать EEPROM и сравнивать адреса) примитивщина. Если это не уметь (или не научится) - нехрен братся за озвученый проект.
Ну, с этим вариантом (EEPROM) не будет проблем только если меняется один сенсор. При замене двух и более - попадаем в состояние неопределенности. Да и периодический рескан шин(ы) мне представляется более оптимальным с точки зрения эксплуатации - не нужно бегать и ребутить блок управления при замене датчика.
Можна менять любое кол-во, но по одному. Замена датчиков очень редкий случай в процессе эксплуатации и зацикливатся на нем не стоит. Бегать и ребутить не надо, надо выключить, заменить датчик и включить. Ни одного лишнего действия. Рескан шины в процессе работы - излишество сложное, безсмысленое и из-за этого вредное.
С чего это оно сложное, бессмысленное и вредное? Я вот считаю вредным закладывать в алгоритм работы состояния неопределенного поведения и надеяться на то, что датчики будут договариваться в какой очередности им выйти из строя. Не знаю, как в вашей работе, а в моей и двойное резервирование не всегда является гарантией. А уж надеяться на четкое исполнение инструкций людьми лучше вообще не надеяться.
///С чего это оно сложное, бессмысленное и вредное?
Сложной - алгоритм сложный и реализуется блокирующим кодом, а значить в процессе работы будут те самые замирания. И шина в это время не может быть задействована по прямому назначению. Вам известна неблокирующая быстрая реализация - показывайте! Безсмысленым - замена датчиков процесс очень редкий при корректном построении сети. Например у меня за 5 лет ниразу не требовался. Все 100% живы- здоровы, единственная проблема - исчезает контакт если провод разорвать;) Зачем писать и исполнять код не дающий результата. А вредное - из-за вышеизложеного: отнимает ресурсы у разраба и контролера и не дает результата, т.к. проблема очень редкая.
Какое нафиг "неопределенного поведения", "датчики будут договариваться", "двойное резервирование не всегда является гарантией" и "исполнение инструкций людьми "? В не туда попали, здесь не сказки и не аэрокосмические системы.
ПС. Тема начинает отдавать шизофренией, одному CRC излишне другому двойное резервирование недостаточно, для одного поиск датчиков на шине - слишком сложно, другому реалтаймом он необходимо. Вы там, пацаны, междусобой както договоритесь;) А я пока пожру пойду.
Не стоит забывать тот факт, что разработчик понимает, почему нужно менять по одному датчику, каждый раз выключая и включая блок управления. У копировщика кода такого понимания нет и замена сразу двух датчиков будет для него крайне оптимальной операцией. Законы Мерфи написаны как раз для таких случаев. Почитайте.
Впрочем, я чую, что тут начинается бессмысленный срач в попытке доказать, что "я пять лет МКАД перебегал и ничего страшного", посему предпочту в нем не участвовать, а сходить в кино.
Неблокирующий (на время проведения конверсии) код вам уже, как я помню, ЕвгенийП демонстрировал. Не вижу смысла повторяться.
Сложной - алгоритм сложный и реализуется блокирующим кодом, а значить в процессе работы будут те самые замирания. И шина в это время не может быть задействована по прямому назначению. Вам известна неблокирующая быстрая реализация - показывайте!
На STM TIM+DMA !!!
Быстрая и практически не блокирующая.
Безсмысленым - замена датчиков процесс очень редкий при корректном построении сети.
Для этого достаточно отдать ещё один пин, к которому и тыкать новые датчики для опознавания системой, если уж совсем лень все датчики разделять изначально.
//Неблокирующий (на время проведения конверсии) код вам уже, как я помню, ЕвгенийП демонстрировал. Не вижу смысла повторяться.
Свинорыл пока только свою ограниченость продемонстрировал попутав время преобразования (750мсек) и время считывания (60мксек на бит) ))) А Вы только что попутали код "проведения конверсии" и код поиска датчика. И стояло из-за этого в тему влазить? Лучше бы сразу в кино.
ПС. Последние "Звездные войны" не стоят того чтоб в кино перется.
Дадада!! Только эсесовца тут не хватало ))))
Пропала тема.
Напоследок напишу, может ТС заинтересует, что в крайних своих поделках зачастую разделяю скетч на два. Один конфигурирует, настраивает, проверяет и создает все что можна и нужно, в т.ч. и список датчиков в EEPROM. В нем же и отлаживается переферия, библиотеки и т.д. Второй - основной рабочий с разумным минимумом настроек. Замена датчиков разумеется в первом. Т.к. предусматривать возмость прошивки даже в готовом устройстве всеравно нужно, то такой подход радует.
У женской логики что - обострение сегодня? Эко разбушевался, так и льётся изо всех щелёнок чсв :) :) :)
sadman41, прекращайте спорить с полуграмотным википедиком. Это бесполезно - он всегда и во всём прав! Когда я его вчера ткнул носом в даташит, так он просто послал меня нах и опять же оказался победителем на белом коне! Ну, поймите, человек прав всегда! Что Вы пытаетесь ему доказать? Это ж как с голубем в шахматы играть!
Logic, где я сказал, что CRC излишне? Я сказал, что за три и четыре года эксплуатации двух девайсов нужды в этой фиче не возникло. Последует ТС моему личному опыту (заметьте, не совету) или нет, решать ему, что то навязывать или кого то убеждать не собираюсь, это жизненный принцип. Здесь вроде взрослые дядьки собрались, которые могут сами решить вопрос о критичности и последствиях возникшей ошибки. ИМХО.
От такой разговор по существу)))
Только цитаты.
.... чтобы при считывании показаний не затормаживался весь код?
Само по себе считывание требует времени, отсюда и Ваши затыки.
Опять с херней влазите. Читайте даташит, считывание как и запуск преобразования пролетают очень быстро, десятки микросекунд. А цикл измерения и преобразования по умолчанию 750мсек. Оно и тормозит, кривая либа просто ждет эти 750мс.
All read time slots must be a minimum of 60μs
Temperature conversion!!!!!!! takes up to 750 ms!!!!!!!
Не? не различаеш?
Ну и ладно ТС уже различил и скетч зделал.
ПС. Послал - чего вернулись? Идитет дальше, там заждались ;)
Сперва скажите, где это будет работать, а потом уже решать, нужен ли весь этот тюнинг в "Московском зоопарке". Мне пока не понадобился.
Надобность проверок CRC вобщето не обсуждается. Их всегда проверяют, она для того и создана и посчитана. Просто тяжело обяснять одному человеку почему CRC надо проверять, а другому рассказывать почему датчики у нормальных людей редко выходят из строя и заменяются. Это две крайности в представлении о системе, Вы считаете что никогда не сбойнет, а sadman41 постоянный поиск заменяемого датчика да двойное резервирование и гарячую замену считает нужным. Плюс учесть что эксплуатирует идиот безграмотный. Это кто? ТС наверное? ;)
Я пытаюсь ТС удержать от этих крайностей в рамках разумного подхода. Тож по софту: одному реализовать поиск датчика - запредельно сложно кажется, другой его реалтайм предлагает (правда тут же путает поиск и опрос :), а я представляю последствия и опять же неопытному ТС советую делать, но без фанатизма.
Это две крайности в представлении о системе, Вы считаете что никогда не сбойнет, а sadman41 постоянный поиск заменяемого датчика да двойное резервирование и гарячую замену считает нужным. Плюс учесть что эксплуатирует идиот безграмотный. Это кто? ТС наверное? ;)
Я пытаюсь ТС удержать от этих крайностей в рамках разумного подхода. Тож по софту: одному реализовать поиск датчика - запредельно сложно кажется, другой его реалтайм предлагает (правда тут же путает поиск и опрос :), а я представляю последствия и опять же неопытному ТС советую делать, но без фанатизма.
Я не считаю, что никогда на сбойнет, просто последствия разового сбоя минимальны и смысл его отслеживания теряется. Если что то делаю в другие руки (это очень редко), там да и контроль и алярм и новогодняя елка, а может и принудительное отключение. Запись, сверка, принадлежность датчика были, во второй версии просто выкинул за ненадобностью, если отвалится, я это и так увижу и полезу с паяльником, а там и перезалить быстрее, чем их зажигалкой по очереди греть. Опять таки, личные выводы и предпочтения. Для серийной продукции такие методы не подходят.