Ошибка времени выполнения в arduino
Я пытаюсь подключить несколько клиентов к серверу, все они используют nodeMCU. Я получаю странную ошибку времени выполнения в Server Serial Monitor Arduino IDE, когда загружаю код.
Вот мой код сервера:
#include <ESP8266WiFi.h>
#define Max_Clients 5
WiFiServer server(80);
WiFiClient *clients[Max_Clients] = {NULL};
String inputs [Max_Clients] = {""}; //Инициализация для хранения строки, полученной от клиентов
void setup() {
pinMode(D1,OUTPUT); //Инициализация выводов для отображения выхода и входа
pinMode(D2,OUTPUT);
pinMode(D3,OUTPUT);
pinMode(A0,INPUT);
Serial.begin(9600); //Начать связь между ESP8266-12E и окном монитора
WiFi.mode(WIFI_AP); //Этот ESP8266-12E — точка доступа
WiFi.softAP("NodeMCU_js", "12345678"); //Укажите (SSID, пароль)
IPAddress myIP = WiFi.softAPIP(); //Получаем IP сервера
Serial.println("Server IP is: "); //Выводим IP-адрес в окно монитора
Serial.println(myIP);
server.begin(); //Запускаем HTTP-сервер
}
void loop() {
WiFiClient client = server.available(); //Проверяем, подключился ли новый клиент к серверу
if (client) {
Serial.println("A new Client has connected :)");
for (int i=0 ; i<Max_Clients ; ++i){ //Подтверждает и настраивает новых клиентов
if (NULL == clients[i]){
clients[i] = new WiFiClient(client); //ничего в client[i] не означает, что это новый клиент
break;
}
}
}
for(int i=0 ; i<Max_Clients ; ++i){ //Для доступных клиентов
if (NULL != clients[i] && clients[i]->available()){
String request = clients[i]->readStringUntil('\r');
Serial.println("The string of client "+String(i+1)); //Печать сообщения клиента
inputs[i] = request;
Serial.println(inputs[i]);
int duty[4];
duty[i] = inputs[i].toInt();
if (i == 0){
analogWrite(D1, duty[i]);
clients[i]->println("To client 1.\r");
}
if (i == 1){
analogWrite(D2, duty[i]);
clients[i]->println("To client 2.\r");
}
if (i == 2){
analogWrite(D3, duty[i]);
clients[i]->println("To client 3.\r");
}
clients[i]->flush(); //Ожидание завершения передачи
clients[i]->stop();
}
}
} //закрытие цикла void
Вот мой клиентский код (который будет одинаковым для всех клиентов):
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
char ssid[] = "NodeMCU_js";
char password[] = "12345678";
WiFiClient client; // Создает клиента, который может подключаться к указанному IP-адресу и порту в Интернете, как определено в client.connect()
IPAddress server(192,168,4,1);
void setup() {
pinMode(A0,INPUT);
pinMode(D6,OUTPUT);
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
Serial.begin(9600); //Последовательное соединение
WiFi.begin(ssid,password); //WiFi-подключение
while (WiFi.status() != WL_CONNECTED) { //Ждем завершения подключения WiFI
delay(500);
Serial.println("Connecting...");
}
Serial.println("Connected.");
client.connect(server, 80); // Подключение к серверу
}
void loop() {
if(WiFi.status() == WL_CONNECTED){ //Проверка статуса подключения WiFi
int sense = 200;
client.println(sense+"\r"); //Сообщение клиента серверу
String answer = client.readStringUntil('\r'); //Чтение ответа с сервера
Serial.println("from server: " + answer); //Печать ответа
client.flush();
delay(3600000);
}
else{
Serial.println("Error in WiFi connection");
}
}
При загрузке этого кода последовательный монитор на сервере показывает:
Подключился новый Клиент :) Строка клиента 1 nt8_t* BufferedStreamDataSource::get_buffer(size_t) [с TStream = >ProgmemStream; uint8_t = беззнаковый символ; size_t = беззнаковое целое] Строка клиента 1
В то время как последовательный монитор на клиенте показывает:
Подключение... Подключение... Подключение... Подключение... Подключение... Подключение... Подключение... Подключено. с сервера: Клиенту 1.
Я понятия не имею об источнике этой ошибки. Любая помощь приветствуется.
Заранее спасибо.
@Dingodudesir, 👍0
Обсуждение2 ответа
Лучший ответ:
Я подозреваю, что проблема на стороне клиента. Эта строка:
client.println(sense+"\r"); //Сообщение клиента серверу
не делает то, что вы думаете.
sense
— это число (200). "\r"
— это строковая константа, расположенная по адресу в памяти. Когда вы складываете их вместе, вы не объединяете две строки, а добавляете 200 к адресу строковой константы, а затем отправляете все, что она находит в этом месте.
"\r" на самом деле излишен в любом случае, так как вы используете println
, который добавляет \r\n
в конец печати. Однако, если вы хотите сделать это вручную, вам просто нужно разделить его на два отпечатка:
client.print(sense);
clienr.print("\r");
Могу ли я просто сделать строку 'смысловой'? Она должна передаваться как String и вносить изменения на клиенте., @Dingodudesir
Можно, но зачем? Это пустая трата ресурсов и никакой пользы., @Majenko
Исследуйте WL_CONNECTED, я думаю, вы обнаружите, что это состояние подключения к вашей точке доступа, а не состояние, если устройство подключилось, также существуют проблемы с этой переменной. Состояние не меняется при разрыве соединения.
Чтобы установить соединение, вам нужно сделать запрос GET или POST на страницу на вашем сервере, например...
если (клиент.подключение(сервер, httpPort)) { // подключен к ресурсу // отправить данные client.print("GET /myfile"); клиент.println(" HTTP/1.1"); client.println("Хост: IP-АДРЕС"); client.println("Соединение: закрыто"); клиент.println(); } еще { // Нет соединения с сервером // возможно, следует продолжать повторять попытки, иначе ждем следующего вызова } // конец, если соединение установлено
Ваш серверный код должен обслуживать страницу и постоянно проверять наличие соединения с
webServer.on("/", doRoot);
Затем есть функция, которая записывает HTML обратно клиенту, например...
void doRoot() { // написать HTML Строка html; html = ""; html += "
Моя страница
"; // и отправить его webServer.send(200, "текст/html", html); }
Извините, я не могу разобраться с форматированием для этого сайта. Я использую Enter Code, и там написано Enter Code here, но когда вставляю, получается мусор., @Brian Moreau
Да, блоки кода и нумерованные списки плохо работают вместе., @Majenko
WiFiClient — это TCP-сокет. Его можно использовать как есть. Нет необходимости использовать протокол HTTP между двумя устройствами. Но не очень удобно использовать порт 80, который по стандарту зарезервирован для HTTP., @Juraj
Это может хорошо работать для связи на основе веб-сервера. Однако в моем случае один из nodeMCU является сервером., @Dingodudesir
- Как определить размер Flash?
- В ESP-12E NodeMCU, какой выход PIN A0?
- Преобразование byte* в int в Arduino
- Каково использование зарезервированных контактов и контактов SDD2, SDD3 NodeMCU?
- NodeMCU (Arduino IDE) «DynamicJsonBuffer» не был объявлен в этой области
- NodeMCU поддерживает внедрение ключей?
- Датчик движения PIR (HC-SR501) ложные результаты с NodeMCU
- Как получить текущую дату
не используйте порт 80, если это не HTTP. используйте порт 23 или 2323, который указывает на связь по простому сокету (telnet). и вы можете протестировать сервер с помощью клиента telnet., @Juraj
Вам не следует использовать 23, так как это подразумевает интерактивное соединение. Вам следует использовать *любой* порт, кроме 80 - в идеале не использовать порт, связанный с каким-либо известным протоколом. Но на самом деле не имеет значения, какой порт вы используете во встроенной системе... Кстати, telnet может подключаться к любому порту - даже к 80., @Majenko
Ну, я уже успешно использовал этот порт для установления соединения. Какие еще порты доступны?, @Dingodudesir
порты до 1023 зарезервированы https://en.wikipedia.org/wiki/Список_номеров_портов_TCP_и_UDP, @Juraj