Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблемы с DS18B20
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Letis
Разработал устройство на меге8 с датчиком DS18B20. До этого все работало отлично, даже в промышленных условиях. Но возникла проблема, когда возле устройства установить и запустить частотник (для регулировки оборотов двигателя) то температура на устройстве показывает -1. В чем может быть проблема. Я уже использовал для связи с датчиком экранированную витую пару, но это не помогло. Подскажите.
Dx!
Помеха. Смотреть осциллоскопом. CRC8 не считаем раз -1 ? Зря, зря.
Letis
СRC я считую, вот внизу, или чтото не так :

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
if(ds==0) if(w1_init()==0) {ds=45; Tp=-9999;} ;
if(ds==1) w1_write(0xCC);
if(ds==2) w1_write(0xBE);
if(ds==3) if(w1_init()==0) {ds=45; Tp=-9999;} ;
if(ds==4) w1_write(0xCC);
if(ds==5) w1_write(0x44); //ïåðåòâîðåííÿ
if(ds==30) if(w1_init()==0) {ds=45; Tp=-9999;} ;
if(ds==31) w1_write(0xCC);
if(ds==32) { w1_write(0xBE); p=(char *) &__ds18b20_scratch_pad;}
if(ds==33) *(p++)=w1_read();
if(ds==34) *(p++)=w1_read();
if(ds==35) *(p++)=w1_read();
if(ds==36) *(p++)=w1_read();
if(ds==37) *(p++)=w1_read();
if(ds==38) *(p++)=w1_read();
if(ds==39) *(p++)=w1_read();
if(ds==40) *(p++)=w1_read();
if(ds==41){*(p++)=w1_read(); !w1_dow_crc8(&__ds18b20_scratch_pad,9); }
if(ds==42) if(w1_init()==0) {ds=45; Tp=-9999;} ;
if(ds==43) Tp = (*((int *) &__ds18b20_scratch_pad.temp_lsb) & 0xFFF8)*0.0625;
if(Tp>1000) Tp=Tp-4096;
ds++; if(ds>50) ds=0;
}
Dx!
-1 приходит без ошибок в CRC ?
Видимо помеха не в интерфейсе а в питании.

UPD:
Программа ужасна... что вы считаете и с чем сравниваете?
!w1_dow_crc8(&__ds18b20_scratch_pad,9); <-- это что?

Ужас ужас... Есть же приличные соры в сети...
Letis
А вот так будет правильно ?


struct __ds18b20_scratch_pad_struct
{
unsigned char temp_lsb,temp_msb,
temp_high,temp_low,
conf_register,
res1,
res2,
res3,
crc;
} __ds18b20_scratch_pad;


unsigned char *p;
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
if(ds==0) if(w1_init()==0) {ds=45; Tp=-9999;} ;
if(ds==1) w1_write(0xCC);
if(ds==2) w1_write(0xBE);
if(ds==3) if(w1_init()==0) {ds=45; Tp=-9999;} ;
if(ds==4) w1_write(0xCC);
if(ds==5) w1_write(0x44); //ïåðåòâîðåííÿ
if(ds==30) if(w1_init()==0) {ds=45; Tp=-9999;} ;
if(ds==31) w1_write(0xCC);
if(ds==32) { w1_write(0xBE); p=(char *) &__ds18b20_scratch_pad;}
if(ds==33) *(p++)=w1_read();
if(ds==34) *(p++)=w1_read();
if(ds==35) *(p++)=w1_read();
if(ds==36) *(p++)=w1_read();
if(ds==37) *(p++)=w1_read();
if(ds==38) *(p++)=w1_read();
if(ds==39) *(p++)=w1_read();
if(ds==40) *(p++)=w1_read();
if(ds==41) *(p++)=w1_read();
if(ds==42) if(!w1_dow_crc8(&__ds18b20_scratch_pad,9)==0) {ds=45; Tp=-9999;};
if(ds==43) if(w1_init()==0) {ds=45; Tp=-9999;} ;
if(ds==44) Tp = (*((int *) &__ds18b20_scratch_pad.temp_lsb) & 0xFFF8)*0.0625;
if(Tp>1000) Tp=Tp-4096;
ds++; if(ds>50) ds=0;
}
WHALE
ужос... Куда у вас р смотрит?И вы про свитч знаете?
и вам уже советовали взять готовые сорцы для DS18B20 и не изобретать велосипед.
Letis
Да работает оно все. Я использую библиотеку, и все нормально. Но проблема в том где то появляются помехи я не знаю где - или в питании или линии связи вот какой мне нужен ответ и соответственно как их устранить. Подтягивающий резистор у меня 1к, стоит в устройстве, линия - три провода без паразитного питания, кроме того стоит возле датчика кондюк 0805 - 0,1мкФ. Помогите !!! Я уже сделал 10 устройств и все в порядке, но вот тут начало высвечивать на дисплее -1.
kolobok0
Цитата(Letis @ Oct 7 2010, 00:20) *
...использую библиотеку...где то появляются помехи я не знаю где....резистор у меня 1к, стоит в устройстве,....возле датчика кондюк 0805...на дисплее -1..



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

1) про библиотеку не скажу. главное чтоб все временные задержки согласно даташиту. именно особое внимание временным задержкам.
2) линия 1Wire достаточно дальнобойная. если применять спец меры (витая, питание, поменьше резистор) - то вообще несколько сот метров в пром зоне легко. по поводу помех у вас конкретно - смотрите осциллом, тут правильно сказали. так теоретизировать можно долго.
3) резистор можно ом до 300 снижать. присмотритесь к даташиту - в некоторых нарисован резистор возле датчика. существенно помогает когда речь идёт о 30 и более метров.
4) кондюк (чиссо моё имхо) в сад. не нужно это. а вот линию подцеплять лучше через ds9503 согласно рекомендациям от далласа.
5) тут правильно сказали - вам нужно определиться, -1 это с учётом CRC или нет? Если честно - верится с трудом что сам датчик вам такое выдаёт.
6) питание датчика не напрямую соединяется то с питанием МК надеюсь? грязные-чистые земли-питание разведены по уму?
7) попробуйте закрыть частотник в железном ящике типа старой советской стиралке. Если ситуацию не измениться - по питанию у вас лезет. дросели по питанию проверить у частотника чтоб живые были и в питание цифры.
8) обычно на надёжность цифры влияет всякие пусковые выбросы. гасящие элементы ставят. при этом проблемы с питанием МК чаще чем всё остальное обычно бывает. хотя зависит от фильтрации по питанию сильно.


удачи вам
надеюсь навёл на умную мысль какую нить smile.gif
(круглый)
Letis
Цитата
гасящие элементы ставят.


Какие гасящие элементы ставлят ?
У меня питание устройства - 24 В переменка. Можно ли на входе питание поставить параельно резистор 24к и конденсатор 1 мкФ?
Kovrov
Феррит кольцо... в помощь..
или в макс близости от контроллера
или доп контроллер с другим интефейсом связи с верхним уровнем..
alexeyv
Были похожие проблемы.
Длина линии с датчиком 30м. Шнур не экранированный. Опрос датчика примерно раз в 2 секунды. Работа устройства проверялась при включенном на шнур генераторе электромагнитных помех.

1. Гальваническая развязка между платой и датчиком
2. Для проверки тайминги шины надо выставить в максимум (потом можно и сократить)
3. При приходе от датчика всех нулей CRC расчитывается правильно (!!!!), поэтому все байты в приходящем пакете складываются по ИЛИ и сравниваются с нулем.
4. При правильном приеме СRC, температура сравнивалась с предыдущей - разница в показаниях не должна быть большой (инерционность датчика однако!!!)
5. Интерфейс между датчиком и КПУ был сделан с использованием полевика (на КПу шли вход и выход по отдельности, а с полевика на датчик - один провод) - для получения резких фронтов от КПУ на датчик

Устройство выдерживало наведенные помехи 1000Гц/1000В, на длине шнура 8 метров (по ГОСТУ на аналогичное оборудование 1000Гц/500В/2м, но точно не помню)
Letis
Цитата
Феррит кольцо... в помощь..

Где оно должно быть - на кабеле датчика ?

И еще как уменьшить помехи со стороны питания устройства, так как частотник и устройство питаются от одной сети. Если не сложно нарисуйте схему.
Kovrov
кольцо берете с мин проницаемостью: лучше 400нн
берете ваш кабель (там 2 или 3 проводка) и 1-2 витка пронизывате в кольцо..
...........
нарисовать схему чего?
Letis
Здесь понятно. А как устранить со стороны питания устройства в целом?
Дело в том, что если выключить частотник, то датчик работает, если включить не работает.
Если же датчик розместить прямо на около устройства и включить частотник, датчик не работает. Значит частотник дает збой по питанию, я правильно мыслю. Как защитить устройство ?
xemul
Цитата(Letis @ Oct 7 2010, 17:44) *
Дело в том, что если выключить частотник, то датчик работает, если включить не работает.
Если же датчик розместить прямо на около устройства и включить частотник, датчик не работает. Значит частотник дает збой по питанию, я правильно мыслю. Как защитить устройство ?

Какая длина шнурка к датчику?
Устройство без датчика с вкл/выкл частотником ведёт себя одинаково?
Устройство с датчиком, подключённым без шнурка, с вкл/выкл частотником ведёт себя одинаково?
Вы поминали, что экранирование шнурка ничего не дало. В какой (или каких?) точке был подключен экран?
Пока, ей-ей, не понятно, что сбоит, да и сбоит или так и задумано.

думы за жисть:
После ++ в
if(ds==41) *(p++)=w1_read();
*p будет указывать куда-то мимо __ds18b20_scratch_pad.

Вместо
if( !w1_dow_crc8(&__ds18b20_scratch_pad, 9) == 0 ) ...
достаточно
if( w1_dow_crc8(&__ds18b20_scratch_pad, 9) ) ...
или
if( w1_dow_crc8(&__ds18b20_scratch_pad, 8) != *p) ... // если if(ds==41) *p = w1_read();

А если CRC считать на лету при приёме бита, то можно
Код
if(ds==32) { w1_write(0xBE); p=(char *) &__ds18b20_scratch_pad; CRC = 0; }
...
if(ds==42) if( !CRC ) ...

Фразы
Код
if(ds==44) Tp = (*((int *) &__ds18b20_scratch_pad.temp_lsb) & 0xFFF8)*0.0625;
if(Tp>1000) Tp=Tp-4096;

не понял. И зачем напрягать компилятор ...*0.0625, если можно .../16 или ...>>4?
И зачем вообще считать CRC и Tp (с плавучкой, если компилятор не сообразит) в прерывании?

Но коль "Да работает оно все", то и ладно.
kolobok0
Цитата(Letis @ Oct 7 2010, 12:45) *
Где оно должно быть - на кабеле датчика ?...


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

если у вас проблема по питанию - поискать соответствующий дросель. постоянка-переменка пофигу. на 'советских' БП от ЕС техники - стоял прям по вхоу 220В, с кондюками на корпус.


(круглый)
Letis
Цитата
Какая длина шнурка к датчику?

около 30м.
Цитата
Устройство без датчика с вкл/выкл частотником ведёт себя одинаково?
Еще непробывал, завтра напишу.
Цитата
Устройство с датчиком, подключённым без шнурка, с вкл/выкл частотником ведёт себя одинаково?

Нет, с выключеным частотником работает, с включенным неработает.
Цитата
Вы поминали, что экранирование шнурка ничего не дало. В какой (или каких?) точке был подключен экран?

Только возле устройства.

Я понимаю что прошу возможно слишком много, но не могли бы вы исходя с моего примера написать программу чтения с датчика более грамотно и более подробнее с оглашением всех переменных, тогда бы я был уверен что проблема в программе. Переменную ds я испозую, чтобы между операциями с датчиком работать с динамической индикацией. Я очень вас прошу.

Kovrov
Цитата(Letis @ Oct 7 2010, 17:44) *
Здесь понятно. А как устранить со стороны питания устройства в целом?

главное что нужно помнить..
помехи не устраняют их обходят..
--------
лет 10 назад был проект зарядно подзарядного устройства АБ в Московском метро...
для термокомпенсации подзаряда АБ стоял также DS 1820
в цеху все это работало без проблем с длинной кабеля 20 метров...
на объекте ни в какую!!!
чтоб не городить огород - так как проблему начисто это полюбому не решит..
прошлось делать конвертор протокола
брал контроллер 2313 и преобразовывал интерфейс 1wire в RS485 (выбор протоколов широк)
что навсегда решило проблему.. и сомнения о будущем..
Советую и вам идти по этому пути...
xemul
Цитата(Letis @ Oct 8 2010, 03:51) *
Цитата
Устройство без датчика с вкл/выкл частотником ведёт себя одинаково?
Еще непробывал, завтра напишу.

Имелось в виду: оторвать датчик, но оставить шнурок.
Цитата(Letis @ Oct 8 2010, 03:51) *
Цитата
Устройство с датчиком, подключённым без шнурка, с вкл/выкл частотником ведёт себя одинаково?

Нет, с выключеным частотником работает, с включенным неработает.

Т.е. устройство сбоит в непосредственной близости от частотника? Тогда Вам нужно разобраться с помехоустойчивостью устройства.
Можно начать с поиска по конфе и статьи Помехоустойчивые_устройства.
Цитата(Letis @ Oct 8 2010, 03:51) *
Цитата
В какой (или каких?) точке был подключен экран?
Только возле устройства.

И сразу соединён с минусом питания датчика? Если общий провод не приходит в эту точку обширным полигоном, от экрана толка чуть-да-ничего.
Цитата(Letis @ Oct 8 2010, 03:51) *
Я понимаю что прошу возможно слишком много, но не могли бы вы исходя с моего примера написать программу чтения с датчика более грамотно и более подробнее с оглашением всех переменных, тогда бы я был уверен что проблема в программе. Переменную ds я испозую, чтобы между операциями с датчиком работать с динамической индикацией. Я очень вас прошу.

Цитата
- Не вижу в этом никакого смысла! - сказал Кролик.
- Я тоже, - сказал Винни-Пух, - но когда я начинал говорить, он точно здесь был.

- лечить программно болячки неясной, но, предположительно, аппаратной, этиологии бессмысленно;
- я верю, что Вы легко справитесь самостоятельно. Инфы сейчас даже слишком много. Если будут конкретные вопросы, спрашивайте - здесь на грамотно заданный вопрос обычно можно получить такой же ответ.
Dx!
Цитата(Letis @ Oct 8 2010, 03:51) *
Я понимаю что прошу возможно слишком много, но не могли бы вы исходя с моего примера написать программу чтения с датчика более грамотно и более подробнее с оглашением всех переменных, тогда бы я был уверен что проблема в программе. Переменную ds я испозую, чтобы между операциями с датчиком работать с динамической индикацией. Я очень вас прошу.

Писать вам ни кто ничего не будет. В интернете полно приличных сорцов. Отдаю то, с чем работаю я. Имхо - опросы в основном теле программы а динамическую индикацию делать через прерывания по таймеру.

Из вашего кода непонятно что вы делаете со считанной и проверенной CRC? Выкидываете ли вы неверные значения? Даже если бы чтение удавалось читать раз из десяти - с проверкой CRC работало бы прилично.

Код
//--------------------------------------------------------------------------------------------

// Безадресно запускаем преобразование во всех DS18b20 на линии

    if (!OW_DetectPresence())
    {
        OW_SendByte(OW_Net_SkipNetAddress);
        OW_SendByte(OW_DS18B20_Func_CONVERT_T);
    }


//--------------------------------------------------------------------------------------------


// По адресу (если датчик всего один то можно и безадресно) считываем. Если CRC8 Не совпадает,
// то вместо температуры передаем "код ошибки" 0x4000

    SomeVarT = 0x4000;

    if (!OW_DetectPresence())
    {
        uint8_t i;
        OW_SendByte(OW_Net_MatchNetAddress);
        for (i=0; i!=8; i++)
        {
            OW_SendByte(pgm_read_byte( &DS18B20_Addr[i] ));
        }

        OW_SendByte(OW_DS18B20_Func_READ_SCRATCHPAD);
        for (i=0; i!=4; i++)
        {
            Some16bitBuf[i] = (OW_ReceiveByte()) + (OW_ReceiveByte()<<8);
        }
        Some16bitBuf[i] = OW_ReceiveByte();    //CRC8

        if ((crc8( (uint8_t *)&Some16bitBuf[i-4], 8)) == Some16bitBuf[i])
            SomeVarT = usRegInputBuf[i-4];
    }


//--------------------------------------------------------------------------------------------

// Пример вывода на текстовый LCD
// Выводим для 16.25 градусов цельсия цифру 1625

    if(SomeVarT!=0x4000)
        LCD_PrintfS16Dec6_100(((int32_t)((int16_t)SomeVarT)*100)/16);
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.