Разрешение датчика температуры
- Войдите на сайт для отправки комментариев
Ср, 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.