18B20+ LCD1602 I2C

Тема в разделе "Arduino & Shields", создана пользователем vitek73, 25 окт 2015.

  1. vitek73

    vitek73 Нуб

    Не могу разобратца с выводом данных на 1602,
    кто подскажет как это исправтить?
    на монитор выводитца ,но вот на дисплей вывести пока нехватает мыслей как воплотить.

    Код (C++):

    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS 9 // датчик подключен к пин 9
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    DeviceAddress Thermometer1 = {
      0x28, 0x7E, 0x7B, 0xB9, 0x05, 0x00, 0x00, 0xBF};  // 3точки
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup() {
      lcd.init();                      // initialize the lcd
      lcd.init();
      lcd.backlight();

      sensors.begin();
      sensors.setResolution(Thermometer1, 10);
      Serial.begin(9600);
    }

    void printTemperature(DeviceAddress deviceAddress) {
      float tempC = sensors.getTempC(deviceAddress);
      Serial.println(tempC);
    }
    void loop() {
      sensors.requestTemperatures();
      Serial.print("T1 ");
      lcd.setCursor(0, 0);
      lcd.print("tempC");
    // lcd.println (T1);// не фурычит
    // lcd.println (Thermometer1);// не фурычит

      printTemperature(Thermometer1);

    }
     
  2. FlyingKot

    FlyingKot Нерд

    lcd.println - и не будет работать.
    tempC - вынеси в глобальные переменные (перед void setup):

    float tempC;

    и вместо этого всего барахла впиши следующее:

    void printTemperature(DeviceAddress deviceAddress){
    tempC = sensors.getTempC(deviceAddress);
    Serial.println(tempC);
    }

    void loop () {
    sensors.requestTemperatures();
    printTemperature(Thermometer1);
    lcd.setCursor(0, 0); //устанавливаем курсор в начальную позицию (строка 0, колонка 0)
    lcd.print("Temp: ");
    lcd.print(int(tempC)); // если надо выводить знаки после запятой - убери инт и скобки вокруг переменной
    lcd.print(" *C");
    }
     
    Последнее редактирование: 27 окт 2015
    vitek73 нравится это.
  3. vitek73

    vitek73 Нуб

    Спасибо ваш пример заработал, но когда я попробовал зацепить остальные датчики, выдаёт непонятно что,
    Код (C++):
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS 9 // датчик подключен к пин 9
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    DeviceAddress Thermometer1 = {
      0x28, 0x7E, 0x7B, 0xB9, 0x05, 0x00, 0x00, 0xBF};  // 3точки
    DeviceAddress Thermometer2 = {
      0x28, 0xE9, 0x46, 0xB9, 0x05, 0x00, 0x00, 0xE3 }; // 2точки
    DeviceAddress Thermometer3 = {
      0x28, 0x45, 0xC3, 0xB8, 0x05, 0x00, 0x00, 0x54 }; // 1точки
    DeviceAddress Thermometer4 = {
      0x28, 0x9A, 0xD4, 0xB9, 0x05, 0x00, 0x00, 0x16 }; // синий

    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup() {
      lcd.init();                      // initialize the lcd
      lcd.init();
      lcd.backlight();

      sensors.begin();
      sensors.setResolution(Thermometer1, 10);
       sensors.setResolution(Thermometer2, 10);
      sensors.setResolution(Thermometer3, 10);
      sensors.setResolution(Thermometer4, 10);  
      Serial.begin(9600);
    }
    float tempC;
    void printTemperature(DeviceAddress deviceAddress) {
    //  float tempC = sensors.getTempC(deviceAddress);
    tempC = sensors.getTempC(deviceAddress);
      Serial.println(tempC);
    }
    void loop() {
      sensors.requestTemperatures();
      printTemperature(Thermometer1);
      printTemperature(Thermometer2);
      printTemperature(Thermometer3);
      printTemperature(Thermometer4);
    //  Serial.print("T1 ");
      lcd.setCursor(0, 0);
      lcd.print(" T1-");
      // тобиш на монитор с этих датчиков выдаёт чётко 25.60
      // а на дисплей какуюто фигню.
      lcd.print(int(Thermometer1));//вместо 25 выводит 280
    //lcd.print(int(tempC)); // если надо выводить знаки после запятой - убери инт и скобки вокруг переменной
      lcd.print(" T2-");
    lcd.print(int(Thermometer2));//вместо 25 выводит 272
      lcd.setCursor(0, 1);
      lcd.print(" T3-");//вместо 25 выводит 264
    lcd.print(int(Thermometer3)); // если надо выводить знаки после запятой - убери инт и скобки вокруг переменной
      lcd.print(" T4-");
    lcd.print(int(Thermometer4));//вместо 25 выводит 256
    // lcd.println (T1);// не фурычит
    // lcd.println (Thermometer1);// не фурычит

    // printTemperature(Thermometer1);

    }
     
  4. FlyingKot

    FlyingKot Нерд

    Значит так. Ты вызываешь функцию printTemperature несколько раз подряд, задавая адрес термометра в качестве входного параметра. В самой функции у тебя переменная tempC получает значение. Но дальше ты ее нигде не используешь, а пытаешься на экран вывести значение своего адреса (содержимое константы Thermometer1..4). Ясен пень у тебя прога будет показывать уровень дождей в Китае вместо температуры на датчиках.

    Ты или сделай так:
    printTemperature(Thermometer1);
    lcd.print("T1 - ");
    lcd.print(tempC);
    delay(2000);
    lcd.clear();
    printTemperature(Thermometer2);
    lcd.print("T2 - ");
    lcd.print(tempC);
    delay(2000);
    lcd.clear();
    и так далее до конца своих термометров
    или посмотри ниже

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

    Код (C++):
    // include the library code:
    #include <DallasTemperature.h>
    #include <OneWire.h>

    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 20, 4);// set the LCD address to 0x27 for a 16 chars and 2 line display

    // I2C на пине 8 - используй свою распиновку
    #define TEMP_WIRE_BUS 8
    OneWire tempWire(TEMP_WIRE_BUS); //объявили переменную датчиков
    DallasTemperature TempSensors(&tempWire); //объявили структуру типа Даллас термометр

    // define variables
    float tempSensor[5]; // массив куда читается температура c датчиков. У меня 5 штук, соответсвенно массив на 5 элементов. Если больше - меняется цифра.
    byte qty; // количество градусников на шине. Оставил динамической, чтоб менять число датчиков лишь в массиве.
    byte gradus[8] = {
      0b00110,
      0b01001,
      0b01001,
      0b00110,
      0b00000,
      0b00000,
      0b00000,
      0b00000
    }; // символ градуса

    // /////////////////////////////////////////////////////////////////
    void getTemp(){ // читаем температуру и заполняем массив
      TempSensors.requestTemperatures(); //команда сенсорам заполнить свою память новыми данными
       for (int i = 0; i < qty; i++) tempSensor[i] = TempSensors.getTempCByIndex(i);//в цикле заполняем массив полученными данными, уже приведенными к градусам Цельсия.
    }
    // /////////////////////////////////////////////////////////////////

    // /////////////////////////////////////////////////////////////////
    void printData(){
      /////// вывод инфы на экран
       for (int i = 0; i < qty; i++) {
            lcd.setCursor(0, 0);
            lcd.print("Sensor");
            lcd.print(i);
            lcd.print(": ");
            lcd.print(int(tempSensor[i]));  // показываем температуру с датчика
            lcd.write(1);
            lcd.print("C");
            lcd.setCursor(0, 1);
            lcd.print("Sensors: "); // число датчиков
            lcd.print(qty);
            delay(2000); //2 сек пауза
        }
    }
    // /////////////////////////////////////////////////////////////////

    // ////////////////////////////////////////////////////////////////////
    void setup() {
      TempSensors.begin(); //инициализируем сенсоры
      qty = TempSensors.getDeviceCount(); // количество датчиков на шине
      lcd.init();
      lcd.createChar(1, gradus);// создаем символ градуса
      Serial.begin(9600);//инициализируем серийный порт
    }
    // //////////////////////////////////////////////////////////////////

    // /////////////////////////////////////////////////////////////////
    void loop() {
      getTemp(); // читаем температуру с датчиков
      lcd.clear();//очистили экран от предыдущего вывода
      printData();//печатаем данные
    }
    // /////////////////////////////////////////////////////////////////
    пробуй, разбирайся.
     
    Последнее редактирование: 29 окт 2015
  5. vitek73

    vitek73 Нуб

    Попробовал он показывает температуру с одного и того же датчика на четырёх термометрах
    и похоже строчки
    printTemperature(Thermometer2);
    наверно адрес, потомучто значение у них постоянное и от температуры не меняетца, и на каждом датчике своё, чето неполучаетца этот лего собрать, ))) а в нижнем примере у вас сканирование адресов датчика, а мне надо чтоб они были постоянные и не менялись если вдруг я их местами меняю,
    Код (C++):
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS 9 // датчик подключен к пин 9
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensorss(&oneWire);
    DeviceAddress Thermometer1 = {
      0x28, 0x7E, 0x7B, 0xB9, 0x05, 0x00, 0x00, 0xBF};  // 3точки
    DeviceAddress Thermometer2 = {
      0x28, 0xE9, 0x46, 0xB9, 0x05, 0x00, 0x00, 0xE3 }; // 2точки
    DeviceAddress Thermometer3 = {
      0x28, 0x45, 0xC3, 0xB8, 0x05, 0x00, 0x00, 0x54 }; // 1точки
    DeviceAddress Thermometer4 = {
      0x28, 0x9A, 0xD4, 0xB9, 0x05, 0x00, 0x00, 0x16 }; // синий

    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup() {
      lcd.init();                      // initialize the lcd
      lcd.init();
      lcd.backlight();

      sensorss.begin();
      sensorss.setResolution(Thermometer1, 10);
       sensorss.setResolution(Thermometer2, 10);
      sensorss.setResolution(Thermometer3, 10);
      sensorss.setResolution(Thermometer4, 10);
      Serial.begin(9600);
    }
    float tempC;
    void printTemperature(DeviceAddress deviceAddress) {
    //  float tempC = sensorss.getTempC(deviceAddress);
    tempC = sensorss.getTempC(deviceAddress);
      Serial.println(tempC);
    }
    /////////////////////
    void loop() {
      start:
      sensorss.requestTemperatures();
      printTemperature(Thermometer1);
      printTemperature(Thermometer2);
      printTemperature(Thermometer3);
      printTemperature(Thermometer4);
    //  Serial.print("T1 ");
    lcd.clear();
      lcd.setCursor(0, 0);
      // тобиш на монитор с этих датчиков выдаёт чётко 25.60
      // а на дисплей какуюто фигню.
    lcd.print(int(Thermometer1));//вместо 25 выводит 280
    // lcd.print(float(Thermometer1,DEC));//вместо 25 выводит 280
      lcd.print(" T1-");
      lcd.print(tempC);//вместо 25 выводит 280
      delay (5000);
        lcd.setCursor(0, 1);
      // тобиш на монитор с этих датчиков выдаёт чётко 25.60
      // а на дисплей какуюто фигню.
      lcd.print(int(Thermometer2));//вместо 25 выводит 272
      lcd.print(" T2-");
      lcd.print(tempC);//вместо 25 выводит 280
      delay (5000);
    lcd.clear();
        lcd.setCursor(0, 0);
      // тобиш на монитор с этих датчиков выдаёт чётко 25.60
      // а на дисплей какуюто фигню.
      lcd.print(int(Thermometer3));//вместо 25 выводит 280
      lcd.print(" T3-");
      lcd.print(tempC);//вместо 25 выводит 264
      delay (5000);
            lcd.setCursor(0, 1);
      // тобиш на монитор с этих датчиков выдаёт чётко 25.60
      // а на дисплей какуюто фигню.
      lcd.print(int(Thermometer4));//вместо 25 выводит 256
      lcd.print(" T4-");
      lcd.print(tempC);//вместо 25 выводит 280
      delay (5000);
     
    //   lcd.print(sensorss);
    goto start;
    ////////////////////////////////////////////
     
    //lcd.print(int(tempC)); // если надо выводить знаки после запятой - убери инт и скобки вокруг переменной
      lcd.print(" T2-");
    lcd.print(int(Thermometer2));//вместо 25 выводит 272
      lcd.setCursor(0, 1);
      lcd.print(" T3-");//вместо 25 выводит 264
    lcd.print(int(Thermometer3)); // если надо выводить знаки после запятой - убери инт и скобки вокруг переменной
      lcd.print(" T4-");
    lcd.print(int(Thermometer4));//вместо 25 выводит 256
    // lcd.println (T1);// не фурычит
    // lcd.println (Thermometer1);// не фурычит

    // printTemperature(Thermometer1);

    }
     
  6. Vetrinus

    Vetrinus Гик

    В скетчи сильно не вникал, но, т.к. имел дело с lcd дисплеями, и ds18b20, могу посоветовать подумать в направлении вот таком.
    Запрашиваешь температуру с датчика с помощью
    Код (C++):
    void printTemperature(DeviceAddress deviceAddress) {
    tempC = sensorss.getTempC(deviceAddress);
      Serial.println(tempC);
    а переменную tempC сделай глобальной(для того, чтобы была видима не только внутри printTemperature). Сразу после запроса выведи данные на дисплей, и уже далее запрашивай температуру с другого датчика, и у тебя в tempC будут данные с другого датчика уже. Теперь снова выведи их на дисплей.
    Могу ошибаться)))
    Кстати, зачем тебе goto start?
     
  7. FlyingKot

    FlyingKot Нерд

    Так. Еще раз. По порядку. Ты собираешь цепь. Датчики у тебя уже штатно установлены и на каждом свое значение или лежат рядом на этапе тестирования? Тогда у них у всех одно значение и будет (плюс-минус погрешность). Попробуй разнести их и один греть, второй заморозить, чтоб точно знать - ху из ху. Тогда будет яснее.
    Далее. Тот кусок кода, где ты 4 раза подряд вызываешь printTemperature - 4 раза подряд он присвоит переменной cTemp значение термометра, адрес которого ты передаешь в функцию в качестве параметра. Но ты ее нигде дальше в своем коде не пользуешь кроме вывода в сериал порт. А на экран пытаешься вывести адрес своего градусника в десятичном формате. Что у тебя в сериал порт выдает в таком случае? Сделай скрин хотя бы своей сборки и результатов работы программы. А то пока что похоже на удаление аппендицита по телефону.
     
  8. FlyingKot

    FlyingKot Нерд

    Ну у него cTemp и так глобальная, так что с получением и выводом данных при правильной сборке не должно быть, если правильно код написан. А вот с кодом тут проблема как раз.
     
  9. vitek73

    vitek73 Нуб

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

    vitek73 Нуб

    [​IMG] Так на монитор то вижу расхождение тобиш если ггрею дотчик, то и температура меняетца на всех,поскольку они рядушком, но всё равно есть разница в пару градусов , а на lcd выводит 4 раза одну и туже температуру, она падает и получаетца что такаяже температура и на 3х остальных, а на мониторе всё чётко, падает на одном, а на других которые не грел ,чуток уже другая, и все 4 показывают разную температуру,(на мониторе) щя буду колдовать со своими ляпами )
     
  11. vitek73

    vitek73 Нуб

    Спасибо народ ваши подсказки сработали, я с кодом лоханулся, ну яж пока учюсь, т буду делать дальше, всё заработало как надо, ))как оделаю проект выложу на обозрение ну или на одобрение ))