Датчик температуры DS18B20
- Войдите на сайт для отправки комментариев
Вс, 27/12/2015 - 16:40
Пподскажите пожалуйста. Используется код для вывода температуры на дисплей. Фишка в том, что на дисплее температура постоянно показывается со значениями, например 5.000 градусов, а бывает 5.00 и всё такое. Т.е. разное кол-во нулей. Как сделать наиболее точный вывод температуры, с возможными половинами крадуса ?
Вот код:
#include <LiquidCrystal.h> #include <OneWire.h> OneWire ds(13); // Подключаем датчик к 8 цифровому пину LiquidCrystal lcd(32, 30, 28, 26, 24, 22); //Подключаем LCD void setup(void) { pinMode(9, OUTPUT); analogWrite(9, 0); lcd.begin(16, 2); //16 знаков, 2 строки lcd.print("Temp:"); //Печатаем верхнюю строку LCD } void loop(void) { byte i; byte type_s; byte data[12]; byte addr[8]; float celsius, fahrenheit; // Ищем алрес датчика if ( !ds.search(addr)) { Serial.println(); ds.reset_search(); delay(250); return; } // Проверяем не было ли помех при передаче if (OneWire::crc8(addr, 7) != addr[7]) { Serial.println("CRC is not valid!"); return; } Serial.println(); // Определяем серию датчика switch (addr[0]) { case 0x10: type_s = 1; break; case 0x28: type_s = 0; break; case 0x22: type_s = 0; break; default: return; } ds.reset(); ds.select(addr); // Выбираем адрес ds.write(0x44, 1); // Производим замер, в режиме паразитного питания delay(10000); ds.reset(); ds.select(addr); ds.write(0xBE); // Считываем оперативную память датчика for ( i = 0; i < 9; i++) { data[i] = ds.read(); // Заполняем массив считанными данными } // Данные о температуре содержатся в первых двух байтах, переведем их в одно значение и преобразуем в шестнадцатиразрядное число int16_t raw = (data[1] << 8) | data[0]; // Переводим температуру в шкалы по Цельсию и Фаренгейту if (type_s) { raw = raw << 3; } if (data[7] == 0x10) { raw = (raw & 0xFFF0) + 12 - data[6]; } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw << 3; else if (cfg == 0x20) raw = raw << 2; else if (cfg == 0x40) \ raw = raw << 1; } celsius = (float)raw / 16.0; lcd.setCursor(8, 0); //Пишем в LCD на 2 строке lcd.print(celsius); //Цельсии }
lcd.print(celsius , 1)
Вроде так
Ну и это округлит до целых ? Может ли датчик выводить точне значения ? 1.5C; 1,2C и всё остальное ?
Округлит до 1 знака после запятой. Вы бы хоть попробовали сперва.
Разрядность самого датчика при 12бит - 0,00625гр.цельсия
Ну теперь постоянно показывает чисто.ноль. (-4.0 ; 3.0). А хочу, чтоб более точное значение было, с десятым/сотыми. Подскажите пожалуйста.
Х-ня у вас какая то, попробуйте отсюда код, четвертый пост, для одного датчика. В третьей строке впишите адрес своего датчика. Если будет также гнать только целыми, раскомментируйте блок с 12 по 17 строки. Отпишитесь, что получилось.
Вот состряпал такой франкенштейн-код. И на экране просто написанно " -1 ".
f0rZzZ, вы что, через строчку читаете то, что вам пишут? Перечитайте ещё раз второе предложение из #5
Простите, немного туговат ) Подскажите, как узнать адресс своего датчика ?
Нужно умножить показания на 0,0625. Пример #A8 168*0,0625= 10,5
f0rZzZ, запускаете примеры из OneWire для DS18, какой то из них показывает адреса. Зачем вы создаете себе проблемы, экран на компьютере не работает? Добейтесь сперва нормального считывания, а потом работоспособный код прикручивайте к LCD.
terminal, а откуда вы такое узнали?
Так, ну в терминал выдаёт теперь температуру как и хотелось бы: -5.56
Пподскажите пожалуйста. Используется код для вывода температуры на дисплей. Фишка в том, что на дисплее температура постоянно показывается со значениями, например 5.000 градусов, а бывает 5.00 и всё такое. Т.е. разное кол-во нулей. Как сделать наиболее точный вывод температуры, с возможными половинами крадуса ?
Вот код:
Тут ошибка
data имеет тип byte при сдвиге обнулится, потому делать нужно так
Далее, для получения результата с точностью после запятой делаем следующее
Так, ну в терминал выдаёт теперь температуру как и хотелось бы: -5.56
Я вам для чего ссылку дал, чтобы посмотрели, как у Dimax сделаны ваши раскоряченные сдвиги и преобразования. Не нужна "собака", уберите ее и останется два фрагмента - на преобразование и на считывание. Между ними задержка 750мС при 12бит. И крутите эти фрагменты, как вам нравится.
Простите, но так и не разобрался, что подправить для большей выдержки (
Добавьте инициализацию LCD. После сериалпринтов, напишите аналогично команды для своего LCD. До делая команды на преобразование, после на считывание. В первый проход покажет чушь, все последующие правда.
Что нужно сделать, чтобы сразу показало правду?
Благодарю всех. Сделал, всё шикарно.
Ну, если нет желания поразбираться, ваше право.
Дак я понял в чём суть, подправил что надо и добился желаемого результата.
Так delay(750), это фи. 3/4 секунды программа висит. Если только выводить температуру, без разницы. Начнете приделывать кнопки и прочие фишки, начнет раздражать или непонятно работать. Собака у Dimax не просто так прикручена была.
Ну пока просто температуру и вывожу. А потом хочу попробовать проект Arduino Mega Server
Собака у Dimax не просто так прикручена была.
Alexino, конечно проще, какай разговор! А ещё проще взять даллосовскую библу, и не забивать голову лишними командами. А ещё проще вообще ничего не делать, а лежать на диване и пить пиво. Зачем извращаться и что-то самому колхозить, когда всё можно купить готовое? :)
Ну... скатились до "купить" :) Причём тут это ? Просто для чего использовать какие то нестандартные решения, если для этого есть стандартные ? Нужен периодичный опрос - юзаем системный таймер - это вполне обоснованное и адекватное решение.
Собака... Вообще, на сколько мне известно, собака ресетит чип. В таком случае, использовать её для периодичных интервалов - не совсем айс.
Далласовская библиотека. Тут она тоже немного не в тему. Она не реализует никаких периодичных опросов. Так что, не известно, проще ли её взять.
Ничего не делать. Хм... заманчиво, но не по-нашему :)
Нужен периодичный опрос - юзаем системный таймер - это вполне обоснованное и адекватное решение.
Собака... Вообще, на сколько мне известно, собака ресетит чип. В таком случае, использовать её для периодичных интервалов - не совсем айс.
Что значит не айс? Вотчдог это такой же таймер. Даже в чём-то более удобный, т.к. может работать когда МК спит.
А он не ресетит микроконтроллер ?
Alexino, по желанию. У него три варианта по истечению счёта: только прерывание, только ресет, прерывание и за ним ресет.
Всё ясно. Ну тогда да, как вариант....
Но всё равно, через millis более стандартно ))))))