Разрешение датчика температуры
- Войдите на сайт для отправки комментариев
Ср, 02/12/2015 - 22:32
Доброго всем! Начинаю изучать Ардуино, с чем могу-разбираюсь, а тут затупил. Собрал что-то вроде логера, берёт температуру с трёх 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);}}*/
С чем же Вы его таким точным сравнивали?
Открываем даташит на DS18B20 и читаем "is accurate to ±0.5°C over the range of -10°C to +85°C". Так что +/- 0,5С - заявленная производителем норма!
Никак.
вставь в setup строчки
С чем же Вы его таким точным сравнивали?
Я не имею ввиду его абсолютную точность (достоверность показаний), я имею ввиду дискретность отображения. То есть один датчик (из трёх подключенных) меняет показания по 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- бит."
Не, ну вы что, издеваетесь? Конечно же нужно вместо "sensors" использовать имя вашего объекта из скетча! А это помоему - "ds".
Зачем же тупо подставлять предложенное?
В библиотеке DallasTemperature есть пример Tester, который позволяет изменить разрешение датчика температуры.
https://milesburton.com/Dallas_Temperature_Control_Library
Благодарю всех отписавшихся, получилось! Почитал по вашим ссылкам и вставил в свой скетч
Отсюда возникает следующий вопрос: где почитать про функции библиотек и языка С в целом. Вот написано (&oneWire);? что это означает? DallasTemperature является переменной или классом? Почему внутри функции оно работает, а вне-нет? Справочник по программированию на этом сайте я, конечно читаю, но там только конкретика, а где взять более полное, общее опсание правил языка?
клик
Ищите)
Тарас Петрович, имейте только в виду, что в С классов нет. Они есть в С++, а это совсем другой язык. Так что одного K&R будет недостаточно.
Вставлю свои пять копеек.
Есть точность - здесь +-0.5 градуса
Есть разрешение - оно устанавливается и одно из значений 0.0625.