Jump to content

    
Sign in to follow this  
letis

Проблемы с DS18B20

Recommended Posts

Разработал устройство на меге8 с датчиком DS18B20. До этого все работало отлично, даже в промышленных условиях. Но возникла проблема, когда возле устройства установить и запустить частотник (для регулировки оборотов двигателя) то температура на устройстве показывает -1. В чем может быть проблема. Я уже использовал для связи с датчиком экранированную витую пару, но это не помогло. Подскажите.

Share this post


Link to post
Share on other sites

С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;

}

Share this post


Link to post
Share on other sites

-1 приходит без ошибок в CRC ?

Видимо помеха не в интерфейсе а в питании.

 

UPD:

Программа ужасна... что вы считаете и с чем сравниваете?

!w1_dow_crc8(&__ds18b20_scratch_pad,9); <-- это что?

 

Ужас ужас... Есть же приличные соры в сети...

Edited by Dx!

Share this post


Link to post
Share on other sites

А вот так будет правильно ?

 

 

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;

}

Share this post


Link to post
Share on other sites

Да работает оно все. Я использую библиотеку, и все нормально. Но проблема в том где то появляются помехи я не знаю где - или в питании или линии связи вот какой мне нужен ответ и соответственно как их устранить. Подтягивающий резистор у меня 1к, стоит в устройстве, линия - три провода без паразитного питания, кроме того стоит возле датчика кондюк 0805 - 0,1мкФ. Помогите !!! Я уже сделал 10 устройств и все в порядке, но вот тут начало высвечивать на дисплее -1.

Share this post


Link to post
Share on other sites
...использую библиотеку...где то появляются помехи я не знаю где....резистор у меня 1к, стоит в устройстве,....возле датчика кондюк 0805...на дисплее -1..

 

 

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

 

1) про библиотеку не скажу. главное чтоб все временные задержки согласно даташиту. именно особое внимание временным задержкам.

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

3) резистор можно ом до 300 снижать. присмотритесь к даташиту - в некоторых нарисован резистор возле датчика. существенно помогает когда речь идёт о 30 и более метров.

4) кондюк (чиссо моё имхо) в сад. не нужно это. а вот линию подцеплять лучше через ds9503 согласно рекомендациям от далласа.

5) тут правильно сказали - вам нужно определиться, -1 это с учётом CRC или нет? Если честно - верится с трудом что сам датчик вам такое выдаёт.

6) питание датчика не напрямую соединяется то с питанием МК надеюсь? грязные-чистые земли-питание разведены по уму?

7) попробуйте закрыть частотник в железном ящике типа старой советской стиралке. Если ситуацию не измениться - по питанию у вас лезет. дросели по питанию проверить у частотника чтоб живые были и в питание цифры.

8) обычно на надёжность цифры влияет всякие пусковые выбросы. гасящие элементы ставят. при этом проблемы с питанием МК чаще чем всё остальное обычно бывает. хотя зависит от фильтрации по питанию сильно.

 

 

удачи вам

надеюсь навёл на умную мысль какую нить :)

(круглый)

Share this post


Link to post
Share on other sites
гасящие элементы ставят.

 

Какие гасящие элементы ставлят ?

У меня питание устройства - 24 В переменка. Можно ли на входе питание поставить параельно резистор 24к и конденсатор 1 мкФ?

Share this post


Link to post
Share on other sites

Были похожие проблемы.

Длина линии с датчиком 30м. Шнур не экранированный. Опрос датчика примерно раз в 2 секунды. Работа устройства проверялась при включенном на шнур генераторе электромагнитных помех.

 

1. Гальваническая развязка между платой и датчиком

2. Для проверки тайминги шины надо выставить в максимум (потом можно и сократить)

3. При приходе от датчика всех нулей CRC расчитывается правильно (!!!!), поэтому все байты в приходящем пакете складываются по ИЛИ и сравниваются с нулем.

4. При правильном приеме СRC, температура сравнивалась с предыдущей - разница в показаниях не должна быть большой (инерционность датчика однако!!!)

5. Интерфейс между датчиком и КПУ был сделан с использованием полевика (на КПу шли вход и выход по отдельности, а с полевика на датчик - один провод) - для получения резких фронтов от КПУ на датчик

 

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

Share this post


Link to post
Share on other sites
Феррит кольцо... в помощь..

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

 

И еще как уменьшить помехи со стороны питания устройства, так как частотник и устройство питаются от одной сети. Если не сложно нарисуйте схему.

Share this post


Link to post
Share on other sites

кольцо берете с мин проницаемостью: лучше 400нн

берете ваш кабель (там 2 или 3 проводка) и 1-2 витка пронизывате в кольцо..

...........

нарисовать схему чего?

Share this post


Link to post
Share on other sites

Здесь понятно. А как устранить со стороны питания устройства в целом?

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

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

Edited by Letis

Share this post


Link to post
Share on other sites
Дело в том, что если выключить частотник, то датчик работает, если включить не работает.

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

Какая длина шнурка к датчику?

Устройство без датчика с вкл/выкл частотником ведёт себя одинаково?

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

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

Пока, ей-ей, не понятно, что сбоит, да и сбоит или так и задумано.

 

думы за жисть:

После ++ в

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 (с плавучкой, если компилятор не сообразит) в прерывании?

 

Но коль "Да работает оно все", то и ладно.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this