DS18B20 && Arduino

Тема в разделе "Arduino & Shields", создана пользователем Salk, 1 мар 2015.

  1. ИгорьК

    ИгорьК Гуру

    Да, эта функция тормознутая - объективно.
    1. Поэтому Вам надо сделать так, чтобы она вызывалась, например, раз в 5 секунд. Ничего же не произойдет страшного за эти пять секунд?

    2. Кроме того, Вы можете возвращать из функции не float celsius =(float)raw /16.0; а просто raw и пересчитывать его в цельсий за пределами функции.

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

    4. В конце концов можно покопаться в работе библиотеки IRremote.h. Не исключаю,что ее можно настроить на работу с прерываниями. То есть, когда начинает приниматься сигнал - все "бросается" и происходит его обработка вне очереди.
     
    Последнее редактирование: 17 мар 2016
  2. sanky

    sanky Нуб

    Да, спасибо. Попробовал,секунды задержки достаточно чтобы все работало.
     
  3. Onkel

    Onkel Гуру

    при нативном считывании данных с DS18B20 мне пришлось разделить функцию на 5 функций, чтобы не ожидать каждый раз окончания ожиданий. В зависимости от разрешения опрос датчика может занимать до 0,8 с.
     
    Limoney и ИгорьК нравится это.
  4. Limoney

    Limoney Гик

    В большинстве случаев эта функция не нужна.
    Если длина проводника несколько метров от датчика
    Код (C++):
    for (byte i = 0; i < 9; i++)  {
         // we need 9 bytes
         data[i] = ds.read ();
    }
    В остальном она нужна.
     
    Последнее редактирование: 18 мар 2016
  5. Onkel

    Onkel Гуру

    если питание паразитное, то задержка нужна по даташиту. Если питание от Vcc, то эта задержка (возможно) не нужна.
     
  6. anatoliyrnd

    anatoliyrnd Нуб

    В принципе ждать не обязательно при нормальном питании, только результаты будет после окончания преобразования , а до этого будут результаты предыдущего преобразования.
    Я сам сейчас курю даташит и стандартную дуиновскую библиотеку OnWire для работы с несколькими (4) датчиками. Пока не нашел как осуществить проверку CRC и как узнать что температура отрицательная?
    Зато можно использовать следующую команду для запуска преобразования сразу на всех датчиках одновременно.
    Да еще точность измерений зависит не от того сколько вы бит прочитаете а от того что записано в регистр конфигурации bit5 bit6 , и от этого зависит скорость преобразования. При 9битной точность будет 0,5 гр Ц и скорость преобразованиям 93.75милисек.
     
    Последнее редактирование: 7 апр 2016
  7. papakaplo

    papakaplo Нуб

    вопрос: Не совсем понял откуда брать значения адресов датчиков температуры, если допустим у меня 5 данных датчиков? Или делается запрос индивидуально для каждого датчика и возвращенное значение прописывается с скетче? Или все же ручками прописывается на моё усмотрение?
     
  8. Salk

    Salk Гик

    На ваше усмотрение, можете посмотреть адрес датчиков, используя встроенную либу Arduino IDE - "OneWire => DS18x20_Temperature" и прописать их в свой код железно, как сделано у меня (byte addr1[8], byte addr2[8] ... ), либо использовать алгоритм считывания каждого датчика, как сделано в примере той же либы. Вроде:
    Код (C++):
      Serial.print("ROM =");
      for( i = 0; i < 8; i++) {
        Serial.write(' ');
        Serial.print(addr[i], HEX);
      }
    Возможно на это тратится какое-то время, может, имеет смысл данный цикл вывести в setup.

    Onkel, сначала делаю, потом читаю, ну или как дальше пойдет. Если честно корпус, по моему, для этих датчиков выбран неудачный, лучше было бы КТ27, TO220 ...
     
  9. papakaplo

    papakaplo Нуб


    Спасибо, за ответ.

    специально для размещения в защитной гильзе.
     
  10. Добрый день, попала сюда через гугл в поисках информации о подключении DS18B20 к Arduino. Муж пытался подключить по статье, но у него ничего не выходит, он компьютерщик, круглыми сутками за компьютером сидит, работает дома, и сейчас кстати тоже сидит... Говорит что проблема именно в схеме, хотя мне кажется что у него просто руки руки растут не из плечей. Вот та схема, которая на первой странице представлена, она рабочая, и вообще по теме ли я? Или скиньте в ЛС, если вам не тяжело, а то сказал что не получается, и на этом всё закончилось, а меня это не устраивает.
     
  11. Limoney

    Limoney Гик

    Схема по ссылке реально не рабочая.
    Нужно резистор соединить между VDD и DQ
     
    Последнее редактирование: 3 авг 2016
    nashpilkah2016 нравится это.
  12. Onkel

    Onkel Гуру

    и еще бывают путаницы с цветом проводов у датчиков в нержавейке. Попробуйте голай 18В20.
     
    nashpilkah2016 нравится это.
  13. А как узнать что температура стала отрицательная чтоб вывести на индикатор знак минус ?
     
  14. Tomasina

    Tomasina Сушитель лампочек Модератор

    в стандартной библиотеке это делается автоматически.
     
  15. А если библа <DallasTemperature.h> не используется ?
    Как например в посте 34 .
     
  16. netesla

    netesla Нуб

    тоже интересует этот вопрос. не хочется использовать библиотеку dallas
    Код (C++):
    #include <OneWire.h>
    #include <IRremote.h>            // IR
    #include <Wire.h>                // I2C
    #include <LiquidCrystal_I2C.h>  // LCD

    #define IR_PIN        5

    OneWire ds (4);
    byte data[12];
    byte addr1[8] = {0x28, 0xFF, 0xF2, 0x9C, 0x67, 0x14, 0x04, 0xF7}; // ID индивидуально для каждого датчика
    byte addr2[8] = {0x28, 0xFF, 0xA1, 0x9B, 0x67, 0x14, 0x04, 0xAA};
    unsigned int raw;
    float temp1, temp2;

    bool LampState4 = false;

    LiquidCrystal_I2C lcd(0x27, 20, 4);

    IRrecv irrecv(IR_PIN);
    decode_results results;

    void setup()
    {
      Wire.begin();
      lcd.init();
      lcd.backlight(); // вкл. подсветку LCD (noBack-выкл)
      lcd.clear();
      irrecv.enableIRIn(); // Включаем ресивер
    }

    void loop()
    {
      temp1 = DS18B20(addr1);
      temp2 = DS18B20(addr2);

      if (irrecv.decode(&results))
      {
        if (results.value == 565343)
          LampState4 = !LampState4;
        if (LampState4)
        {
          lcd.noBacklight(); // выкл. подсветку
        }
        else
        {
          lcd.backlight(); // вкл. подсветку
        }
        irrecv.resume(); // Получаем следующее значение
      }
      lcd.setCursor(9, 0);
      lcd.print("T1: ");
      lcd.print(temp1); // отображение температуры
      lcd.print("C ");

      lcd.setCursor(9, 1);
      lcd.print("T1: ");
      lcd.print(temp2); // отображение температуры
      lcd.print("C ");
    }

    //==================================================================================
    //                            Считывание температуры  . как понимаю надо тут подправить
    //==================================================================================
    float DS18B20(byte *adres)
    {
      ds.reset();
      ds.select(adres);
      ds.write(0x44, 1); // start conversion, with parasite power on at the end
      ds.reset();
      ds.select(adres);
      ds.write(0xBE); // Read Scratchpad

      for (byte i = 0; i < 9; i++) // можно увеличить точность измерения до 0.0625 *С (от 9 до 12 бит)
      { // we need 9 bytes
        data[i] = ds.read ();
      }
      raw =  (data[1] << 8) | data[0];//=======Пересчитываем в температуру
      float celsius =  (float)raw / 16.0;
      return celsius;
    }
     
  17. ИгорьК

    ИгорьК Гуру


    upload_2018-3-1_16-26-50.png
     
  18. ИгорьК

    ИгорьК Гуру

  19. 9xA59kK

    9xA59kK Гик

    Попробуйте вот эту библиотеку. Довольно свежая.
    1. OneWireHub
    ps\\ в старых версиях IDE при компиляции много ошибок вылетает , думаю можно разобраться при желании.
     
    Последнее редактирование: 1 мар 2018
    ИгорьК нравится это.
  20. b707

    b707 Гуру

    Этот код поддерживает и отрицательные значения, только raw надо описать как знаковый тип, в даташите на DS18B20 все подробно описано
    Код (C++):

    for (byte i = 0; i < 9; i++) // можно увеличить точность измерения до 0.0625 *С (от 9 до 12 бит)
      { // we need 9 bytes
        data[i] = ds.read ();
      }
      raw =  (data[1] << 8) | data[0];//=======Пересчитываем в температуру
      float celsius =  (float)raw / 16.0;
     
    Последнее редактирование: 2 мар 2018
    ИгорьК нравится это.