DS18B20

Тема в разделе "Arduino & Shields", создана пользователем Perun61, 15 ноя 2012.

  1. Miheeei

    Miheeei Нерд

    Спасибо за литературу.
    Во общем попробовала разные варианты, Оставила решение такое, может и не совсем правильное но поака работает так.
    Запрос температуры у меня идет по таймеру раз пять минут.
    Отключила задержку в библиотеки dallas, другую задержку тоже не делала. Оставила так:
    Код (C++):
    sensors.setWaitForConversion(false);
    sensors.requestTemperatures();                                                          
    Term = sensors.getTempCByIndex(0);
    Выходит что при первоначальной загрузке МК я запрашиваю температуру, используя паузу получаю ответ.
    А далее каждые пять минут делаю запрос, затем тут же без паузы запрашиваю ответ, Соответственно ответ не готов и я получаю старый данные(прошлых 5 минут).
    Так и и повторяется цикл каждые 5 минут, Запросила новую температуру а получаю предыдущую.
    Меня это вполне устаревает, так как измеряю уличную температуру, думаю резких перепадов температуры не будет, тем более для моего проекта это не критично.
    Моя цель включать Обогрев водопроводной трубы если температура за бортом <= 3 C.
    Всем СПАСИБО за помощь.
     
  2. rkit

    rkit Гуру

    Эти две строчки нужно поменять местами, в таком случае.
     
  3. Miheeei

    Miheeei Нерд

    т.е.
    Сначала получаем результат, затем новый запрос.
    Поняла, Спасибо
     
  4. lokos

    lokos Нуб

    Ребят всем привет. Нужно написать скетч, чтоб arduino отправляла email в соответствии с показаниями датчика. Если температура меньше 24, то горит зеленый светодиод, если больше 24 и меньше 30, то дуина отправляет email о предупреждении и загорается синий светодиод, если температура перепрыгивает порог в 30 градусов, то отправляется email, что скоро все "умрут" и горит красный диод. Я написал, но проблема в том, что email'ы приходят когда захотят, чаше всего при первом запуске, когда горит синий светодиод, но при повышении показания датчика дуина не может законектиться подскажите плиз, что я делаю не так? =)
    Код (C++):
    #include <Base64.h>
    // библиотека для работы с SPI
    #include <SPI.h>
    // библиотека для работы с Ethernet Shield
    #include <Ethernet2.h>
    #include <OneWire.h>                  // Подключаем библиотеку для взаимодействия с устройствами, работающими на шине и по протоколу 1-Wire
    #include <DallasTemperature.h>        // Подключаем библиотеку с функциями для работы с DS18B20 (запросы, считывание и преобразование возвращаемых данных)

    #define ONE_WIRE_BUS 2                // Указываем пин подключения data-вывода датчика температуры
    #define term_power 4                  // Указываем пин подключения питания датчика температуры

    double temp; // переменная для хранения температуры
    int ledGreen = 8;
    int ledBlue = 7;
    int ledRed = 12;
    int flag = 0;
    int current = 0;

    struct Message
    {
      String From;//адрес отправителя
      String To;// адрес получателя
      String Subject;// Тема письма
      String Body;// Текст письма
    };

    // MAC-адрес контроллера
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    // адрес запрашиваемого сервера
    IPAddress server(1, 1, 1, 1);
    // задаем статический IP-адрес
    // на тот случай, если у DHCP выдать IP-адрес не получится
    IPAddress ip(10, 0, 72, 14);
    IPAddress myDNS(10, 0, 72, 254);
    IPAddress gateway(10, 0, 72, 3);
    IPAddress subnet(255, 255, 255, 0);

    // логин и пароль к почтовому сервису
    char login[] = "login";
    char password[] = "pass";

    // создаём клиента, который будет подключаться
    // к необходимому для нас серверу и порту
    // портом по умолчанию для SMTP является 25
    EthernetClient client;

    OneWire oneWire(ONE_WIRE_BUS);        // Сообщаем библиотеке об устройстве, работающем по протоколу 1-Wire
    DallasTemperature sensors(&oneWire);  // Связываем функции библиотеки DallasTemperature с нашим 1-Wire устройством (DS18B20)

    void setup(void)
    {
      delay(5000);
      Ethernet.begin(mac, ip, myDNS, gateway, subnet);
      pinMode(ledGreen, OUTPUT);
      pinMode(ledBlue, OUTPUT);
      pinMode(ledRed, OUTPUT);
      Serial.begin(9600);             // Запускаем вывод данных на серийный порт
      sensors.begin();                // Запускаем библиотеку измерения температуры
      pinMode(term_power, OUTPUT);    // Определяем пин подключения питания датчика температуры
    }



    float temperature() { // Измеряем температуру 10 секунд
      digitalWrite(term_power, HIGH);                // Включаем питание датчика температуры
      delay(100);                                    // Задержка перед первым измерением
      sensors.requestTemperatures();                 // Запрос на измерение температуры (1-й ошибочный)
      delay(500);                                    // Задержка перед поторным измерением
      sensors.requestTemperatures();                 // Запрос на измерение температуры (повторный)
      float t = float(sensors.getTempCByIndex(0));   // Получаем значение температуры
      digitalWrite(term_power, LOW);                 // Отключаем питание датчика температуры
      delay(1000);                                   // Задержка, чтобы датчик не нагревался от частых измерений
      return(t);                                     // Возвращаем значение температуры в место вызова функции
    }

    void loop(void)
    {
      temp = temperature();
      Serial.println(temp,1);                // Выводим текущее значение температуры датчика, округленное до десятых
      Serial.println(flag);
      Serial.println(current);


    if (temp <= 24) {
      digitalWrite(ledGreen, HIGH);
      digitalWrite(ledBlue, LOW);
      digitalWrite(ledRed, LOW);
      current = 0;
      if (flag != current) {
           SendMessage();
           
        }
      }

     
      if (temp > 24 && temp <= 30) {
        digitalWrite(ledGreen, LOW);
        digitalWrite(ledBlue, HIGH);
        digitalWrite(ledRed, LOW);
        current = 1;
        if (flag != current){
       SendMessage();
         
          }
      }

     
        if (temp > 30) {
        digitalWrite(ledGreen, LOW);
        digitalWrite(ledBlue, LOW);
        digitalWrite(ledRed, HIGH);
        current = 2;
        if (flag != current){
          SendMessage();
         
      }
    }
    }


    // метод подключения к серверу
    bool connectToServer(){
      if(client.connected()){
      }
      else{
        if(client.connect(server,25)){
          return true;
        }
        else{
          return false;
        }
      }
    }

    // кодировка Base64
    String strToBase64(char str[]){
      char charArray[64];
      base64_encode(charArray,str,strlen(str));
      String result = charArray;
      return result;
    }


    // подключение к сереверу и авторизация
    void LogPass(){
      char array[64];// массив для кодирования
      if(connectToServer()){
        client.println(F("helo 194.85.88.244"));
        delay(250);
        client.println(F("AUTH LOGIN"));
        delay(250);
        client.println(strToBase64(login));
        delay(250);
        client.println(strToBase64(password));
        delay(250);

      }
      else{
        Serial.println("Server not connected...");
      }

    }


    // метод отправки сообщения
    void SendMessage(){
      Serial.println("Please wite...");
      LogPass();
      Message message = {
        "arduino@magtrk.ru",
        "lokos49rus@gmail.com",
        "Hello from arduino",//тема
        "DANGER" };//само сообщение
      client.println("MAIL From:<"+message.From+">");
      delay(250);
      client.println("RCPT To:<"+message.To+">");
      delay(250);
      client.println("DATA");
      delay(250);
      client.println("From:"+message.From);
      client.println("To:"+message.To);
      client.println("Subject:"+message.Subject);
      delay(250);
      client.println(message.Body);
      delay(250);
      client.println();
      client.println(".");// по приходу точки сервер ставит сообщение в очередь
      delay(250); // на отправку
      client.println("QUIT");// как только закрыли соединение, сообщение улетает
      delay(250);
      Serial.println("Message sending...");
      flag = current;
    }
     
  5. ronik

    ronik Нерд

    Сразу извиняюсь, может спрошу глупость, но возникла такая проблема. В общем, есть влагозащищенный датчик DS18B20, подключен по трем проводам, резистор 4.7 кОм имеется, но в ответ на следующее
    Код (C++):
    var ow = new OneWire(A0);
    var sensor = require("DS18B20").connect(ow);
    setInterval(function() {
      sensor.getTemp(function (temp) {
        console.log("Temp is "+temp+"°C");
      });
    }, 1000);
    получаю вот этот самый "null"
    Снимок3.JPG
    При этом с ардуинкой и таким же подключением, датчик работает и показывает температуру.
    Здесь на форуме перерыл по моему все, но, не фига не нашел. В общем help!, как говорится, сограждане, может кто подскажет?
     
  6. ronik

    ronik Нерд

    Вот, нашел в библиотеке
    /* Copyright (c) 2016 Gordon Williams, Pur3 Ltd. See the file LICENSE for copying permission. */
    /*
    Module for the DS18B20 temperature sensor

    ```
    var ow = new OneWire(A1);
    var sensor = require("DS18B20").connect(ow);
    sensor.getTemp(function (temp) { console.log("Temp is "+temp+"°C"); });
    sensor.setRes(9);
    sensor.getTemp(function (temp) { console.log("Temp is "+temp+"°C"); });
    var sensor2 = require("DS18B20").connect(ow, 1);
    var sensor3 = require("DS18B20").connect(ow, -8358680895374756824);
    ```
    */

    var C = {
    CONVERT_T: 0x44,
    COPY: 0x48,
    READ: 0xBE,
    WRITE: 0x4E
    };

    function DS18B20(oneWire, device) {
    this.bus = oneWire;
    if (device === undefined) {
    this.sCode = this.bus.search()[0];
    } else {
    if (parseInt(device).toString()==device && device >= 0 && device <= 126) {
    this.sCode = this.bus.search()[device];
    } else {
    this.sCode = device;
    }
    }
    if (!this.sCode) throw new Error("No DS18B20 found");
    // device type
    this.type=parseInt(this.sCode[0]+this.sCode[1]);
    }

    /** For internal use - read the scratchpad region */
    DS18B20.prototype._r = function() {
    var b = this.bus;
    b.select(this.sCode);
    b.write(C.READ);
    return b.read(9);
    };

    /** For internal use - write to the scratchpad region */
    DS18B20.prototype._w = function (th, tl, conf) {
    var b = this.bus;
    b.select(this.sCode);
    b.write([C.WRITE,th,tl,conf]);
    b.select(this.sCode);
    b.write(C.COPY);
    b.reset();
    };

    /** Set the sensor resolution in bits. From 9 to 12.
    This setting is stored in device's EEPROM so it persists even after the sensor loses power. */
    DS18B20.prototype.setRes = function (res) {
    var spad = this._r();
    res = [0x1F, 0x3F, 0x5F, 0x7F][E.clip(res, 9, 12) - 9];
    this._w(spad[2], spad[3], res);
    };

    /** Return the resolution in bits. From 9 to 12 */
    DS18B20.prototype.getRes = function () {
    return [0x1F, 0x3F, 0x5F, 0x7F].indexOf(this._r()[4]) + 9;
    };

    /** Return true if this device is still connected to the OneWire Bus */
    DS18B20.prototype.isPresent = function () {
    return this.bus.search().indexOf(this.sCode) !== -1;
    };


    /** Get a temperature reading in degrees C. If callback is supplied,
    it will be called with the current temperature. If it isn't the *last*
    temperature will be returned and a new reading will be started. This
    means that with no callback, the first call to getTemp will return
    an invalid temperature. If the CRC fails, 'null' will be returned */
    DS18B20.prototype.getTemp = function(callback) {
    function read(me) {
    var s = me._r();
    var c = 0;
    // do the CRC
    for (var i=0;i<8;i++) {
    c^=s;
    for (var j=0;j<8;j++)
    c=(c>>1) ^ 0x8C*(c&1);
    }
    var temp = null;
    if (c == s[8]) {
    temp = s[0] + (s[1]<<8);
    if (temp & 32768) temp -= 65536;
    temp = temp / ((me.type==10)?2:16);
    }
    if (callback) callback(temp);
    return temp;
    }
    this.bus.select(this.sCode);
    this.bus.write(C.CONVERT_T, true);
    if (!callback) return read(this); // if no callback, read now - we'll get the last temperature
    var tim = {9:94, 10:188, 11:375, 12:750}; // Thermometer Resolution (bit) : Max Conversion Time (ms)
    setTimeout(read, tim[this.getRes()], this);
    }

    /** Return a list of all DS18B20 sensors with their alarms set */
    DS18B20.prototype.searchAlarm = function() {
    return this.bus.search(0xEC);
    };

    /** Set alarm low and high values in whole degrees C - see DS18B20.prototype.searchAlarm.
    If the temperature goes below `lo` or above `hi` the alarm will be set. */
    DS18B20.prototype.setAlarm = function(lo,hi) {
    lo--; // DS18B20 alarms if (temp<=lo || temp>hi), but we want (temp<lo || temp>hi)
    if (lo<0) lo+=256;
    if (hi<0) hi+=256;
    var spad = this._r();
    this._w(hi,lo,spad[4]);
    };

    /** Initialise a DS18B20 device. Use either as:
    connect(new OneWire(pin)) - use the first found DS18B20 device
    connect(new OneWire(pin), N) - use the Nth DS18B20 device
    connect(new OneWire(pin), ID) - use the DS18B20 device with the given ID
    */
    exports.connect = function(oneWire, device) {
    return new DS18B20(oneWire, device);
    };
    сей момент, где присутствует гадский "null",
    Код (C++):
    / ** Получите показание температуры в градусах C. Если включен обратный вызов,
    Он будет вызываться с текущей температурой. Если это не последний *
    Температура будет возвращена, и начнется новое чтение. Эта
    Означает, что без обратного вызова первый вызов getTemp вернется
    Недопустимая температура. Если CRC терпит неудачу, возвращается «null» * /
    DS18B20.prototype.getTemp = function(callback) {
      function read(me) {
        var s = me._r();
        var c = 0;
        // do the CRC
        for (var i=0;i<8;i++) {
          c^=s[i];
          for (var j=0;j<8;j++)
            c=(c>>1) ^ 0x8C*(c&1);
        }
        var temp = null;
        if (c == s[8]) {
          temp = s[0] + (s[1]<<8);
          if (temp & 32768) temp -= 65536;
          temp = temp / ((me.type==10)?2:16);
        }
        if (callback) callback(temp);
        return temp;
    но, так как, не программист не разу, не пойму не фига что там считается. Короче, смотрю в книгу,вижу фигу:(
    В общем, кто нибудь может расшифровать вот это?
    Код (C++):
      var temp = null;
        if (c == s[8]) {
          temp = s[0] + (s[1]<<8);
          if (temp & 32768) temp -= 65536;
          temp = temp / ((me.type==10)?2:16);
        }
        if (callback) callback(temp);
        return temp;
     
  7. rkit

    rkit Гуру

    Проверяйте подключение.
     
  8. ronik

    ronik Нерд

    по подключению все ОК, на ардуино таже макетка с датчиком и резистором работает без проблем.
     
  9. ronik

    ronik Нерд

    В общем, дело было в датчике. Купил сегодня пару датчиков в корпусах TO-92, воткнул в макетку вместо влагозащищённого и все заработало... Но почему он, собака влагозащищенная, на ардуино работает, а на искре не хочет, так и не понял.
     
  10. rkit

    rkit Гуру

    Значит плохая пропайка в датчике
     
  11. ronik

    ronik Нерд

    Была-бы проблема в контакте, были-бы косяки и с ардуино, так мне кажется. Может я не прав, но по моему, проблема в разнице библиотек для ардуино и искры. В моем датчике какой-то косяк, не критичный для расчетов одной и заметный для второй библиотеки. Поэтому и задал вопрос по приведенному фрагменту кода. Посмотрим, сейчас рыл переводы даташита в плане преобразования температуры, но уперся в полное непонимание синтаксиса логических операторов сравнения (вот такой я нуб), в общем, разбираюсь потихоньку.
     
  12. rkit

    rkit Гуру

    А, ну да. Может быть, то была китайская подделка под датчик. Они любят такое.
     
  13. ronik

    ronik Нерд

    На высшее погоняете! У Амперки брал:rolleyes:
     
  14. ronik

    ronik Нерд

    на самом деле может я его и сам пожег, первое включение было с резистором 10 кОм,
    но так написано у амперки( для одного датчика), мне не понятно его нынешнее поведение.
     
  15. rkit

    rkit Гуру

    10к это смешно.
     
  16. ИгорьК

    ИгорьК Гуру

    10k ничего не испортит.
    Разница между Ардуино и Искрой - 5 и 3.3 вольт. Возможно, все таки контакт где-то плохой
     
  17. ronik

    ronik Нерд

    не смешно
    5555.JPG
    по питанию вопрос разобрал, пробовал и 5v и 3.3v, результат тот же. Смотрел ваше описание работы с ds18b20
    на ардуино, смотрел ваши проекты на искре с этим датчиком, предполагаю, что разницу в библиотеках , если она есть, вы понимаете... Может поделитесь?:)
     
  18. ИгорьК

    ИгорьК Гуру

    Посмотрел в закромах - библиотека стандартная. Абсолютно с сайта.
     
  19. ИгорьК

    ИгорьК Гуру

    Код (Javascript):
    var ow = new OneWire(A0);
    var sensor = require("DS18B20").connect(ow);
    setInterval(function() {
      sensor.getTemp(function (temp) {
        console.log("Temperature now is "+temp.toFixed(2)+"°C");
      });
    }, 10000);
    Все то же самое.
     
  20. ronik

    ronik Нерд

    я, по секрету поинтересуюсь, в библиотеке к ардуино ( я понимаю, не та ветка форума и все такое) этот "null"
    есть?