DS18B20 и отрицательные температуры (отображение)
- Войдите на сайт для отправки комментариев
Добрый день. Хотелось сделать уличный термометр, самый простой и без заморочек. Все получилось, но выяснилось одно: он не показывает отрицательные температуры. То есть ноль показывает как ноль, а все что ниже нуля - как плюсовые температуры. Пытаюсь разобраться, что мешает. На данный момент выяснил что за знак отвечает "бит признака", где-то написано что регистр "S". Но как реализовать - темный лес (пока). Есть код самого проекта.
#include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 10 // номер пина к которому подключен DS18B20 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); #include <OLED_I2C.h> OLED myOLED(8, 9, 8); // 8pin - SDA , 9pin - SCL extern uint8_t RusFont[]; // Русский шрифт extern uint8_t MegaNumbers[]; // Подключение больших шрифтов extern uint8_t SmallFont[]; // Базовый шрифт без поддержки русскийх символов. void setup() { sensors.begin(); myOLED.begin(); } void loop() { sensors.requestTemperatures(); myOLED.clrScr(); // очищаем экран myOLED.setFont(RusFont); // Устанавливаем русский шрифт myOLED.print("Ntvgthfnehf", CENTER, 0); // Выводим надпись "Температура" myOLED.setFont(SmallFont); myOLED.print("iarduino.ru", CENTER, 55); // вывод текста myOLED.setFont(MegaNumbers); myOLED.print(String(sensors.getTempCByIndex(0) , 1), CENTER, 9); // Отображение температуры myOLED.update(); delay(100); }
Вот ссылка на источник:
https://lesson.iarduino.ru/page/termometr-na-baze-ds18b20-i-oled-displeya-128x64/
С ардуино знаком пока на уровне "мигания", вот пытаюсь продвинуться дальше.
По термометрам находил еще один проект, хорошо формленный, но с той же проблемой. Нет "минуса".
Вот ссылка: http://arduino-project.net/oled-chasy-na-arduino/
Немного сложнее с конвертацией и загрузкой изображений, но и интереснее. Скетч который я загружал по этому проекту:
#include <OLED_I2C.h> OLED myOLED(SDA, SCL, 8); extern uint8_t MegaNumbers[]; extern uint8_t RusFont[]; extern uint8_t SmallFont[]; extern uint8_t term[]; extern uint8_t grad[]; #include <DS1307.h> DS1307 rtc(A0, A1); Time t; #include <OneWire.h> OneWire ds(4); int x = 0; void setup() { myOLED.begin(); rtc.halt(false); //rtc.setDOW(WEDNESDAY); //rtc.setTime(21, 24, 0); //rtc.setDate(29, 4, 2015); } void loop() { if (x >= 10) { temp(); x=0; } else { watch(); } x++; } void watch() { myOLED.setFont(RusFont); t = rtc.getTime(); switch (t.dow) { case 1: myOLED.print("GJYTLTKMYBR", CENTER, 0); break; case 2: myOLED.print("DNJHYBR", CENTER, 0); break; case 3: myOLED.print("CHTLF", CENTER, 0); break; case 4: myOLED.print("XTNDTHU", CENTER, 0); break; case 5: myOLED.print("GZNYBWF", CENTER, 0); break; case 6: myOLED.print("CE<<JNF", CENTER, 0); break; case 7: myOLED.print("DJCRHTCTYMT", CENTER, 0); break; } String stringOne = rtc.getTimeStr(); myOLED.setFont(MegaNumbers); myOLED.print(stringOne.substring(0, 2), 4, 12); myOLED.print("/", 51, 12); myOLED.print(stringOne.substring(3, 5), 75, 12); myOLED.setFont(RusFont); switch (t.mon) { case 1: myOLED.print(String(t.date), 30, 57); myOLED.print("ZYDFHZ", CENTER, 57); myOLED.print(String(t.year), 88, 57); break; case 2: myOLED.print(String(t.date), 26, 57); myOLED.print("ATDHFKZ", CENTER, 57); myOLED.print(String(t.year), 92, 57); break; case 3: myOLED.print(String(t.date), 30, 57); myOLED.print("VFHNF", CENTER, 57); myOLED.print(String(t.year), 88, 57); break; case 4: myOLED.print(String(t.date), 30, 57); myOLED.print("FGHTKZ", CENTER, 57); myOLED.print(String(t.year), 88, 57); break; case 5: myOLED.print(String(t.date), 36, 57); myOLED.print("VFZ", CENTER, 57); myOLED.print(String(t.year), 82, 57); break; case 6: myOLED.print(String(t.date), 35, 57); myOLED.print("B>YZ", CENTER, 57); myOLED.print(String(t.year), 81, 57); break; case 7: myOLED.print(String(t.date), 35, 57); myOLED.print("B>KZ", CENTER, 57); myOLED.print(String(t.year), 81, 57); break; case 8: myOLED.print(String(t.date), 28, 57); myOLED.print("FDUECNF", CENTER, 57); myOLED.print(String(t.year), 90, 57); break; case 9: myOLED.print(String(t.date), 24, 57); myOLED.print("CTYNZ<HZ", CENTER, 57); myOLED.print(String(t.year), 94, 57); break; case 10: myOLED.print(String(t.date), 26, 57); myOLED.print("JRNZ<HZ", CENTER, 57); myOLED.print(String(t.year), 92, 57); break; case 11: myOLED.print(String(t.date), 28, 57); myOLED.print("YJZ<HZ", CENTER, 57); myOLED.print(String(t.year), 90, 57); break; case 12: myOLED.print(String(t.date), 26, 57); myOLED.print("LTRF<HZ", CENTER, 57); myOLED.print(String(t.year), 92, 57); break; } myOLED.update(); delay(450); myOLED.setFont(MegaNumbers); myOLED.print("-", 51, 12); myOLED.update(); delay(450); } void temp() { for(int x = 0; x < 10; x++){ byte data[2]; ds.reset(); ds.write(0xCC); ds.write(0x44); delay(150); ds.reset(); ds.write(0xCC); ds.write(0xBE); data[0] = ds.read(); data[1] = ds.read(); int Temp = (data[1] << 8) + data[0]; Temp = Temp >> 4; String stringOne = rtc.getTimeStr(); myOLED.clrScr(); myOLED.setFont(SmallFont); myOLED.print(stringOne.substring(0, 5), 98, 0); myOLED.print(rtc.getDateStr(), 0, 0); myOLED.setFont(RusFont); myOLED.print("NTVGTHFNEHF", CENTER, 57); myOLED.drawBitmap(4, 12, term, 19, 40); myOLED.setFont(MegaNumbers); myOLED.print(String(Temp), CENTER, 12); myOLED.drawBitmap(92, 12, grad, 13, 12); myOLED.update(); myOLED.clrScr(); } }
P.S. Если эта тема уже поднималась, прошу сильно не пинать.
Узрите на стр.6 http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf Там получаемые от датчика 2 байта расписаны подробней просто некуда. Далее несложная отладка очевидными методами.
Узрите на стр.6 http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf Там получаемые от датчика 2 байта расписаны подробней просто некуда. Далее несложная отладка очевидными методами.
Узрел, не в первый раз. Можете просветить как эти два байта прочитать, отобразить, да и про отладку и где нужно изменить код? Я не такой профессионал в программировании.
а вот это разве не решает все проблемы, а остальное проблемы вывода, а не измерения и снятия данных
А теперь смотрим на оба скетча, особенно на строку 140 первого и 11 второго )))
То есть в 140 строке заменить вместо:
поставить
идеологически более правильно выделять целую, дробную и знак.
температуру округлять до 0.1 или до целых по неободимсти.
//идеологически более правильно выделять целую, дробную и знак.
А в чем тайный смысл такой идеи? Зачем. Там все логично, отрицательная температура в дополнительном коде как обычные отрицательные числа. Просто цена младшего разряда 1/16 градуса, что и корректируется соответственно.
затем чтобы распихивать по знакоместам жки или рф пакета например, округлять, а не тупо отбрасывать дробную часть, ну или сравнивать с константой.
Неужели все так сложно даже для профи? Думал что все просто...
затем чтобы распихивать по знакоместам жки или рф пакета например, округлять, а не тупо отбрасывать дробную часть, ну или сравнивать с константой.
Кстати, в исходном тексте программы дробная часть не учитывается ввиду очень маленького OLED экрана. Да и на самом деле без дробной части нормально показывают.
Столкнулся с такой же проблемой. Повезло быстро решить. В папке с библиотекой OLED I2C есть файл DefaultFonts.c открываем его с помощью блокнота и видим что в команде MegaNumbers нет символа минус а вот в команде BigNumbers есть. Меняем в коде везде где встречается Mega (3раза) меняем на Big. Все работает. Но шрифт теперь занимает не весь экран что не очень эстетически.