Сторона сервера NodeMCU не может отправлять данные на сторону клиента — подключено несколько клиентов

Технически мне нужна ваша помощь, когда я работаю над своим проектом, я обнаружил, что моя серверная часть не может отправлять данные на клиентскую сторону, моя серверная часть сделана с помощью WiFiServer(80) так что, когда моя клиентская сторона выполняет client.print, она может отправлять на серверную сторону, а серверная сторона просто легко отправляет на сторону Python с помощью Serial, и Python все еще может отправить его на серверную сторону, но серверная сторона не может отправить его на клиентскую сторону. Базовый код взят с этой страницы

  1. Код сервера

Вот код:

#include <SPI.h>
#include <ESP8266WiFi.h>
#define led LED_BUILTIN
char ssid[] = "AP";
char pass[] = "Science_Fair";
WiFiServer server(80);
WiFiClient client;
IPAddress ip(10, 241, 241, 27);
IPAddress gateway(10, 241, 241, 254);
IPAddress subnet(255, 255, 255, 0);
int i;

void setup()
{
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
  }
  // Serial.println("Connected to WiFi");
  server.begin();
  pinMode(led, OUTPUT);
}

void loop()
{
  client = server.available();
  client.setTimeout(3000);
  Serial.setTimeout(2000);
  if (client)
  {

    // Serial.println("Available");
    if (client.connected())
    {
      Serial.println("Connected");
    }

    while (client.connected())
    {
      // Serial.println(".");

      String request = client.readStringUntil('e');
      if (request == "LR")
      {
        digitalWrite(led, LOW);
        Serial.println("LR");
        for (i = 0; i < 3; i++)
        {
          String reply = Serial.readStringUntil('e');
          if (reply == "WARN_B")
          {
            Serial.println("Confirm");
            client.print("WARN_Be");
            break;
          }
          yield();
        }
      }
      else if (request == "RR")
      {
        Serial.println("RR");
        for (i = 0; i < 3; i++)
        {
          String reply = Serial.readStringUntil('e');
          yield();
          if (reply == "WARN_A")
          {
            Serial.println("Confirm");
            client.print("WARN_Ae");
            break;
          }
          yield();
        }
        yield();
      }
      yield();
    }
  }
  // Serial.println("");
  client.stop();
}

  1. Код клиента
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#define PIR_A D3
#define PIR_B D8
#define led LED_BUILTIN
const char ssid[] = "AP";
const char pass[] = "Science_Fair";
SoftwareSerial DFPlayer_Mini(D1, D2);
WiFiClient client;
IPAddress server(10, 241, 241, 27);
IPAddress ip(10, 241, 241, 28);
IPAddress gateway(10, 241, 241, 254);
IPAddress subnet(255, 255, 255, 0);

void setup()
{
    pinMode(PIR_A, INPUT);
    pinMode(PIR_B, INPUT);
    pinMode(led, OUTPUT);
    DFPlayer_Mini.begin(9600);
    mp3_set_serial(DFPlayer_Mini);
    mp3_set_volume(30);
    WiFi.mode(WIFI_STA);
    WiFi.config(ip, gateway, subnet);
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(100);
    }
    Serial.begin(9600);
}

void loop()
{
    int i;
    float time = 0;
    int PIR_A_VAL = digitalRead(PIR_A);
    int PIR_B_VAL = digitalRead(PIR_B);
    client.connect(server, 80);
    client.setTimeout(1500);
    if (PIR_A_VAL == HIGH)
    {
        while (1)
        {
            time += 1;
            delay(1);
            if (time >= 1000)
            {
                Serial.println("OFD");
                for (i = 0; i < 40; i++)
                {
                    delay(100);
                    yield();
                }
                break;
            }
            else if (PIR_B_VAL == HIGH)
            {
                if (time == 1)
                {
                    client.print("RRe");
                    client.flush();
                    for (i = 0; i < 40; i++)
                    {
                        delay(100);
                        yield();
                    }
                    break;
                }
                break;
            }
            PIR_B_VAL = digitalRead(PIR_B);
            yield();
        }
    }
    else if (PIR_B_VAL == HIGH)
    {
        String fromServer = client.readStringUntil('e');
        yield();
        if (fromServer == "WARN_A")
        {
            mp3_play();
        }
        Serial.println("B Triggered");
        for (i = 0; i < 2; i++)
        {
            delay(1250);
            yield();
        }
    }
    Serial.println("OFL");
    client.stop();
}
  1. Код клиента B
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#define PIR_A D7
#define PIR_B D8
#define led LED_BUILTIN
const char ssid[] = "AP";
const char pass[] = "Science_Fair";
SoftwareSerial DFPlayer_Mini(D1, D2);
WiFiClient client;
IPAddress server(10, 241, 241, 27);
IPAddress ip(10, 241, 241, 29);
IPAddress gateway(10, 241, 241, 254);
IPAddress subnet(255, 255, 255, 0);

void setup()
{
    pinMode(PIR_A, INPUT);
    pinMode(PIR_B, INPUT);
    pinMode(led, OUTPUT);
    DFPlayer_Mini.begin(9600);
    mp3_set_serial(DFPlayer_Mini);
    mp3_set_volume(30);
    WiFi.mode(WIFI_STA);
    WiFi.config(ip, gateway, subnet);
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(100);
    }
    Serial.begin(9600);
}

void loop()
{
    int i;
    float time = 0;
    int PIR_A_VAL = digitalRead(PIR_A);
    int PIR_B_VAL = digitalRead(PIR_B);
    client.connect(server, 80);
    client.setTimeout(1500);
    if (PIR_A_VAL == HIGH)
    {
        while (1)
        {
            time += 1;
            delay(1);
            if (time >= 1000)
            {
                Serial.println("OFD");
                for (i = 0; i < 40; i++)
                {
                    delay(100);
                    yield();
                }
                break;
            }
            else if (PIR_B_VAL == HIGH)
            {
                if (time == 1)
                {
                    client.print("LRe");
                    client.flush();
                    for (i = 0; i < 40; i++)
                    {
                        delay(100);
                        yield();
                    }
                    break;
                }
                break;
            }
            PIR_B_VAL = digitalRead(PIR_B);
            yield();
        }
    }
    else if (PIR_B_VAL == HIGH)
    {
        String warnStatus = client.readStringUntil('e');
        yield();
        if (warnStatus == "WARN_B")
        {
            mp3_play();
        }
        Serial.println("B Triggered");
        for (i = 0; i < 2; i++)
        {
            delay(1250);
            yield();
        }
    }
    Serial.println("OFL");
    client.stop();
}

Я пробовал: - Использование client.print вместо client.printf - Использование данных с подчеркиванием вместо пробелов - Добавлен client.flush - Добавлен client.stop - Изменен NodeMCU -Проверены провода - проверен блок питания - Проверил данные для отправки - Увеличен таймаут - проверенный динамик Но ни один из них не работает

Пожалуйста, помогите мне, ребята, я тороплюсь, спасибо!

, 👍-1

Обсуждение

попытаться создать минимальный воспроизводимый пример без попыток обходного пути, @Juraj

@Juraj Я уже сделал это, это работает, но я не смог решить проблему таким образом, @Sax Ted

И это почти то же самое (я нашел один, не закодированный), @Sax Ted

Ссылка [здесь](https://www.instructables.com/id/WiFi-Communication-Between-Two-ESP8266-Based-MCU-T/), я использовал пример этого парня, @Sax Ted

код в инструкции красивый и чистый. почему у тебя так захламлено?, @Juraj

@Juraj, технически, мне нужно добавить много вещей, например, HC-SR501 и многое другое., @Sax Ted


1 ответ


Лучший ответ:

0

Прочитал инструкцию и нашел - скрытое в комментариях следующее

Автор инструкции:
Хотите отправить сообщение четыре клиента одновременно?

Если это правильно, я не могу вас поддержать. Я не эксперт в этой теме. Мой сервер отправляет сообщение только текущему клиенту, который запускает сервер. Используя этот скетч, вы можете отправить такое же сообщение клиентам, но в разное время. (Замечание codebreaker007: это все равно не сработает!)

Итак, это решение в вашем коде должно работать только с одним клиентом. Таким образом, вы должны реализовать своего рода ком-последовательность, запускаемую сервером или на стороне клиента. Вот краткое описание того, как добавить эту функциональность:

#define MAX_SRV_CLIENTS 4 // подключается максимальное количество клиентов

WiFiClient serverClients[MAX_SRV_CLIENTS];

в цикле сделайте следующее:

  uint8_t i;
 for (i = 0; i < MAX_SRV_CLIENTS; i++) {
  //проверяем, есть ли новые клиенты
  if (server.hasClient()) {
 //находим свободное/отключенное место клиента
  if (!serverClients[i] || !serverClients[i].connected()) {
    if (serverClients[i]) serverClients[i].stop();
    serverClients[i] = server.available();
    Serial.print("New client: "); Serial.print(i);
    break;
  }
 }

Таким образом, вы можете различать клиентов и отправлять цикл for всем или

 serverClients[2].print("WARN Client 2");

Надеюсь, это решит проблему (а также прочитайте комментарии к инструкциям о проблемах — автор на самом деле новичок)

,

Э-э, извините, я не мог вас понять, вы имеете в виду, что мне нужно дать ему еще несколько кодов, чтобы он мог работать с более чем одним клиентом?, @Sax Ted

ДА ваше решение только для одного клиента!, @Codebreaker007

О, чувак, эта чертова проблема заняла у меня больше месяца, большое спасибо, @Sax Ted

Но я сейчас дома, проверить могу только в своей лаборатории, так что проверю тмр, спс, @Sax Ted

Я уже дал вам лучший ответ!, @Sax Ted

ЖДАТЬ! Нет необходимости в WiFiServer?, @Sax Ted

#include <ESP8266WiFi.h> посмотрите примеры библиотек, эта библиотека поддерживает клиентский и серверный код, @Codebreaker007

Извини, мой мозг был мертв, ха-ха, спс, бро, @Sax Ted

код в инструктаже берет текущего клиента, обрабатывает его, закрывает соединение и забывает клиента. затем он может обрабатывать следующего клиента., @Juraj

Это не помогает OP, если он хочет установить связь, инициированную сервером, с двумя или более клиентами, подключенными одновременно., @Codebreaker007