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 есть примеры и там как раз есть вывод со стольких датчиков, сколько подключено.
Всё просто:
int loByte = data[0]; int hiByte = data[1]; int8_t tempValue; uint8_t tempFract; int temp = (hiByte << 8) + loByte; bool isNegative = (temp & 0x8000); if(isNegative) temp = (temp ^ 0xFFFF) + 1; // DS18B20 ONLY !!! int tc_100 = (6 * temp) + temp/4; tempValue = tc_100/100; if(isNegative) tempValue = -tempValue; tempFract = tc_100 % 100;Я думаю если в 10 строке SignBit сделать беззнаковый тип - все заработает, сталкивался уже с такой проблемой
Отсюда можно нужный кусок взять - 100 % минус показывает
http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=2...