Замена Dallas DS18B20
- Войдите на сайт для отправки комментариев
Втр, 05/07/2016 - 13:13
Добрый день.
нахожу много примеров термостата на Ардуино и везде используется Dallas DS18B20
Но на моем термостате будет балансироваться температура в районе 250 С и даллас такое не тянет.
И я не представляю как изменить код в скетче что бы избавиться от загрузки DallasTemperature.h
Подозреваю, что сабака порылась тут
#include <OneWire.h> OneWire oneWire(15); //Подключаем библиотеку для работы с термометром #include <DallasTemperature.h> //Создаем объект sensors, подключенный по OneWire DallasTemperature sensors(&oneWire);
Но вот как прописать съем инфы с датчика отличного от даллас?
датчика отличного от даллас?
Какого датчика? ХЗ!
Как он подключён? ХЗ!
Но вот как прописать съем инфы
Тогда, это тоже ХЗ!
Датчик термистор NTS 3950 100K
подключен по схеме
где U подсоединен к аналоговому входу А1
Вы уж извиняйте нуба - я только начал пробовать работать с Ардуино
и даже вопросы иногда не корректно формулирую .
Ну, так Вам надо его отградуировать. Для этого Вам нужно иметь доступ к эталонному термометру. Читайте значение с входа А1 функцией analogRead(1), печатайте прочитанное значение и составляйте таблицу "температура - значение". Как составите - вот Вам и будет датчик. Потом будете считывать показание и по таблице узнавать температуру (или формулу придумайте, глядя на таблицу).
Я бы ещё поставил конденсатор между А1 и землёй, чтобы сгладить показания, а то скакать будут. Какой? Тут нужен компромисс - чем больше конденсатор, тем глаже показания (меньше скачут), но тем больше задержка в реакции. Я бы начал с 22 нанофарад а там посмотрел бы, что получается и подобрал бы такой, который бы меня устроил.
Дело в том, что во собрал методом тыка
// include the library code: #include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins LiquidCrystal lcd(8, 9, 4, 5, 6, 7); byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; void setup(){ pinMode(A1, INPUT); Serial.begin(9600); Serial.println("Start"); lcd.createChar(1, gradus); // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.setCursor(0,0); lcd.print("LCD Key Shield"); } void loop(){ float v = analogRead(A1); Serial.print(v); Serial.print("t"); Serial.print(analog2tempBed(v)); Serial.println(); delay(1000); v/=20; lcd.setCursor(0,1); lcd.print(v); lcd.write(1); //выводим символ градуса lcd.print("C"); } const short temptable_11[][2] PROGMEM = { {1, 841}, {54, 255}, {107, 209}, {160, 184}, {213, 166}, {266, 153}, {319, 142}, {372, 132}, {425, 124}, {478, 116}, {531, 108}, {584, 101}, {637, 93}, {690, 86}, {743, 78}, {796, 70}, {849, 61}, {902, 50}, {955, 34}, {1008, 3} }; # define BEDTEMPTABLE_LEN (sizeof(temptable_11)/sizeof(*temptable_11)) #define PGM_RD_W(x) (short)pgm_read_word(&x) static float analog2tempBed(int raw) { float celsius = 0; byte i; for (i = 1; i < BEDTEMPTABLE_LEN; i++) { if (PGM_RD_W(temptable_11[i][0]) > raw) { celsius = PGM_RD_W(temptable_11[i - 1][1]) + (raw - PGM_RD_W(temptable_11[i - 1][0])) * (float)(PGM_RD_W(temptable_11[i][1]) - PGM_RD_W(temptable_11[i - 1][1])) / (float)(PGM_RD_W(temptable_11[i][0]) - PGM_RD_W(temptable_11[i - 1][0])); break; } } // Overflow: Set to last value in the table if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(temptable_11[i - 1][1]); return celsius; }Выводит температуру --- не очень точно, но меня устраивает "пока"
дело в том, что есть много проектов с уже готовыми термостатами для помещений. они мне подходят, но там везде Даллас
думал что можно часть кода заменить на мой, исключить даллас и все заработает.
вот код определения температуры
КОД ДАТЧИКА (термистора)
void setup(){ pinMode(A1, INPUT); Serial.begin(9600); Serial.println("Start"); } void loop(){ int v = analogRead(A1); Serial.print(v); Serial.print("t"); Serial.print(analog2tempBed(v)); Serial.println(); delay(100); } const short temptable_11[][2] PROGMEM = { {1, 841}, {54, 255}, {107, 209}, {160, 184}, {213, 166}, {266, 153}, {319, 142}, {372, 132}, {425, 124}, {478, 116}, {531, 108}, {584, 101}, {637, 93}, {690, 86}, {743, 78}, {796, 70}, {849, 61}, {902, 50}, {955, 34}, {1008, 3} }; # define BEDTEMPTABLE_LEN (sizeof(temptable_11)/sizeof(*temptable_11)) #define PGM_RD_W(x) (short)pgm_read_word(&x) static float analog2tempBed(int raw) { float celsius = 0; byte i; for (i = 1; i < BEDTEMPTABLE_LEN; i++) { if (PGM_RD_W(temptable_11[i][0]) > raw) { celsius = PGM_RD_W(temptable_11[i - 1][1]) + (raw - PGM_RD_W(temptable_11[i - 1][0])) * (float)(PGM_RD_W(temptable_11[i][1]) - PGM_RD_W(temptable_11[i - 1][1])) / (float)(PGM_RD_W(temptable_11[i][0]) - PGM_RD_W(temptable_11[i - 1][0])); break; } } // Overflow: Set to last value in the table if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(temptable_11[i - 1][1]); return celsius; }Дкмал именно заменить даллас своим
в примере с далласом в первом топике
//Создаем объект sensors, подключенный по OneWireсоздается переменная
sensorsу меня в
-----------
переменная VВот и думаю как грамотно вместоsensors арисать Vв за кандер - спасибо.
думаю главное запустить, а улучшать показатели уже потом буду
Ну, в целом, Вы на верном пути. Может упростить как-то, но идея правильная. Я бы подумал над формулой. Кажется в Excel даже есть сервис - сделать формулу по табоице. И таблицу хранить не надо и проще всё.
Ну, в целом, Вы на верном пути. Может упростить как-то, но идея правильная. Я бы подумал над формулой. Кажется в Excel даже есть сервис - сделать формулу по табоице. И таблицу хранить не надо и проще всё.
Подскажите, что надо сделать в коде программы что бы вместо Далласа использовать свой термистор.
А что непонятно в посте №3? Просто читать analogRead'ом значения и переводить в температуру по таблице или по формуле.
А что непонятно в посте №3? Просто читать analogRead'ом значения и переводить в температуру по таблице или по формуле.
я пытался так как вы советуете, и значение температуры присвоил переменной. но постоянно выдаются ошибки
вот в таком коде заменить
#include <EEPROM.h> #include <OneWire.h> #include <DallasTemperature.h> #include <LiquidCrystal.h> const byte OUT[5] = {13, 12, 11, 3, 2}; // номера выходов byte pos; byte tempOUTon[5]; // массив с температурой включения выхода float tempSensor[5]; // массив куда читается температура byte qty; // количество градусников на шине OneWire oneWire(15); // A1 вход датчиков 18b20 DallasTemperature ds(&oneWire); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte on[8] = { 0b00110, 0b01111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11110, 0b01100 }; void readSet(){ for (byte i = 0; i < qty; i++) tempOUTon[i] = EEPROM.read(i); } void outOff(){ // выключает выходы for (byte i = 0; i < qty; i++) digitalWrite(OUT[i], LOW); } void erorr(){ // останавливает работу программы и сигнализирует ошибку outOff(); // выключаем выходы while(1){ // крутим бесконечный цикл analogWrite(10, 100); delay(500); analogWrite(10, 255); delay(500); } } //// byte key(){ //// для кнопок ЛСДшилда int val = analogRead(0); if (val < 50) return 5; else if (val < 150) return 3; else if (val < 350) return 4; else if (val < 500) return 2; else if (val < 800) return 1; else return 0; } //// void setMenu(byte pos){ // установка температуры outOff(); lcd.clear(); while(1){ // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок lcd.setCursor(2, 0); // выводим на экран lcd.print("Out:"); lcd.print(pos+1); lcd.setCursor(9, 0); lcd.print("Pin:"); lcd.print(OUT[pos]); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" PinON: "); lcd.print(tempOUTon[pos]); lcd.write(1); lcd.print("C <>"); if (KEY == 2) { // если нажата кнопка tempOUTon[pos]--; // изменяем значение if (tempOUTon[pos] > 125) tempOUTon[pos] = 0; EEPROM.write(pos, tempOUTon[pos]); // сохраняем в еепром } else if (KEY == 5){ tempOUTon[pos]++; if (tempOUTon[pos] > 125) tempOUTon[pos] = 0; EEPROM.write(pos, tempOUTon[pos]); } delay(200); }///// }// void getTemp(){ // читаем температуру и заполняем массив ds.requestTemperatures(); for (int i = 0; i < qty; i++) tempSensor[i] = ds.getTempCByIndex(i); } void setup() { Serial.begin(9600); ds.begin(); qty = ds.getDeviceCount(); // количество датчиков на шине if (qty > 5) qty = 5; // if (qty < 5) erorr(); // проверка количества датчиков for (int i = 0; i < qty; i++) pinMode(OUT[i], OUTPUT); for (int i = 0; i < qty; i++) digitalWrite(OUT[i], LOW); lcd.createChar(1, gradus); lcd.createChar(2, on); lcd.begin(16, 2); lcd.clear(); readSet(); // читаем настройки из еепром } void loop() { ///// обработка кнопок if (key() == 1) setMenu(pos); // если нажата селект, уходим в настройки else if (key() == 4 && pos < qty-1) pos++; // крутим позицию else if (key() == 3 && pos != 0) pos--; getTemp(); // читаем температуру с датчиков //// сверяем температуру и управляем выходами for (int i = 0; i < qty; i++) { if (tempSensor[i] < tempOUTon[i]) digitalWrite(OUT[i], HIGH); else digitalWrite(OUT[i], LOW); } /////// вывод инфы на экран lcd.setCursor(0, 0); lcd.print(pos+1); lcd.print(". "); lcd.print(tempSensor[pos], 1); // показываем температуру с датчика lcd.write(1); lcd.print("C "); lcd.setCursor(2, 1); lcd.print(tempOUTon[pos]); // показываем установленную температуру lcd.write(1); lcd.print("C "); lcd.setCursor(11, 0); // рисуем статус выхода for (int i = 0; i < qty; i++){ if (digitalRead(OUT[i])) lcd.write(2); else lcd.print(" "); } lcd.setCursor(11, 1); // рисуем номера выходов for (int i = 0; i < qty; i++) lcd.print(i+1); }Ну, вместо строк 104-107 напишите своё:
//void getTemp(){ // читаем температуру и заполняем массив // ds.requestTemperatures(); // for (int i = 0; i < qty; i++) tempSensor[i] = ds.getTempCByIndex(i); //} void getTemp(){ for (int i=0; i<qty; i++) { tempSensor[i] = convertADC2Temp(analogRead(sensorPins[i])); } }При этом Вам потребуется массив sensorPins в котором должны лежать номера пинов, к которым подключены Ваши сенсоры и функция convertADC2Temp, которая должна принимать параметр - то, что прочиталось analogRead'ом и возвращать темепратуру (по таблице или по формуле - это её дело).
Ну, собственно, всё.
Сможете такую функция сами написать?
Сможете такую функция сами написать?
К сожалению не смогу самостоятельно.
Я только в начале пути освоения ардуино и очень многое не понятно, да почти все. но не унываю и читаю, пробую.
думаю надо как-то включить в этот код переменную V из кода датчика
Сможете такую функция сами написать?
так вы ее уже написали? и надо только вставить 15 вместо i вот тут
то есть должно быть так?
void getTemp(){ for (int i=0; i<qty; i++) { tempSensor[] = convertADC2Temp(analogRead(sensorPins[15])); } }Ну, так-то так, но здесь вызывается функция convertADC2Temp, которую писать надо. Кроме того, здесь используется массив sensorPins, который надо описать и инициализировать.