Помогите с битовой арифметикой

Обсуждаем контроллеры компании Atmel.
Ответить
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

Уже голова едет...задолбали датчики 18b20

с флоатом никакой проблемы нету....а вот пытаюсь перейти на фикс поинт

тоесть число 123456789 это 12345.6789 - умноженное на 10000

получаю замер из датчика

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

                      temp = ds_msb;
                      temp = temp<<8;
                      temp = temp+ds_lsb;
                      ds_temp = temp;
                      
                      if(ds_msb&&0b10000000)
                        ds_temp-=40960000;
                      
                      ds_temp = ds_temp*625;
temp это unsigned int
ds_temp это signed long

unsigned char ds_lsb
unsigned char ds_msb

иногда получаю -20 -40....когда там +46...примерно...

что не так?
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

clawham писал(а):...с флоатом никакой проблемы нету....а вот пытаюсь перейти на фикс поинт...
... и зачем все эти "страдания" для 18b20? Считать удобно без всяких "точек" и отобразить дробную часть - тоже не вопрос ....
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

я ничего не понял
int do,posle;
temp = ds_msb;
temp = temp<<8;
temp = temp+ds_lsb;

if(ds_msb&0x80)
{
temp^=0xFFFF;
temp++;
}
do=temp>>4;// целая часть
posle=0;
if(temp & 0x08){posle+= 625*8;}
f(temp & 0x04){posle+= 625*4;}
if(temp & 0x02){posle+= 625*2;}
f(temp & 0x01){posle+= 625*1;}
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск

Сообщение Леонид Иванович »

clawham, а что Вы хотели сделать вот этим?

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

if(ds_msb&&0b10000000)
Если проверить бит на единицу, то нужно так:

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

if(ds_msb & 0b10000000)
Вообще, DS18B20 выдает знаковый результат, никакого шаманства не надо.

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

ds_temp = (signed int)temp;
И вообще, тянуть из DS18B20 более десятой градуса смысла нет, я обычно делаю так:

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

int Temp;
Temp = ds_lsb;
Temp |= ds_msb << 8;
Temp = 10 * Temp / 16;
В Temp температура в десятых градуса.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Сообщение HHIMERA »

Леонид Иванович писал(а): я обычно делаю так:

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

Temp = 10 * Temp / 16;

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

Temp = (Temp >> 1) + (Temp >> 3);
"Я не даю готовых решений, я заставляю думать!"(С)
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

Калькулятор:
(205 SHR(1)) + (205 SHR(3)) =  127 
(5*205) SHR(3) = 128 (мой вариант)
10*205/16 = 128.125 
Реклама
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Сообщение HHIMERA »

Это из-за округления... Тогда... с прибавлением половины от делителя...

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

Temp = (10 * Temp  + 8) / 16;
"Я не даю готовых решений, я заставляю думать!"(С)
Друг Кота
Аватара пользователя
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск

Сообщение Леонид Иванович »

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

Сообщение clawham »

z много всего перепробывал ... остановился на вот таком варианте

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

if(ds_msb&0b10000000)
                      {
                        temp = ds_msb;
                        temp = temp<<8;
                        temp = temp+ds_lsb;
                        temp=temp-65535;
                        temp++;
                        ds_temp = temp;
                        ds_temp = ds_temp*625;
                        ds_temp=0-ds_temp;
                      }
                      else
                      {
                        temp = ds_msb;
                        temp = temp<<8;
                        temp = temp+ds_lsb;
                        ds_temp = temp;
                        ds_temp = ds_temp*625;
                      }

if((ds_temp==850000)||
                         (ds_temp==8000000)||
                         (ds_temp<-20000)||
                         (ds_temp>1200000)||
                         (ds_temp==-625))
                      {
                            TeploCountUpdate_thermo(dserr, i);
                            return;
                      }
                             
                      TeploCountUpdate_thermo(ds_temp, i);

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

void TeploCountUpdate_thermo(signed long int tempr, char ds_crc)
{
    char tmp;  
    static unsigned char errors = 200;
    static unsigned char errord = 200;
    signed long int d=0;  
    for(tmp=0;tmp<maxcounters;tmp++)
        // если теплосчетчик активен
        if(Consts[tmp].En==1)
        {
            // проверяем соответствует ли номер - термометру входа
            //if(Consts[tmp].InpTherm==ds_crc)
            if(ds_crc==0)
            {
                if(CP[tmp].T_in == dserr)
                    CP[tmp].T_in = tempr;
                else
                {
                    d=tempr - CP[tmp].T_in;
                    if((d>100000)||(d<-100000))
                    {
                        if(++errors>60)
                        {
                            errors=0;
                            CP[tmp].T_in += d;
                            //CP[tmp].T_in = CP[tmp].T_in;
                        }
                    }
                    else   
                    {            
                        d=d/100;
                        if((labs(d)<10)&&(d!=0))
                            d=10; 
                        CP[tmp].T_in += d;
                    }
                }                 
            }
             
            // проверяем соответствует ли номер - термометру выхода
            //if(Consts[tmp].OutTherm==ds_crc)
            if(ds_crc==1)
            {   
                if(CP[tmp].T_out == dserr)
                    CP[tmp].T_out = tempr;
                else
                {
                    d=tempr - CP[tmp].T_out;
                    if((d>100000)||(d<-100000))
                    {
                        if(++errord>60)
                        {
                            errord=0;
                            CP[tmp].T_out += d;
                            //CP[tmp].T_out = CP[tmp].T_out;
                        }
                    }
                    else
                    {            
                        d=d/100;
                        if((labs(d)<10)&&(d!=0))
                            d=10; 
                        CP[tmp].T_out += d;
                    }
                }                 
            }
                       
            if((CP[tmp].T_in==dserr)||(CP[tmp].T_out==dserr))
                CP[tmp].Delta_T = 0;
            else
            {   
                
                // считаем перепад
                if(CP[tmp].T_in>CP[tmp].T_out)
                {
                    CP[tmp].Delta_T= CP[tmp].T_in -
                                     CP[tmp].T_out;    
                }
                else                           
                {
                    CP[tmp].Delta_T= CP[tmp].T_out -
                                     CP[tmp].T_in;
                }
            }
        }                                                      
}

точность нужна ибо это теплосчетчик...там абсолютная погрешность не важна а два термометра положенные в стакан с кипятком показывали одинаково..мне важен дифференциал между ними!
пс экономии от перехода на фиксированную точку не получил...зато головняков...:)

тут реализована полная защита от всяких ложных измерений + интегральный фильтр с задержкой на резкие перепады...просто задолбало что иногда приходиш а тебе 2 гигакалорий за ночь насчитало....ибо большой проток и когда граммы перемножаются с дельта температуры....там обычно 5 градусов...но если "вылетит" 85 например то за пару импульсов нагорит киловатт :)лишний киловатт изниоткуда

Это всё часть системы контроля теплового насоса...думаю перейти на мегу 128 чтоб больше не иметь головняков с местом и памятью :) Мега 8 тесноватая для нескольких задач
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

ds_temp - насколько понимаю, типа long.
вместо этого:

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

if(ds_msb&0b10000000)
                      {
                        temp = ds_msb;
                        temp = temp<<8;
                        temp = temp+ds_lsb;
                        temp=temp-65535;
                        temp++;
                        ds_temp = temp;
                        ds_temp = ds_temp*625;
                        ds_temp=0-ds_temp;
                      }
                      else
                      {
                        temp = ds_msb;
                        temp = temp<<8;
                        temp = temp+ds_lsb;
                        ds_temp = temp;
                        ds_temp = ds_temp*625;
                      }
можно написать короче:

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

ds_temp = ( ( ((long)ds_msb<<24) >> 16) | ds_lsb )  * 625;
зачем оперировать 1/10000 градуса? все-равно точность - 1/16. можно считать в "естественных" для датчика "единицах". ;)
и еще - 85 градусов - это что, температура, не имеющая права на жизнь?
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

clawham писал(а):Это всё часть системы контроля теплового насоса...думаю перейти на мегу 128 чтоб больше не иметь головняков с местом и памятью :) Мега 8 тесноватая для нескольких задач
Странно - терморегулятор с линеаризацией (датчик термопара ) и ПИД спокойно влазят в мегу48. Что же за задача такая контроль теплового насоса - просто интересно.
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

clawham писал(а):перейти на мегу 128 чтоб больше не иметь головняков с местом и памятью :) Мега 8 тесноватая для нескольких задач
Ха.... развеселил.....

Я как то в тини13 засунул регистратор температуры, на 2,5 суток (с измерением каждый час), программные часы, программный UART, и все это работало с WIN приложением с автоматическим коннектом.
(Единственное с чем можно поспорить - я писал на асме. Но думаю на Си программа увеличилась бы примерно в полтора раза)

А на Си в mega8, помещается (впритык правда) термо регистратор на 8 каналов с дисплеем WH1602 (чтото вроде этого), с возможностью задавать пороги сигнализации для каждого датчика, работа с DS1302, 24С64 по I2C, настройка девайса через меню или Win-конфигуратор.
Все это с автоконнектом по программному UART

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

Сообщение clawham »

85 градусов выскакивает всегда когда есть проблемы с питанием/ошибками передачи приёма и т.д. это поверон дефаулт температура

что за задача?

ваттметр, файловая система, теплосчетчик, расходомер на 2 насоса бойлер упс-ник генератор бензиновый :)
А-ля умный дом...упс это инвертер на 2 киловатта с синусом, напруга входа 90 вольт 10 амперчасов 20 банок лития

генератор обычный китаец со стартером
две насосные станции

тепловой насос вообще отдельная тема там и разморозка и регулировка ПИДом скорости прокачки и реверс магистралей

ну и конечно же система логгирования на флешку 16 мегабайт и связь с компом...всё просто но .... надоело байты вылавливать

в проекте графический дист 320 240 графики gprs смс тач скрин и т.д..... так что ничего веселого...для меги 8 неподъемная весч...даже рамы на основные переменные хватает с трудом...4 теплосчетчика(программа одна - массив переменных) это уже 8 дсок + ещё 4 на теплонасосе это море адресов...а ещё накопительные лонги промежуточные температуры и т.д.в общем чтоб не мать геморою - мега 128...у меня их 4 штуки на шару есть ...хватит :)
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

clawham писал(а):.....
А ну эт другое дело, тут не грех и CORTEX.....
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

Да уж тут Ченовскую FatFs в мегу8 тяжело впихнуть, правда есть упрощенная.
clawham писал(а):85 градусов выскакивает всегда когда есть проблемы с питанием
После включения/отключения нагрузки задержку перед измерением делаете? Не наблюдал такого в тяжелых условиях.
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

даташит на 18б20 4 страница
TEMPERATURE/DATA RELATIONSHIP Table 2
+85°C* 0000 0101 0101 0000 0550h
*The power-on reset value of the temperature register is +85°C

фишка в том что я все свои 12 термометров опрашиваю ОДНОВРЕМЕННО!

тоесть кидаю СкипРом и Конверт Т

далее даю сильную подтяжку и жду 800 мс

потом начинаю в линию давать резет, адрес устройства, гет скретчпад и читаю первые 2 байта потом снова резет второй адрес и т.д.

в результате самый последний термометр переживший на паразитном питании 12 резетов 12 команд и 12 адресов - может выдать 85 ибо просело ЕГО питание и он вырубился....где-то когда-то...

и ЦРЦ сойдётся и адрес и конфиги сойдутся....но 85 - не настоящая температура...просто то что он наконвертировал и держал в памяти - сбросилось....иногда но бывает....раз в сутки примерно...+-

сразу огражусь от града камней в сторону паразитного питания....дело в том что есть два ds18b20 - одни имеют 3 ноги земля шина и питание вторые тоже имеют землю шину и питание но у первых питание - реальная нога а у вторых - внутри кондер побольше и нога НИКУДА не идёт..не звонится и эффекта не приносит подача туды 5 вольт........так вот у меня вся пачка - именно паразитки....у которых третью ногу хоть отрывай....внешне насколько я понял не отличаются ничем!

сильно помогло уменьший кол-во 85-тых градусов резистор не 4.7 килоом а 1.2...2.4 килоома возле МК и 2.4 килоома от 5-ти вольт стабилизированных на втором конце линии( кабель кат7е(каждая витая пара в своём экране + общий экран + жила заземления) длина линии итого 62 метра с лучами по 2-3 метра примерно по середине и на 80% длины...Драйвер - просто нога атмеги 8-й на 5-ти вольтах с защитными диодами и стабилитронами через 10 омм МЛТ 0.125 - предохранитель...
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

может транзистор поставить: http://chipenable.ru/index.php/programm ... ast-1.html
Друг Кота
Аватара пользователя
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск

Сообщение Леонид Иванович »

clawham писал(а):дело в том что есть два ds18b20....внешне насколько я понял не отличаются ничем!
Есть такая модификация, это DS18B20P (datasheet присоединил). Импульс сброса по длине обычно не лимитирован, но при паразитном питании импульс длительностью более 960 мкс может вызвать power-on reset. К тому же, есть рекомендации при повышенных температурах вообще не пользоваться паразитным питанием. Поэтому лучше возмите обычные DS18B20 и перейдите на обычное питание.
Вложения
DS18B20-PAR.pdf
(141.95 КБ) 433 скачивания
Контактная информация:
Грызет канифоль
Сообщения: 298
Зарегистрирован: Ср дек 30, 2009 09:55:39

Сообщение kolobok0 »

clawham писал(а):85 градусов выскакивает всегда когда есть проблемы...ваттметр, файловая система,...тепловой насос ...и регулировка ПИДом...
85 градусов - то кривизна софта либо как тут уже прозвучало - уходите с паразитного питания - это не для серъёзных объектов.
крутизна системы не столько в её фарше, сколько в параметрах которые необходимо поддерживать реал-тайм. объём задачи и железо - тут Вы сами с усами конечно же.
тепловой насос то не супер сложная вещь. правда с ПИДом - то тот ещё костыль.
по поводу датчиков - я вам больше скажу. разводите их на отдельные линии, и если вам до сотых - то только DS1821 спасут отца русской демократии... двадцатки только до 0,065 градуса разрешающую способность имеют.

удачи вам
(круглый)
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

gj поводу кривизны софта - не согласен!!!
Происходит крайне редко но происходит - недостаток питания изза активного качания шины, её длины и слабости ноги атмеги....особенно в режиме тянуть вверх

меня устраивает на текущий момент счетчик зафиксировал одну ошибку за время со вчера до сегодня и что характерно - на первом (в ряду опрашиваемых) датчиков

Установка эта моя и мне не страшно если чтото не так - это просто полезные данные для утешания себя любимого ибо я в одном месте вижу потребление электричества и приток тепла....и когда там 1 кВт/ч 'k'ythubb входит я получаю 4 кВт/ч тепла...на ходу оценивается работа установки, регулируется Электронный ТРВ и даётся сигнал частотнику крутить больше или меньше компрессор....парралельно под это дело подстраивается уже симистором вентилятор(фазоимпульсное) и коллекторный постоянник-помпа на 48 вольт 5 ампер(просто ШИМка)

в общем мега сыта по горло...все тексты и форматные строки вынесены в еепром...неудобно прошивать..надоело...фу...

до этого было мало термометров и система на стадии доводки - не беспокоило..а сейчас много времени в простое..и лишние 3-4 старта по пол минуты изза термометра - это обидно...зачем...

кроме того температуры больше 60-ти градусов у меня в системе нет...и быть не может...потому не важно ...а так да - начинает дико просаживать линию когда температура к 100 градусам приходит...это да...полевичек внутренний который линией управляет начинает травить....но то не беда...беда вот эти случайные "ошибочки" сейчас меня оно устраивает...кстати раньше и было простым умножением и всё....но надоть куча условий и фильтры... мне хватает 0,0625 гранулы...ибо на работе этих термометров пачка и достаются они мне на шару...с чего бы я стал покупать?
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Ответить

Вернуться в «AVR»