Вопросы по работе с термометрами DS18B20
-
clawham
- Поставщик валерьянки для Кота
- Сообщения: 1957
- Зарегистрирован: Пт окт 31, 2008 09:38:55
- Откуда: Одесса
- Контактная информация:
Ну...чудес наверное не бывает а если на месте термометра уже побывало несколько ДС-ок то я тогда кроме как проблем с индикацией и питанием вобще больше не вижу нигде никаких косяков
Кстати, чтоб этого всего лишнего не городить(всмысле макс232 и т.д.) можно использовать порт инфракрасника если таковой имеется - у него уровни +5В такое конечно сичас редкость но иногда на мамках его разводят в виде колодки -|-|-|- -|-
разобраться что куда наверное не составит проблем
Кстати, чтоб этого всего лишнего не городить(всмысле макс232 и т.д.) можно использовать порт инфракрасника если таковой имеется - у него уровни +5В такое конечно сичас редкость но иногда на мамках его разводят в виде колодки -|-|-|- -|-
разобраться что куда наверное не составит проблем
-
clawham
- Поставщик валерьянки для Кота
- Сообщения: 1957
- Зарегистрирован: Пт окт 31, 2008 09:38:55
- Откуда: Одесса
- Контактная информация:
А я поначалу для ком порта использовал КПК свою - Fujitsu-Siemens Pocket LOOX 720 - у него ком порт тоже разведен и 5-тивольтовый
А терминалов для Кпк просто пруд пруди всяких разных
П.С.
А кто бы мне помог с алгоритмом?
есть у меня две переменные чаровские - старшый и младшый разряды результата измерения температуры Дской - дальше нужно эти два числа в флоат перевести я сейчас делаю
Где-то конечно понимаю что это страшно неэффективно и т.д. но понять как преобразовать в температуру простым выражением не могу
Где-то такое чтото должно было б получиться но.... подскажите кто знает?
А терминалов для Кпк просто пруд пруди всяких разных
П.С.
А кто бы мне помог с алгоритмом?
есть у меня две переменные чаровские - старшый и младшый разряды результата измерения температуры Дской - дальше нужно эти два числа в флоат перевести я сейчас делаю
Код: Выделить всё
// примитивный расчет температуры термометров
// обработаем старший байт - если он отрицателен то все биты надо инвертировать
temp = ds_scratch_pad.temp_msb;
if((temp>>6)&1)
{
below=1;
temp = temp^0b11111111;
}
else
below=0;
ds_temp = (float)((temp&1)*16+((temp>>1)&1)*32+((temp>>2)&1)*64);
// теперь младший
temp = ds_scratch_pad.temp_lsb;
// если число отрицательно - инвертируем
if(below)
temp=temp^0b11111111;
ds_temp = ds_temp + (float)((temp&1)*0.0625+((temp>>1)&1)*0.125+((temp>>2)&1)*0.25
+((temp>>3)&1)*0.5+((temp>>4)&1)+((temp>>5)&1)*2+
((temp>>6)&1)*4+((temp>>7)&1)*8);
if(below)
ds_temp = (float)(0-ds_temp);
// выводим на экранчик
sprintf(a2, "t%u=%+.4f\xf8C\n\r",i+1, ds_temp);
lcd_clear_row(2+i);
lcd_gotoxy(1,2+i);
lcd_putstr(a2); // выводим на экранчик
// строчка для com порта
printf("t%u(%i)= %f \n\r",i+1, rom_codes[i], ds_temp);
Где-то конечно понимаю что это страшно неэффективно и т.д. но понять как преобразовать в температуру простым выражением не могу
Код: Выделить всё
/*
// упрощенный
ds_temp = (*((int *) &__ds18b20_scratch_pad.temp_lsb) & bit_mask[resolution])*0.0625;
*/
Где-то такое чтото должно было б получиться но.... подскажите кто знает?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
господи, ну что вы такое понаписали-то? смотрите: DS выдает байты температуры в привычном формате младший-старший... то есть если обратиться к двум байтам, как к переменной int - мы сразу получим температуру в 0,0625 долях градуса... чтобы перевести это во float, всего-навсего надо целую температуру поделить на 16... вот так:
Код: Выделить всё
unsigned char buf[8];// массив, возвращенный DS18B20
int T = *(int*)buf;
float Tf = T / 16.0;если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
-
clawham
- Поставщик валерьянки для Кота
- Сообщения: 1957
- Зарегистрирован: Пт окт 31, 2008 09:38:55
- Откуда: Одесса
- Контактная информация:
Dctulf пожалуйста помоч и большое спасибо...
я чесно говоря немного не понял
Есть у меня два чара LSB и MSB я их в массив кидаю по порядку а потом обращяюсь через разименование как к инту ну и само собой делю на 16 так?
П.С.в математике всегда не понимал этих трансформаций
уж извините
просто меня это сразу сбило тем что если делать как вы сказали надо буфер а у меня структура
поэтому строка принимает вид
но результатом как ни странно всегда является целое число!!!
и в протеусе и в реальном устройстве
потом уже вот только что понял в чём прикол - надо так
его оказывается число 16 сбивало видать в чаре потому что
я чесно говоря немного не понял
Есть у меня два чара LSB и MSB я их в массив кидаю по порядку а потом обращяюсь через разименование как к инту ну и само собой делю на 16 так?
П.С.в математике всегда не понимал этих трансформаций
уж извините
просто меня это сразу сбило тем что если делать как вы сказали надо буфер а у меня структура
Код: Выделить всё
struct ds_scratch_pad_struct
{
unsigned char temp_lsb,temp_msb,
temp_high,temp_low,
conf_register,
res1,
res2,
res3,
crc;
} ds_scratch_pad;поэтому строка принимает вид
Код: Выделить всё
CurrDev = *(int*)&ds_scratch_pad.temp_lsb;
ds_temp = CurrDev/16;но результатом как ни странно всегда является целое число!!!
и в протеусе и в реальном устройстве
потом уже вот только что понял в чём прикол - надо так
Код: Выделить всё
CurrDev = *(int*)&ds_scratch_pad.temp_lsb;
ds_temp = CurrDev/(float)16;его оказывается число 16 сбивало видать в чаре потому что
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
во-первых, все вы поняли: массив или структура - без разницы.
а во-вторых, невнимательно читали мой примерчик - там написано деление на 16.0, а не просто на 16 - вот где собака порылась! заметьте, что ваше решение (float)16 выглядит куда более убого, чем 16.0 - а ведь это одно и то же!
а во-вторых, невнимательно читали мой примерчик - там написано деление на 16.0, а не просто на 16 - вот где собака порылась! заметьте, что ваше решение (float)16 выглядит куда более убого, чем 16.0 - а ведь это одно и то же!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
есть простое правило, знание которого сбережет вам много сил и нервов при отладке программ: при вычислении любого выражения компилятор приводит все члены выражения к наибольшему (в смысле - наидлиннейшему) типу, который имеется среди членов выражения, и только потом производит вычисления.clawham писал(а):Не спорю
Думал - не имеет значения - видать 16.0 говорит компиллеру что не целочисленное деление будет
Спасибо большое - век живи век учись
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Когда-то нашёл на одном из форумов и сам повторял где-то, но приведу цитату ещё раз:
----------
Датчик DS18B20 возвращает температуру с фиксированной запятой, 4 знака после запятой.
Таким образом для получения температуры с точностью 0.1 градуса нам нужно возвращаемое значение умножить на 0.625
Код: value = (value>>1) + (value>>3);
Как всё просто! И никаких дробей и т.д. Как работает ...
Сдвиг вправо на один бит -- это деление на два. Сдвиг вправо на три бита -- это деление на восемь
Перепишем... Код:
value = value*(1/2) + value* (1/8) = value*(4/8) + value * (1/8) = value * (5/8) = value* 0.625
Напоследок весь код функции: (Полное его объяснение не входит в мою задачу, смотрите даташит на датчик)
Преобразования в формат с фиксированной запятой (1 знак после запятой):
Код:
int16_t ds1w_12bit_to_celsius(uint16_t value)
{uint8_t uc1;
uc1 = (value>>8) & 0x80; //запомнить знак числа
if (uc1) value = 0-value; //если нужно, проинвертировать
value = (value>>1) + (value>>3); //скорректировать
if (uc1) value = 0-value; //восстановить знак
return(value);
}
----------
PS Ссылка на первоисточник: http://www.remexpert.com/ipb/ipb.html?s ... ost&p=5947
Кстати, при 3-х проводном подключении DS18B20 можно не отсчитывать 750mS...
Проще опрашивать шину - датчик сам скажет (отпустив шину в "1"), когда он закончил измерять температуру. Всё описано в даташите.
----------
Датчик DS18B20 возвращает температуру с фиксированной запятой, 4 знака после запятой.
Таким образом для получения температуры с точностью 0.1 градуса нам нужно возвращаемое значение умножить на 0.625
Код: value = (value>>1) + (value>>3);
Как всё просто! И никаких дробей и т.д. Как работает ...
Сдвиг вправо на один бит -- это деление на два. Сдвиг вправо на три бита -- это деление на восемь
Перепишем... Код:
value = value*(1/2) + value* (1/8) = value*(4/8) + value * (1/8) = value * (5/8) = value* 0.625
Напоследок весь код функции: (Полное его объяснение не входит в мою задачу, смотрите даташит на датчик)
Преобразования в формат с фиксированной запятой (1 знак после запятой):
Код:
int16_t ds1w_12bit_to_celsius(uint16_t value)
{uint8_t uc1;
uc1 = (value>>8) & 0x80; //запомнить знак числа
if (uc1) value = 0-value; //если нужно, проинвертировать
value = (value>>1) + (value>>3); //скорректировать
if (uc1) value = 0-value; //восстановить знак
return(value);
}
----------
PS Ссылка на первоисточник: http://www.remexpert.com/ipb/ipb.html?s ... ost&p=5947
Кстати, при 3-х проводном подключении DS18B20 можно не отсчитывать 750mS...
Проще опрашивать шину - датчик сам скажет (отпустив шину в "1"), когда он закончил измерять температуру. Всё описано в даташите.
Последний раз редактировалось smg123 Вс июн 14, 2009 09:30:00, всего редактировалось 1 раз.
- Секретный кот
- Поставщик валерьянки для Кота
- Сообщения: 2106
- Зарегистрирован: Ср сен 17, 2008 14:32:15
- Откуда: Старые Васюки
- Контактная информация:
- acm_fan
- Первый раз сказал Мяу!
- Сообщения: 27
- Зарегистрирован: Чт фев 12, 2009 23:00:03
- Откуда: Днепропетровск
- Контактная информация:
Экспериментрую с DS18B20 и mega8, используя Codevision и ISIS Proteus. Температура корректно отображается (на LCD) при частотах 0,9-18 МГц. Мне необходима более низкая частота - 0,4 МГц или даже 32768 Гц (еще не решил), при 0,8 МГц и ниже температура уже некорректная. Подскажите, в чем может быть загвоздка.
Hallowed be Thy Name, Iron Maiden!
- sheva_s
- Грызет канифоль
- Сообщения: 256
- Зарегистрирован: Пт апр 27, 2007 14:32:48
- Откуда: Украина Кривой Рог
- Контактная информация:
Всем привет.
Пытаюсь разобраться с датчиком температуры . Для опроса датчика и разложения числа использую вот такой код.
Были глюки с индикацией поборол тем что начал делать проверку на то что датчик неприслал ошибку, стали показания нормально показывать поборол вот этой строчкой
Вот только возник вопрос пишу в КОД ВИЖЕН если число 9999 оставляю с плюсом то индикация глючит переодически выскакивают ошибки в отображении температуры, а вот если с минусом то все работает нормально. А по форуму встречал что число должно быть с плюсом вот и непойму в чем может быть глюк. Может кто то подскажет.
Получился оффтоп.
А если точнее нашел в умной книжке что датчик при ошибке возвращяет значение -9999
Пытаюсь разобраться с датчиком температуры . Для опроса датчика и разложения числа использую вот такой код.
Код: Выделить всё
temp=ds18b20_temperature(&ds18b20_rom_codes[0][0]);
if(temp!=-9999){
temp1=temp;
A=temp1/10;
B= temp1%10;
delay_ms(200);
};Были глюки с индикацией поборол тем что начал делать проверку на то что датчик неприслал ошибку, стали показания нормально показывать поборол вот этой строчкой
Код: Выделить всё
if(temp!=-9999)Вот только возник вопрос пишу в КОД ВИЖЕН если число 9999 оставляю с плюсом то индикация глючит переодически выскакивают ошибки в отображении температуры, а вот если с минусом то все работает нормально. А по форуму встречал что число должно быть с плюсом вот и непойму в чем может быть глюк. Может кто то подскажет.
Получился оффтоп.
А если точнее нашел в умной книжке что датчик при ошибке возвращяет значение -9999
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
если и на самом деле в книжке это было написано про датчик DS18B20 - то это наоборот, самая глупая книжка, фтопку ее!
датчик ничего не возвращает при ошибке, вообще понятие "ошибка" отсутствует для него в принципе. это функция CVAVR чего-то там возвращает...
датчик ничего не возвращает при ошибке, вообще понятие "ошибка" отсутствует для него в принципе. это функция CVAVR чего-то там возвращает...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!