3 датчика DS18B20+Arduino

alexxkr
Offline
Зарегистрирован: 30.12.2012

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

что делает строка №36

 present = ds.reset  ();

я так понимаю, что ds.reset()  ресетит шину.  что же тогда присваевается переменной present?

maksim
Offline
Зарегистрирован: 12.02.2012

alexxkr пишет:

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

что делает строка №36

 present = ds.reset  ();

я так понимаю, что ds.reset()  ресетит шину.  что же тогда присваевается переменной present?

4. Любое устройство, подключенное к 1-Wire после получения питания выдает в линию DQ импульс присутствия, называемый "Presence pulse" (далее я буду использовать термин PRESENCE). Этот же импульс устройство всегда выдает в линию, если обнаружит сигнал RESET.
5. Появление в шине 1-Wire импульса PRESENCE после выдачи RESET однозначно свидетельствует о наличии хотя бы одного подключенного устройства.

Источник

maksim
Offline
Зарегистрирован: 12.02.2012

EvgenKir пишет:

У меня такой вопрос, я хочу сделать опрос по датчикам, а потом к примеру через время 5-10 секунд сделать следующий опрос. Но я никак не могу понять, в какую часть кода мне вписат ьвременную задержку для следующего опроса


#include <OneWire.h>
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
  byte  address_1[8] = {0x28, 0xA0, 0x21, 0x33, 0x04, 0x00, 0x00, 0x29};
  byte  address_2[8] = {0x28, 0x08, 0x22, 0x33, 0x04, 0x00, 0x00, 0x9A};
  byte  address_3[8] = {0x28, 0x29, 0x41, 0x33, 0x04, 0x00, 0x00, 0x44};
  byte  address_4[8] = {0x28, 0x05, 0x12, 0x33, 0x04, 0x00, 0x00, 0x54};


OneWire ds (30); // все OneWire устройства на pin 10
int led_pin=13; // определили pin 13 для светодиода
byte done[8];

void setup() {
  Serial.begin  (9600);
  pinMode(led_pin, OUTPUT);
}

void reeds()
{
  if(ds.search(addr) != 1) 
  {
    ds.reset_search();
    delay(250);
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    return;
  }
  ds.reset();
  ds.select(addr);

  Serial.println("----------");
  Serial.print("Addr: ");
  for(byte i = 0; i < 8; i++)
  {
   Serial.print("0x");
   if(addr[i] < 0x10) Serial.print("0");
    Serial.print(addr[i], HEX);
    if(i == 7) Serial.println();
    else Serial.print(", ");
  }

  ds.write(0x44, 1); // start conversion, with parasite power on at the end

  delay(750); // maybe 750ms is enough, maybe not
  // we might do a ds.depower  () here, but the reset will take care of it.

  present = ds.reset  ();
  ds.select(addr);
  ds.write(0xBE); // Read Scratchpad

  for(i = 0; i < 9; i++) data[i] = ds.read ();

  // convert the data to actual temperature
  unsigned int raw =  (data[1] << 8) | data[0];
  if(type_s) 
  {
    raw = raw << 3; // 9 bit resolution default
    if(data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6];
  } 
  else 
  {
    byte cfg = data[4] & 0x60;
    if(cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
    else if(cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if(cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
  }

  celsius = (float)raw / 16.0;
  //Serial.print("Temperature = ");
  //Serial.println(celsius);
  //Serial.print(" ");
  Serial.flush(); //очищаем значения порта

}

  void loop () 
{
  reeds();
  if (!memcmp(address_1, addr, 8)) 
  { // (address == '28190C040074')
    Serial.print  ("T1 = ");
    Serial.println  (celsius);
  }
  if (!memcmp(address_2, addr, 8)) 
  { //(address == '28564C04003A')
    Serial.print  ("T2 = ");
    Serial.println  (celsius);
  }
  if (!memcmp(address_3, addr, 8)) 
  { //(address == '28564C04003A')
    Serial.print  ("T3 = ");
    Serial.println  (celsius);
  }
  if (!memcmp(address_4, addr, 8)) 
  { //(address == '28564C04003A')
    Serial.print  ("T4 = ");
    Serial.println  (celsius);
    
  }

}

if(!ds.search(addr) ) 
  {
    ds.reset_search();
    delay(5000);
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    return;
  }
alexxkr
Offline
Зарегистрирован: 30.12.2012

maksim, спасибо. С логикой работы интефрейса вроде-бы понятно.

Вопрос заключался в том, что я не понял, что именно делает этот участок кода.

Я себе это вижу так: в начале loop() мы объявили какую-то произвольную переменную "present" типа byte, а в этой строке присваиваем ей значение, возвращаемое функцией ds.reset(). Но что может вернуть функция, назначение которой, цитирую, "Reset the 1-wire bus. Usually this is needed before communicating with any device"?

EvgenKir
Offline
Зарегистрирован: 17.09.2013

Спасибо большое

EvgenKir
Offline
Зарегистрирован: 17.09.2013

 Здравствуйте еще раз.

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

-ниже чем 750 мс опрос не может быть, но хотелось бы ниже

-выскакивают ошибки, 3-4 значения датчиков выкидывает сначала, а потом переходит в нужный порядок датчиков, как можно избавиться от этого?

 



#include <OneWire.h>
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
  byte  address_1[8] = {0x28, 0xC9, 0x0A, 0x33, 0x04, 0x00, 0x00, 0xF4};
  byte  address_4[8] = {0x28, 0xA3, 0xFE, 0x32, 0x04, 0x00, 0x00, 0xCE};
  byte  address_5[8] = {0x28, 0x07, 0x10, 0x33, 0x04, 0x00, 0x00, 0xB9};
  byte  address_7[8] = {0x28, 0x08, 0x22, 0x33, 0x04, 0x00, 0x00, 0x9A};
  byte  address_6[8] = {0x28, 0xA0, 0x21, 0x33, 0x04, 0x00, 0x00, 0x29};
  byte  address_2[8] = {0x28, 0x29, 0x41, 0x33, 0x04, 0x00, 0x00, 0x44};
  byte  address_3[8] = {0x28, 0x05, 0x12, 0x33, 0x04, 0x00, 0x00, 0x54};
  byte  address_8[8] = {0x28, 0x7E, 0xF7, 0x32, 0x04, 0x00, 0x00, 0xB3};



OneWire ds (30); // все OneWire устройства на pin 10
//byte done[8];

void setup() {
  Serial.begin  (9600);
  
}

void reeds()
{
  if(ds.search(addr) != 1) 
  {
    ds.reset_search();
    delay(150);
    for(byte i = 0; i < 10; i++) addr[i] = 0;
    return;
  }
  ds.reset();
  ds.select(addr);

  //Serial.println("----------");
  //Serial.print("Addr: ");
  //for(byte i = 0; i < 8; i++)
  //  {
  // Serial.print("0x");
  // if(addr[i] < 0x10) Serial.print("0");
  // Serial.print(addr[i], HEX);
  //if(i == 8) Serial.println();
  // else Serial.print(", ");
  //}

  ds.write(0x44, 1); // start conversion, with parasite power on at the end

  delay(750); // maybe 750ms is enough, maybe not
  // we might do a ds.depower  () here, but the reset will take care of it.

  present = ds.reset  ();
  ds.select(addr);
  ds.write(0xBE); // Read Scratchpad

  for(i = 0; i < 10; i++) data[i] = ds.read ();

  // convert the data to actual temperature
  unsigned int raw =  (data[1] << 8) | data[0];
  if(type_s) 
  {
    raw = raw << 3; // 9 bit resolution default
    if(data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6];
  } 
  else 
  {
    byte cfg = data[4] & 0x60;
    if(cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
    else if(cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if(cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
  }

  celsius = (float)raw / 16.0;
  //Serial.print("Temperature = ");
  //Serial.println(celsius);
  //Serial.print(" ");
 //Serial.flush(); //очищаем значения порта

}

  void loop () 
{
    reeds();
  if (!memcmp(address_1, addr, 8)) 
  { Serial.print  ("Tbx. = ");
    Serial.println  (celsius);
      }
  if (!memcmp(address_2, addr, 8)) 
  { Serial.print  ("T1 = ");
    Serial.println  (celsius);
  }

  if (!memcmp(address_3, addr, 8)) 
    { 
    Serial.print  ("T2 = ");
    Serial.println  (celsius);

     }
   if (!memcmp(address_4, addr, 8)) 
  { 
    Serial.print  ("T3 = ");
    Serial.println  (celsius);
   }
    if (!memcmp(address_5, addr, 8)) 
  { 
    Serial.print  ("T4 = ");
    Serial.println  (celsius);
    
  }
  if (!memcmp(address_6, addr, 8)) 
  { //(address == '28564C04003A')
    Serial.print  ("T5 = ");
    Serial.println  (celsius);
  }
  if (!memcmp(address_7, addr, 8)) 
  { //(address == '28564C04003A')
    Serial.print  ("T6 = ");
    Serial.println  (celsius);
  }
  if (!memcmp(address_8, addr, 8)) 
  { //(address == '28564C04003A')
    Serial.print  ("T7 = ");
    Serial.println  (celsius);
    Serial.println("------------");
  }
}

 

а вот что на выходе показывает

 

T5 = 22.56
T6 = 22.56
T7 = 22.50
------------
Tbx. = 21.94
T1 = 22.62
T2 = 22.31
T3 = 22.06
T4 = 22.44
T5 = 22.56
T6 = 22.50
T7 = 22.50

 

нужно избавиться от 

 

T5 = 22.56
T6 = 22.56
T7 = 22.50

 

 

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

EvgenKir пишет:

 Здравствуйте еще раз.

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

-ниже чем 750 мс опрос не может быть, но хотелось бы ниже

-выскакивают ошибки, 3-4 значения датчиков выкидывает сначала, а потом переходит в нужный порядок датчиков, как можно избавиться от этого?

читаем спецификацию!

Convert temperature to 12-Bit Digital Word in 750ms (Max)

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

И снова досвиданья!

LincikG
Offline
Зарегистрирован: 15.01.2013

Привет Borland
Меня очень интересует Ваш проект (пост #16). Немогли бы Вы кинуть его мне на мыло lincikg@gmail.com или поделится ним на форуме. Спосибо за рание.

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

Всем привет!Подскажите в чем может быть дело при подключении 3-х датчиков 18b20 последовательно с подтяжкой 4,7кОм регистром,если подключить 3 датчика,то все они начинают показывать -127,если один или два любых,то все нормально?

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

sadovod пишет:

Всем привет!Подскажите в чем может быть дело при подключении 3-х датчиков 18b20 последовательно с подтяжкой 4,7кОм регистром,если подключить 3 датчика,то все они начинают показывать -127,если один или два любых,то все нормально?

питание отдельно?

длина линии?

резистор поставь раза в 2-3 поменьше и/или возле каждого датчика.

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

отдельно от чего?Питание от ножки ардуино уно 5в подключил как здесь:

http://did5.ru/arduino/arduino-neskolko-datchikov-temperatury-ds18b20.html

только для экономии места датчики на макетки идут друг за другом с подводкой питания,земли и сигнала

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

есть ещё схема подключения питания от самой линии, но лучше отдельно

странно, должно работать, может контакты плохие на макетке?

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

все-таки резистор возьми 2.2к

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

попробую поменять резистор,ставил 1 кОм ,больше нет,но че то не помогло.А может быть проблема в самих библиотеках OneWire.h

DallasTemperature.h  ?
sadovod
Offline
Зарегистрирован: 09.10.2015

Всем спасибо,проблему удалось решить действительно сменой сопротивления,а поскольку 2,2кОм я не нашел,поставил последовательно 2шт 1кОм регистра и не только все заработало,но и все 3 датчика стали показывать одинаковую температуру,а раньше у них разброс был до 5 градусов при 4,7кОм сопротивлении.Еще раз всем спасибо!

maksim
Offline
Зарегистрирован: 12.02.2012
KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

DallasTemperature вещь не только не нужная, но и вредная, достаточно только OneWire (к неё есть пример работы с DS18B20)

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

Насколько я понял с помощью OneWire нельзя считывать данные с определенного датчика,обращение идет сразу ко всем и какой именно отдал даные не понятно.А мне надо точно знать на каком датчике какая температура. Или я криво читал?

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

sadovod пишет:

Насколько я понял с помощью OneWire нельзя считывать данные с определенного датчика,обращение идет сразу ко всем и какой именно отдал даные не понятно.А мне надо точно знать на каком датчике какая температура. Или я криво читал?

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

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

Ой,спасибо большое,я на такой материал не поподал,действительно можно использовать адрес.Попаду домой выкину DallasTemperature и попробую без него.Еще раз спасибо.

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

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

sadovod пишет:

Насколько я понял с помощью OneWire нельзя считывать данные с определенного датчика,обращение идет сразу ко всем и какой именно отдал даные не понятно.А мне надо точно знать на каком датчике какая температура. Или я криво читал?

Не правильно поняли. Откройте пример из библиотеки OneWire. Он идет по всем существующим адресам, но опрос происходит конкретного адреса, полученого ранее.

  ds.select(addr);

 

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

Думал поборол проблему с 3-мя датчиками,но не тут то было.Возник вопрос почему при включении в код работы с SD картой датчики показывают -127,как только кусо кода отвечающий за SD  убираю,датчики нормально работают.3 датчика подключены на макетке друг за другом,сопротивления ставил разные,питание отдельное.Помогите понять суть.У меня такое чувство,что не хватает питания,но физически на макетке модуль SD снят,только код.Цепляю все к ардуино уно.

#include <SD.h>;
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>//библиотека для дисплея
#include <Wire.h>//Эта библиотека позволяет общаться с I2C / TWI устройствами .


// датчики подключены в порт 9
#define ONE_WIRE_BUS 9
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensors(&oneWire);
DeviceAddress Thermometer;

int value, old_value,pause;
int flagSD = 0, SD_Init = 0;

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);// Задаем адрес и размерность дисплея
File myFile;

byte count;
int dy = 3;
// сюда вставляется результат работы кода
DeviceAddress myAddress[] = {
    {0x28, 0xFF, 0x52, 0x22, 0x71, 0x15, 0x02, 0xC2},
    {0x28, 0xFF, 0x81, 0x1E, 0x71, 0x15, 0x02, 0x88},
    {0x28, 0xFF, 0xDE, 0x26, 0x71, 0x15, 0x02, 0x26}
};



void setup()
{  
  // запускаем библиотеку для 18В20
  sensors.begin();
   Serial.begin(9600);

  // узнаем общее кол-во подключенных датчиков
  count = sensors.getDeviceCount();
 
  for (int i=0; i<count; i++){
    sensors.setResolution(Thermometer, TEMPERATURE_PRECISION);// set the resolution to 9 bit   
  
  }

    lcd.begin(16, 2);
  lcd.clear();

  //для SD карты если все это убрать датчики работают
  while (!Serial) {
    ; //Ждём инициализации серийного порта. Нужно для Leonardo
  }
  // Магия. Этот вывод должен быть настроен как выход.
  // Иначе, некоторые функции могут не работать.
   pinMode(10, OUTPUT);
  lcd.setCursor(0, 0);

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");

    lcd.print("SD initialization " );
    lcd.setCursor(0, 1);
    lcd.print("failed!(No SD card)" );
   delay (4000);
    lcd.clear();
    return;
  }
  else {
    Serial.println("initialization done.");
  
    lcd.print("SD initialization " );
    lcd.setCursor(0, 1);
    lcd.print("done.(Real SD card)" );
    SD_Init = 1;

  }
//конец программы SD
  delay (4000);
  lcd.clear();

}

void loop()
{ 
  // даем команду на считывание температур всем датчикам одновременно
  sensors.requestTemperatures();
  // считываем и выводим температуру
  for (int i=0; i<count; i++){
    Serial.println("T"+String(i)+" "+ sensors.getTempC(myAddress[i]));
  }
  delay(500);
}


причем если заремить весь код для SD c 50 по 74 строку ,но оставить просто 55 строку (pinMode(10, OUTPUT)) так же датчики сходят с ума,а если и ее убрать,то все нормально.Два дня уже голову ломаю,что за аномалия такая

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

Еще пару дней борьбы с проблемой результата не дали.Вопрос к знатокам:возможен глюк описанный мной выше быть из-за глюков самой ардуины?Разве может такое быть,чтобы при инициализации SD карты SD.begin датчики 18в20 переставали работать?

rus
Offline
Зарегистрирован: 03.12.2016

Уважаемые форумчане. У меня ардуино уно r3, пытаюсь подключить датчик температуры DS 1820? не могу его найти в Параметрах, а так же, ни один найденный скин не подходит. Подскажите, что можно сделать.Заранее спасибо.

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

Библиотека OneWire, "Примеры".
А что вы пытаетесь найти в "Параметрах"?