Два датчика DS18b20 и вывод на Lcd

Thorn
Offline
Зарегистрирован: 07.11.2014

Приветствую форумчан.

Задумал автоматизировать свое аквахозяйство на предмет контроля темпиратур воды и радиаторов светодиодных сборок а также включений самих сборок (без диммирования) и подачи Со2.

Для начала прикупил 2560R3 с Ali тамже  IIC/I2C/TWI/SPI Serial Interface Board к 4-х стрчному дисплею (как потом выяснилось что библиотек к нему найти ой ка как непросто) релюшки и даллас-датчики. Пока жду часики для Ардуино решил с реле незаниматсья а выводить темпиратуры. Почитав форумы понял что датчики можно подключать паралельно и в мониторе найти их адреса. Все получилось и выводится в окне мониторинга порта. Однако при выводе на дисплей я получаю только одну темпиратууру которая выводится в оба поля для t1 и t2. Библотек неприлагаю, так как вопрос исключительно теоретический. Где я упустил код? Собственно вот скетчик 

#include <Wire.h>
#include <LiquidCrystal_I2C.h> 
#include <OneWire.h>

LiquidCrystal_I2C lcd(0x27,20,4);
int TSensorPin = 10;
OneWire ds(TSensorPin); 
//--------------------------------------------------------------
void setup()
{
  digitalWrite(TSensorPin,HIGH); 
  Wire.begin();
  lcd.init(); 
  lcd.setBacklight(1); 
  
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Temp. Controller");
    lcd.setCursor(0, 1);
    lcd.print("      v1.0      ");
    delay(5000);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("t1=");
    lcd.setCursor(10, 1);
    lcd.print("t2=");
} 
//--------------------------------------------------------------
void loop()   
{
  float temp = getTemp();                         
  float temp2 = getTemp();                         
  lcd.setCursor(3, 1);                       
  lcd.print(temp);
  lcd.setCursor(13, 1);                          
  lcd.print(temp2);
 
}

//--------------------------------------------------------------
  float getTemp()  
  {                               
    byte data[12];
    byte addr[8];

   if ( !ds.search(addr)) {                      
        
        lcd.setCursor(0, 0);
        lcd.print("NO more addrss!");

        ds.reset_search();
        return -1001;
     }

    if ( OneWire::crc8( addr, 7) != addr[7]) {
          lcd.setCursor(0, 0);
          lcd.print("CRC is not valid!");
 
        return -1002;
    }

    if ( addr[0] != 0x10 && addr[0] != 0x28) {
          lcd.setCursor(0, 0);
          lcd.print("NOT recognizd!");

        return -1003;
    }

    ds.reset();
    ds.select(addr);
    ds.write(0x44,1); 

    byte present = ds.reset();
    ds.select(addr); 
    ds.write(0xBE); 


    for (int i = 0; i < 9; i++) { 
        data[i] = ds.read();
    }

    ds.reset_search();

    byte MSB = data[1];
    byte LSB = data[0];

    float TRead = ((MSB<<8) | LSB); 
    float Temperature = TRead / 16;

    return Temperature;
}    

 

Araris
Offline
Зарегистрирован: 09.11.2012

Функция getTemp() честно возвращает при каждом вызове температуру первого датчика, все правильно. Для работы с несколькими датчиками есть два пути:

1. Сложный - считывать адреса всех датчиков, сидящих на пине, и обращаться затем к конкретному датчику за температурой.

2. Простой - второй датчик посадить на другой пин и сделать что-то типа

int TSensorPin1 = 10; int TSensorPin2 = 11;

OneWire ds1(TSensorPin1); OneWire ds2(TSensorPin2); , и далее работать с ds1 и ds2.

 

Thorn
Offline
Зарегистрирован: 07.11.2014

Второй я уже немного пробовал, однако решил все-же их на ОДНОМ пине пользовать. Вот таким счетчиком вывожу в монтор порта:

#include <Wire.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <DallasTemperature.h>
 
#define ONE_WIRE_BUS 10
 
OneWire oneWire(ONE_WIRE_BUS);
LiquidCrystal_I2C lcd(0x27,20,4);  
DallasTemperature sensors(&oneWire);
 
DeviceAddress Thermometer1 = { 
  0x28, 0xF2, 0x29, 0xEB, 0x05, 0x00, 0x00, 0xE1 };  //адрес датчика DS18B20 28F229EB050000E1
DeviceAddress Thermometer2 = { 
  0x28, 0x86, 0x48, 0xEA, 0x05, 0x00, 0x00, 0xF6 };   //адрес датчика DS18B20 288648EA050000F6
 
void setup() {
 
  Wire.begin();
  sensors.begin();
  sensors.setResolution(Thermometer1, 10);
  sensors.setResolution(Thermometer2, 10);
  lcd.init();
  lcd.setBacklight(1);    
  Serial.begin(9600);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("t1=");
    lcd.setCursor(10, 1);
    lcd.print("t2=");

}
 
void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);
  Serial.println(tempC);
 lcd.setCursor(3, 1);                            
 lcd.print(tempC);

}
void loop() {
 
  sensors.requestTemperatures();
  Serial.print("Temp1  ");
  printTemperature(Thermometer1);
  Serial.print("Temp2  ");
  printTemperature(Thermometer2);
}

 

Thorn
Offline
Зарегистрирован: 07.11.2014

#include <Wire.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 10

OneWire oneWire(ONE_WIRE_BUS);
LiquidCrystal_I2C lcd(0x27,20,4);
DallasTemperature sensors(&oneWire);

DeviceAddress Thermometer1 = {
0x28, 0xF2, 0x29, 0xEB, 0x05, 0x00, 0x00, 0xE1 }; //адрес датчика DS18B20 28F229EB050000E1
DeviceAddress Thermometer2 = {
0x28, 0x86, 0x48, 0xEA, 0x05, 0x00, 0x00, 0xF6 }; //адрес датчика DS18B20 288648EA050000F6

void setup() {

Wire.begin();
sensors.begin();
sensors.setResolution(Thermometer1, 10);
sensors.setResolution(Thermometer2, 10);
lcd.init();
lcd.setBacklight(1);
Serial.begin(9600);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("t1=");
lcd.setCursor(10, 1);
lcd.print("t2=");

}

void printTemperature(DeviceAddress deviceAddress) {
float tempC = sensors.getTempC(deviceAddress);
Serial.println(tempC);
lcd.setCursor(3, 1);
lcd.print(tempC);

}
void loop() {

sensors.requestTemperatures();
Serial.print("Temp1 ");
printTemperature(Thermometer1);
Serial.print("Temp2 ");
printTemperature(Thermometer2);
}

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Паузы - кто делать будет? Зачем Вам нужна температура с частотой процессора? :) Это на считая того, что там всякие глюки начинают вылезать при частом считывании.

Thorn
Offline
Зарегистрирован: 07.11.2014

Эммм, признаться я полнейший пока "нуль" поэтому если незатруднит покажите что куда добавить. Однако я заметил что вывод значений во вторм моем скетче выглядит "жоско". И по сути - как же выводить второй датчик на дисплей по первому скетчуц (если возможно). Дальше то нужно будет использовать это значение для определния порога срабатывания реле. Дисплей по большому счёту нужен чисто номинально, однако сним намного всё нагляднее.

Thorn
Offline
Зарегистрирован: 07.11.2014

Господа подскажите-же куда добавить строки вида. Каждый датчик на своем пине можно но хочу имеено на одном. Весь инет перерыл - нетолько форум, никто невыводит таким образом. Даже в самомй популярной статейке http://arduino-project.net/podklyuchenie-ds18b20-arduino/ внизу коментарий один единственный с вопросом тоже без ответа.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Если делать хорошо и правильно, надо ваять цикл, сравнивающий текущее значение millis() с заданием таймаута опроса.

...
unsigned long SENSOR_READTIME = 9000;
unsigned long old_millis = 0;
...
void setup() {
...
}

void loop() {
...


/* Collect sensor data */
  if( millis() - old_millis > SENSOR_READTIME ){
    old_millis = millis();

    Serial.println( millis() );

/* Здесь делаем опрос датчиков */

   } # if
...
} # loop

 

Thorn
Offline
Зарегистрирован: 07.11.2014

Попробовал сделать так:

void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);
  Serial.println(tempC);
 lcd.setCursor(3, 1);                            
 lcd.print(tempC);
 lcd.setCursor(13, 1);                            
 lcd.print(tempC);
delay(1000);
}

В итоге темпиратура выводится на оба t1 и t2 однако показания снова равные, и вывод идет сначала первого датчика затем второго, :)

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Thorn пишет:

Попробовал сделать так:

void printTemperature(DeviceAddress deviceAddress) {

В итоге темпиратура выводится на оба t1 и t2 однако показания снова равные, и вывод идет сначала первого датчика затем второго, :)

А зачем Вы все бездумно выносите в одну функцию? Сделайте сначала обычным текстом и для каждого датчика отдельно. Потом будете код оптимизировать...

Thorn
Offline
Зарегистрирован: 07.11.2014

япросто ЛОГИЧЕСКИ немогу понять ПОЧЕМУ в COM- порт выводится все прекрасно и с задержкой между показаниями а на экран иначе. Я так понимаю что получили тмпиратуру с первого t1 -вывели в порт, получили с освторого T2  -вывели. Почему же на LCD выводится только одно значение потом второе/

Кстати последний мой кусочек кода из стандартного ПРИМЕРА уже - я решил его использовать для понимания, но и тут несмог.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Thorn пишет:

япросто ЛОГИЧЕСКИ немогу понять ПОЧЕМУ в COM- порт выводится все прекрасно и с задержкой между показаниями а на экран иначе.

Экран надо принудительно перерисовывать. Выведите два значения в одну строку, но чтобы у каждого было свое знако-место - увидите. Хотя нет, у Вас ошибка в том, что Вы два раза печатаете одну и ту же переменную tempC... А надо - принять от двух датчиков два разных значения в две разные переменные. Или в массив, но в разные позиции элементов.

Thorn
Offline
Зарегистрирован: 07.11.2014

Всё, я сдался. Посадил два датчика на разные пины. Создал 

 

int TSensorPin1 = 10;

int TSensorPin2 = 11;

OneWire ds(TSensorPin); 

OneWire ds2(TSensorPin2);

Далее 

//----------Вывод температуры на ЖК--------------
float temp = getTemp();
float temp2 = getTemp();
lcd.setCursor(3, 1);
lcd.print(temp);
lcd.setCursor(13, 1);
lcd.print(temp2);

Что мне поправить здесь:

float getTemp()                                    //функция чтения значения температуры с датчика DS18B20 по шине OneWire
{                                       
                                   
    byte data[12];
    byte addr[8];

   if ( !ds.search(addr)) {                      
        
        lcd.setCursor(0, 0);
        lcd.print("NO more addrss!");

        ds.reset_search();
        return -1001;
     }

    if ( OneWire::crc8( addr, 7) != addr[7]) {
          lcd.setCursor(0, 0);
          lcd.print("CRC is not valid!");
 
        return -1002;
    }

    if ( addr[0] != 0x10 && addr[0] != 0x28) {
          lcd.setCursor(0, 0);
          lcd.print("NOT recognizd!");

        return -1003;
    }

    ds.reset();
    ds.select(addr);
    ds.write(0x44,1); 

    byte present = ds.reset();
    ds.select(addr); 
    ds.write(0xBE); 


    for (int i = 0; i < 9; i++) { 
        data[i] = ds.read();
    }

    ds.reset_search();

    byte MSB = data[1];
    byte LSB = data[0];

    float TRead = ((MSB<<8) | LSB); 
    float Temperature = TRead / 16;

    return Temperature;
}

 

Thorn
Offline
Зарегистрирован: 07.11.2014
float getTemp()                                    //функция чтения значения температуры с датчика DS18B20 по шине OneWire
{                                       
                                   
    byte data[12];
    byte addr[8];

   if ( !ds.search(addr)) {                      
        
        lcd.setCursor(0, 0);
        lcd.print("NO more addrss!");

        ds.reset_search();
        return -1001;
     }

    if ( OneWire::crc8( addr, 7) != addr[7]) {
          lcd.setCursor(0, 0);
          lcd.print("CRC is not valid!");
 
        return -1002;
    }

    if ( addr[0] != 0x10 && addr[0] != 0x28) {
          lcd.setCursor(0, 0);
          lcd.print("NOT recognizd!");

        return -1003;
    }

    ds.reset();
    ds.select(addr);
    ds.write(0x44,1); 

    byte present = ds.reset();
    ds.select(addr); 
    ds.write(0xBE); 


    for (int i = 0; i < 9; i++) { 
        data[i] = ds.read();
    }

    ds.reset_search();

    byte MSB = data[1];
    byte LSB = data[0];

    float TRead = ((MSB<<8) | LSB); 
    float Temperature = TRead / 16;

    return Temperature;
}

 

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Функции надо передавать адрес термометра. На т о она и функция, что как молоток лежит до поры, до времени, а потом Вы его берете и стучите куда надо.

bwn
Offline
Зарегистрирован: 25.08.2014

Почитайте даташит на DS18 (есть на русском Чернова.Г.), поймете как работать с ним и с шиной.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

попробуй так. у меня все работало

http://arduino.ru/forum/apparatnye-voprosy/ds18b20-pokazyvaet-127#commen...

Thorn
Offline
Зарегистрирован: 07.11.2014

jeka_tm пишет:

попробуй так. у меня все работало

http://arduino.ru/forum/apparatnye-voprosy/ds18b20-pokazyvaet-127#commen...

Ну что сказать, ОГРОМНОЕ спасибо - ничего несказать, всё просто и доступно. Я понимаю МЕГА-Гуру с++ пытаются нам дать удочку а не рыбу, все правильно ОДНАКО - я сделал один проект с помощью или без, да и забыл. Парни ну неужели просто нельзя было "написать" или скопипастить в конце концов правильное решение :)

Я к чему, ниже код и благодаря jeka_tm всё пучком завелось и выводится и в порт и на дисплей. Как привязать значения термодатчиков к реле - другая задумка.

#include <Wire.h>                                    
#include <LiquidCrystal_I2C.h>  
#include <OneWire.h>
LiquidCrystal_I2C lcd(0x27,20,4); 
int TSensorPin = 10;                               
OneWire ds(TSensorPin); 
byte data[12];
byte addr1[8] = {0x28, 0xF2, 0x29, 0xEB, 0x05, 0x00, 0x00, 0xE1};  //адрес датчика DS18B20
byte addr2[8] = {0x28, 0x86, 0x48, 0xEA, 0x05, 0x00, 0x00, 0xF6};  //адрес датчика DS18B20
unsigned int raw;
float temp1, temp2;

void setup() {
  Serial.begin  (9600);
  Wire.begin();  
    lcd.init();                                     
    lcd.setBacklight(1);  
    lcd.clear();
    lcd.setCursor(2, 0);
    lcd.print("Temp. Controller");
    lcd.setCursor(2, 1);
    lcd.print("      v1.0      ");
    delay(3000);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("t1=");
    lcd.setCursor(10, 1);
    lcd.print("t2=");
    lcd.setCursor(8, 3);
    lcd.print("R3=");    
}

void loop(){
  temp1 = DS18B20(addr1);
  temp2 = DS18B20(addr2);
  
  Serial.print("Temp1=");
  Serial.print(temp1);
  Serial.print("\t");
  Serial.print("Temp2=");
  Serial.println(temp2);
  Serial.flush(); 
 lcd.setCursor(3, 1);                       
 lcd.print(temp1);
 lcd.setCursor(13, 1);                          
 lcd.print(temp2);
}

//====================================================================//==================================================================================
//                             Считывание температуры
//====================================================================//==================================================================================
float DS18B20(byte *adres){
  ds.reset();
  ds.select(adres);
  ds.write(0x44,1); // start conversion, with parasite power on at the end
  delay(1000);
  ds.reset();
  ds.select(adres);
  ds.write(0xBE); // Read Scratchpad
  for (byte i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read ();
  }
  raw =  (data[1] << 8) | data[0];//=======Пересчитываем в температуру
  float celsius =  (float)raw / 16.0;
  return celsius;
}

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

или понимаешь вроде все, а код неправильно работает. накололся недавно с радиомодулями

тогда проще дать кусок кода если он есть и писать с нуля не надо

Thorn
Offline
Зарегистрирован: 07.11.2014

Кстати а какой параметр в моем коде задает периоличность опроса темпиратуры и вывод его в (порт и дисплей). А также что задает размер значения температуры после запятой, с моим первым кодом значения значения были вида 25,06......25,12........25,18 тоесть с "точностью" до 0,06 град (хотя сам датчик не точнее 0,5 град вроде :) ) а сейчас 25,00....25,25.....25,50.....

Пока писал вопрос про время замеров temp пробежал по коду и нашёл.

Я добавил вот такой кусочек кода для  отклонения темпиратуры от заданного (чтобы была некая инертность): 



float t0 = 25.5; 
float tGistrsis = 0.5;

А также обработку для реле такой вот кусочек:



if (temp1 < t0-tGistrsis/2)
      {
        digitalWrite(RelayChn3,LOW);               
        lcd.setCursor(11, 3);
        lcd.print("1");
      }     
    else if (temp1 > t0+tGistrsis/2)
      {
        digitalWrite(RelayChn3,HIGH);                
        lcd.setCursor(11, 3);
        lcd.print("0");
      }    

 

Thorn
Offline
Зарегистрирован: 07.11.2014

Теперь хочу, в установленное время подать на вход драйвера PT4115 (восьмая ножка) самый низкий уровень ШИМ,с пина к примеру 25 ардуинки , затем Включить одним из реле (всего их будет штук восемь) одну из трёх линий (подать напряжение на 10 штук 10Вт сборок) и спустя к примеру 10 секи далее поднимать его до значения 255 как я понял это будет соответствовать максимуму горения. Тоесть хочу максимально обесточить все светодиоды (зачем диммировать их если освещение к примеру вообще  ненужно, правильно? )

Все это сделать с небольшим сдвигом для остальных двух. Под сдвигом я понимаю некоторую разницу на включений сборок от задней стенки к передней или от центра. Тоесть сделать некоторое подобие SunSet (расссвет - закат). 

Пока я попробовал самый простой пример, взял пример из скетча про Fade (Изменяем яркость светодиода) и тупо через резистор в 1Ком подал с 11 пина на вход димвхода драйвера светоиода. Получилось, потому как при >0,5В начинает драйвер закрыватсья а при более 2,5В ток через светодиод максимален. Код правда сильно простой да и пробовал я это всё без использования часов а по условию. Ну это уже думаю создать другую ветку в форуме. Всем спасибо, кто пытался достучаться до меня и кто помогал. Всем добра. 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а тут что получилось? должно быть приблизительно также

полградуса это очень точно. рэле может будет часто щелкать если система не инертна, например бак с водой  и водонагревателем сильно инертная система

а керамический резистор ватт на 5 гораздно меньше, хоть и не мгновенно нагревается

можно почитать про пид регулятор

периодичность задаешь ты, но вот время на измерение задано в коде 1000 в функции DS18B20()

можно уменьшить до 750, по даташиту максимальное время измерения с максимальной точностью, насколько помню

хотя для интереса опрашивал каждые 100мс, разницы не заметил, просто смысла так часто опрашивать нет если датчик все равно новое значение температуры выдаст черзе 750мс

 

bwn
Offline
Зарегистрирован: 25.08.2014

При постоянном опросе идет нагрев самого датчика. Точность у него 0,06 градуса, а допустимая погрешность 0,5.

MaxxPDA
Offline
Зарегистрирован: 24.09.2015

Вот мой скетч для вывода температуры на LCD (два датчика на одной ноге)
Я новичок,изучаю Arduino первый день,поэтому не пинайте сильно за код,главное он работает и может кому пригодится.

//скетч от Александра
#include //Подключаем библиотеку для работы с LCD
#include
#include //Подключаем библиотеку датчика температуры
#define ONE_WIRE_BUS 9
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); // инициализируем LCD, указывая управляющие контакты

OneWire OneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&OneWire);

DeviceAddress Thermometer1 = {
0x28, 0xC6, 0x28, 0xEB, 0x05, 0x00, 0x00, 0x1D }; // адрес первого датчика DS18B20
DeviceAddress Thermometer2 = {
0x28, 0xBE, 0x83, 0xEB, 0x05, 0x00, 0x00, 0x67 }; // адрес второго датчика DS18B20

void setup() {

sensors.begin();
sensors.setResolution(Thermometer1, 5);
sensors.setResolution(Thermometer2, 5);

Serial.begin(9600);

lcd.begin(16, 2);// задаем размерность дисплея
lcd.print("Bo" "\xE3" "a"); // выводим на дисплей ВОДА
lcd.setCursor(0, 1); // печатаем вторую строку
lcd.print("Ka" "\xBD" "a" "\xBB" "\xB8\xC7"); // выводим на дисплей КАНАЛИЯ
lcd.setCursor(8, 0); // печатаем вторую строку
lcd.print("ON");
lcd.setCursor(8, 1); // печатаем вторую строку
lcd.print("OFF");
}
// Задаём функцию для первого датчика и выводим на экран
void printTemperature(DeviceAddress deviceAddress) {
float tempC = sensors.getTempC(deviceAddress );
Serial.println(tempC);
lcd.setCursor(12, 0);
lcd.print(tempC);
delay (100);
}
//Задаём функцию для второго датчика и выводим на экран
void printTemperature2(DeviceAddress deviceAddress) {
float tempC = sensors.getTempC(deviceAddress );
Serial.println(tempC);
lcd.setCursor(12, 1);
lcd.print(tempC);
delay (100);
}
void loop() {
sensors.requestTemperatures();
Serial.print("Sensor1 ");
printTemperature(Thermometer1);
Serial.print("Sensor2 ");
printTemperature2(Thermometer2);

}

sharkman89
Offline
Зарегистрирован: 05.01.2018

Уважаемые прошу вашей помощи, использую распространенный скетч

на дисплее отображается температура с сотыми частями, необходимо выводить только целое число.

заранее благодарен!!!

 

/* 
Тестировалось на Arduino IDE 1.6.12
Дата тестирования 23.12.2016г.
*/ 
 
#include <Wire.h>                           // Подключаем библиотеку Wire
#include <LiquidCrystal_I2C.h>              // Подключаем библиотеку LiquidCrystal_I2C 
#include <DallasTemperature.h>              // Подключаем библиотеку DallasTempature
#define DS18B20 2                           // Указываем, к какому выводу подключена DQ
 
byte simvol[8]   = {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000,}; // Символ градуса

LiquidCrystal_I2C lcd(0x3f,16,2);           // Задаем адрес и размер дисплея
OneWire oneWire(DS18B20);                   
DallasTemperature sensors(&oneWire);


 
void setup()
{
  
  sensors.begin();                           // Запуск библиотеки, по умолчанию 9 бит  
  lcd.init();                                // Инициализация lcd    
  lcd.backlight();                           // Включаем подсветку
  lcd.setCursor(2,0);                        // Устанавливаем курсор на 1 строку, ячейка 2
  lcd.print("TEMP");                         // Выводим текст
  lcd.setCursor(2,1);                        // Устанавливаем курсор на 2 строку, ячейка 2 
  lcd.print("www.rchip.ru");                 // Выводим текст
}
void loop()
{
  lcd.createChar(1, simvol);                  // Создаем символ под номером 1
  sensors.requestTemperatures();              // Считываем показания температуры 
  lcd.setCursor(7,0);                         // Устанавливаем курсор на 1 строку, ячейка 7 
  lcd.print(sensors.getTempCByIndex(0));      // Выводим показания температуры
  lcd.setCursor(14,0);                        // Устанавливаем курсор на 1 строку, ячейка 12  
  lcd.print("\1");                            // Выводим символ градуса
  lcd.setCursor(15,0);                        // Устанавливаем курсор на 1 строку, ячейка 13 
  lcd.print("C");                             // Выводим текст 
}

 

MaxxPDA
Offline
Зарегистрирован: 24.09.2015

Используй 

  • floor() — округление вниз
  • ceil() — округление вверх
  • round() — округление в ближайшую сторону
sharkman89
Offline
Зарегистрирован: 05.01.2018

подскажите пожалуйста куда его вставлять)  пока слабоват в програмировании

sharkman89
Offline
Зарегистрирован: 05.01.2018

до смешного дошло, изменил позицию выводимой информации, теперь все в правом углу (21°С), но хотелось бы по правильному решить проблему!!!

void loop()
{
  lcd.createChar(1, simvol);                  // Создаем символ под номером 1
  sensors.requestTemperatures();              // Считываем показания температуры 
  lcd.setCursor(12,0);                         // Устанавливаем курсор на 1 строку, ячейка 7 
  lcd.print(sensors.getTempCByIndex(0));      // Выводим показания температуры
  lcd.setCursor(14,0);                        // Устанавливаем курсор на 1 строку, ячейка 12  
  lcd.print("\1");                            // Выводим символ градуса
  lcd.setCursor(15,0);                        // Устанавливаем курсор на 1 строку, ячейка 13 
  lcd.print("C");                             // Выводим текст 
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

Без округлений: lcd.print(переменная, 0);

Правда 25,9 будет равно 25. Можете просто перед выводом плюсовать 0,5.

MaksVV
Offline
Зарегистрирован: 06.08.2015

можно так ещё без стремной библиотеки даллас

/* 
Тестировалось на Arduino IDE 1.6.12
Дата тестирования 23.12.2016г.
*/ 
#include <OneWire.h> // библиотека для DS18B20
OneWire ds(2); // датчики DS18B20 на 2 пин

byte Sensor_1[8] ={0x28, 0xFF, 0xDA, 0x20, 0x02, 0x15, 0x02, 0x3B}; // адреса датчиков DS18B20 
byte Sensor_2[8] ={0x28, 0xEE, 0x0C, 0x2F, 0x25, 0x16, 0x02, 0xB4}; // их можно узнать залив стандартный пример библиотеки даллас 

volatile int  TempSensor_1 = 20;
volatile int  TempSensor_2 = 20;
volatile int  Temp_Sensor_1 = 20;
volatile int  Temp_Sensor_2 = 20;




 
#include <Wire.h>                           // Подключаем библиотеку Wire
#include <LiquidCrystal_I2C.h>              // Подключаем библиотеку LiquidCrystal_I2C 

 
byte simvol[8]   = {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000,}; // Символ градуса

LiquidCrystal_I2C lcd(0x3f,16,2);           // Задаем адрес и размер дисплея



 
void setup()
{
  WDTCSR=(1<<WDCE)|(1<<WDE); //для датчиков DS18B20
  WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0); // для датчиков DS18B20 (разрешение прерывания + выдержка 8 секунд)
  
  lcd.init();                                // Инициализация lcd    
  lcd.backlight();                           // Включаем подсветку
  lcd.setCursor(2,0);                        // Устанавливаем курсор на 1 строку, ячейка 2
  lcd.print("TEMP");                         // Выводим текст
  lcd.setCursor(2,1);                        // Устанавливаем курсор на 2 строку, ячейка 2 
  lcd.print("www.rchip.ru");                 // Выводим текст
}
void loop()
{
  lcd.createChar(1, simvol);                  // Создаем символ под номером 1
            
  lcd.setCursor(7,0);                         // Устанавливаем курсор на 1 строку, ячейка 7 
  lcd.print(Temp_Sensor_1);      // Выводим показания температуры
  lcd.setCursor(14,0);                        // Устанавливаем курсор на 1 строку, ячейка 12  
  lcd.print("\1");                            // Выводим символ градуса
  lcd.setCursor(15,0);                        // Устанавливаем курсор на 1 строку, ячейка 13 
  lcd.print("C");                             // Выводим текст 
}

// Ниже Считываем показания температуры раз в 8 сек 

ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();  // сброс шины
        ds.write(0xCC);//обращение ко всем датчикам
        ds.write(0x44);// начать преобразование (без паразитного питания)  
       }
else   {ds.reset();
        ds.select(Sensor_1);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSensor_1 =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempSensor_1 = TempSensor_1 / 16;
        if (TempSensor_1 == -127 || TempSensor_1 == 85){
        ds.reset();
        ds.select(Sensor_1);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSensor_1 =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempSensor_1 = TempSensor_1 / 16;}
        
        ds.reset();
        ds.select(Sensor_2);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSensor_2 =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempSensor_2 = TempSensor_2/16;
        if (TempSensor_2 == -127 || TempSensor_2 == 85){
        ds.reset();
        ds.select(Sensor_2);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSensor_2 =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempSensor_2 = TempSensor_2/16;}
        
}
   if  (TempSensor_1 < 150 && TempSensor_1 > -50 && TempSensor_1!= 85 ) Temp_Sensor_1 = TempSensor_1;
   if  (TempSensor_2 < 150 && TempSensor_2 > -50 && TempSensor_2!= 85 ) Temp_Sensor_2 = TempSensor_2;

}

 

radiator
Offline
Зарегистрирован: 09.11.2018

Огромное спасибо всем, кто здесь обитает. Благодаря Вам, оптимизировал под себя вывод температуры с 2-х датчиков ds18b20на LCD 1602

упростил скетч до минимума и вот что у меня получилось:

#include <Wire.h>                                    
#include <LiquidCrystal_I2C.h>  
#include <OneWire.h>
LiquidCrystal_I2C lcd(0x3F,16,2); 
int TSensorPin = 2;     //Номер пина, на котором сидят датчики температуры                          
OneWire ds(TSensorPin); 
byte data[12];
byte addr1[8] = {0x28, 0xFF, 0x04, 0x6E, 0x04, 0x17, 0x03, 0x2C};  //адрес 1 датчика DS18B20 
byte addr2[8] = {0x28, 0xFF, 0x51, 0xD9, 0xA1, 0x17, 0x05, 0x62};  //адрес 2 датчика DS18B20
unsigned int raw;
float temp1, temp2;  //если не нужны сотые доли градуса, а только целые значения, меняете float на byte

void setup() {
   Wire.begin();  
    lcd.init();                                     
    lcd.setBacklight(1);  
    lcd.clear();
    lcd.setCursor(0, 0);  //отображение первой температуры на LCD сначала верхней строки.
    lcd.print("t1=");
    lcd.setCursor(0, 1);  //отображение второй температуры на LCD сначала нижней строки.
    lcd.print("t2=");
     
}

void loop(){
  temp1 = DS18B20(addr1);
  temp2 = DS18B20(addr2);
  
 lcd.setCursor(3, 0);                       
 lcd.print(temp1);
 lcd.setCursor(3, 1);                          
 lcd.print(temp2);
}

//====================================================================//==================================================================================
//                             Считывание температуры
//====================================================================//==================================================================================
float DS18B20(byte *adres){
  ds.reset();
  ds.select(adres);
  ds.write(0x44,1); 
  delay(200);
  ds.reset();
  ds.select(adres);
  ds.write(0xBE); 
  for (byte i = 0; i < 9; i++) { 
    data[i] = ds.read ();
  }
  raw =  (data[1] << 8) | data[0];
  float celsius =  (float)raw / 16.0;
  return celsius;
}

Извиняюсь, не знаю как убрать под кат.

У меня все это работает на связке ESP8266 NodeMCU + 2 DS18B20+LCD1602_I2C

radiator
Offline
Зарегистрирован: 09.11.2018

Подскажите, кто знает, как в последнем скетче выводить на LCD1602 не сотые, а десятые доли градуса?

В 50 строке поменял (float)raw / 16.0 на (float)raw / 10.0 , но на экране LCD сотые доли отображаются как нули, но мне надо убрать именно эти нули.

спасибо заранее.

b707
Онлайн
Зарегистрирован: 26.05.2017

radiator пишет:

Подскажите, кто знает, как в последнем скетче выводить на LCD1602 не сотые, а десятые доли градуса?

В 50 строке поменял (float)raw / 16.0 на (float)raw / 10.0 , но на экране LCD сотые доли отображаются как нули, но мне надо убрать именно эти нули.

спасибо заранее.

вы офигели? вам не пришло в голову. что если поменять  (float)raw / 16.0 на (float)raw / 10.0 - датчик будет выдавать совершенно неверные значения?? - математику в школе прогуливали?

Изменение количества цифр, выводимых на дисплей - настраивается в коде дисплея, а не в коде получения температуры с датчика. Например так:

lcd.print(temperature, 1);

radiator
Offline
Зарегистрирован: 09.11.2018

b707 пишет:

вы офигели? вам не пришло в голову. что если поменять  (float)raw / 16.0 на (float)raw / 10.0 - датчик будет выдавать совершенно неверные значения?? - математику в школе прогуливали?

Каюсь, с математекой не дружу)))

 

b707 пишет:
Изменение количества цифр, выводимых на дисплей - настраивается в коде дисплея, а не в коде получения температуры с датчика. Например так:

lcd.print(temperature, 1);

Спасибо, попробую.

radiator
Offline
Зарегистрирован: 09.11.2018

Благодаря b707 удалось вывести на LCD температуру с датчиков до десятых долей градуса.

вот кусок измененного кода:

 lcd.setCursor(3, 0);                       
 lcd.print(temp1 ,1); //если нужны сотые доли градуса нужно убрать ,1
 lcd.setCursor(3, 1);                          
 lcd.print(temp2 ,1); //если нужны сотые доли градуса нужно убрать ,1
bwn
Offline
Зарегистрирован: 25.08.2014

Если нужны сотые, написать двойку, а тысячные, тройку и т.д.

b707
Онлайн
Зарегистрирован: 26.05.2017

bwn пишет:

Если нужны сотые, написать двойку, а тысячные, тройку и т.д.

и главное - на этот вопрос в ветке вы уже отвечали 10 сообщениями выше :)

bwn
Offline
Зарегистрирован: 25.08.2014

b707 пишет:

bwn пишет:

Если нужны сотые, написать двойку, а тысячные, тройку и т.д.

и главное - на этот вопрос в ветке вы уже отвечали 10 сообщениями выше :)

Хм, и впрямь. Что делать, в башке уже только локальные переменные умещаются, да и те без статика.))))

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

bwn пишет:

Если нужны сотые, написать двойку, а тысячные, тройку и т.д.


Предлагаю четвёрку - точность сразу будет в десятитысячных!
Про пятёрку я вообще молчу......

bwn
Offline
Зарегистрирован: 25.08.2014

trembo пишет:

Предлагаю четвёрку - точность сразу будет в десятитысячных! Про пятёрку я вообще молчу......[/quote]

А что не так? Мне на ректификаторе в коллоне три знака отображает (можно два, но и четыре для него допустимо), а в баке и целых значений достаточно.