Прошу помощи с функцией

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ВН пишет:

да нет, там несколько вещей написано:

- на каждой странице в заголовке -Programmable Resolution;

- The core functionality of the DS18B20 is its direct-todigital temperature sensor. The resolution of the temperature sensor is user-configurable to 9, 10, 11, or 12 bits, corresponding to increments of 0.5°C, 0.25°C, 0.125°C, and 0.0625°C, respectively.

Спрашивается, к чему бы так упираться в это разрешение , если оно и на фиг  не сдалось?

Сорри, но про"спрашивается" не нужно. Тут нет утверждения о гарантированной, пусть даже относительной (то есть без учета калибровки) точности.

ВН пишет:

 Но есть непосредственно и о термостабильности

- Drift (Note 11) ±0.2 °C  , а из Note 11 => Drift data is based on a 1000-hour stress test at +125°C with VDD = 5.5V.

т.е. ±0.2 °C вот такая термостабильность в экстремальных долговременных условиях, соответственно в более щадящих можно рассчитывать на лучшие параметры, что практика и подтверждает.

На это можно сослаться, но, также как и график - это просто справочная  информация о проведенных испытаниях. Типа того: "Мы гарантируем +/- 0.5°, но вот какие мы классные, что испытания показывают +/-0.2°!". ;)))

------------------------------

Снова акцентирую. "Дорогая Ркит", написала, что ДШ утверждает, что "все гораздо сложнее", а не практика или проведенные испытания. А я дое..ался именно до точно написанного заявления нашего дорогого коллеги. Не до сути, а до буквы, что он сам постоянно делает с другими. ;))

Ркит просто вот так удачно подставился, что дало мне возможность повеселиться. Сорри. ;))

SLKH
Offline
Зарегистрирован: 17.08.2015

Читать первые три строки здесь: http://arduino.ru/forum/apparatnye-voprosy/tochnoe-izmerenie-temperatury...

 

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

nibelung пишет:

wdrakula пишет:

Ты отрицательные температуры потерял. Нужно в лонг со знаком переводить, потом обработать знак, оставить модуль и его "разлагать на атомы" ;))).

Знаю. Но не все же делать за ТС, это был его, немного поправленный код. Пусть и сам немного потрудится ))

На всякий, может какому новичку, вроде меня, понадобится. Проблема со знаком проста и решена в первом сообщении

просто проверкой знакового бита.

Эта тема необязательно для Далласа, здесь задача была именно научиться преобразовывать большие числа точно, без потерь. Может подойти для чего угодно

Гриша
Offline
Зарегистрирован: 27.04.2014

Дим-мычъ пишет:

На всякий, может какому новичку, вроде меня, понадобится. Проблема со знаком проста и решена в первом сообщении

просто проверкой знакового бита.

вот прям просто? просто проверили первый бит и все? и Вас даже не смущает,что это стандартное решение и по другому его не решают???

А то не дай ***  тема до пятницы не доживет.

b707
Offline
Зарегистрирован: 26.05.2017

Дим-мычъ пишет:

может какому новичку, вроде меня, понадобится.

Эта тема необязательно для Далласа, здесь задача была именно научиться преобразовывать большие числа точно, без потерь. Может подойти для чего угодно

эт-точно...вдруг еще придет новичок, неспособный умножить число на 0.625...

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

andriano пишет:

Может, я чего-то упустил, но 0.0625 - это 1/16. Т.е. для получения целых надо сдвинуть на 4 разряда вправо, а для получения десятых - выделить эти 4 разряда (по маске) умножить на 10 и снова сдвинуть на 4 разряда вправо. При этом байтовые сложение и умножение выполняются аппаратно (одного байта достаточно), а ресурсоемкое деление не используется вообще. В коде это десятки байтов - не больше.

Тема и так сильно затянулась, поэтому кратко)))

Услышал, спасибо, отлично!


// полное преобразование 11 разрядного(без знака) значения датчика DS18B20
// с разрешением 0.0625
// в десятичные разряды для вывода на индикатор
// byte_high и byte_low - данные с датчика
//===================================================

byte cel = ((high_byte & 0b00000111) << 4) | ((low_byte & 0b11110000) >> 4);
                                                          //выделяем
                                                          // целое значение
a[2] = cel % 10; 
cel = cel /10; 
a[1] = cel % 10; 
a[0] = cel / 10; // выводим целое поразрядно

unsigned int dr = (unsigned int)(low_byte & 0b00001111); 

for(int r = 0; r < 4; r++){
 dr = (dr * 10) >> 1;
}                            // выделяем дробь
for(int t = 6; t > 2; t--){
 a[t] =(byte)( dr % 10);
 dr = dr / 10;              // выводим дробь поразрядно
}

 

Green
Offline
Зарегистрирован: 01.10.2015

Как то всё накручено. Компилятор и помножит, и сдвинет получше вашего.

int temp; //температура с датчика
temp = temp * 10 / 16; //до десятых

 

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

Green пишет:

Как то всё накручено. Компилятор и помножит, и сдвинет получше вашего.

int temp; //температура с датчика
temp = temp * 10 / 16; //до десятых

 

Спасибо за подсказку. Вот упростил. Полная версия, со знаком

void schet(){    // на входе имеем high_byte и low_byte данные температуры с датчика.
                 // биты 7,6,5,4,3  байта high_byte - знаковые. a[0]-a[6]-разряды числа, a[7]- знак
                //  для вывода на 7-сегм.индикатор
//===========================================
//=======  определение знака и перевод данных в беззнаковые            
  unsigned int chislo = 0; 
 
  chislo = (high_byte << 8) | low_byte; // сшиваем байты
  if(high_byte & 0b00010000){  // если число отрицательное            
  chislo = ( ~chislo) + 1; // переводим в беззнаковое
  a[7] = 10;                 // и выодим "-" на индикаторе
  }
  else
  {
  a[7] = 11;
  }                          // иначе гасим знак "-"
//  получаем unsigned int chislo с макс. значением 2047 (т.е. без старших знаковых 5ти разрядов)
//   что при разрешении 0.0625 даёт возможность для вывода значений 
//  датчика в Proteus от + 128.0000 до -55.0000
//  
//====================
int cel = chislo / 16; //получаем целое значение

a[2] = (byte)cel % 10; 
cel = (byte) cel /10; 
a[1] = (byte) cel % 10; 
a[0] = (byte) cel / 10; // выводим целое поразрядно

unsigned int drob = chislo & 0b00001111;
for(int r = 0; r < 4; r++){
drob = (drob * 10) / 2;
}                            // выделяем дробь

for(int t = 6; t > 2; t--){
 a[t] =(byte)( drob % 10);
 drob = drob / 10;              // выводим дробь поразрядно
}
    
}    

 

b707
Offline
Зарегистрирован: 26.05.2017

минус у отрицательных чисел будет в последней позиции индикатора стоять?

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

b707 пишет:

минус у отрицательных чисел будет в последней позиции индикатора стоять?

Пока да. Пока только с числами разбирался. Спасибо за подсказку, на досуге попробую маскировать нули и сдвигать минус

Green
Offline
Зарегистрирован: 01.10.2015

Ужас. Освойте CTRL+T. А так?

  int temp = getTemp() * 10 / 16; //до десятых
  if (temp < 0) {
    temp = -temp;
    // здесь рисуем минус в первой позиции
  }
  // со второй позиции отображаем 3 десятичных разряда температуры и точку
  // теперь один разряд десятых

 

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

Green пишет:

Ужас. Освойте CTRL+T. А так?

  int temp = getTemp() * 10 / 16; //до десятых
  if (temp < 0) {
    temp = -temp;
    // здесь рисуем минус в первой позиции
  }
  // со второй позиции отображаем 3 десятичных разряда температуры и точку
  // теперь один разряд десятых

 

Спасибо за помощь. Вопрос решил, хотя скорее можно и лучше сделать.

Сейчас со временем туго,  если что- позже доделаю.

 

//=========================================
// маскируем не значащие нули , и сдвигаем "-" на 
// ближайшую к числу позицию
// точка фиксирована в третьем разряде и выводится в 
// loop-е добавлением 7-го бита к числу

  if ((cel_1 < 100) & (cel_1 > 9)) { // если целое от 10 до 99
    if (a[7] == 10) {                // и если число отрицательное
      a[7] = 11;                     // маскируем "-" в 0-м разряде
      a[0] = 10;                     // и выводим "-" в 1-ый разряд
    }
    else {                           // если число не отрицательное
      a[0] = 11;                     // маскируем 1-ый разряд
    }
  }
  else {                             // если целое не число от 10 до 99
    if (cel < 10) {                  // и если целое от 0 до 9
      if (a[7] == 10) {              // и если число отрицательное
        a[7] = 11;                   // маскируем "-" в "0" разряде
        a[0] = 11;                   // маскируем 1-ый разряд
        a[1] = 10;                   //  выводим "-" во 2-ой разряд
      }
      else {                         // если число не отрицательное
        a[7] = 11;                   // маскируем 0-2 разряды
        a[0] = 11;
        a[1] = 11;
      }
    }
  }

Всё работает, всем спасибо!

Лепота!)))

 

Гриша
Offline
Зарегистрирован: 27.04.2014

пост 162 - просто агонь!!!! откуда третий и четвертый разряды?!?! датчик больше двух не выдает!!! 

и куда пропало уравнение Шреденгера для вашей системы? Нам теперь и проверить ну никак... так бы хоть по производным пересчитали, а теперь я в растерянности - могу только поздравить с получением прекрасного результата !!!!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Дим-мычъ,

можете внятно объяснить нахрена выводить 4 знака с датчика, точность которого ±0,5?

«Недостатки математического образования с наибольшей отчётливостью проявляются в чрезмерной точности численных расчётов»
(Карл Фридрих Гаусс)

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ЕвгенийП пишет:

Дим-мычъ,

можете внятно объяснить нахрена выводить 4 знака с датчика, точность которого ±0,5?

ТС уже ушат говна вылил на форум, потому что "мы не понимаем" ;))).

Про точность - читай выше по теме чудную дискуссию с ...Ркит, конечно!

----------------------

Тут ладно, хрен с ним, пусть хочется иметь показания не теряющие не точность, а цену lsb датчика. Датчик отдает данные с ценой lsb в 1/16°. Два десятичных разряда - 1/100° - уже в 6 раз выше. Тут уже неделю ржут на дурачком...

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

ЕвгенийП пишет:

Дим-мычъ,

можете внятно объяснить нахрена выводить 4 знака с датчика, точность которого ±0,5?

«Недостатки математического образования с наибольшей отчётливостью проявляются в чрезмерной точности численных расчётов»
(Карл Фридрих Гаусс)

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

Ранее я проверял данные так

и смотрел в памяти MK в Proteus

 int low_data = 0;                   // эта часть временная только для проверки  правильности приема данных
  low_data = low_data | low_byte;     //============= данные high_byte и low_byte верны (!) =============
  int *p = (int*)0x0200;              //
  *p = low_data;                      //

  int high_data = 0;                  //
  high_data = high_data | high_byte;  //
  int *p1 = (int*)0x0202;             //
  *p1 = high_data;                    //

А теперь можно просто увидеть на индикаторе, и убедится, что всё норм.

Температура для меня вторична, хотя если Далласы так делают, значит это для чего-то нужно.

Может, пусть даже и для рекламы...

Теперь буду доделывать дальше. 1-wire хоть и работает, но даже сам вижу много косяков, и сделана "топором")))

Возможно впредь не придётся платить за ключи от домофона)))

В любом случае всем ( а всем это значит всем))) спасибо.

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

P.S. Для тех , кому проще обзываться, чем разок даташит глянуть...

Green
Offline
Зарегистрирован: 01.10.2015

Дим-мычъ пишет:

P.S. Для тех , кому проще обзываться, чем разок даташит глянуть...


"Кто обзывается, тот сам так называется" (с). (((

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

«Недостатки математического образования с наибольшей отчётливостью проявляются в чрезмерной точности численных расчётов»
(Карл Фридрих Гаусс)

только не говорите, что помогали с расчётом Швейцарских эфемерид, там такое наворочали  )))

PS с праздником!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

только не говорите, что помогали с расчётом Швейцарских эфемерид

Я - нет. Может, Гаусс помогал?

P.S. И Вас тоже.