Разрешение датчика температуры

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

Доброго всем! Начинаю изучать Ардуино, с чем могу-разбираюсь, а тут затупил. Собрал что-то вроде логера, берёт температуру с трёх 18Б20 (подключены по трём проводам, параллельно, выводит на дисплей и на СД карточку кидает. (Ещё в проге прикручен опрос дальномера, просто он у меня появился вместе с Ардуино, я с него начал, а потом не убрал). Всё это даже работает. Но с перого датчика температура приходит с точностью 0,0625 С (видимо, датчик в 12 бит опрашивается?) А с двух других-с точностью 0,5С. Как бы это поправить? Скетч сумбурный, но что мог)))


#include <DS1307RTC.h> //Библиотека для работы с часами реального времени
#include <Time.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#include <SPI.h> //Библиотека для работы с картой памяти
#include <SD.h>  //Библиотека для работы с картой памяти                    
    #define echoPin 7 // Вывод 7  Echo Pin
    #define trigPin 8 // Вывод 8  TrigPin

#include <OneWire.h>
#include <DallasTemperature.h>
 
OneWire oneWire(15); // вход датчиков 18b20
DallasTemperature ds(&oneWire);


//ROM = 28 8A 1A 9C 6 0 0 D8

//ROM = 28 FF 15 46 62 15 1 A8

//ROM = 28 FF A3 88 62 15 1 57
  
DeviceAddress sensor1 = {0x28, 0x8A, 0x1A, 0x9C, 0x06, 0x0, 0x0, 0xD8};
DeviceAddress sensor2 = {0x28, 0xFF, 0x15, 0x46, 0x62, 0x15, 0x1, 0xA8};
DeviceAddress sensor3 = {0x28, 0xFF, 0xA3, 0x88, 0x62, 0x15, 0x1, 0x57};



float Temper1 = ds.getTempC(sensor3);
float Temper2 = ds.getTempC(sensor2);
 float Temper3 = ds.getTempC(sensor1);

   float ExTemper1 = 0.0;
   float ExTemper2 = 0.0;
   float ExTemper3 = 0.0;






 long duration, distance; // Переменные для длительности взвращенного дальномером импулься и расчитанного расстояния
 const int chipSelect = 4; // Вывод 4 это CS карты памяти
 LiquidCrystal lcd(2, 3, 9, 10, 5, 6); //Запуск дисплея с инициализацией выводов

                                            
void setup() {
 ds.begin();

Serial.begin (9600);

 while (!Serial) {
                ; 
                 }


Serial.print("Initializing SD card...");
 if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
 return;
                             }
Serial.println("card initialized.");


 
  lcd.begin(20, 4); //Инициализируем дисплей по количеству строк и столбцов

  pinMode(trigPin, OUTPUT); //Настраиваем выводы для работы с уз дальномером
   pinMode(echoPin, INPUT); //Настраиваем выводы для работы с уз дальномером
                               } //Конец функции сетап

 

void loop() {

 tmElements_t tm;

 
  if (RTC.read(tm)) {
 
  ds.requestTemperatures(); // считываем температуру с датчиков


//float Temper1 = ds.getTempC(sensor1);



    lcd.clear();
    lcd.setCursor(0, 1);
                                             //lcd.print("Dvadcat' Znakov str"); 
    //Serial.print("Sensor 1: ");
    lcd.print(Temper1); // отправляем температуру
    lcd.print("c ");
    //Serial.print("Sensor 2: ");
    lcd.print(ds.getTempC(sensor2));
    lcd.print("c ");
    //Serial.print("Sensor 3: ");
    lcd.print(ds.getTempC(sensor3));
    lcd.print("c");
    
                                            lcd.setCursor(3, 0);
                                             lcd.print(" SANTIMETROV");
                                              lcd.setCursor(2, 3);
                                             lcd.print(tm.Day);
                                             lcd.print(".");
                                             lcd.print(tm.Month);
                                             lcd.print(".");
                                           //lcd.print((tm.Year-30)); 
                                             lcd.print(tmYearToCalendar(tm.Year));
                                             lcd.print(" ");
                                             lcd.print(tm.Hour);
                                             lcd.print(":");
                                                  if (tm.Minute >= 0 && tm.Minute < 10) {
                                                  lcd.print('0');                       }                                            
                                             lcd.print(tm.Minute);
                                             lcd.print(":");
                                                  if (tm.Second >= 0 && tm.Second < 10) {
                                                  lcd.print('0');                       }
                                             lcd.print(tm.Second);
                                                                                         } 
    else   
     if (RTC.chipPresent()) {
     Serial.println("The DS1307 is stopped.  Please run the SetTime");
     Serial.println("example to initialize the time and begin running.");
     Serial.println();
                      } 
       else {
Serial.println("DS1307 read error!  Please check the circuitry.");
Serial.println();
                                                                             }
              

  // float Temper1 = ds.getTempC(sensor3);
 // float Temper2 = ds.getTempC(sensor2);
   // float Temper3 = ds.getTempC(sensor1);
                                       
       String dataString = ""; //Формируем строку для вывода на карту памяти
       dataString += String(distance);
       dataString += " ,Santimetrov ";
       dataString += String(tm.Hour);
       dataString += ":";
       if (tm.Minute >= 0 && tm.Minute < 10) {
        dataString += "0";                      }
         dataString += String(tm.Minute);
          dataString += ":";
           if (tm.Second >= 0 && tm.Second < 10) {
            dataString += "0";;                       }
              dataString += String(tm.Second);  
             dataString += " //Temp 1-st sensor: ";
               dataString += String(Temper1);
               dataString += "C ";
               dataString += " //Temp 2-nd sensor: ";
                dataString += String(Temper2);
              dataString += "C ";
              dataString += " //Temp 3-rd sensor: ";
              dataString += String(Temper3);
              dataString += "C ";

                                                                            
                                                                                                         

           File dataFile = SD.open("datalog.txt", FILE_WRITE); //Открываем или создаём файл на флешке
           if (dataFile)      {
          dataFile.println(dataString);
            dataFile.close();
    
                                }
               else {
Serial.println("error opening datalog.txt");  
delay(9000);
                          }
   
          int tries=0;//Локальная переменная для подсчёта количества попыток обнуления дальномера
          do                {
           digitalWrite(trigPin, LOW);
           delayMicroseconds(2);
           digitalWrite(trigPin, HIGH);
           delayMicroseconds(10);
           digitalWrite(trigPin, LOW);
 
          duration = pulseIn(echoPin, HIGH, 50000); // Измеряем время возврата импульса с дальномера
          distance = (duration/58.2); //производим расчёт расстояния исходя из скорости звука

          if (duration == 0 ) {
            delay(100);
            pinMode(echoPin, OUTPUT);
            digitalWrite(echoPin, LOW);
            delay(100);
            pinMode(echoPin, INPUT);
                              }
                            } 
          while (duration == 0 && ++tries < 3);
              if (duration == 0){
      // Out of range
//Serial.print(" ");  
                                             lcd.setCursor(0, 0);
                                             lcd.print("Out Of Range");
//Serial.println(" ");
         delay(500);
                                }
              else      {            
                                             lcd.setCursor(0, 0);
//Serial.print("Rasstoyanie  ");
//Serial.print(distance);
//Serial.println("  Cm");
                                              
                                             lcd.print(distance);
                                             //lcd.setCursor(3, 0);
                                             //lcd.print(" SANTIMETROV");
                                             
                        }

             
 
 delay(900); 
 //lcd.clear();
              }

  /* void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);}}*/
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Тарас Петрович пишет:
Но с перого датчика температура приходит с точностью 0,0625 С

С чем же Вы его таким точным сравнивали?

Тарас Петрович пишет:
А с двух других-с точностью 0,5С.

Открываем даташит на DS18B20 и читаем "is accurate to ±0.5°C over the range of -10°C to +85°C". Так что +/- 0,5С - заявленная производителем норма!

Тарас Петрович пишет:
Как бы это поправить?

Никак.

 
Штирлиц
Штирлиц аватар
Offline
Зарегистрирован: 13.06.2015

вставь в setup строчки

 sensors.setResolution(sensor1, 9);
sensors.setResolution(sensor2, 9);
sensors.setResolution(sensor3, 9);

 

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

ЕвгенийП пишет:

С чем же Вы его таким точным сравнивали?

Я не имею ввиду его абсолютную точность (достоверность показаний), я имею ввиду дискретность отображения. То есть один датчик (из трёх подключенных) меняет показания по 6 соток (tt.06 или tt.12 или tt.24 и т.д), а два других- или tt.00 или tt.50

ЕвгенийП пишет:

Открываем даташит на DS18B20 и читаем "is accurate to ±0.5°C over the range of -10°C to +85°C". Так что +/- 0,5С - заявленная производителем норма!

Совершенно согласен, и там же : "Основные функциональные возможности DS18B20 - его температурный преобразователь. Разрешающая способность температурного преобразователя может быть изменена пользователем и составляет 9, 10, 11, или 12 битов, соответствуя приращениям (дискретности измерения температуры) 0.5 °C, 0.25°C, 0.125°C, и 0.0625°C, соответственно. Разрешающая способность по умолчанию установлена 12- бит."

Тарас Петрович
Offline
Зарегистрирован: 21.11.2015
To ШТИРЛИЦ : Вставляю, возникает такя ошибка.
 
 
Arduino: 1.6.6 (Windows 7), Плата:"Arduino/Genuino Uno"
 
D:\MyArduinoProjects\Zagotovka_Loggera\Zagotovka_Loggera.ino: In function 'void setup()':
 
Zagotovka_Loggera:44: error: 'sensors' was not declared in this scope
 
    sensors.setResolution(sensor1, 9);
 
    ^
 
exit status 1
'sensors' was not declared in this scope
 
  Это сообщение будет содержать больше информации чем
  "Отображать вывод во время компиляции"
  включено в Файл > Настройки
 
alexvs
Offline
Зарегистрирован: 22.07.2014

Не, ну вы что, издеваетесь? Конечно же нужно вместо "sensors" использовать имя вашего объекта из скетча! А это помоему - "ds".

Зачем же тупо подставлять предложенное?

arduinec
Offline
Зарегистрирован: 01.09.2015

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

https://milesburton.com/Dallas_Temperature_Control_Library

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

Благодарю всех отписавшихся, получилось! Почитал по вашим ссылкам и вставил в свой скетч  

DallasTemperature sensors(&oneWire);

Отсюда возникает следующий вопрос: где почитать про функции библиотек и языка С в целом. Вот написано (&oneWire);? что это означает? DallasTemperature является переменной или классом? Почему внутри функции оно работает, а вне-нет? Справочник по программированию на этом сайте я, конечно читаю, но там только конкретика, а где взять более полное, общее опсание правил языка?

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

клик

Ищите)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Тарас Петрович, имейте только в виду, что в С классов нет. Они есть в С++, а это совсем другой язык. Так что одного K&R будет недостаточно.

pav2000
Offline
Зарегистрирован: 15.12.2014

Вставлю свои пять копеек.

Есть точность  - здесь +-0.5 градуса

Есть разрешение - оно устанавливается  и одно из значений 0.0625.