DS18B20 (нужна помощь)
- Войдите на сайт для отправки комментариев
Ср, 24/01/2018 - 20:33
Помогите, есть 2 датчика DS18B20 все работает, но нет минусового значения никак не получается
#include <OneWire.h> OneWire ds(2); // Завесим датчики на pin 2 (и обязательно подтянем к плюсу 4.7K резистором) byte i; // Любимый счетчик byte data[8]; // Сюда попадают данные из датчиков byte addr[8]; // Здесь хранятся адреса датчиков float celsius; // Всякая хрень для работы с температурой int signBit, tc_100, whole, fract; void setup(void) { Serial.begin(9600); } void loop(void) { // Функция последовательно ищет адреса устройств if (!ds.search(addr)) { // и запоминает их в addr. Если очередного устройства не найдено ds.reset_search(); // поиск сбрасывается и все начинается сначала delay(250); return; } ds.reset(); // Сбрасываем линию ds.select(addr); // Выбираем найденный адрес ds.write(0x44, 1); // Пишем 0x44 - команда на расчет температуры и 1 - если паразитное питание, если обычное (соединение три провода) то 0. delay(1000); // Для преобразования при паразитном питании надо 750ms, берем с запасом. Если питание обычное - достаточно 100 ds.reset(); // Опять сброс и выбор адреса - так положено по инструкции. ds.select(addr); ds.write(0xBE); // Команда датчику, чтобы он начал отдавать данные. Serial.print(" Data = "); Serial.print(" "); for ( i = 0; i < 9; i++) { // Читаем 8 байт. А зачем нам все 8? Достаточно первых двух! data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } int16_t raw = (data[1] << 8) | data[0]; // int кодировка сотоит из двух байт, причем каждая единичка значит 0.0625 градуса celsius = (float)raw / 16.0; // Превращаем int во float и делим на 16, что равно умножению на 0.0625, потому что Serial.print("First Temperature = "); // 1 делить на 16 равно 0.0625. Serial.print(celsius); signBit = raw & 0x8000; // Проверяем самый левый бит: 0x8000= 0b10000000 00000000 if (signBit) // Если там единица - число отрицательное и его надо преобразовать { // Стандартное преобразование отрицательного числа, которое в микроконтроллере в дополнительной кодировке raw = (raw ^ 0xffff) + 1; // Путем исключающего ИЛИ плюс единица http://www.inf1.info/additionalcode } tc_100 = (6 * raw) + raw / 4; // Это хитрая запись умножения на 6.25 - поиграйте с дробями на бумажке: (25raw)/4 // Вообще то, нужно было умножать на 0.0625, но число наше - int, и тогда мы потеряем // все данные. Поэтому умножили еще на 100. whole = tc_100 / 100; // Делим на сто, и получаем целое число (помним, что int отбросит дробь) fract = tc_100 % 100; // Остаток от деления на 100 будет дробной частью. Serial.print("Second Temperature = "); // И напечатаем все это для сравнения. if(signBit) { Serial.print("-"); } Serial.print(whole); Serial.print("."); if(fract < 10) { Serial.print("0"); } Serial.println(fract); }
Или берите даташит, читайте как они (отрицательные температуры) хранятся и обрабатывайте, или возьмите готовую библиотеку DallasTemperature - там всё уже сделано, причём более грамотно - проверяется контрольная сумма, обрабатываются ошибки и т.п..
Или берите даташит, читайте как они (отрицательные температуры) хранятся и обрабатывайте, или возьмите готовую библиотеку DallasTemperature - там всё уже сделано, причём более грамотно - проверяется контрольная сумма, обрабатываются ошибки и т.п..
сам не силен может подскажешь на 2 датчика код, вообще вывод надисплей OLED LCD 128x64 0.96 I2C но хватит и монитор порта там как нить сам доделал бы
Подскажу. Вместе с библиотекой DallasTemperature есть примеры и там как раз есть вывод со стольких датчиков, сколько подключено.
Всё просто:
Я думаю если в 10 строке SignBit сделать беззнаковый тип - все заработает, сталкивался уже с такой проблемой
Отсюда можно нужный кусок взять - 100 % минус показывает
http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=2...