Вопросы по работе с термометрами DS18B20

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
RoTToR
Открыл глаза
Сообщения: 73
Зарегистрирован: Вс июн 07, 2009 23:16:16
Контактная информация:

Сообщение RoTToR »

К сожалению нет у меня МАХ232 под рукой, нужно ехать покупать...

Вы говорили что то может быть по питаю не так, питается у меня весь термометр от стабилизатора 7805 (1А), с параллельно включены конденсатором на 0,1 мкФ.
clawham
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса
Контактная информация:

Сообщение clawham »

Ну...чудес наверное не бывает а если на месте термометра уже побывало несколько ДС-ок то я тогда кроме как проблем с индикацией и питанием вобще больше не вижу нигде никаких косяков :)
Кстати, чтоб этого всего лишнего не городить(всмысле макс232 и т.д.) можно использовать порт инфракрасника если таковой имеется - у него уровни +5В такое конечно сичас редкость но иногда на мамках его разводят в виде колодки -|-|-|- -|-
разобраться что куда наверное не составит проблем :)
clawham
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса
Контактная информация:

Сообщение clawham »

А я поначалу для ком порта использовал КПК свою - 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
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

господи, ну что вы такое понаписали-то? смотрите: DS выдает байты температуры в привычном формате младший-старший... то есть если обратиться к двум байтам, как к переменной int - мы сразу получим температуру в 0,0625 долях градуса... чтобы перевести это во float, всего-навсего надо целую температуру поделить на 16... вот так:

Код: Выделить всё

unsigned char buf[8];// массив, возвращенный DS18B20
int T = *(int*)buf;
float Tf = T / 16.0;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
RoTToR
Открыл глаза
Сообщения: 73
Зарегистрирован: Вс июн 07, 2009 23:16:16
Контактная информация:

Сообщение RoTToR »

clawham Вы были правы, проблема была зарыта в питании, поставил электролит на 100 мкФ после стабилизатора, и все стало на свои места.
Спасибо за внимание!!! Изменяюсь за то, что поморочил голову!:)
clawham
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса
Контактная информация:

Сообщение clawham »

Dctulf пожалуйста помоч и большое спасибо...
я чесно говоря немного не понял :)
Есть у меня два чара 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
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

во-первых, все вы поняли: массив или структура - без разницы.
а во-вторых, невнимательно читали мой примерчик - там написано деление на 16.0, а не просто на 16 - вот где собака порылась! заметьте, что ваше решение (float)16 выглядит куда более убого, чем 16.0 - а ведь это одно и то же! :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
clawham
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса
Контактная информация:

Сообщение clawham »

Не спорю :)
Думал - не имеет значения - видать 16.0 говорит компиллеру что не целочисленное деление будет :)
Спасибо большое - век живи век учись :)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

clawham писал(а):Не спорю :)
Думал - не имеет значения - видать 16.0 говорит компиллеру что не целочисленное деление будет :)
Спасибо большое - век живи век учись :)
есть простое правило, знание которого сбережет вам много сил и нервов при отладке программ: при вычислении любого выражения компилятор приводит все члены выражения к наибольшему (в смысле - наидлиннейшему) типу, который имеется среди членов выражения, и только потом производит вычисления.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
smg123
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Вс июл 22, 2007 10:23:21

Сообщение smg123 »

Когда-то нашёл на одном из форумов и сам повторял где-то, но приведу цитату ещё раз:
----------
Датчик 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 раз.
CyxoeBuHo
Открыл глаза
Сообщения: 51
Зарегистрирован: Вс июн 14, 2009 00:19:53
Контактная информация:

Сообщение CyxoeBuHo »

привет, коты!!! а можно термометр сделать на тини 2313??
Аватара пользователя
Секретный кот
Поставщик валерьянки для Кота
Сообщения: 2106
Зарегистрирован: Ср сен 17, 2008 14:32:15
Откуда: Старые Васюки
Контактная информация:

Сообщение Секретный кот »

Можно.
Даже остановленные часы два раза в сутки показывают правильное время.
Аватара пользователя
acm_fan
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт фев 12, 2009 23:00:03
Откуда: Днепропетровск
Контактная информация:

Сообщение acm_fan »

Экспериментрую с DS18B20 и mega8, используя Codevision и ISIS Proteus. Температура корректно отображается (на LCD) при частотах 0,9-18 МГц. Мне необходима более низкая частота - 0,4 МГц или даже 32768 Гц (еще не решил), при 0,8 МГц и ниже температура уже некорректная. Подскажите, в чем может быть загвоздка.
Hallowed be Thy Name, Iron Maiden!
Аватара пользователя
Aiudara
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Пт июл 31, 2009 21:52:18

Сообщение Aiudara »

Наверно не успевает работать по 1-wire. Может надо разгонятся на время измерения температуры. Ее ведь можно с перерывами мерить.

Либо просто датчик другой попробуйте. Есть с выходом частотным или скважностью дающий информацию.
clawham
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса
Контактная информация:

Сообщение clawham »

а зачем такой изврат?
тактуйте МК встроенными 8-мю мегагерцами а часовой кварц повесьте на таймер
Veg@
Родился
Сообщения: 3
Зарегистрирован: Сб авг 22, 2009 17:59:01

Сообщение Veg@ »

все обыскал.. напишите, плз, как на DS18B20 установить разрешение 9 бит и как вычислить отрицательную десятичную температуру (на Асме)(положительную просто делю на 16). заранее спасибо.
clawham
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса
Контактная информация:

Сообщение clawham »

положительная = отрицательной
отрицательная - если старший бит старшего байта равен 1 надо всё инвертировать и получите как бы положительное число - делите его на 16 получите температуру а знак - минус если в исходном старшем байте старший бит 1
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

Сообщение Pooher »

используйте комманду ассемблера com для первого байта если второй байт равен FF.
все обыскал.

??? В DataSheet всё конкрктно описано!
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Аватара пользователя
sheva_s
Грызет канифоль
Сообщения: 256
Зарегистрирован: Пт апр 27, 2007 14:32:48
Откуда: Украина Кривой Рог
Контактная информация:

Сообщение sheva_s »

Всем привет.
Пытаюсь разобраться с датчиком температуры . Для опроса датчика и разложения числа использую вот такой код.

Код: Выделить всё

 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
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

если и на самом деле в книжке это было написано про датчик DS18B20 - то это наоборот, самая глупая книжка, фтопку ее!

датчик ничего не возвращает при ошибке, вообще понятие "ошибка" отсутствует для него в принципе. это функция CVAVR чего-то там возвращает...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»