Замена Dallas DS18B20

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

Добрый день.

 

нахожу много примеров термостата на Ардуино и везде используется Dallas DS18B20

Но на моем термостате будет балансироваться температура в районе 250 С и даллас такое не тянет.

И я не представляю как изменить код в скетче что бы избавиться от загрузки DallasTemperature.h

Подозреваю, что сабака порылась тут

#include <OneWire.h>
OneWire oneWire(15);

//Подключаем библиотеку для работы с термометром
#include <DallasTemperature.h>

//Создаем объект sensors, подключенный по OneWire
DallasTemperature sensors(&oneWire);

Но вот как прописать съем инфы с датчика отличного от даллас?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

konsys пишет:

датчика отличного от даллас?

Какого датчика? ХЗ!

Как он подключён? ХЗ!

konsys пишет:

Но вот как прописать съем инфы

Тогда, это тоже ХЗ!

 

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

Датчик термистор NTS 3950 100K

подключен по схеме

где U подсоединен к аналоговому входу А1

 

Вы уж извиняйте нуба - я только начал пробовать работать с Ардуино

и даже вопросы иногда не корректно формулирую                                                     .

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, так Вам надо его отградуировать. Для этого Вам нужно иметь доступ к эталонному термометру. Читайте значение с входа А1 функцией analogRead(1), печатайте прочитанное значение и составляйте таблицу "температура - значение". Как составите - вот Вам и будет датчик. Потом будете считывать показание и по таблице узнавать температуру (или формулу придумайте, глядя на таблицу).

Я бы ещё поставил конденсатор между А1 и землёй, чтобы сгладить показания, а то скакать будут. Какой? Тут нужен компромисс - чем больше конденсатор, тем глаже показания (меньше скачут), но тем больше задержка в реакции. Я бы начал с 22 нанофарад а там посмотрел бы, что получается и подобрал бы такой, который бы меня устроил.

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

Дело в том, что во собрал методом тыка

  // 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;
}

Дкмал именно заменить даллас своим

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

в примере с далласом в первом топике

//Создаем объект sensors, подключенный по OneWire

   
DallasTemperature sensors(&oneWire);

создается переменная sensors

у меня в

int v = analogRead(A1);

-----------

переменная V

Вот и думаю как грамотно вместо sensors арисать V

в за кандер  - спасибо.

думаю главное запустить, а улучшать показатели уже потом буду

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, в целом, Вы на верном пути. Может упростить как-то, но идея правильная. Я бы подумал над формулой. Кажется в Excel даже есть сервис - сделать формулу по табоице. И таблицу хранить не надо и проще всё.

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

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

Ну, в целом, Вы на верном пути. Может упростить как-то, но идея правильная. Я бы подумал над формулой. Кажется в Excel даже есть сервис - сделать формулу по табоице. И таблицу хранить не надо и проще всё.

 

Подскажите, что надо сделать в коде программы что бы вместо Далласа использовать свой термистор.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А что непонятно в посте №3? Просто читать analogRead'ом значения и переводить в температуру по таблице или по формуле.

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

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

А что непонятно в посте №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); 

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, вместо строк 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'ом и возвращать темепратуру (по таблице или по формуле - это её дело).

Ну, собственно, всё.

Сможете такую функция сами написать?

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

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

Сможете такую функция сами написать?

К сожалению не смогу самостоятельно.

Я только в начале пути освоения ардуино и очень многое не понятно, да почти все. но не унываю и читаю, пробую.

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

думаю надо как-то включить в этот код переменную V из кода датчика

konsys
konsys аватар
Offline
Зарегистрирован: 04.07.2016

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

Сможете такую функция сами написать?

так вы ее уже написали? и надо только вставить 15 вместо i  вот тут

tempSensor[i] = convertADC2Temp(analogRead(sensorPins[i]));

 

то есть должно быть так?

	void getTemp(){

	   for (int i=0; i<qty; i++) {

	         tempSensor[] = convertADC2Temp(analogRead(sensorPins[15]));

	   }

	}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, так-то так, но здесь вызывается функция convertADC2Temp, которую писать надо. Кроме того, здесь используется массив sensorPins, который надо описать и инициализировать.