Проблема последовательной связи программного обеспечения между 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.");
}
}
@Earth_Lovers, 👍2
Обсуждение1 ответ
Это не тот способ использования 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
- Добавление WiFi к моему замку клавиатуры Arduino
- Простой запрос GET с ESP8266HTTPClient
- Что выбрать между датчиками температуры и влажности: AM230x или DHT22?
- Проблемы с подключением I2C на ESP8266 — 12F, какие контакты использовать?
- Загрузка кода Arduino, OTA, через подключенный ESP8266-12E с запущенным Esp-Link
- Почему dtostrf() не работает для этого значения?
- Проблема с WiFi на Mega + WiFi R3 ATmega2560 + ESP8266
- Отправка данных из ESP8266 в PHP
Зачем использовать Software Serial, если на обеих этих платах есть дополнительные реальные последовательные порты для использования? SoftwareSerial предназначен для имитации последовательных портов с помощью программного обеспечения, когда у вас нет настоящих. Но у вас остались реальные порты. Они будут работать намного лучше, если вы их используете., @Delta_G
Протестируйте базовый скетч связи, чтобы убедиться, что связь SoftwareSerial между ESP8266 и Arduino Mega работает правильно без интеграции Blynk., @tepalia