Почистил скетч примера работы с DS18B20 из библы OneWire..

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

А то уж больно захламлён, смотреть неприятно. И положил в прерывание вотчдога, егойный простецкий таймер в самый раз для таких дел :) Теперь всё компактно, наглядно и красиво :)

#include <OneWire.h>
OneWire  ds(2); 
byte addr[8]={0x28,0x04,0x13,0x80,0x06,0x00,0x00,0xF8};
float celsius;

void setup(void) {
Serial.begin(9600);
WDTCSR=B00011000; //установить биты WDCE WDE (что б разрешить запись в другие биты
WDTCSR=B01000110; // разрешение прерывания + выдержка 1 секунда(55 страница даташита)
}                 // можно выбрать от 16мс до 8 с 

void loop(void) { } 
 
ISR (WDT_vect){
static boolean n=0;
n=~n;
if (n) {ds.reset(); 
        ds.select(addr); 
        ds.write(0x44);    
        }
else   {ds.reset();
        ds.select(addr);    
        ds.write(0xBE);   
        celsius =  (ds.read() | (ds.read()<<8))/16.0;
        Serial.print("  Temperature = ");
        Serial.println(celsius);
        }
}
  
 Автодетекта адреса ds18b20 нет, так что нужно адрес указать вручную. Работает в дефолтовом 9-бит режиме. 

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Немного критики, если хотите.

Вот уж действительно, почистил, а зачем убирать комментарии типа "// start conversion, with parasite power on at the end" и "// Read Scratchpad"?

А вот это "(55 страница даташита)" из какого ДШ? Для какого камня. Да и для одного камня бывает море ДШ разных размеров, соответственно номера страниц в них разные.

Магические числа нравятся? Почему бы не написать, например, так "WDTCSR = (1 << WDCE) | (1 << WDE);" и т.п.

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

Вобщем, дело, конечно, хозяйское.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

kisoft, ну по поводу недостатка  комментариев -и "магических" чисел полностью согласен :)  А вывод в сериал из ISR чисто для проверки.

Даташит дефолтовый http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf 

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

... А вы , батенька ЭСТЭТ ;)

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Издание второе, исправленное и дополненное )  Вставил возможность включить максимальную точность (12-бит режим), дописаны комментарии. В сериал гонит результат только для теста,  данные обновляются  1 раз в 2 секунды.

Вариант с 1м датчиком

#include <OneWire.h>
OneWire  ds(2);
byte addr[8]={0x28,0x04,0x13,0x80,0x06,0x00,0x00,0xF8};
volatile int celsius;
void setup(void) {
Serial.begin(9600);
pinMode (13,OUTPUT);
WDTCSR=(1<<WDCE)|(1<<WDE); //установить биты WDCE WDE (что б разрешить запись в другие биты
WDTCSR=(1<<WDIE)| (1<<WDP2)|(1<<WDP1); // разрешение прерывания + выдержка 1 секунда
// (55 страница <a href="http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf" rel="nofollow">даташита</a>)
// снять все ремарки если нужно поменять разрешение
//  ds.reset(); // сброс шины
//  ds.select(addr); //выставить адрес
//  ds.write(0x4E); // разрешение записать конфиг
//  ds.write(0x7F); // Th контроль температуры макс 128грд
//  ds.write(0xFF); //Tl контроль температуры мин -128грд
//  ds.write(0x60); // 0x60 12-бит разрешение, 0x00 -9бит разрешение
}

void loop(void) {
Serial.print("  Temperature = ");
Serial.println(celsius/16.0);
}
 
ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();  // сброс шины
        ds.select(addr); // выбор адреса
        ds.write(0x44); // начать преобразование (без паразитного питания)
        }
else   {ds.reset();
        ds.select(addr);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        celsius =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        }
}
 
 


  
 

Вариант с 2-мя датчиками

#include <OneWire.h>
OneWire  ds(2);
byte addr1[8]={0x28,0x04,0x13,0x80,0x06,0x00,0x00,0xF8};
byte addr2[8]={0x28,0x47,0x1F,0x5C,0x06,0x00,0x00,0xE6};

volatile int temp1,temp2;

void setup(void) {
Serial.begin(9600);
WDTCSR=(1<<WDCE)|(1<<WDE); //установить биты WDCE WDE (что б разрешить запись в другие биты
WDTCSR=(1<<WDIE)| (1<<WDP2)|(1<<WDP1); // разрешение прерывания + выдержка 1 секунда
// (55 страница <a href="<a href="http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf" rel="nofollow">http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf</a>" rel="nofollow">даташита</a>)
// снять все ремарки если нужно поменять разрешение
//  ds.reset(); // сброс шины
//  ds.select(addr2); //выставить адрес
//  ds.write(0x4E); // разрешение записать конфиг
//  ds.write(0x7F); // Th контроль температуры макс 128грд
//  ds.write(0xFF); //Tl контроль температуры мин -128грд
//  ds.write(0x60); // 0x60 12-бит разрешение, 0x00 -9бит разрешение
}

void loop(void) {
Serial.print("Temp1= ");
Serial.print(temp1/16.0);
Serial.print("   ");
Serial.print("Temp2= ");
Serial.println(temp2/16.0);

}
 
ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();  // сброс шины
        ds.write(0xCC);//обращение ко всем датчикам
        ds.write(0x44);// начать преобразование (без паразитного питания)  
       }
else   {ds.reset();
        ds.select(addr1);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        temp1 =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        // получение с 2-го датчика
        ds.reset();
        ds.select(addr2);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        temp2 =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
       }
}
 
 
  
 

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Пара "приколов" - отсутствие volatile для celsius и использование float.

Остальное так, ворчание :)

И лично я бы использовал условную компиляцию вместо закомментаренного куска в setup, потому что там не совсем очевидно, нужно ли все строки раскомментаривать, либо только часть. Честно говоря не юзал на ардуине DS18B20, но наверняка уже кто то все команды в виде define описал. А вот нашел, библиотека DallasTemperature вроде код культурный.

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

kisoft, спасибо, "приколы" исправил. Условную компиляцию -да, наверно грамотнее бы. Было-бы.. Но я уж  и так это вставил несмотря на то, что мне не нужно, так что оставлю как есть ) Этот кусок нужно выполнить один раз для перешивания конфига еепром. В даллосовской библе чисто визуально всё культурно, но в её коде висит delay на 750мс, вот такой "привет" от разработчиков :)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Я не усмотрел, но это нужный delay для библиотеки, ну тогда можно спереть их дефайны команд ;)

 

bwn
Offline
Зарегистрирован: 25.08.2014

Ну как чайнику не влезть? Вместо строк 36-40 можно ds.write(0xCC); - дает команду на преобразование для всех датчиков на линии.
 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

bwn, век живи...  Поправил :)

bwn
Offline
Зарегистрирован: 25.08.2014

dimax , спасибо за такой труд, а то я в строках битности преобразования увяз.

Pyotr
Offline
Зарегистрирован: 12.03.2014

Как вариант опроса одного ds18b20 без ввода адреса (при смене датчика не переписывать код) и работа с целыми числами.



#include <OneWire.h>
OneWire ds(2);
#define START_CONVERT 0
#define READ_TEMP 1

void setup() {
  Serial.begin(9600);
  tempProcess(START_CONVERT);//конвентируем
  delay(1000);
}

void loop() {
  int temp=0;
  temp= tempProcess(READ_TEMP);//читаем Т
  tempProcess(START_CONVERT);
  Serial.print("Temperature = ");
  // Serial.print(temp); //если в целых *С
  Serial.print(temp/10); Serial.print(",");Serial.print(temp%10);//если в десятых *C
  Serial.println(" *C");
  delay(1000);//только для примера
}
//============================== 
int tempProcess(boolean ch){
  int t=0; 
  if(!ch){
    ds.reset(); 
    ds.write(0xCC);
    ds.write(0x44);
  }
  else{
    ds.reset();
    ds.write(0xCC);
    ds.write(0xBE);
    t= ds.read(); 
    t = t | (ds.read()<<8); 
    //return  t>>4;//целые *C, десятые отброшены
    //return  (t+8)>>4;//целые *С с округлением
    return  (t*10)>>4;//целое в десятых *C (214=>21,4*C)
  }
}

Чтобы всем было понятно, что возвращает функция  tempProcess().
t>>4; -делим целое двубайтное t на 16 (делим на 2 четыре раза или делим на 2 в степени 4).  
(t+8)>>4  это тоже, что (t+16/2)/16 - получаем целые градусы с округлением. Всё это когда не требуются десятые доли градуса.
(t*10)>>4   =  (t*10)/16 - получаем целое число равное температуре в десятых градуса, сотые отбрасываются: число 214 соответствует температуре 21,4 *С

 

      
dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Pyotr, вся задумка была в чём? Что б полностью отказаться от delay(), а у вас он стоит в loop(), и если его убрать то будут глюки, т.к.  по даташиту между запросом температуры и её чтением должно пройти от 100  до 750мс в зависимости от разрядности. Поэтому я и повесил обработчик на таймер.

itehno
Offline
Зарегистрирован: 18.04.2015

dimax пишет:

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

Pyotr
Offline
Зарегистрирован: 12.03.2014

>>Pyotr, вся задумка была в чём? Что б полностью отказаться от delay(),

Я так и указал в скетче:   
delay(1000); //только для примера

А вызывать функцию tempProcess() можно через таймер, millis(), по какому то событию-это кому как нравится.
И функция 
tempProcess() возвращает целое число в градусах Цельсия, а не просто 2 байта, которые ещё нужно перевести в градусы. Думаю, для начинающих это понятнее.
 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

itehno, это проще чем просто :) в выводе температуры  где temp/16.0  напишите temp/16

itehno
Offline
Зарегистрирован: 18.04.2015

Спасибо. А Вы не могли бы подробнее описать этот участок кода? Почему 16?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

itehno, данные "после запятой" записываются дополнительными 4-мя битами, что даёт общее 16-кратное умножение того целого числа, что записано в регистрах температуры.

itehno
Offline
Зарегистрирован: 18.04.2015

dimax пишет:

itehno, данные "после запятой" записываются дополнительными 4-мя битами, что даёт общее 16-кратное умножение того целого числа, что записано в регистрах температуры.

Спасибо

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Я вот только не пойму как после получения  16 бит числа
идёт декодирование допустим вот этих, выделенных мной, измерений в табличке из документации:

TEMPERATURE     DIGITAL OUTPUT  (BINARY)         DIGITAL OUTPUT(HEX)
+125                        0000 0111 1101 0000                           07D0h
+85                          0000 0101 0101 0000                           0550h
+25.0625                 0000 0001 1001 0001                           0191h
  +10.125                   0000 0000 1010 0010                           00A2h
+0.5                         0000 0000 0000 1000                            0008h
0                              0000 0000 0000 0000                            0000h
-0.5                          1111 1111 1111 1000                            FFF8h
  -10.125                    1111 1111 0101 1110                            FF5Eh
-25.0625                  1111 1110 0110 1111                            FE6Fh
-55                           1111 1100 1001 0000                            FC90h

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

trembo, дык это мозговзрывательный счёт отрицательных чисел. Если в старшем бите единица, значит всё слово инвертируется, и к нему ещё прибавляется единица ) Т.е. ~ FF5Eh == (0xA1h + 1) = 162(dec)   А 162/16 = то самое число

itehno
Offline
Зарегистрирован: 18.04.2015

dimax пишет:

Прошу прощения. Может Вы подскажете. Не получается объединить Ваш код, с моим так, что бы одновременно можно было управлять яркостью светодиода. Помогите разобраться, пожалуйста.

#include <OneWire.h>
OneWire  ds(10);
byte addr1[8]={0x28,0xA8,0xB9,0x89,0x06,0x00,0x00,0xC4};
byte addr2[8]={0x28,0x0C,0xB3,0x89,0x06,0x00,0x00,0xF9};
#define led 9
#define potenciometr A0
int x;
volatile int temp1,temp2;


void setup(void) {
WDTCSR=(1<<WDCE)|(1<<WDE);                    //установить биты WDCE WDE (что б разрешить запись в другие биты
WDTCSR=(1<<WDIE)| (1<<WDP2)|(1<<WDP1);        // разрешение прерывания + выдержка 1 секунда
  pinMode(led, OUTPUT);		      //Определение режима работы вывода
  pinMode(potenciometr, INPUT);		      //Определение режима работы вывода
  Serial.begin(9600);
 }

void loop(void) 
{
	x = analogRead(potenciometr) / 4;		//Считываем показания с переменного резистора в диапазоне от 0 до 1024 и делим на 4
  Serial.print("1 ");
Serial.print(temp1/16);
  Serial.println();
  Serial.print("2 ");
Serial.println(temp2/16);
}
ISR (WDT_vect){                                //вектор прерывания WD
static boolean n=0;                            // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();                            // сброс шины
        ds.write(0xCC);                        //обращение ко всем датчикам
        ds.write(0x44);                        // начать преобразование (без паразитного питания)  
       }
else   {ds.reset();
        ds.select(addr1);    
        ds.write(0xBE);                        // Read Scratchpad (чтение регистров)  
        temp1 =  ds.read() | (ds.read()<<8);   //прочитаны 2 байта       
        // получение с 2-го датчика
        ds.reset();
        ds.select(addr2);    
        ds.write(0xBE);                        // Read Scratchpad (чтение регистров)  
        temp2 =  ds.read() | (ds.read()<<8);   //прочитаны 2 байта  
       }
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

itehno, с потенциометра вы считываете, а куда дальше это знание деваете?

itehno
Offline
Зарегистрирован: 18.04.2015

Точно. Забыл про analogWrite(led, x);

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

Можно ещё вопрос? Как записать данные температурных датчиков в переменные? К примеру temper1 и temper2. С использованием библиотеки <DallasTemperature.h> я делал так:

  int temper1, temper2;
  sensors.requestTemperatures();
  printTemperature(Thermometer1,"1 ");
  printTemperature(Thermometer2,"2 ");
  temper1 = sensors.getTempC(Thermometer1);
  temper2 = sensors.getTempC(Thermometer2);

 

bwn
Offline
Зарегистрирован: 25.08.2014

А чем вас не устраивают temp1 и temp2? По религиозным соображениям, можно так: temper1=temp1;   )))))

Да, на 16 поделить не забудьте.

itehno
Offline
Зарегистрирован: 18.04.2015

Прошу, не судите строго. Я только постигаю азы.

Если я Вас правильно понял, то должно быть так?

  int temp_1, temp_2;
  temp_1= dat_t1/16;
  if (temp_1 > 30) x=255;

СПАСИБО, СПАСИБО, СПАСИБО! 

ВСЁ РАБОТАЕТ!

ОГРОМНОЕ СПАСИБО ЗА ВАШЕ РЕШЕНИЕ!

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

А вот не выходит каменный цветок:

Ставил напрямую    

  byte t1= 0xff;
  byte t2= 0x5e;
  t = t1 | t2;

  00A2   результат 10.1    (+10.125)  ОК

  FF5E   результат  15.9   (-10.125)  не ОК

http://mcucpu.ru/index.php/pdevices/datchiki/110-preobrazovanie-koda-tsifrovykh-datchikov-temperatury

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

trembo, не надо так допозна засиживаться, с утра голова лучше считает :). Отбросим старшие байты, они в очевидной инверсии.  Итого имееем A2 и 5E

A2 = 10100010;

5E=  01011110  инвертируем их, получаем 

~5E  10100001 прибавляем 1 получаем 
     10100010

 

sadovod
Offline
Зарегистрирован: 09.10.2015

Добрый день!А подскажите пожалуйста,я использовал даный скетч на 3 датчика,с записью данных каждую секунду на карту памяти и выводом через I2C на дисплей 16х2.Проблема в том,что по прошествии некоторго времени дисплей начинает отображать всякие иероглифы,приходится всю систему перегружать дабы вернуть читаемые показания на дисплее,но на карту данные пишутся корректно.Может быть глюк экрана связан с использованием в данном скетче прирываний?Когда использовал библиотеку даласс такого глюка не было.Все смонтированно пока на макетке в связке с ардуино уно.Или может быть в схему надо добавить конденсатор для более стабильной работы дисплея?

Надеюсь все понятно описал ))

d00m
Offline
Зарегистрирован: 21.02.2013

скажите, а этот скетч работает при паразитном подключении нескольких датчиков?

у меня чето пока вот так

Temp1= 85.00   Temp2= 85.00
                                                   
Temp1= 85.00   Temp2= 85.00
                                                   
Temp1= 85.00   Temp2= 85.00
                                                   
Temp1= 85.00   Temp2= 85.00
                                                   
Temp1= 85.00   Temp2= 85.00
 
           
 

 

bwn
Offline
Зарегистрирован: 25.08.2014

В 19 строке скетча из первого поста попробуйте изменить 0х44 на 0х44 , 1.
И почитайте это , сразу станет понятнее.

d00m
Offline
Зарегистрирован: 21.02.2013

спасибо. я пользуюсь кодом для двух датчиков, поэтому добавил подключение питания на время преобразования (,1) в 36 строку для Варианта с двумя датчиками

чуть получше..

Temp1= 23.87   Temp2= 85.00
                                                   
Temp1= 23.87   Temp2= 85.00
                                                   
Temp1= 23.87   Temp2= 85.00
                                                   
Temp1= 23.87   Temp2= 85.00
                                                   
Temp1= 23.87   Temp2= 85.00
 
со вторым сенсором какаято беда была и под DallasTemperature. 

 

bwn
Offline
Зарегистрирован: 25.08.2014

Судя по 85гр, похоже не хватает питания для преобразования. Это значение записывается в регистр в момент подключения. Проверьте все соединения, возможно нужен конденсатор на последний датчик. Датчики подключаем на один шлейф (не звездой).

d00m
Offline
Зарегистрирован: 21.02.2013

да оба датчика подключены на один и тот же бредборд рядом.

тем более даже если он один то все равно показывает 85.

странно вот еще что - если в коде меняю порядок вывода данных, то есть сначала 

   ds.select(addr2); 

а потом

   ds.select(addr1);

то ОБА и ПО ОДНОМУ показывают нормальную температуру.

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

bwn
Offline
Зарегистрирован: 25.08.2014

Предлагаю у Dimax не флудить, а вернуться в вашу тему. К коду это точно отношения не имеет.

Тарас Петрович
Offline
Зарегистрирован: 21.11.2015

Здравствуйте! Меня заинтересовала идея использования сторожевого таймера для генерации прерываний по времени, думаю, для Ардуино это актуально. Посмотрел стр55 даташита (по ссылке) и обнаружил, что WDE и WDIE подняты (что должно не только вызывать прерывание, но и ресетить контроллер. Ресета не происходит, потому что он не разрешен фьюзами? Я просто этот способ с таймером хочу взять на вооружение. Какие могут быть грабли?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Тарас Петрович, ресета нет потому,  что биты WDE и WDIE не поднимаются одновременно.  Граблей никаких нет, я использую этот таймер давно.

Тарас Петрович
Offline
Зарегистрирован: 21.11.2015

Теперь понял. 

WDTCSR=(1<<WDCE)|(1<<WDE); //установить биты WDCE WDE (что б разрешить запись в другие биты
WDTCSR=(1<<WDIE)| (1<<WDP2)|(1<<WDP1); // разреш

Значение регистра из первой строчки не переносится во вторую. Благодарю за код для датчика, а особенно за идею с WDT, уже опробовал))

emserg
Offline
Зарегистрирован: 25.01.2016

При использовании внешнего питания 18В20 считывать температуру можно даже в процессе конвертирования. Если разрешение 11 бит, то max время преобразования будет 375ms, т.е. опрос и преобразование можно вести каждые 0,5 сек (со скоростью моргания точки часов) с точностью 0,125 градуса. (т.е. данные температуры будем получать каждую секунду)

При линии более 20м на датчике получил слишком зашумлённую паразитную линию. Это привело к получению некорректных данных (когда раз в 5 мин, когда через 30сек) - в логе считывалась не правильная температура. Добавил проверку контрольной суммы:

 if (OneWire::crc8(data_DS_out, 8) != data_DS_out[8]) { Serial.println ("OUTPUT CRC is not valid!"); goto read_ds;

Это избавило от ложных срабатываний. Рекомендую.

А в четвёртый байт конфигурации правильнее будет писать так:

ds.write(0x5F); // точность 0,5гр = 1F; 0,25гр = 3F; 0,125гр = 5F; 0,0625гр = 7F 

bwn
Offline
Зарегистрирован: 25.08.2014

emserg, при опросе каждую секунду, вы реально можете получить плюс пару градусов к фактической температуре (не успевает он мощность рассеивать). Смысл в таком опросе?
20 метров для них вполне комфортно (здесь у кого то более 100метров и датчиков вагон), проверьте аппаратную часть (резисторы и соответствие питания на конце линии).

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

bwn пишет:

emserg, при опросе каждую секунду, вы реально можете получить плюс пару градусов к фактической температуре (не успевает он мощность рассеивать). Смысл в таком опросе?
20 метров для них вполне комфортно (здесь у кого то более 100метров и датчиков вагон), проверьте аппаратную часть (резисторы и соответствие питания на конце линии).

Да, и 305 метров на корбке витой пары проверял, но только не на паразитном питании

bwn
Offline
Зарегистрирован: 25.08.2014

trembo пишет:

Да, и 305 метров на корбке витой пары проверял, но только не на паразитном питании

Ну, паразитное питание это уже от безысходности.(((( ИМХО.

emserg
Offline
Зарегистрирован: 25.01.2016

Я использую такой быстрый опрос в газовом котле BAXI для тёплого пола.  Т.к. это неграмотный котёл (зато дешёвый, скорость нагрева воды в 3 раза быстрее прокачки насосом 70л/мин) скорость нагрева воды очень быстрая и за 1сек у меня обновляется полность вода в контуре. Нагрев дачика при НЕПРЕРЫВНОЙ конвертации составляет 0,5 грдуса, и в чём разница между моим опросом и конвертацией каждую секунду при 12 битах? Любое непрерывное преобразование вызывает лишь разницу на собственный нагрев, так скомпенсируйте его просто вычитая этот нагрев (например 0,5 сравните с ртутным если это актуально и принципиально) из считанного с датчика. Большинству людей в обычной обстановке достаточно точности 0,5 градуса, но иногда, если нужно, то скорость нарастания от 30 до 40 градусов за 20 сек с такой дискретностью вычислить сложно. 

ПРОВЕРКА на бухте в 305м и РЕАЛЬНАЯ работа с ГАРАНТИЕЙ КАЧЕСТВА - разные вещи.

По поводу контрольной суммы: при отладке одного проекта возникли сложности (рядом работало несколько Danfoss приводов) при нормальном питании (по тестеру) обычная китайская ЭКРАНИРОВАННАЯ витая пара (UTP5E) работала как антена. На КАЖДОМ из всех трёх датчиков сразу на выводах висели безкорпусные КЕРАМИЧЕСКИЕ конденсаторы по 0,01; 0,22; 10,0 мкф (от материнских плат); питание ATMEGA328 и DS18B20 через свой БП с UPS СИНУСОИДАЛЬНОЙ формой - НЕ СПАСЛО!!! Резисторы подбирались от 5,1К до 560 Ом (осциллографом DSO8060 разглядывали форму). Одевали всякие ферритовые колечки, добавляли дроссели, НО, как только добавили проверку контрольной суммы, проблема решилась. 

У каждого человека в голове свои тараканы. (К примеру, у меня вместо батарей 10 петлей тёплого пола. Все петли подключены через электромагнитные клапана. Котёл думает, что работает только на один контур, а arduino UNO ему постоянно мозги пудрит играя клапанами в зависимости от температуры в каждой комнате).

Поэтому, мне в моём "умном доме" к примеру, включение котла на 1 сек из-за случайного сбоя передачи данных, (по МЕДНОМУ FTP 5E кабелю)  который показал +5 или -29 в КОМНАТЕ один раз в сутки (или один раз в 5 мин) НЕНАДО! А вот использование CRC (которая уже реализована в этом протоколе) просто добавляет надёжности. Каждый волен выбирать сам, лишь бы был выбор. Я предложил, а не навязывал. Потеря в скорости сомнительна, т.к. нового опроса по шине нет (при отсутствии подпора резистором считываются 00000 и контрольная сумма считывается правильная =0 (для этого я просто добавил проверку на 0 в помещении и 0 CRC; хотя этого НИКОГДА не будет в помещении, но ведь у меня ещё есть и уличные датчики)), а вот надёжность гарантирована, даже если будет сбой один раз за сто лет.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

огромное спасибо! действительно очень классная тема!

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

возник только глупый вопрос.

зачем указвается void setup(void),  если можно писать просто void setup()??

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

dimax пишет:

trembo, дык это мозговзрывательный счёт отрицательных чисел. Если в старшем бите единица, значит всё слово инвертируется, и к нему ещё прибавляется единица ) Т.е. ~ FF5Eh == (0xA1h + 1) = 162(dec)   А 162/16 = то самое число

допКод ?

alexvs
Offline
Зарегистрирован: 22.07.2014

А если WDT в проекте уже занят по прямому назначению, то надо использовать другой таймер?

bwn
Offline
Зарегистрирован: 25.08.2014

alexvs пишет:

А если WDT в проекте уже занят по прямому назначению, то надо использовать другой таймер?

Берите с бабушкой millis().

//***Функция считывания температуры c Далласов*****
void dallRead(unsigned long interval){
  static unsigned long prevTime = 0;
  if (millis() - prevTime > interval) { //Проверка заданного интервала
  static boolean flagDall = 0; //Признак операции
  prevTime = millis();
  flagDall =! flagDall; //Инверсия признака
  if (flagDall) {
    ds.reset();
    ds.write(0xCC); //Обращение ко всем датчикам
    ds.write(0x44); //Команда на конвертацию
    flagDallRead = 1; //Время возврата в секундах
  }
  else {
    byte i;
     int temp;
    for (i = 0; i < 3; i++){ //Перебор количества датчиков
     ds.reset();
     ds.select(addr[i]);
     ds.write(0xBE); //Считывание значения с датчика
     temp = (ds.read() | ds.read()<<8); //Принимаем два байта температуры
     Temp[i] = (float)temp / 16.0; 
     flagDallRead = 2; //Время возврата в секундах
     }
   }
  }
}
//--------------------------------------------------

Вызов из loop - dallRead(flagDallRead*1000);

alexvs
Offline
Зарегистрирован: 22.07.2014

Эээээ..... а бабушка причем?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

это мама всех проггеров , кому 50+
:)-

тибе - бабушка точьно

"Момент истины" - бабушка приехала !!!!!!
у америкосов аналоги - орёл вылетел , птичька в гнезде и т.д.

миллис() - "бабушка" всем другим операторам :)

....базовая , старшая

bwn
Offline
Зарегистрирован: 25.08.2014

SU-27-16 пишет:

это мама всех проггеров , кому 50+
:)-

тибе - бабушка точьно

"Момент истины" - бабушка приехала !!!!!!
у америкосов аналоги - орёл вылетел , птичька в гнезде и т.д.

миллис() - "бабушка" всем другим операторам :)

....базовая , старшая

Ну ты летчик завернул. Это из Di Halta: "Бабушка Миллис постоянно в лупе вяжет носки....."