ArduinoIDE + NodeMCU + LCD1602 + I2C

Тема в разделе "Arduino & Shields", создана пользователем daiver, 22 ноя 2016.

  1. daiver

    daiver Нерд

    Добрый день всем!
    Собрал я рабочую модель на Arduino Uno, которая считывает данные с датчика DHT11 и показывает на экране LCD1602_I2C (уже с припаяной платой i2c).
    Затем занялся переносом на NodeMCU v3, с вебсервером.
    Споткнулся я на двух моментах:
    1.Датчик DHT11 сильно врет при 3.3 вольтах. Подскажите как питать модули и датчики от 5 вольт отдельно от NodeMCU. Простенький пример-схема будет достаточно.
    2.Экран не показывает текст. Я скетчем нашел адрес на котором сидит i2c экран, подключил, он реагирует на включение-выключение подсветки, но print не печатает. Либо не хватка питания (хотя 3.3 ему должно хватать), либо что-то с передачей данных, так как IDE пишет предупреждение
    Скетч, который хотел запустить
    Код (C++):
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x3F, 16, 2);

    void setup(void) {
      Serial.begin(115200);

      lcd.init();
      lcd.backlight();
      lcd.setCursor(0, 0);
      lcd.print("test");
      lcd.setCursor(0, 1);
      lcd.print("LCD");

      Serial.println("...ok...");
    }

    void loop(void) {
    }
    В наличии есть MB102, которая выдает 3.3 и/или 5 вольт.
    [​IMG]

    Буду благодарен за ссылки и направление в котором копать!
     
  2. rkit

    rkit Гуру

    1. Питание к пяти вольтам, сигнал через преобразователь логических уровней, земля общая.
    2 Пробовали прочитать, что написано в предупреждении?
     
    daiver нравится это.
  3. daiver

    daiver Нерд

    1. Спасибо! Доп вопрос, подходит ли этот преобразователь для цифровых и аналоговых сигналов? Сигналы SDA и SCL так же надо преобразовывать? (например между ESP и lcd1602)

    2. Да, конечно, прочитал. И даже у гугла спрашивал, но не нашел похожей с моей проблемы. Понимания разницы в видах архитектур у меня нет. Есть куча примеров, даже с картинками, мол берете ESP (в виде ESP01 или NodeMCU) и LCD - и жените их "вот-так". Вроде как у народа нет такой проблемы. Например здесь https://www.losant.com/blog/how-to-connect-lcd-esp8266-nodemcu
     
  4. rkit

    rkit Гуру

    Преобразователь логических уровней, как следует из названия, предназначен для цифровых сигналов.
    Нужен ли он для подключения к дисплею - не знаю. Читайте даташит на дисплей.
     
  5. alp69

    alp69 Гик

    Отдельно потому, что стабилизатор 3.3 в NodeMCU не тянет? Тогда внешние 5 вольт и объединить GND. Поддерживаю rkit.
    Так-то NodeMCU запитывается 5 вольтами. У него на борту 3.3 стабилизатор. Но вот уровни выходов датчиков и NodeMCU нужно будет согласовывать.
    Не хотите ds18b20 использовать? И компактнее, и точнее.
     
    Последнее редактирование: 23 ноя 2016
  6. daiver

    daiver Нерд

    В общем я собрал такую схему:
    Screenshot_2.png

    Input 1 может питаться отдельно, или от компьютера или другого источника
    Input 2 питается от MB102 5v

    Это в режиме разработки. В продакшн input 1 кидаю на Input 2 и все хорошо работает. Датчик DHT-11 перестал врать, экранчик прекрасно себя чувствует.

    Дело получается было в нехватке тока с платы NodeMCU, которая питалась от usb компьютера или повербанка, хотя китайская ардуинка от компьютера нормально питала все модули...
     
    alp69 нравится это.
  7. daiver

    daiver Нерд

    Спасибо за ответ! В схеме я использую ds18b20, но он не считает влажность. С ним проблем нет и не было, показывает хорошие результаты.
    Заказал более точные компоненты: Si7021 для влажности и BMP280 для давления. Думаю от DHT-11 откажусь.

    Скажите пожалуйста, схему которую я собрал без согласования, имеет право на жизнь, или стоит сделать нормально?
     
  8. rkit

    rkit Гуру

    Если работает без сбоев, то пусть живет. Лишнее напряжение будет стекать на питание 8266. На какой-то ущерб этого тока не должно хватить.
     
    daiver нравится это.
  9. daiver

    daiver Нерд

    Спасибо! Я пока продолжу подключать датчики (датчик протечки, датчик движения, температурный ds18b20), посмотрим как все это заработает и на Mosquitto покажет...
     
  10. alp69

    alp69 Гик

    Покажете код? Спортивный интерес :)
     
  11. daiver

    daiver Нерд

    Конечно, может подскажите узкие моменты )))

    Код сырой! Но рабочий =)

    Приложение для андроида сделал на http://ai2.appinventor.mit.edu/

    Screenshot_20161123-154436.png

    Код (C++):
    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266mDNS.h>
    #include <LiquidCrystal_I2C.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include "DHT.h"
    #define DHTTYPE DHT11   // DHT 11
    //#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
    //#define DHTTYPE DHT21   // DHT 21 (AM2301)

    const char* ssid = "Creora.ru";
    const char* password = "12345678";

    const int ledtest = 0;
    const int sensor18b20 = 2;
    const int sensorDHT11 = 5;
    #define DHTPIN 12
    const int sensorLight = 4;
    const int led = 13;
    int ledStatus;

    // VALUES
    int valueDS18B20 = 0;
    int valuesDHT[] = {0, 0, 0};
    int lastupdates[] = {0};

    byte temp_cel[8] = {
      B00010,
      B00101,
      B00010,
      B00000,
      B00000,
      B00000,
      B00000 };

    ESP8266WebServer server(80);
    OneWire oneWire(sensor18b20);
    DallasTemperature DS18B20(&oneWire);
    DHT dht(DHTPIN, DHTTYPE);
    LiquidCrystal_I2C lcd(0x3F, 16, 2);

    ///////////// SETUP //////////////////////////////////////

    void setup(void) {
      pinMode(led, OUTPUT);
      pinMode(ledtest, OUTPUT);
      pinMode(sensorLight, INPUT);
      digitalWrite(led, 0);
      digitalWrite(ledtest, 0);
      Serial.begin(115200);
      WiFi.begin(ssid, password);
      Serial.println("");

      dht.begin();

      lcd.init(); // инициализация LCD
      lcd.createChar(1, temp_cel);
      lcd.backlight(); // включаем подсветку
      lcd.setCursor(0, 0);
      lcd.print("Alexandr P.    C");
      lcd.setCursor(14, 0);
      lcd.print("\1");
      lcd.setCursor(0, 1);
      lcd.print("Creora.ru      %");

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.print("Connected to ");
      Serial.println(ssid);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());

      if (MDNS.begin("esp8266")) {
        Serial.println("MDNS responder started");
      }

      server.on("/", handleRoot);

      server.on("/inline", []() {
        server.send(200, "text/plain", "this works as well");
      });

      server.on("/gpio/0", handleLedOff);
      server.on("/gpio/1", handleLedOn);
      server.on("/gpio", handleLedStatus);
      server.on("/sens1", handleSensorLightStatus);
      server.on("/test.svg", drawGraph);
      server.on("/dht/t", handleSensorDhtT);
      server.on("/dht/h", handleSensorDhtH);
      server.on("/sensorWaterTemperature", handleSensorWaterTemperature);

      server.onNotFound(handleNotFound);

      server.begin();
      Serial.println("HTTP server started");
    }

    /* LOOP */
    void loop(void) {
      server.handleClient();
      loopDHTsensor();
      showValuesOnLCD();
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    void handleRoot() {
      digitalWrite(led, 1);
      char message[400];
      int sec = millis() / 1000;
      int min = sec / 60;
      int hr = min / 60;

      snprintf ( message, 400,

                 "<html>\
     <head>\
       <meta http-equiv='refresh' content='5'/>\
       <title>ESP8266 Demo</title>\
       <style>\
         body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
       </style>\
     </head>\
     <body>\
       <h1>Hello from ESP8266!</h1>\
       <p>Uptime: %02d:%02d:%02d</p>\
       <p>Temperature DS18B20: %02d C</p>\
       <p>Humidity DHT-11: %02d %</p>\
       <p>Temperature DHT-11: %02d C</p>\
       <img src=\"/test.svg\" />\
     </body>\
    </html>"
    ,

                 hr, min % 60, sec % 60, valueDS18B20, valuesDHT[0], valuesDHT[1]
               );
      server.send(200, "text/html", message);
      digitalWrite(led, 0);
    }

    void handleNotFound() {
      digitalWrite(led, 1);
      String message = "File Not Found\n\n";
      message += "URI: ";
      message += server.uri();
      message += "\nMethod: ";
      message += (server.method() == HTTP_GET) ? "GET" : "POST";
      message += "\nArguments: ";
      message += server.args();
      message += "\n";
      for (uint8_t i = 0; i < server.args(); i++) {
        message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
      }
      server.send(404, "text/plain", message);
      digitalWrite(led, 0);
    }

    void handleSensorLightStatus() {
      digitalWrite(led, 1);
      ledStatus = digitalRead(sensorLight);
      String message = String(ledStatus);
      server.send(200, "text/plain", message);
      digitalWrite(led, 0);
    }

    void handleLedStatus() {
      digitalWrite(led, 1);
      ledStatus = digitalRead(ledtest);
      String message = String(ledStatus);
      server.send(200, "text/plain", message);
      digitalWrite(led, 0);
    }

    void handleLedOff() {
      digitalWrite(led, 1);
      digitalWrite(ledtest, 0);
      ledStatus = digitalRead(ledtest);
      String message = String(ledStatus);
      server.send(200, "text/plain", message);
      digitalWrite(led, 0);
    }

    void handleLedOn() {
      digitalWrite(led, 1);
      digitalWrite(ledtest, 1);
      ledStatus = digitalRead(ledtest);
      String message = String(ledStatus);
      server.send(200, "text/plain", message);
      digitalWrite(led, 0);
    }

    void handleSensorWaterTemperature() {
      digitalWrite(led, 1);
      String message = String(valueDS18B20);
      server.send(200, "text/plain", message);
      digitalWrite(led, 0);
    }
    void handleSensorDhtT() {
      digitalWrite(led, 1);
      String message = String(valuesDHT[1]);
      server.send(200, "text/plain", message);
      digitalWrite(led, 0);
    }
    void handleSensorDhtH() {
      digitalWrite(led, 1);
      String message = String(valuesDHT[0]);
      server.send(200, "text/plain", message);
      digitalWrite(led, 0);
    }

    void drawGraph() {
      String out = "";
      char temp[100];
      out += "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"400\" height=\"150\">\n";
      out += "<rect width=\"400\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"1\" stroke=\"rgb(0, 0, 0)\" />\n";
      out += "<g stroke=\"black\">\n";
      int y = rand() % 130;
      for (int x = 10; x < 390; x += 10) {
        int y2 = rand() % 130;
        sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"1\" />\n", x, 140 - y, x + 10, 140 - y2);
        out += temp;
        y = y2;
      }
      out += "</g>\n</svg>\n";

      server.send ( 200, "image/svg+xml", out);
    }

    int getTempDS18B20() {
      DS18B20.requestTemperatures();
      int temp = DS18B20.getTempCByIndex(0);
      return temp;
    }

    void loopDHTsensor() {

      unsigned long currentMillis = millis();
      if (currentMillis - lastupdates[0] >= 5000) {
        //Serial.print(currentMillis);
        //Serial.print(" - ");
        //Serial.println(lastupdates[0]);
        lastupdates[0] = currentMillis;
        getDataFromDHTsensor();

        valueDS18B20 = getTempDS18B20();
      }
    }

    void getDataFromDHTsensor() {
      // Reading temperature or humidity takes about 250 milliseconds!
      // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
      float h = dht.readHumidity();

      valuesDHT[0] = h;

      // Read temperature as Celsius (the default)
      float t = dht.readTemperature();

      valuesDHT[1] = t;

      if (isnan(h) || isnan(t)) {
        Serial.println("Failed to read from DHT sensor!");
        return;
      }

      // Compute heat index in Celsius (isFahreheit = false)
      float hic = dht.computeHeatIndex(t, h, false);

      valuesDHT[2] = hic;

      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" %\t");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.print(" *C ");
      Serial.print("Heat index: ");
      Serial.print(hic);
      Serial.println(" *C ");
    }

    void showValuesOnLCD() {
      int t = valuesDHT[1];
      int h = valuesDHT[0];
      if (isnan(t) || isnan(h)) {
        lcd.setCursor(12, 0);
        lcd.print('--');
        lcd.setCursor(12, 1);
        lcd.print("--");
        return;
      }
      lcd.setCursor(12, 0);
      lcd.print(t);
      lcd.setCursor(12, 1);
      lcd.print(h);
    }
     
     
  12. daiver

    daiver Нерд

    Сейчас в таком состоянии
    20161123_155339.jpg

    Обратить внимание - если не подключится к вайфаю, ничего показывать не будет.
    Сервер для брокера MQTT пока вовсе не готов. Изучаю мат часть.

    Заказал твердотельные реле, если подружу с ESP-01 буду ставить на выключатели в доме...
     
  13. Скажите вы сделали проект с более точными компонентами ?