Проблема последовательной связи программного обеспечения между ESP8266 и Arduino Mega для системы мониторинга растений (с использованием Blynk IoT)

Мы используем ESP8266 для получения данных с платы Arduino Mega, к которой подключены наши датчики. Предположительно, наш ESP подключен к приложению Blynk. Однако значения, отображаемые на нашей панели, равны 0, хотя приложение сообщает, что устройство находится в сети.

Значения датчиков отображаются на нашем ЖК-дисплее, поэтому мы думаем, что проблема в соединении между ESP и Arduino.

Ниже мы прикрепили код ESP и Arduino Mega для справки.

Код ESP:

    #define BLYNK_TEMPLATE_ID           "ID"
    #define BLYNK_TEMPLATE_NAME         "CROPBOX"
    #define BLYNK_AUTH_TOKEN            "TOKEN"

    /* Comment this out to disable prints and save space */
    #define BLYNK_PRINT Serial

    #include <ESP8266WiFi.h>
    #include <BlynkSimpleEsp8266.h>
    #include <SoftwareSerial.h>

    // Ваши учетные данные WiFi.
    // Установите пароль «» для открытых сетей.
    char ssid[] = "WiFi_Name";
    char pass[] = "WiFi_PW";

    // Эта функция вызывается каждый раз, когда устройство подключается к Blynk.Cloud

    SoftwareSerial swSerial(V5, V6);  // RX, TX

    void setup()
    {

    // Консоль отладки
    Serial.begin(9600);
    Serial.println("ESP8266 standalone test");
    swSerial.begin(9600);
    Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
    Serial.print("connecting to WiFi");
    Serial.print(ssid);
    WiFi.begin(ssid, pass);
    Serial.println();
    Serial.print("Connecting");
    while(WiFi.status() != WL_CONNECTED ){
    delay(1000);
    Serial.println(".");
    }
    Serial.print("NodeMCU IP Address:");
    Serial.print(WiFi.localIP());
      
      pinMode(V5, INPUT);
      pinMode(V6, OUTPUT);
    }
    
    void loop()
    {
      
      Blynk.run();
      
      int i = 30;
      swSerial.print(i);
      swSerial.println("\n");
      delay(30);
      // Вы можете внедрить свой собственный код или объединить его с другими набросками.
      // Проверьте другие примеры того, как общаться с Blynk. Запомнить
      // чтобы избежать функции delay()!
      
    }

Код Arduino:

     /* Введите здесь информацию из Blynk Device Info */
    #define BLYNK_TEMPLATE_ID "ID"
    #define BLYNK_TEMPLATE_NAME "CROPBOX"
    #define BLYNK_AUTH_TOKEN "TOKEN"
    
    // Библиотеки
    #include <Wire.h>
    #include <RTClib.h>
    #include <LiquidCrystal_I2C.h>
    #include <DHT.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <HCSR04.h>
    #include <SoftwareSerial.h>
    #include <SD.h> // Включить библиотеку SD для функциональности карты microSD
    #include <BlynkSimpleStream.h>
    #include <Blynk.h>
    
    // Соединения контактов
    #define DHTPIN 2
    #define DHTTYPE DHT11
    #define ONE_WIRE_BUS 4
    #define MQ135_AO A3
    #define MQ135_DO 7
    #define SD_CHIP_SELECT 53 // Контакт 51 в Arduino Mega соответствует контакту 53 для SD_CHIP_SELECT
    #define CS_PIN 53        // Выбор контакта чипа для SD-карты
    #define SCK_PIN 52       // SCK-контакт для SD-карты
    #define MOSI_PIN 51      // MOSI-контакт для SD-карты
    #define MOSO_PIN 50      // MISO-контакт для SD-карты
    
    // Инициализация
    DHT dht(DHTPIN, DHTTYPE);
    float calibration_value = 1 + 0.6;  // pH
    int phval = 0;
    unsigned long int avgval;
    int buffer_arr[10], temp;
    float ph_act;
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    namespace pin {
      const byte tds_sensor = A1;
    }
    namespace device {
      float aref = 4.3;
    }
    namespace sensor {
      float ec = 0;
      unsigned int tds = 0;
      float waterTemp = 0;
      float ecCalibration = 1;
    }
    
    
    UltraSonicDistanceSensor distanceSensor(12, 11);
    RTC_DS3231 rtc;
    LiquidCrystal_I2C lcd(0x27, 16, 2);
    SoftwareSerial s(5, 6);
    String str;
    
    File dataFile;
    
    
    void setup() {
      Serial.begin(9600);
      //ArduinoMega.begin(4800);
      Serial.println("Humidity and Temperature");
      dht.begin();
      sensors.begin();
      if (!rtc.begin()) {
        Serial.println("Couldn't find RTC");
        while (1);
      }
      lcd.begin(16, 2);
      lcd.backlight();
      s.begin(9600);
    
      // Инициализация SD-карты
      if (!SD.begin(SD_CHIP_SELECT)) {
        Serial.println("Initialization failed!");
        return;
      }
      Serial.println("Initialization done.");
    
      // Создать файл на SD-карте, если его нет
      if (!SD.exists("data.txt")) {
        dataFile = SD.open("data.txt", FILE_WRITE);
        if (dataFile) {
          dataFile.close();
          Serial.println("File created.");
        } else {
          Serial.println("Error creating file.");
        }
      }
    }
    
    void loop() {
    
      // Считать все значения датчиков
      float h = readHumidity();
      float t = readAirTemperature();
      float ph = readPH();
      float waterTemp = readWaterTemperature();
      unsigned int tds = readTDS();
      float ec = readEC();
      float distance = readDistance();
      int lightIntensity = readLightIntensity();
      int co2Level = readCO2Level();
      DateTime now = rtc.now();
      
      Blynk.virtualWrite(V1, ec);
      Blynk.virtualWrite(V2, tds);
      Blynk.virtualWrite(V3, waterTemp);
      Blynk.virtualWrite(V4, ph);
      Blynk.virtualWrite(V5, h);
      Blynk.virtualWrite(V6, t);
      Blynk.virtualWrite(V7, distance);
      Blynk.virtualWrite(V8, lightIntensity);
      Blynk.virtualWrite(V9, co2Level);
       
      // Последовательный вывод
      printToSerial(h, t, ph, waterTemp, tds, ec, distance, lightIntensity, co2Level, now);
    
      // Отображение данных на ЖК-дисплее
      LCDisplay(h, t, ph, waterTemp, tds, ec, distance, lightIntensity, co2Level, now);
    
      // Отправить в NodeMCU
      sendToNodeMCU(h, t, ph, waterTemp, tds, ec, distance, lightIntensity, co2Level);
    
      // Запись данных на SD-карту
      writeDataToSDCard(h, t, ph, waterTemp, tds, ec, distance, lightIntensity, co2Level, now);
      
    
      delay(3000);
    }
    
    
    float readHumidity() {
      return dht.readHumidity();
    }
    
    float readAirTemperature() {
      return dht.readTemperature();
    }
    
    float readPH() {
      for (int i = 0; i < 10; i++) {
        buffer_arr[i] = analogRead(A0);
        delay(30);
      }
      for (int i = 0; i < 9; i++) {
        for (int j = i + 1; j < 10; j++) {
          if (buffer_arr[i] > buffer_arr[j]) {
            temp = buffer_arr[i];
            buffer_arr[i] = buffer_arr[j];
            buffer_arr[j] = temp;
          }
        }
      }
      avgval = 0;
      for (int i = 2; i < 8; i++)
        avgval += buffer_arr[i];
      float volt = (float)avgval * 5.0 / 1024 / 6;
      return -5.70 * volt + calibration_value;
    }
    
    float readWaterTemperature() {
      sensors.requestTemperatures();
      return sensors.getTempCByIndex(0);
    }
    
    unsigned int readTDS() {
      sensors.requestTemperatures();
      sensor::waterTemp = sensors.getTempCByIndex(0);
      float rawEc = analogRead(pin::tds_sensor) * device::aref / 1024.0;
      float temperatureCoefficient = 1.0 + 0.02 * (sensor::waterTemp - 25.0);
      sensor::ec = (rawEc / temperatureCoefficient) * sensor::ecCalibration;
      sensor::tds = (133.42 * pow(sensor::ec, 3) - 255.86 * sensor::ec * sensor::ec + 857.39 * sensor::ec) * 0.5;
      return sensor::tds;
    }
    
    float readEC() {
      return sensor::ec;
    }
    
    float readDistance() {
      return distanceSensor.measureDistanceCm();
    }
    
    int readLightIntensity() {
      return analogRead(A2);
    }
    
    int readCO2Level() {
      return analogRead(MQ135_AO);
    }
    
    void LCDisplay(float h, float t, float ph, float waterTemp, unsigned int tds, float ec, float distance, int light, int co2, DateTime now) {
      lcd.clear();
      lcd.print("AirTemp: " + String(t) + "C");
      lcd.setCursor(0, 1);
      lcd.print("AirHumid: " + String(h) + "%");
      delay(2500);
      lcd.clear();
    
      lcd.print("pH: " + String(ph));
      lcd.setCursor(0, 1);
      lcd.print("WtrTemp: " + String(waterTemp) + "C");
      delay(2500);
      lcd.clear();
    
      lcd.print("TDS: " + String(tds) + "ppm");
      lcd.setCursor(0, 1);
      lcd.print("EC: " + String(ec) + " mS/cm");
      delay(2500);
      lcd.clear();
    
      lcd.print("WtrLvl: " + String(distance) + "cm");
      lcd.setCursor(0, 1);
      lcd.print("Light: " + String(light) + " units");
      delay(2500);
      lcd.clear();
    
      lcd.print("CO2: " + String(co2) + " ppm");
      delay(2500);
      lcd.clear();
      
      lcd.print(String(now.day()) + "/" + String(now.month()) + "/" + String(now.year()));
      lcd.setCursor(0, 1);
      lcd.print(String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second()));
      delay(2500);
    }
    
    void readTdsQuick() {
      sensors.requestTemperatures();
      sensor::waterTemp = sensors.getTempCByIndex(0);
      float rawEc = analogRead(pin::tds_sensor) * device::aref / 1024.0;
      float temperatureCoefficient = 1.0 + 0.02 * (sensor::waterTemp - 25.0);
      sensor::ec = (rawEc / temperatureCoefficient) * sensor::ecCalibration;
      sensor::tds = (133.42 * pow(sensor::ec, 3) - 255.86 * sensor::ec * sensor::ec + 857.39 * sensor::ec) * 0.5;
      Serial.print("TDS: ");
      Serial.println(sensor::tds);
      Serial.print("EC: ");
      Serial.println(sensor::ec, 2);
    }
    
    void printToSerial(float h, float t, float ph, float waterTemp, unsigned int tds, float ec, float distance, int lightIntensity, int co2Level, DateTime now) {
      Serial.print("Air Humidity: ");
      Serial.print(h);
      Serial.println("% ");
      Serial.print("Air Temperature: ");
      Serial.print(t);
      Serial.println("C ");
      
      Serial.print("pH Val: ");
      Serial.println(ph);
      
      Serial.print("Water Temperature: ");
      Serial.println(waterTemp);
    
      Serial.print("TDS: ");
      Serial.println(tds);
      
      Serial.print("EC: ");
      Serial.println(ec, 2);
    
      Serial.print("Ultrasonic Distance: ");
      Serial.println(distance);
      
      Serial.print("Light Intensity: ");
      Serial.println(lightIntensity);
      
      Serial.print("CO2 Level: ");
      Serial.println(co2Level);
      
      Serial.print(now.dayOfTheWeek());
      Serial.print(" ");
      Serial.print(now.day(), DEC);
      Serial.print('/');
      Serial.print(now.month(), DEC);
      Serial.print('/');
      Serial.print(now.year(), DEC);
      Serial.print(" -- ");
      Serial.print(now.hour(), DEC);
      Serial.print(':');
      Serial.print(now.minute(), DEC);
      Serial.print(':');
      Serial.println(now.second(), DEC);
    }
    
    void sendToNodeMCU(float h, float t, float ph, float waterTemp, unsigned int tds, float ec, float distance, int lightIntensity, int co2Level) {
      s.print(h, 2);    s.print("A");
      s.print(t, 2);    s.print("B");
      s.print(ph, 2); s.print("C");
      s.print(ec, 2); s.print("D");
      s.print(tds, 2); s.print("E");
      s.print(distance, 2); s.print("F");
      s.print(waterTemp, 2); s.print("G");
      s.print(co2Level); s.print("H");
      s.print("\n");
      delay(500);
    }
    
    void writeDataToSDCard(float h, float t, float ph, float waterTemp, unsigned int tds, float ec, float distance, int light, int co2, DateTime now) {
      // Открыть файл данных в режиме записи
      dataFile = SD.open("data.txt", FILE_WRITE);
      if (dataFile) {
        // Записываем данные датчика в файл
        dataFile.print(h);
        dataFile.print(",");
        dataFile.print(t);
        // Аналогично записываем данные других датчиков
        dataFile.print(",");
        dataFile.print(ph);
        dataFile.print(",");
        dataFile.print(waterTemp);
        dataFile.print(",");
        dataFile.print(tds);
        dataFile.print(",");
        dataFile.print(ec);
        dataFile.print(",");
        dataFile.print(distance);
        dataFile.print(",");
        dataFile.print(light);
        dataFile.print(",");
        dataFile.print(co2);
    
        // Запись временной метки
        dataFile.print(",");
        dataFile.print(now.year(), DEC);
        dataFile.print("/");
        dataFile.print(now.month(), DEC);
        dataFile.print("/");
        dataFile.print(now.day(), DEC);
        dataFile.print(" ");
        dataFile.print(now.hour(), DEC);
        dataFile.print(":");
        dataFile.print(now.minute(), DEC);
        dataFile.print(":");
        dataFile.println(now.second(), DEC);
      
        // Закрыть файл
        dataFile.close();
      } else {
        Serial.println("Error opening data file.");
      }
    }

, 👍2

Обсуждение

Зачем использовать Software Serial, если на обеих этих платах есть дополнительные реальные последовательные порты для использования? SoftwareSerial предназначен для имитации последовательных портов с помощью программного обеспечения, когда у вас нет настоящих. Но у вас остались реальные порты. Они будут работать намного лучше, если вы их используете., @Delta_G

Протестируйте базовый скетч связи, чтобы убедиться, что связь SoftwareSerial между ESP8266 и Arduino Mega работает правильно без интеграции Blynk., @tepalia


1 ответ


0

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

Есть несколько вариантов использования esp8266 для подключения к Blynk.

Один из вариантов — то, что вы пытаетесь сделать. Скетч esp8266 с Blynk, который обменивается данными с основным Arduino. Но вам нужно закодировать обмен. Библиотека Blynk вам в этом не поможет.

Лучшим вариантом будет использовать только плату разработки esp8266, например, Wemos D1 mini или плату NodeMCU, и подключить к ней датчики и приводы. Тогда у вас будет один скетч с Blynk.

Если вам нужно использовать esp8266 только как адаптер WiFi и вам нужен другой Arduino для работы с датчиками, проще поместить прошивку AT в esp8266 и использовать библиотеку WiFi в Arduino. Я рекомендую мою библиотеку WiFiEspAT (доступную в менеджере библиотек). В ней есть пример того, как использовать ее с Blynk. (Я вижу, что пример немного устарел, но он поможет.)

,

Когда я использую команду AT и ввожу «AT» на последовательном мониторе модуля ESP8266, ничего не отображается., @Earth_Lovers

а ты вставил прошивку AT в esp8266? теперь там твой скетч., @Juraj