ds1821 help!!!

Dec 27, 2005 32 Replies

Hi All !



íÏÖÅÔ ÌÉ ËÔÏ ÎÉÂÕÔØ ÐÒÉÄÕÍÁÔØ ÁÌÇÏÒÉÔÍ ÐÏÌÕÞÛÅ ÉÂÏ ÜÔÏÔ ÐÒÉ ËÏÍÐÉÌÑÃÉÉ winavr ÓÔÁÎÏ×ÉÔÓÑ ÖÉÒÎÙÍ. öÅÌÁÔÅÌØÎÏ ÂÙ ÉÓÐÏÌØÚÏ×ÁÔØ AT90S2313, ÎÏ ÐÒÉ ÍÏÅÍ ×ÁÒÉÁÎÔÅ ×ÓÑ ÐÒÏÇÒÁÍÍËÁ ×ÍÅÓÔÅ Ó ÐÒÉ×ÅÄÅÎÎÙÍ ÎÉÖÅ ËÕÓËÏÍ × ÎÅÇÏ ÅÌÅ ×ÌÁÚÉÔ (1,9ËÂ):((, Á ÅÅ ÅÝÅ ÁÐÇÒÅÊÄÉÔØ É ÁÐÇÒÅÊÄÉÔØ... ó ÍÏÉÍ ×ÁÒÉÁÎÔÏÍ ÎÕÖÎÏ ÂÒÁÔØ ÍÅÇÕ, ÎÏ ÐÌÁÔÁ ÕÖÅ ÒÁÚ×ÅÄÅÎÁ ÄÌÑ AT90S2313.

HÅÏÂÈÏÄÉÍÏ ÓÞÉÔÁÔØ ÄÁÎÎÙÅ Ï ÔÅÍÐÅÒÁÔÕÒÅ Ó ÄÁÔÞÉËÁ DS1821 (ÉÍÅÎÎÏ Ó ÜÔÏÇÏ Ô.Ë. ÏÎ ÎÅÄÏÒÏÇÏÊ É Õ ÎÅÇÏ ÎÕÖÎÁÑ ÐÏÇÒÅÛÎÏÓÔØ ÐÒÉ ÉÚÍÅÒÅÎÉÉ ÔÅÍÐÅÒÁÔÕÒÙ ÔÅÌÁ ÞÅÌÏ×ÅËÁ) É ×Ù×ÅÓÔÉ ÉÈ ÎÁ öëé (íåìô10-ô7). ðÒÏÂÌÅÍÍÁ ÓÏÓÔÏÉÔ × ×ÙÞÉÓÌÅÎÉÉ ÔÅÍÐÅÒÁÔÕÒÙ. ïÎÁ ×ÙÞÉÓÌÑÅÔÓÑ ÐÏ ÆÏÒÍÕÌÅ:



temperature=temp-0.5+(COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C;



þÉÓÌÏ ÐÏÌÕÞÁÅÔÓÑ ÄÒÏÂÎÏÅ. ôÏÞÎÏÓÔØ ÎÕÖÎÁ ÄÏ ÄÅÓÑÔÙÈ ÐÒÉÞÅÍ Ó ÏËÒÕÇÌÅÎÉÅÍ Á ÎÅ Ó ÏÂÒÅÚÁÎÉÅÍ. ñ ÐÒÉÄÕÍÁÌ ×ÏÔ ËÁË:

=== Cut === uint8_t out[10]; uint8_t temp; uint16_t COUNT_REMAIN,COUNT_PER_C; float temperature;



//skip //ÔÕÔ ÓÞÉÔÙ×ÁÀÔÓÑ temp(8 ÂÉÔ ÉÎÆÏÒÍÁÃÉÏÎÎÙÈ),COUNT_PER_C(9 ÂÉÔ ÉÎÆÏÒÍÁÃÉÏÎÎÙÈ) //É COUNT_REMAIN (9 ÂÉÔ ÉÎÆÏÒÍÁÃÉÏÎÎÙÈ) //skip



temperature=temp-0.5+(COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C; //×ÙÄÅÌÑÀ ÓÏÔÎÉ, ÄÅÓÑÔËÉ, ÅÄÉÎÉÃÙ É ÓÏÔÙÅ ÄÏÌÉ out[6]=temperature/100; out[7]=(temperature-out[6]*100)/10; out[8]=temperature-out[6]*100-out[7]*10; temperature=floor((temperature-out[6]*100-out[7]*10-out[8])*10+0.5); out[9]=temperature; //ÔÁÍ ÄÁÌØÛÅ out[] ->ÜÔÏ ÃÉÆÒÙ, ËÏÔÏÒÙÊ ×Ù×ÏÄÑÔÓÑ ÎÁ ÉÎÄÉËÁÔÏÒ Ó //ÜÔÉÍ ÐÒÏÂÌÅÍ ÎÅÔ



=== Cut ===



åÓÌÉ ÌÕÞÛÅ ÎÅ ÐÏÌÕÞÉÔÓÑ ÂÕÄÕ ÂÒÁÔØ ÍÅÇÕ8. íÏÖÅÔ ËÔÏ ÓÔÁÌËÉ×ÁÌÓÑ, ËÁËÉÅ Õ ÎÅÅ ÅÓÔØ ÏÓÏÂÅÎÎÏÓÔÉ ÐÒÉ ÐÏÄËÌÀÞÅÎÉÉ ÐÉÔÁÎÉÑ, ÐÒÏÇÒÁÍÍÉÒÏ×ÁÎÉÉ(Õ ÍÅÎÑ PONYPROG) É Ô.Ð.


ŽžžŽžžž ÷ÔÏÒÎÉË, äÅËÁÂÒØ 27 2005 21:40



2ž461Ž32ž23 ÷ÓÅÇÏ ÈÏÒÏÛÅÇÏ. Alexander.

Hello, Alexander Panasovsky! You wrote in conference fido7.ru.embedded to All on Tue, 27 Dec 2005 21:58:54 +0300:

AP> Hеобходимо считать данные о температуре с датчика DS1821 AP> (именно с этого т.к. AP> он недорогой и у него нужная погрешность при измерении AP> температуры тела человека) и вывести их на ЖКИ (МЕЛТ10-Т7). AP> Проблемма состоит в вычислении температуры. Она вычисляется по AP> формуле:

AP>

AP> temperature=temp-0.5+(COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C;

AP> Число получается дробное. Точность нужна до десятых причем с AP> округлением а не с обрезанием. Я придумал вот как:

Зачем вообще считать с плавающей точкой? Умножь все на 256 и считай в целых, в конце смасштабируешь. Кстати точность у этих датчиков маловата для измерения температуры тела...

dima

formatting link

Tue Dec 27 2005 20:58, Alexander Panasovsky wrote to All:

AP> Может ли кто нибуть придумать алгоритм получше ибо этот при компиляции AP> winavr становится жирным. Желательно бы использовать AT90S2313, но при AP> моем варианте вся программка вместе с приведенным ниже куском в него еле AP> влазит (1,9кб):((, а ее еще апгрейдить и апгрейдить... С моим вариантом AP> нужно брать мегу, но плата уже разведена для AT90S2313.

AP> Hеобходимо считать данные о температуре с датчика DS1821 (именно с этого AP> т.к. AP> он недорогой и у него нужная погрешность при измерении температуры тела AP> человека) и вывести их на ЖКИ (МЕЛТ10-Т7). Проблемма состоит в вычислении AP> температуры. Она вычисляется по формуле:

AP> temperature=temp-0.5+(COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C;

AP> Число получается дробное. Точность нужна до десятых причем с округлением AP> а не с обрезанием.

Плавающая точка нужна, в действительности, редко когда. А часть libc её реализующая имеет немерянный размер обычно. Потому и не влазит. Там ещё плавающий printf небось цепляется. Тоже тяжёлый.

Я у себя сделал так: температуру, считываемую из термометра, домножаю сразу на 256. В градусах. Так она хранится, так всё и считается. Диапазон -120 -- +120 вполне умещается в 16-разрядном int с точностью до 1/256 доли градуса. Выводится примерно так:

unsigned ta = abs(temp) + 1; /* 256*0.005 = 1.28 */ sprintf(buf, "%c%d.%2.2uC", /* знак */ (temp<0 ? '-' : '+'), /* целая часть */ ta>>8, /* дробная часть */ (100*(ta&0xff))>>8) );

Видно, что операции деления на 256 -- на самом деле сдвиги, из тяжёлых вычислений только умножение на 100. При вводе всё-таки использую плавающую точку -- разбирать вручную строки описываемые регулярными выражениями вида "^[0-9]*([.,][0-9]*)?([eE][+-]?[0-9]*)?$" нудно как-то...

Температура, считанная из термометра, преобразуется во внутренний для программы формат таким образом:

temp = \ ((((0xff00|scratch.temp_msb)<<8)|scratch.temp_lsb)<<7) - (256/4) \ + 256*(unsigned)(scratch.cpc-scratch.remain)/scratch.cpc;

где scratch описывается такой структурой:

struct scartch { UFAST temp_lsb, temp_msb, TH, TL, R0, R1, remain, cpc, crc; };

это scratch-буфер из даташита.

AP> temperature=temp-0.5+(COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C; AP> //выделяю сотни, десятки, единицы и сотые доли AP> out[6]=temperature/100; AP> out[7]=(temperature-out[6]*100)/10; AP> out[8]=temperature-out[6]*100-out[7]*10; AP> temperature=floor((temperature-out[6]*100-out[7]*10-out[8])*10+0.5); AP> out[9]=temperature; AP> //там дальше out[] ->это цифры, который выводятся на индикатор с AP> //этим проблем нет

Изобретаешь самодельный printf? В любом случае плавающую точку лучше выкинуть.

Wed Dec 28 2005 12:31, Kirill Frolov wrote to Alexander Panasovsky:

KF> temp = \ KF> ((((0xff00|scratch.temp_msb)<<8)|scratch.temp_lsb)<<7) - (256/4) KF> \ KF> + 256*(unsigned)(scratch.cpc-scratch.remain)/scratch.cpc;

И наверняка оно неправильно работает в области отрицательных температур.

Hi Dmitry !

óÒÅÄÁ, äÅËÁÂÒØ 28 2005 × 00:59, Dmitry Orlov ÐÉÓÁÌ Ë Alexander Panasovsky:

AP>> ðÒÏÂÌÅÍÍÁ ÓÏÓÔÏÉÔ × ×ÙÞÉÓÌÅÎÉÉ ÔÅÍÐÅÒÁÔÕÒÙ. ïÎÁ ×ÙÞÉÓÌÑÅÔÓÑ ÐÏ AP>> ÆÏÒÍÕÌÅ:

AP>>

AP>> temperature=temp-0.5+(COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C;

AP>> þÉÓÌÏ ÐÏÌÕÞÁÅÔÓÑ ÄÒÏÂÎÏÅ. ôÏÞÎÏÓÔØ ÎÕÖÎÁ ÄÏ ÄÅÓÑÔÙÈ ÐÒÉÞÅÍ Ó AP>> ÏËÒÕÇÌÅÎÉÅÍ Á ÎÅ Ó ÏÂÒÅÚÁÎÉÅÍ. ñ ÐÒÉÄÕÍÁÌ ×ÏÔ ËÁË:

DO> úÁÞÅÍ ×ÏÏÂÝÅ ÓÞÉÔÁÔØ Ó ÐÌÁ×ÁÀÝÅÊ ÔÏÞËÏÊ? õÍÎÏÖØ ×ÓÅ ÎÁ 256 É ÓÞÉÔÁÊ × DO> ÃÅÌÙÈ, × ËÏÎÃÅ ÓÍÁÓÛÔÁÂÉÒÕÅÛØ. ëÓÔÁÔÉ ÔÏÞÎÏÓÔØ Õ ÜÔÉÈ ÄÁÔÞÉËÏ× DO> ÍÁÌÏ×ÁÔÁ ÄÌÑ ÉÚÍÅÒÅÎÉÑ ÔÅÍÐÅÒÁÔÕÒÙ ÔÅÌÁ...

ôÏÂÉÛØ ÓÄÅÌÁÔØ ËÁË Ñ ÐÒÉ×ÅÌ ÎÉÖÅ?

uint16_t temperature,COUNT_PER_C,COUNT_REMAIN; uint8_t temp; // //ÓÞÉÔÁ×ÁÎÉÅ // temperature=(uint16_t)(temp*256)-(0.5*256)+(uint16_t)((COUNT_PER_C-COUNT_REMAIN )*256)/COUNT_PER_C;

ŽžžŽžžž óÒÅÄÁ, äÅËÁÂÒØ 28 2005 23:15

2ž461Ž32ž23 ÷ÓÅÇÏ ÈÏÒÏÛÅÇÏ. Alexander.

Hi Kirill !

óÒÅÄÁ, äÅËÁÂÒØ 28 2005 × 13:31, Kirill Frolov ÐÉÓÁÌ Ë Alexander Panasovsky:

AP>> þÉÓÌÏ ÐÏÌÕÞÁÅÔÓÑ ÄÒÏÂÎÏÅ. ôÏÞÎÏÓÔØ ÎÕÖÎÁ ÄÏ ÄÅÓÑÔÙÈ ÐÒÉÞÅÍ Ó AP>> ÏËÒÕÇÌÅÎÉÅÍ Á ÎÅ Ó ÏÂÒÅÚÁÎÉÅÍ.

KF> ðÌÁ×ÁÀÝÁÑ ÔÏÞËÁ ÎÕÖÎÁ, × ÄÅÊÓÔ×ÉÔÅÌØÎÏÓÔÉ, ÒÅÄËÏ ËÏÇÄÁ. á ÞÁÓÔØ libc KF> ţ ÒÅÁÌÉÚÕÀÝÁÑ ÉÍÅÅÔ ÎÅÍÅÒÑÎÎÙÊ ÒÁÚÍÅÒ ÏÂÙÞÎÏ. ðÏÔÏÍÕ É ÎÅ ×ÌÁÚÉÔ. ôÁÍ KF> Åݣ ÐÌÁ×ÁÀÝÉÊ printf ÎÅÂÏÓØ ÃÅÐÌÑÅÔÓÑ. ôÏÖÅ ÔÑ֣ÌÙÊ.

KF> ñ Õ ÓÅÂÑ ÓÄÅÌÁÌ ÔÁË: ÔÅÍÐÅÒÁÔÕÒÕ, ÓÞÉÔÙ×ÁÅÍÕÀ ÉÚ ÔÅÒÍÏÍÅÔÒÁ, KF> ÄÏÍÎÏÖÁÀ ÓÒÁÚÕ ÎÁ 256. ÷ ÇÒÁÄÕÓÁÈ. ôÁË ÏÎÁ ÈÒÁÎÉÔÓÑ, ÔÁË ×ӣ É KF> ÓÞÉÔÁÅÔÓÑ. äÉÁÐÁÚÏÎ -120 -- +120 ×ÐÏÌÎÅ ÕÍÅÝÁÅÔÓÑ × 16-ÒÁÚÒÑÄÎÏÍ int Ó KF> ÔÏÞÎÏÓÔØÀ ÄÏ 1/256 ÄÏÌÉ ÇÒÁÄÕÓÁ. ÷Ù×ÏÄÉÔÓÑ ÐÒÉÍÅÒÎÏ ÔÁË:

KF> unsigned ta = abs(temp) + 1; /* 256*0.005 = 1.28 */ KF> sprintf(buf, "%c%d.%2.2uC", KF> /* ÚÎÁË */ (temp<0 ? '-' : '+'), KF> /* ÃÅÌÁÑ ÞÁÓÔØ */ ta>>8, KF> /* ÄÒÏÂÎÁÑ ÞÁÓÔØ */ (100*(ta&0xff))>>8) KF> );

âÏÌØÛÏÅ ÓÐÁÓÉÂÏ - ÔÏ ÞÔÏ ÎÕÖÎÏ. ñ ×ÓÅ ÔÁËÉ ÎÅ ×ÓÅ ÐÏÎÑÌ: ËÁË ÐÒÏÉÓÈÏÄÉÔ ÏËÒÕÇÌÅÎÉÅ, ÉÌÉ × ÜÔÏÍ ÐÒÉÍÅÒÅ ÅÇÏ ÎÅÔ? úù: á ÇÄÅ ÍÏÖÎÏ ÐÏÞÉÔÁÔØ ÐÒÏ ÆÕÎËÃÉÉ printf ÄÌÑ AVR? âÕÄÕ ÂÌÁÇÏÄÁÒÅÎ ÓÓÙÌËÅ × ÉÎÔÅÒÎÅÔÅ.

ŽžžŽžžž þÅÔ×ÅÒÇ, äÅËÁÂÒØ 29 2005 00:08

2ž461Ž32ž23 ÷ÓÅÇÏ ÈÏÒÏÛÅÇÏ. Alexander.

Hello Alexander!

28 Dec 05 13:31, Kirill Frolov wrote to you:

AP>> temperature=temp-0.5+(COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C;

IMHO COUNT_PER_C === CONST

ïÔÓÀÄÁ ×ÙÔÅËÁÅÔ ÍÁÓÓÏ×ÁÑ ÏÐÔÉÍÉÚÁÃÉÑ.

Anatoly

úÄÒÁ×ÓÔ×ÕÊ, Alexander!

Tuesday December 27 2005 21:58, you (2:461/32.23) wrote to All:

AP> íÏÖÅÔ ÌÉ ËÔÏ ÎÉÂÕÔØ ÐÒÉÄÕÍÁÔØ ÁÌÇÏÒÉÔÍ ÐÏÌÕÞÛÅ ÉÂÏ ÜÔÏÔ ÐÒÉ ËÏÍÐÉÌÑÃÉÉ AP> winavr ÓÔÁÎÏ×ÉÔÓÑ ÖÉÒÎÙÍ. öÅÌÁÔÅÌØÎÏ ÂÙ ÉÓÐÏÌØÚÏ×ÁÔØ AT90S2313, ÎÏ ÐÒÉ AP> ÍÏÅÍ ×ÁÒÉÁÎÔÅ ×ÓÑ ÐÒÏÇÒÁÍÍËÁ ×ÍÅÓÔÅ Ó ÐÒÉ×ÅÄÅÎÎÙÍ ÎÉÖÅ ËÕÓËÏÍ × ÎÅÇÏ AP> ÅÌÅ ×ÌÁÚÉÔ (1,9ËÂ):((, Á ÅÅ ÅÝÅ ÁÐÇÒÅÊÄÉÔØ É ÁÐÇÒÅÊÄÉÔØ... ó ÍÏÉÍ

õÖÏÓÎÁÈ...

AP> ×ÁÒÉÁÎÔÏÍ ÎÕÖÎÏ ÂÒÁÔØ ÍÅÇÕ, ÎÏ ÐÌÁÔÁ ÕÖÅ ÒÁÚ×ÅÄÅÎÁ ÄÌÑ AT90S2313.

äÅÌÁÌ ËÁË-ÔÏ ÄÌÑ DS1621 ÎÁ ATmega16. åÓÓÎÏ ÄÌÑ AT90 ÔÏÖÅ ÐpÏËÁÎÁÅÔ. éÎÄÉËÁÃÉÑ Ó ÔÏÞÎÏÓÔØÀ ÐÏÌÇpÁÄÕÓÁ - ÄÌÑ ÔÅpÍÏÍÅÔpÁ ÔÕÌÏ×ÉÝÁ ÂÏÌÅÅ ÞÅÍ ÄÏÓÔÁÔÏÞÎÏ, ÄÕÍÁÀ. HÅÔ ÏÐÅpÁÃÉÊ ÄÅÌÅÎÉÑ É ÐpÏÞÉÈ ÖÉpÎÏÓÔÅÊ ÔÉÐÁ ÐpÉÎÔÆ. òÁÚÍÅp ÓËÏÍÐÉÌÉpÏ×ÁÎÎÏÇÏ WinAVR'ÏÍ ËÏÄÁ - 144 ÂÁÊÔ. ïÐÔÉÍÉÚÁÃÉÑ -Os.

/************************************************************************/ void temperature_to_string (unsigned int temperature, char* string_buffer) {

/* unsigned int temperature - ÔÏ, ÞÔÏ ÐÏÌÕÞÉÌÉ ÉÚ ÍÉËpÏÓÈÅÍÙ. char* string_buffer - ÕËÁÚÁÔÅÌØ ÎÁ ÏÂÌÁÓÔØ ïúõ, ÔÕÄÁ ÂÕÄÅÔ ÐÏÍÅÝÅÎÁ ASCIZ ÓÔpÏËÁ.

*/

char is_dec = 0; char is_hex = HIBYTE(temperature); char minus = 0;

if (is_hex < 0) { is_hex = ~is_hex; if (!(LOBYTE(temperature))) { is_hex++; } minus = '-'; }

while (is_hex >= 100) { is_hex -= 100; is_dec ++; }

if (string_buffer [0] != '-') { string_buffer [0] = (is_dec + 0x30); }

is_dec = 0;

while (is_hex >= 10) { is_hex -= 10; is_dec ++; }

string_buffer [1] = (is_dec + 0x30); string_buffer [2] = (is_hex + 0x30); string_buffer [3] = ',';

if (string_buffer [0] == '0') /* ÚÁÇÁÓÉÔØ ÎÅÚÎÁÞÁÝÉÅ ÎÕÌÉ ÓÌÅ×Á */ { string_buffer [0] = ' '; }

if ((string_buffer [0] == ' ') && (string_buffer [1] == '0')) { string_buffer [1] = ' '; }

if (minus) { if ((string_buffer [0] == ' ') && (string_buffer [1] == ' ')) { string_buffer [1] = '-'; }

else { string_buffer [0] = '-'; } }

if (LOBYTE(temperature)) { string_buffer [4] = '5'; }

else { string_buffer [4] = '0'; }

string_buffer [5] = 'C'; string_buffer [6] = 0; }

éÚ×ÉÎÑÀÓØ ÚÁ ÓÔÉÌØ ÐpÏÇpÁÍÍÉpÏ×ÁÎÉÑ - ÎÁÓÌÅÄÉÅ ÔÑÖÅÌÏÊ ÁÓÓÅÍÂÌÅpÎÏÊ ÍÏÌÏÄÏÓÔÉ...

AP> åÓÌÉ ÌÕÞÛÅ ÎÅ ÐÏÌÕÞÉÔÓÑ ÂÕÄÕ ÂÒÁÔØ ÍÅÇÕ8. íÏÖÅÔ ËÔÏ ÓÔÁÌËÉ×ÁÌÓÑ,

á ޣ ÎÅ ÐÅÎÔiÕÍß ?

Alex

Hello, Alex Gavrikov! You wrote in conference fido7.ru.embedded to Alexander Panasovsky on Thu, 29 Dec

2005 21:38:28 +0300:

AG> Индикация с точностью полгpадуса - для теpмометpа туловища AG> более чем достаточно, думаю. Hет опеpаций деления и пpочих

Вообще-то обычный медицинский ртутный градусник имеет точность около 0.1 градуса и разрешение примерно вдвое выше (полделения отчетливо отсчитываются), что на этих полупроводниковых термометрах представляется проблематичным получить.

AG> жиpностей типа пpинтф.

А вот они действительно совершенно лишние, что при точности в полградуса, что половине десятой градуса.

dima

formatting link

Wed Dec 28 2005 23:08, Alexander Panasovsky wrote to Kirill Frolov:

KF>> unsigned ta = abs(temp) + 1; /* 256*0.005 = 1.28 */ KF>> sprintf(buf, "%c%d.%2.2uC", KF>> /* знак */ (temp<0 ? '-' : '+'), KF>> /* целая часть */ ta>>8, KF>> /* дробная часть */ (100*(ta&0xff))>>8) KF>> );

AP> Большое спасибо - то что нужно. Я все таки не все понял: как происходит AP> округление, или в этом примере его нет?

round(a) == floor(a+0.5). 0.5 -- это, в действительнсти, 1.28, поэтому берётся просто единица.

AP> ЗЫ: А где можно почитать про функции printf для AVR? Буду благодарен AP> ссылке в интернете.

formatting link

Wed Dec 28 2005 23:08, Alexander Panasovsky wrote to Kirill Frolov:

AP> ЗЫ: А где можно почитать про функции printf для AVR? Буду благодарен AP> ссылке в интернете.

Да, самодельный integer_to_string на языке C принципиально невозможно написать, если только у МК не (аппаратной) инструкции деления. У AVR начиная с каких-то есть. А иначе только в ассемблере.

Hello, Alexander Panasovsky! You wrote in conference fido7.ru.embedded to Dmitry Orlov on Wed, 28 Dec 2005 23:15:21

+0300:

AP>>> temperature=temp-0.5+(COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C;

AP>>> Число получается дробное. Точность нужна до десятых причем с AP>>> округлением а не с обрезанием. Я придумал вот как:

DO>> Зачем вообще считать с плавающей точкой? Умножь все на 256 и DO>> считай в целых, в конце смасштабируешь. Кстати точность у DO>> этих датчиков маловата для измерения температуры тела...

AP> Тобишь сделать как я привел ниже?

AP> uint16_t temperature,COUNT_PER_C,COUNT_REMAIN; AP> uint8_t temp; AP> // AP> //считавание // AP> temperature=(uint16_t)(temp*256)-(0.5*256)+(uint16_t)((COUNT_ AP> PER_C-COUNT_REMAIN )*256)/COUNT_PER_C;

Да, в таком духе.

dima

formatting link

Hello, Kirill Frolov! You wrote in conference fido7.ru.embedded to Alexander Panasovsky on Fri, 30 Dec

2005 09:18:38 +0000 (UTC): AP>> ЗЫ: А где можно почитать про функции printf для AVR? Буду AP>> благодарен ссылке в интернете.

KF> Да, самодельный integer_to_string на языке C принципиально KF> невозможно написать, если только у МК не (аппаратной) KF> инструкции деления. У AVR начиная с каких-то есть. А иначе KF> только в ассемблере.

Не понял, какая связь С с наличием каких-то инструкций. Нет инструкции, есть функция в rtl.

dima

formatting link

Wed Dec 28 2005 23:08, Alexander Panasovsky wrote to Kirill Frolov:

AP> úù: á ÇÄÅ ÍÏÖÎÏ ÐÏÞÉÔÁÔØ ÐÒÏ ÆÕÎËÃÉÉ printf ÄÌÑ AVR?

á ÍÏÖÅÔ ÔÅÂÅ ÅÝÅ ÉÎÓÔÒÕËÃÉÀ ÄÌÑ ôÅÔÒÉÓÁ ÐÒÉÓÌÁÔØ?

/* Convert signed/unsigned 16-bit value x to ASCII decimal zero terminated string. Outputs given (or less then) number of decimal digits = 1....5 Leading zeroes are supressed. If the number is bigger then can be represented with num_digits, it is clipped to +/- max representable number Returns length of output string (including zero terminator)

*/

u8 IntToStr(u8 *s, s16 x, u8 sign, u8 num_digits) { u8 i,c; u8 first_flag,neg_flag; s16 itmp; u8 *s0;

const s16 sub_value[5] = { 10000, 1000, 100, 10, 1 };

s0 = s;

neg_flag = 0;

if(sign) // if signed number { if(x&0x8000) // if negative { x = -x; // convert to positive neg_flag = 1; // remember sign } }

// If can't represent with given number of digits, // clip to max. representable number

if(num_digits < 5) { itmp = sub_value[4 - num_digits]; if(x >= (u16)itmp) x = itmp - 1; }

// Here is conversion

first_flag = 0;

for(i = 5 - num_digits; i <= 4; i++) { c = '0';

while(( itmp = (s16)(x - sub_value[i]) ) >= 0) { x = itmp; c++; }

if(!first_flag) { if(c != '0') { first_flag = 1; if(neg_flag) *s++ = '-';

*s++ = c; } } else *s++ = c; }

if(!first_flag) *s++ = '0';

*s = 0;

return 1 + (u8)(s - s0); }

"ñ ÄÏÂÒÙÊ, É ÜÔÏ ÅÄÉÎÓÔ×ÅÎÎÙÊ ÍÏÊ ÎÅÄÏÓÔÁÔÏË" (äÏÓÔÏÅ×ÓËÉÊ)

ðÒÉ×ÅÔ Kirill!

30 Dec 05 12:18, Kirill Frolov ÐÉÓÁÌ Alexander Panasovsky:

KF> äÁ, ÓÁÍÏÄÅÌØÎÙÊ integer_to_string ÎÁ ÑÚÙËÅ C ÐÒÉÎÃÉÐÉÁÌØÎÏ KF> ÎÅ×ÏÚÍÏÖÎÏ ÎÁÐÉÓÁÔØ, ÅÓÌÉ ÔÏÌØËÏ Õ íë ÎÅ (ÁÐÐÁÒÁÔÎÏÊ) ÉÎÓÔÒÕËÃÉÉ KF> ÄÅÌÅÎÉÑ.

??? üÔÏ ÛÕÔËÁ? ëÁË ×ÏÚÍÏÖÎÏÓÔÉ ÑÚÙËÁ ÍÏÇÕÔ ÂÙÔØ Ó×ÑÚÁÎÙ Ó ×ÏÚÍÏÖÎÏÓÔÑÍÉ ÐÌÁÔÆÏÒÍÙ?

÷ÓÅÇÏ ÎÁÉÌÕÞÛÅÇÏ, [Team PCAD 2000] áÌÅËÓÅÊ í. ... þÅÍ ×ÅÔÅÒÉÎÁÒÙ ËÏÒÍÑÔ Ó×ÏÉÈ ÓÏÂÁË? âÅÌÙÊ ÆÏÓÆÏÒ. ÷ÁÛÁ ÓÏÂÁËÁ Ó×ÅÔÉÔÓÑ!

Hi Alex!

29 ÄÅËÁÂpÑ 2005 21:38, Alex Gavrikov ÐÉÓÁÌ Alexander Panasovsky:

AG> éÎÄÉËÁÃÉÑ Ó ÔÏÞÎÏÓÔØÀ ÐÏÌÇpÁÄyÓÁ - ÄÌÑ ÔÅpÍÏÍÅÔpÁ ÔyÌÏ×ÉÝÁ ÂÏÌÅÅ ÞÅÍ AG> ÄÏÓÔÁÔÏÞÎÏ, ÄyÍÁÀ.

ôÙ ÓËÁÖÅÛØ ÔÏÖÅ, 36,6 - ÚÄÏpÏ×, 37,1 yÖÅ ÂÏÌØÎÏÊ.

Best regard, Roman Gubaev! [Team Beer - rulez forever!] Å-ÍÙÌÏ: rgubaevyandexru (ÞÔÏ ËyÄÁ ×ÓÔÁ×ÉÔØ - ÓÁÍÉ ÄÏÇÁÄÁÅÔÅÓØ :-))

... òáï "åüó òÏÓÓÉÉ", èÁËÁÓÜÎÅpÇÏÓÂÙÔ, ÇpyÐÐÁ áóëõü

Hi Alex !

þÅÔ×ÅÒÇ, äÅËÁÂÒØ 29 2005 × 21:38, Alex Gavrikov ÐÉÓÁÌ Ë Alexander Panasovsky:

AG> /********************************************************************* AG> ***/ void temperature_to_string (unsigned int temperature, char* AG> string_buffer) {

..skip..

AG> éÚ×ÉÎÑÀÓØ ÚÁ ÓÔÉÌØ ÐpÏÇpÁÍÍÉpÏ×ÁÎÉÑ - ÎÁÓÌÅÄÉÅ ÔÑÖÅÌÏÊ ÁÓÓÅÍÂÌÅpÎÏÊ AG> ÍÏÌÏÄÏÓÔÉ...

óÐÁÓÉÂÏ ÚÁ ÐÒÉÍÅÒÞÉË.. âÕÄÕ ÉÍÅÔØ..

AP>> åÓÌÉ ÌÕÞÛÅ ÎÅ ÐÏÌÕÞÉÔÓÑ ÂÕÄÕ ÂÒÁÔØ ÍÅÇÕ8. íÏÖÅÔ ËÔÏ ÓÔÁÌËÉ×ÁÌÓÑ,

AG> á ޣ ÎÅ ÐÅÎÔiÕÍß ?

ðÏÔÏÍÕÞÔÏ ÜÔÁ ÍÅÇÁ Õ ÎÁÓ ÎÁ 1ÇÒÎ ÄÏÒÏÖÅ ÞÅÍ 2313..

ŽžžŽžžž ðÑÔÎÉÃÁ, äÅËÁÂÒØ 30 2005 23:32

2ž461Ž32ž23 ÷ÓÅÇÏ ÈÏÒÏÛÅÇÏ. Alexander.
úÄÒÁ×ÓÔ×ÕÊ, Dmitry!

Friday December 30 2005 01:11, you (2:5020/400) wrote to me:

AG>> éÎÄÉËÁÃÉÑ Ó ÔÏÞÎÏÓÔØÀ ÐÏÌÇpÁÄÕÓÁ - ÄÌÑ ÔÅpÍÏÍÅÔpÁ ÔÕÌÏ×ÉÝÁ AG>> ÂÏÌÅÅ ÞÅÍ ÄÏÓÔÁÔÏÞÎÏ, ÄÕÍÁÀ. HÅÔ ÏÐÅpÁÃÉÊ ÄÅÌÅÎÉÑ É ÐpÏÞÉÈ

DO> ÷ÏÏÂÝÅ-ÔÏ ÏÂÙÞÎÙÊ ÍÅÄÉÃÉÎÓËÉÊ ÒÔÕÔÎÙÊ ÇÒÁÄÕÓÎÉË ÉÍÅÅÔ ÔÏÞÎÏÓÔØ ÏËÏÌÏ DO> 0.1 ÇÒÁÄÕÓÁ É ÒÁÚÒÅÛÅÎÉÅ ÐÒÉÍÅÒÎÏ ×Ä×ÏÅ ×ÙÛÅ (ÐÏÌÄÅÌÅÎÉÑ ÏÔÞÅÔÌÉ×Ï

ôÏÞÎÏ. óÅÊÞÁÓ ÎÁÛÅÌ × ÁÐÔÅÞËÅ ÜÔÏÔ ÄÅ×ÁÊÓ - 0,1 ÇpÁÄÕÓ/ÄÅÌÅÎÉÅ. óÏÇÌÁÓÅÎ, ÞÔÏ ÐÏÌÇpÁÄÕÓÁ ÔÕÐÏ×ÁÔÏ ÂÕÄÅÔ. 36,6 ÚÄÏpÏ×ÙÊ ÞÅÌÏ×ÅË, 37,0 ÇpÁÄÕÓÏ× ÕÖÅ ÂÏÌØÎÏÊ. éÎÉÃÉÁÔÏp ÔpÅÄÁ Ñ×ÎÏ ÐpÏÍÁÈÎÕÌÓÑ Ó ×ÙÂÏpÏÍ DS1821. DS1624 ÐpÅÄÐÏÞÔÉÔÅÌØÎÅÅ.

Alex

Hi, Alex !

AG>>> éÎÄÉËÁÃÉÑ Ó ÔÏÞÎÏÓÔØÀ ÐÏÌÇpÁÄÕÓÁ - ÄÌÑ ÔÅpÍÏÍÅÔpÁ ÔÕÌÏ×ÉÝÁ AG>>> ÂÏÌÅÅ ÞÅÍ ÄÏÓÔÁÔÏÞÎÏ, ÄÕÍÁÀ. HÅÔ ÏÐÅpÁÃÉÊ ÄÅÌÅÎÉÑ É ÐpÏÞÉÈ DO>> ÷ÏÏÂÝÅ-ÔÏ ÏÂÙÞÎÙÊ ÍÅÄÉÃÉÎÓËÉÊ ÒÔÕÔÎÙÊ ÇÒÁÄÕÓÎÉË ÉÍÅÅÔ ÔÏÞÎÏÓÔØ ÏËÏÌÏ DO>> 0.1 ÇÒÁÄÕÓÁ É ÒÁÚÒÅÛÅÎÉÅ ÐÒÉÍÅÒÎÏ ×Ä×ÏÅ ×ÙÛÅ (ÐÏÌÄÅÌÅÎÉÑ ÏÔÞÅÔÌÉ×Ï AG> ôÏÞÎÏ. óÅÊÞÁÓ ÎÁÛÅÌ × ÁÐÔÅÞËÅ ÜÔÏÔ ÄÅ×ÁÊÓ - 0,1 ÇpÁÄÕÓ/ÄÅÌÅÎÉÅ. AG> óÏÇÌÁÓÅÎ, ÞÔÏ ÐÏÌÇpÁÄÕÓÁ ÔÕÐÏ×ÁÔÏ ÂÕÄÅÔ. 36,6 ÚÄÏpÏ×ÙÊ ÞÅÌÏ×ÅË, AG> 37,0 ÇpÁÄÕÓÏ× ÕÖÅ ÂÏÌØÎÏÊ. AG> éÎÉÃÉÁÔÏp ÔpÅÄÁ Ñ×ÎÏ ÐpÏÍÁÈÎÕÌÓÑ Ó ×ÙÂÏpÏÍ DS1821. AG> DS1624 ÐpÅÄÐÏÞÔÉÔÅÌØÎÅÅ.

äÙË Õ ÎÅÇÏ ÔÏÞÎÏÓÔØ ÔÏÖÅ 0.5 ÇÒÁÄÕÓÁ, ÔÏÌØËÏ ÒÁÚÒÅÛÅÎÉÅ ÂÏÌØÛÅ. éÎÔÅÒÅÓÎÏ ÄÒÕÇÏÅ: ÐÏÌÏÖÉÍ, ÅÓÔØ ×ÏÚÍÏÖÎÏÓÔØ ÏÔËÁÌÉÂÒÏ×ÁÔØ 18÷20 (ÒÅÚÒÅÛÅÎÉÅ ÒÅÚÕÌØÔÁÔÁÔÁ - 12 ÂÉÔ) ÐÏ ÒÅÆÅÒÅÎÓÎÏÍÕ ÒÔÕÔÎÏÍÕ ÔÅÒÍÏÍÅÔÒÕ Ó ÔÏÞÎÏÓÔØÀ 0,1 ó. ðÏÔÏÍ ÎÅ ÐÏÑ×ÉÔÓÑ ÏÛÉÂËÁ Ó ÔÅÞÅÎÉÅÍ ×ÒÅÍÅÎÉ (ÓËÁÖÅÍ, ÞÅÒÅÚ ÇÏÄ)? éÌÉ ÉÚ-ÚÁ ËÏÌÅÂÁÎÉÊ ÐÉÔÁÎÉÑ? ÷ÓÅÇÏ ÎÁÉÌÕÞÛÅÇÏ, Alex!

Hello, Alex Gavrikov! You wrote in conference fido7.ru.embedded to Dmitry Orlov on Sat, 31 Dec 2005 01:49:23

+0300:

AG>>> Индикация с точностью полгpадуса - для теpмометpа туловища AG>>> более чем достаточно, думаю. Hет опеpаций деления и пpочих

DO>> Вообще-то обычный медицинский ртутный градусник имеет DO>> точность около DO>> 0.1 градуса и разрешение примерно вдвое выше (полделения DO>> отчетливо

AG> Точно. Сейчас нашел в аптечке этот девайс - 0,1 AG> гpадус/деление.

AG> Согласен, что полгpадуса туповато будет. 36,6 здоpовый AG> человек, 37,0 гpадусов уже больной.

AG> Инициатоp тpеда явно пpомахнулся с выбоpом DS1821. AG> DS1624 пpедпочтительнее.

Достичь такой _точности_ и стабильности полупроводниковым градусником врядли удастся. Замечал, что дешевые цифровые градусники показывают весьма неточно, хотя конечно безопасней ртутных.

dima

formatting link

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required