Вопрос в том как можно отработать обратную связь: делать запрос из php устройсту, чтобы то запустило какой-то набор действий на arduino? Или это только путем поднятия web-сервера на arduino?
Тут два момента: кто должен быть инициатором соединения? Может ардуина обратиться к серверу и получить ответ, который будет содержать какие-то команды на исполнение. Или же php (curl) будет инициировать запрос к ардуине и тоже передавать ей какие-то GET-параметры...
У меня примерно так дистанционно включается и выключается генерация на grid-tie инверторе: если в параметрах строки запроса к ардуине переменная a=6 то ардуина дергает ножкой и включает мосфет.
Вопрос в том как можно отработать обратную связь: делать запрос из php устройсту, чтобы то запустило какой-то набор действий на arduino? Или это только путем поднятия web-сервера на arduino?
Тут два момента: кто должен быть инициатором соединения? Может ардуина обратиться к серверу и получить ответ, который будет содержать какие-то команды на исполнение. Или же php (curl) будет инициировать запрос к ардуине и тоже передавать ей какие-то GET-параметры...
У меня примерно так дистанционно включается и выключается генерация на grid-tie инверторе: если в параметрах строки запроса к ардуине переменная a=6 то ардуина дергает ножкой и включает мосфет.
php инициирует get запросы, а arduino их должна принять и обрабаотать. и в случае если что-то произошло на самой arduino отправить в другую сторону новой статус или значение.
до этого все было построенно на nrf24, а хочется на wifi(универсальнее).
да web сервер развернут на компе с встроенным wifi
В адресной строке браузера вводим http://192.168.1.111/ , IP соответствующий. В этот момент уже что-то (GET) будет отправлено. Сможете ли Вы принять "что-то" ?
В адресной строке браузера вводим http://192.168.1.111/ , IP соответствующий. В этот момент уже что-то (GET) будет отправлено. Сможете ли Вы принять "что-то" ?
не - ничего не приходит.
скорее всего я где-то накосячил.
вот полный код, который я сейчас использую. посмотри пожалуйста- может увидешь что не так- со стороны веднее:
#define SSID "SmartHome" //имя сети
#define PASS "12345678" //пароль
#define DST_IP "192.168.0.10" //ip web сервера
const String id="t01"; //id устройства
String WiFiMessage=""; //принимаемое сообщение
unsigned int readChar; //переменная для посимвольного чтения сообщения
String ip = ""; //переменная для хранения ip устройства
char character;
int hardReset = 6; //пин arduino, на котором весит ch_pd
boolean connected=false; //флаг соединения WiFi
void setup()
{
pinMode(hardReset, OUTPUT);
Serial.begin(9600);
Serial.setTimeout(5000);
Serial1.begin(9600);
Serial1.setTimeout(5000);
digitalWrite(hardReset, LOW);
delay(100);
digitalWrite(hardReset, HIGH);
delay(5000);
for(int i=0;i<5;i++)
{
if(connectWiFi())
{
connected = true;
break;
}
}
if (!connected){while(1);}
delay(5000);
Serial1.println("AT+CIPMUX=1");
}
void loop()
{
if (Serial1.available())
{
Serial.print(Serial1.read());
}
}
/*функция конекта к wifi сети*/
boolean connectWiFi()
{
Serial1.println("AT+CWMODE=1");
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.print("Connecting to ");
Serial.println(SSID);
Serial1.println(cmd);
delay(2000);
if(Serial1.find("OK"))
{
Serial.println("OK, Connected to WiFi.");
Serial1.println("AT+CIFSR");
Serial1.flush();
delay(1000);
ip="";
while(Serial1.available())
{
character = Serial1.read();
if(character=='.' || character>='0' && character<='9')
ip.concat(character);
}
if(ip != "")
{
Serial.print("IP Address of ESP8266: ");
Serial.println(ip);
}
Serial1.println("AT+CIPMODE=0");
Serial1.println("AT+CIPSERVER=1,80");
Serial1.println("AT+CIPSTO=120");
return true;
}
else
{
Serial.println("Can not connect to the WiFi.");
return false;
}
}
1. К коду претензий не имею, мы явно брали код-основу из одного источника. Я еще AT+RST посылаю вначале, а так все один в один почти. А вот почему ничего не принимает, вряд ли догадаюсь, дальше я иду другим путем (ловлю бродкастные UDP-пакеты)
2. А что это за длинный ряд цифр в окне монитора порта ?
Нано (SoftwareSerial) и Мега (Hardware Serial). Какую - неважно.
Я бы посоветовал посмотреть в connectWiFi(), что отвечает Ардуина на команды AT+CWMODE=1 , AT+CIPMODE=0 , AT+CIPSERVER=1,80 , AT+CIPSTO=120.
посмотрел ответы на все AT команды. одни кракозябры. причем если искать Serial.find то находит что нужно. Почему же в монитор порта выводится всякая аброкодабра?
посмотрел ответы на все AT команды. одни кракозябры. причем если искать Serial.find то находит что нужно. Почему же в монитор порта выводится всякая аброкодабра?
Не совпадают скорость, битность, сама программа "монитора порта" кривая... Причем, иногда скорость на порту выставляешь, а она не выставляется - бывают и такие глюки.
Serial.println("Send AT+CWMODE=1");
Serial1.println("AT+CWMODE=1");
Serial1.flush();
delay(2000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("send AT+CWJAP");
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial1.flush();
delay(2000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("send AT+CIPMODE=0");
Serial1.println("AT+CIPMODE=0");
Serial1.flush();
delay(2000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
/*cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += DST_IP;
cmd += "\",80";
Serial.println("send AT+CIPSTART=TCP");
Serial1.println(cmd);*/
Serial.println("send AT+CIPMUX=1");
Serial1.println("AT+CIPMUX=1");
Serial1.flush();
delay(2000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("Send AT+CIPSERVER=1,80");
Serial1.println("AT+CIPSERVER=1,80");
Serial1.flush();
delay(2000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("Send AT+CIPSTO=120");
Serial1.println("AT+CIPSTO=120");
Serial1.flush();
delay(2000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
В результате:
Send AT+CWMODE=1
answer no found OK
send AT+CWJAP
answer no found OK
send AT+CIPMODE=0
answer OK
send AT+CIPMUX=1
answer OK
Send AT+CIPSERVER=1,80
answer OK
Send AT+CIPSTO=120
answer OK
Странно что при конекте к сети wifi не находит ОК, но все равно конектится к сети.
А если смотреть просто, без поиска, что выводится в ответ, то на команды, на которые ответ ОК, выводятся, правильные ответы типа ок, linked. не понятно что не так....
Вот и славно. delay(2000); - многовато, можно сильно уменьшить.
Еще один маленький вопросик: правильно ли я понимаю, чтобы отправить сообщение web-серверу, находясь в режиме tcp сервера, вначале перейти в режим tcp клиента и потом только отправлять сообщения. затем чтобы снова иметь возможность получать сообщения от web-сервера - снова перейти в режим tcp сервера????
Почти правильно, режим сервера (AT+CIPSERVER=) включается при старте/рестарте модуля (на самом деле модуль помнит его и без этого, но это уже другая история), режим клиента запускаем (AT+CIPSTART=) перед отправкой (AT+CIPSEND=) и закрываем после отправки (AT+CIPCLOSE=). Можно и не закрывать, я пробовал, и без закрытия работает. Интуиция подсказывает, что AT+CIPSTART= перед каждой отправкой тоже можно не делать, но так я не пробовал.
Почти правильно, режим сервера (AT+CIPSERVER=) включается при старте/рестарте модуля (на самом деле модуль помнит его и без этого, но это уже другая история), режим клиента запускаем (AT+CIPSTART=) перед отправкой (AT+CIPSEND=) и закрываем после отправки (AT+CIPCLOSE=). Можно и не закрывать, я пробовал, и без закрытия работает. Интуиция подсказывает, что AT+CIPSTART= перед каждой отправкой тоже можно не делать, но так я не пробовал.
Похоже рано обрабовался.
если поднимать tcp сервер, а после этого клиент - для отправки сообщений, то команда на поднятие клиента выдает ошибку:
AT+CIPSTART="TCP","192.168.0.10",80
Link typ ERROR
вот кусок кода:
void loop()
{
Serial.println("Send AT+CWMODE=1");
Serial1.println("AT+CWMODE=1");
Serial1.flush();
delay(1000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("send AT+CWJAP");
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial1.flush();
delay(1000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("send AT+CIPMODE=0");
Serial1.println("AT+CIPMODE=0");
Serial1.flush();
delay(1000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("send AT+CIPMUX=1");
Serial1.println("AT+CIPMUX=1");
Serial1.flush();
delay(1000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("Send AT+CIPSERVER=1,80");
Serial1.println("AT+CIPSERVER=1,80");
Serial1.flush();
delay(1000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
Serial.println("Send AT+CIPSTO=120");
Serial1.println("AT+CIPSTO=120");
Serial1.flush();
delay(1000);
if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}
cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += DST_IP;
cmd += "\",80";
Serial.println("send AT+CIPSTART=TCP");
Serial1.println(cmd);
Serial1.flush();
delay(1000);
while(Serial1.available())
{
character=Serial1.read();
ip.concat(character);
}
Serial.println(ip);
delay(1000000);
}
Два serial порта потому что, для arduino pro micro Serial - это usb, а Serial1 - это как раз выводы TX и RX yf плате.
Честно говоря не понял. Разве этот USB-UART распаянный на самой плате ардуино не к тем же единственным RxTx подцеплен?
Тогда я не верно спросил, походу. У меня не совсем Ардуино про мини. У меня голая atmega328p с кварцем, прошитая загрузчиком Arduino Pro mini 5v 8MHz. У неё есть только её выходы, только один RxTx и к нему я цепляюсь UARTом чтоб шить её.
Я могу периписать код, вывинув оттуда софтовый Serial и отладочную инфу, а ESP-01 подцепить к хардварному RxTx моей самопальной ардуины?
Ничё не могу понять. Прошил модуль. Скорость 115200. Поставил её в скетче. Подключил модуль. Модуль моргает, но к сети не подключается. Подцепился терминалом, вроде всё норм, сообщения такие на модуль уходят:
AT+CWMODE=1
AT+CWJAP="My_AP","pass12345"
Но он к сети не коннектится. Если терминалом на модуль это самое отправляю, то коннектится к сети нормально.
Ладно. Модуль настроил, к сети он подключается. А дальше что? Должен быть доступен веб сервер на его IP?
Скеч, на всякий случай:
#define SSID "My_AP" //им€ сети
#define PASS "pass12345" //пароль
#define DST_IP "192.168.1.121" //ip web сервера
const String id="t01"; //id устройства
#define START_CHAR '!' //начальный символ принимаемого сообщения
#define END_CHAR '$' //конечный символ принимаесого сообщения
String WiFiMessage=""; //принимаемое сообщение
unsigned int readChar; //переменная для посимвольного чтения сообщения
boolean readingWiFi; //флаг чтения сообщения
String ip = ""; //переменна€ дл€ хранени€ ip устройства
char character;
int hardReset = 6; //пин arduino, на котором весит ch_pd
boolean connected=false; //флаг соединения WiFi
void setup()
{
pinMode(hardReset, OUTPUT);
Serial.begin(115200);
Serial.setTimeout(5000);
digitalWrite(hardReset, LOW);
delay(100);
digitalWrite(hardReset, HIGH);
delay(5000);
for(int i=0;i<5;i++)
{
if(connectWiFi())
{
connected = true;
break;
}
}
if (!connected){while(1); }
delay(2000);
}
void loop()
{
if (Serial.available() > 0 && !readingWiFi)
{
if (Serial.read() == START_CHAR)
{
WiFiReadData();
}
}
}
void WiFiReadData()
{
WiFiMessage = "";
readingWiFi = true;
iniReading:
if (Serial.available() > 0)
{
readChar = Serial.read();
if (readChar == END_CHAR)
{
goto endReading;
}
else
{
WiFiMessage.concat(readChar);
goto iniReading;
}
}
goto iniReading;
endReading:
readingWiFi = false;
///здесь парсинг сообщения и последующие действия
//Serial.println(WiFiMessage);
}
/*функци€ отправки сообщени€ web-серверу*/
boolean sendMSG(String modul_id,String value,boolean startMSG)
{
String cmd = "AT+CIPSTART=1,\"TCP\",\"";
cmd += DST_IP;
cmd += "\",80";
//Serial.println("Connecting to WebServer");
Serial.println(cmd);
Serial.flush();
delay(1000);
/*if(Serial.find("OK"))
{
//Serial.print("OK, Connected to WebServer ");
//Serial.println(DST_IP);
}
else
{
//Serial.print("Can not connect to WebServer ");
//Serial.println(DST_IP);
}*/
String msg= "GET /ajax/arduino_read.php?act=";
if(startMSG)
{
msg+="new_w&id=";
}
else
{
msg+="s_t_h&id=";
}
msg+= modul_id;
msg+= "&val=";
msg+= value;
msg+= " HTTP/1.1\r\nHost: ";
msg+= DST_IP;
msg+= ":80\r\n\r\n";
Serial.print("AT+CIPSEND=1,");
Serial.println(msg.length());
//Serial.println("Senting MSG");
if (Serial.find(">"))
{
//Serial.print("MSG text: ");
//Serial.println(msg);
Serial.print(msg);
Serial.flush();
}
if(Serial.find("SEND OK"))
{
return true;
}
else
{
return false;
}
}
/*функци€ конекта к wifi сети*/
boolean connectWiFi()
{
ip="";
Serial.println("AT+CWMODE=1");
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
//Serial.print("Connecting to ");
//Serial.println(SSID);
Serial.println(cmd);
delay(1000);
if(Serial.find("OK"))
{
//Serial.println("OK, Connected to WiFi.");
Serial.println("AT+CIFSR");
Serial.flush();
delay(1000);
while(Serial.available())
{
character = Serial.read();
if(character=='.' || character>='0' && character<='9')
ip.concat(character);
}
if(ip != "")
{
//Serial.print("IP Address of ESP8266: ");
//Serial.println(ip);
}
///включаем режим приема/передачи
Serial.println("AT+CIPMODE=0");
Serial.println("AT+CIPMUX=1");
Serial.flush();
delay(1000);
//Serial.println("Starting TCP Server");
Serial.println("AT+CIPSERVER=1,80");
Serial.flush();
delay(1000);
if (Serial.find("OK"))
{
//Serial.println("OK, Strart TCP Server");
}
else
{
//Serial.println("Can not start TCP Server");
}
Serial.println("AT+CIPSTO=120");
Serial.flush();
delay(1000);
//отправл€ем информацию об устройстве при его старте
String msg= "temp_";
msg+= ip;
if(sendMSG(id,msg,true))
{
//Serial.println("Startup info was send");
return true;
}
else
{
//Serial.println("Startup info was not send");
return false;
}
}
else
{
//Serial.println("Can not connect to the WiFi.");
return false;
}
}
String floatToString(float value, byte precision)
{
int intVal = int(value);
unsigned int frac;
if(intVal >= 0)
{
frac = (value - intVal) * precision;
}
else
{
frac = (intVal - value) * precision;
}
return String(intVal) + "." + String(frac);
}
Ты устройству, устройство по сом порту на ардуино, ардуино обрабатывает команду.
Только так.
Я для пересылки данных между Ардуинами пользуюсь UDP. (В этом случае даже необязательно знать IP-адрес получателя).
Для приема:
1. Поднимаем сервер.
ESPSerial.println("AT+CWMODE=1");
ESPSerial.println("AT+CIPMUX=1");
ESPSerial.println("AT+CIPSERVER=1,48569");
ESPSerial.println("AT+CIPSTO=120");
2. Ждем приема, получаем принятый пакет в строку.
while (ESPSerial.available())
{
char c = ESPSerial.read();
ReceivedString += c;
}
3. Парсим строку всячески.
Вопрос в том как можно отработать обратную связь: делать запрос из php устройсту, чтобы то запустило какой-то набор действий на arduino? Или это только путем поднятия web-сервера на arduino?
Тут два момента: кто должен быть инициатором соединения? Может ардуина обратиться к серверу и получить ответ, который будет содержать какие-то команды на исполнение. Или же php (curl) будет инициировать запрос к ардуине и тоже передавать ей какие-то GET-параметры...
У меня примерно так дистанционно включается и выключается генерация на grid-tie инверторе: если в параметрах строки запроса к ардуине переменная a=6 то ардуина дергает ножкой и включает мосфет.
Вопрос в том как можно отработать обратную связь: делать запрос из php устройсту, чтобы то запустило какой-то набор действий на arduino? Или это только путем поднятия web-сервера на arduino?
Тут два момента: кто должен быть инициатором соединения? Может ардуина обратиться к серверу и получить ответ, который будет содержать какие-то команды на исполнение. Или же php (curl) будет инициировать запрос к ардуине и тоже передавать ей какие-то GET-параметры...
У меня примерно так дистанционно включается и выключается генерация на grid-tie инверторе: если в параметрах строки запроса к ардуине переменная a=6 то ардуина дергает ножкой и включает мосфет.
php инициирует get запросы, а arduino их должна принять и обрабаотать. и в случае если что-то произошло на самой arduino отправить в другую сторону новой статус или значение.
до этого все было построенно на nrf24, а хочется на wifi(универсальнее).
да web сервер развернут на компе с встроенным wifi
ты имееш в виду типа этого:
void loop() { if (Serial1.available() > 0 && !readingWiFi) { if (Serial1.read() == START_CHAR) { WiFiReadData(); } } } void WiFiReadData() { WiFiMessage = ""; readingWiFi = true; iniReading: if (Serial1.available() > 0) { readChar = Serial1.read(); if (readChar == END_CHAR) { goto endReading; } else { WiFiMessage.concat(readChar); goto iniReading; } } goto iniReading; endReading: readingWiFi = false; ///здесь парсинг сообщения и последующие действия Serial.println(WiFiMessage); }??
Если да, то тогда остается вопрос как послать данные устройству с сервера(через php скрипт). пробовал так:
<? $fp = fsockopen("ip модуля", 80, $errno, $errstr); if (!$fp) { echo "ERROR: $errno - $errstr<br />\n"; } else { fwrite($fp, "!my_text$"); $output=fread($fp, 4096); fclose($fp); } ?>Но скрипт выдает что не может соедениться. Если пинговать адрес- все ок. Если делать telnet, то тоже выдает что не может соедениться.
Может что-то надо еще на модуле включить(какую-нибудь AT команду выполнить)? Кто-нибудь пробовал подобное провернуть?
...как послать данные устройству с сервера(через php скрипт). пробовал так:
<? $fp = fsockopen("ip модуля", 80, $errno, $errstr); if (!$fp) { echo "ERROR: $errno - $errstr<br />\n"; } else { fwrite($fp, "!my_text$"); $output=fread($fp, 4096); fclose($fp); } ?>Но скрипт выдает что не может соедениться. Если пинговать адрес- все ок. Если делать telnet, то тоже выдает что не может соедениться.
Может что-то надо еще на модуле включить(какую-нибудь AT команду выполнить)? Кто-нибудь пробовал подобное провернуть?
Ардуино "слушает" в этот момент 80-й порт ?
Я имею в виду AT+CIPSERVER=1,80
Ардуино "слушает" в этот момент 80-й порт ?
Я имею в виду AT+CIPSERVER=1,80
Пробовал и AT+CIPSERVER=1,80 и AT+CIPSTART режимы. Одно и тоже - не может достучаться. не php не telnet. Есть еще какие-нибудь предположения?
А кто-то другой, кроме php / telnet, может достучаться ? В WiFiMessage хоть из браузера можно что-нибудь получить ?
А кто-то другой, кроме php / telnet, может достучаться ? В WiFiMessage хоть из браузера можно что-нибудь получить ?
не понял... что значит из браузера?
В адресной строке браузера вводим http://192.168.1.111/ , IP соответствующий. В этот момент уже что-то (GET) будет отправлено. Сможете ли Вы принять "что-то" ?
В адресной строке браузера вводим http://192.168.1.111/ , IP соответствующий. В этот момент уже что-то (GET) будет отправлено. Сможете ли Вы принять "что-то" ?
не - ничего не приходит.
скорее всего я где-то накосячил.
вот полный код, который я сейчас использую. посмотри пожалуйста- может увидешь что не так- со стороны веднее:
#define SSID "SmartHome" //имя сети #define PASS "12345678" //пароль #define DST_IP "192.168.0.10" //ip web сервера const String id="t01"; //id устройства String WiFiMessage=""; //принимаемое сообщение unsigned int readChar; //переменная для посимвольного чтения сообщения String ip = ""; //переменная для хранения ip устройства char character; int hardReset = 6; //пин arduino, на котором весит ch_pd boolean connected=false; //флаг соединения WiFi void setup() { pinMode(hardReset, OUTPUT); Serial.begin(9600); Serial.setTimeout(5000); Serial1.begin(9600); Serial1.setTimeout(5000); digitalWrite(hardReset, LOW); delay(100); digitalWrite(hardReset, HIGH); delay(5000); for(int i=0;i<5;i++) { if(connectWiFi()) { connected = true; break; } } if (!connected){while(1);} delay(5000); Serial1.println("AT+CIPMUX=1"); } void loop() { if (Serial1.available()) { Serial.print(Serial1.read()); } } /*функция конекта к wifi сети*/ boolean connectWiFi() { Serial1.println("AT+CWMODE=1"); String cmd="AT+CWJAP=\""; cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; Serial.print("Connecting to "); Serial.println(SSID); Serial1.println(cmd); delay(2000); if(Serial1.find("OK")) { Serial.println("OK, Connected to WiFi."); Serial1.println("AT+CIFSR"); Serial1.flush(); delay(1000); ip=""; while(Serial1.available()) { character = Serial1.read(); if(character=='.' || character>='0' && character<='9') ip.concat(character); } if(ip != "") { Serial.print("IP Address of ESP8266: "); Serial.println(ip); } Serial1.println("AT+CIPMODE=0"); Serial1.println("AT+CIPSERVER=1,80"); Serial1.println("AT+CIPSTO=120"); return true; } else { Serial.println("Can not connect to the WiFi."); return false; } }после подключения выводит следующие значения:
1. К коду претензий не имею, мы явно брали код-основу из одного источника. Я еще AT+RST посылаю вначале, а так все один в один почти. А вот почему ничего не принимает, вряд ли догадаюсь, дальше я иду другим путем (ловлю бродкастные UDP-пакеты)
2. А что это за длинный ряд цифр в окне монитора порта ?
Вот, для сравнения
boolean ESPRestart() { ESPRestartsCounter++; #ifdef DEBUG Serial.println("Resetting soft.."); #endif ESPSerial.println("AT+RST"); ESPFlushSerial(100); String ESPcmd; ESPcmd = "AT+CWJAP=\""; ESPcmd += TARGETSSID; ESPcmd += "\",\""; ESPcmd += PASS; ESPcmd += "\""; #ifdef DEBUG Serial.println("Connecting to WiFi.."); #endif for ( int i = 1; i <= ESPNumberConnectRetries; i++ ) { #ifdef DEBUG Serial.print("Try "); Serial.println(i); #endif ESPSerial.println(ESPcmd); delay(3000); if ( ESPSerial.find("OK") ) { #ifdef DEBUG Serial.println("OK, Connected to WiFi."); #endif ESPSerial.println("AT+CWMODE=1"); ESPFlushSerial(100); ESPSerial.println("AT+CIPMUX=1"); ESPFlushSerial(100); ESPSerial.println("AT+CIPSERVER=1,48569"); ESPFlushSerial(100); ESPSerial.println("AT+CIPSTO=120"); ESPFlushSerial(100); ESPSendErrorCounter = 0; ESPLastReceivedTimer = millis(); return true; } } #ifdef DEBUG Serial.println("Can not connect to the WiFi."); #endif ESPLastConnectFailure = millis(); return false; } void ESPFlushSerial(int delaymsec) { if ( !ESPConnected ) return; delay(delaymsec); while ( ESPSerial.available() ) { ESPSerial.read(); } }длинный ряд - это то что ловится в serial1 после того как произошло подключение к wifi. Что это за фигня- фиг знает.
длинный ряд - это то что ловится в serial1 после того как произошло подключение к wifi. Что это за фигня- фиг знает.
Ага. Я, кстати, на всякий случай даю паузу и чищу буфер после каждой команды ( ESPFlushSerial(delay) )
длинный ряд - это то что ловится в serial1 после того как произошло подключение к wifi. Что это за фигня- фиг знает.
Ага. Я, кстати, на всякий случай даю паузу и чищу буфер после каждой команды ( ESPFlushSerial(delay) )
А у тебя при обращении из браузера - что-то отлавливается на arduino????
Отлавливалось +IPD,id,len:data , но потом я ушел с TCP на UDP.
Впрочем, неважно, там та же +IPD приходит.
Отлавливалось +IPD,id,len:data , но потом я ушел с TCP на UDP.
Впрочем, неважно, там та же +IPD приходит.
А какую arduino ты использовал для тестов???
Нано (SoftwareSerial) и Мега (Hardware Serial). Какую - неважно.
Я бы посоветовал посмотреть в connectWiFi(), что отвечает Ардуина на команды AT+CWMODE=1 , AT+CIPMODE=0 , AT+CIPSERVER=1,80 , AT+CIPSTO=120.
Спасибо. так и сделаю, но теперь уже дома.
посмотрю выводы после каждой команды! может станет что-то яснее.
Если нет то попробую поднять web сервер на arduino и с ним работать
Если нет то попробую поднять web сервер на arduino и с ним работать
Даже не пытайтесь сделать веб сервер на ардуине с 1кб ОЗУ - максимум пару строк вывести реально. Памяти не хватит. На МЕГЕ заработает.
Тут так получается, что надо размер знать странички и для этого поместить её сначала в буфер..
Нано (SoftwareSerial) и Мега (Hardware Serial). Какую - неважно.
Я бы посоветовал посмотреть в connectWiFi(), что отвечает Ардуина на команды AT+CWMODE=1 , AT+CIPMODE=0 , AT+CIPSERVER=1,80 , AT+CIPSTO=120.
посмотрел ответы на все AT команды. одни кракозябры. причем если искать Serial.find то находит что нужно. Почему же в монитор порта выводится всякая аброкодабра?
посмотрел ответы на все AT команды. одни кракозябры. причем если искать Serial.find то находит что нужно. Почему же в монитор порта выводится всякая аброкодабра?
Не совпадают скорость, битность, сама программа "монитора порта" кривая... Причем, иногда скорость на порту выставляешь, а она не выставляется - бывают и такие глюки.
Прогнал вот так :
Serial.println("Send AT+CWMODE=1"); Serial1.println("AT+CWMODE=1"); Serial1.flush(); delay(2000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("send AT+CWJAP"); String cmd="AT+CWJAP=\""; cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; Serial1.flush(); delay(2000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("send AT+CIPMODE=0"); Serial1.println("AT+CIPMODE=0"); Serial1.flush(); delay(2000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} /*cmd = "AT+CIPSTART=\"TCP\",\""; cmd += DST_IP; cmd += "\",80"; Serial.println("send AT+CIPSTART=TCP"); Serial1.println(cmd);*/ Serial.println("send AT+CIPMUX=1"); Serial1.println("AT+CIPMUX=1"); Serial1.flush(); delay(2000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("Send AT+CIPSERVER=1,80"); Serial1.println("AT+CIPSERVER=1,80"); Serial1.flush(); delay(2000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("Send AT+CIPSTO=120"); Serial1.println("AT+CIPSTO=120"); Serial1.flush(); delay(2000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");}В результате:
Send AT+CWMODE=1
answer no found OK
send AT+CWJAP
answer no found OK
send AT+CIPMODE=0
answer OK
send AT+CIPMUX=1
answer OK
Send AT+CIPSERVER=1,80
answer OK
Send AT+CIPSTO=120
answer OK
Странно что при конекте к сети wifi не находит ОК, но все равно конектится к сети.
А если смотреть просто, без поиска, что выводится в ответ, то на команды, на которые ответ ОК, выводятся, правильные ответы типа ок, linked. не понятно что не так....
Как ни странно - прям мистика, но при обращении из браузера появился ответ, да и через сокеты тоже все ок. урааааааа!!!!!
Вот и славно. delay(2000); - многовато, можно сильно уменьшить.
Вот и славно. delay(2000); - многовато, можно сильно уменьшить.
Еще один маленький вопросик: правильно ли я понимаю, чтобы отправить сообщение web-серверу, находясь в режиме tcp сервера, вначале перейти в режим tcp клиента и потом только отправлять сообщения. затем чтобы снова иметь возможность получать сообщения от web-сервера - снова перейти в режим tcp сервера????
Почти правильно, режим сервера (AT+CIPSERVER=) включается при старте/рестарте модуля (на самом деле модуль помнит его и без этого, но это уже другая история), режим клиента запускаем (AT+CIPSTART=) перед отправкой (AT+CIPSEND=) и закрываем после отправки (AT+CIPCLOSE=). Можно и не закрывать, я пробовал, и без закрытия работает. Интуиция подсказывает, что AT+CIPSTART= перед каждой отправкой тоже можно не делать, но так я не пробовал.
Почти правильно, режим сервера (AT+CIPSERVER=) включается при старте/рестарте модуля (на самом деле модуль помнит его и без этого, но это уже другая история), режим клиента запускаем (AT+CIPSTART=) перед отправкой (AT+CIPSEND=) и закрываем после отправки (AT+CIPCLOSE=). Можно и не закрывать, я пробовал, и без закрытия работает. Интуиция подсказывает, что AT+CIPSTART= перед каждой отправкой тоже можно не делать, но так я не пробовал.
Похоже рано обрабовался.
если поднимать tcp сервер, а после этого клиент - для отправки сообщений, то команда на поднятие клиента выдает ошибку:
void loop() { Serial.println("Send AT+CWMODE=1"); Serial1.println("AT+CWMODE=1"); Serial1.flush(); delay(1000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("send AT+CWJAP"); String cmd="AT+CWJAP=\""; cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; Serial1.flush(); delay(1000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("send AT+CIPMODE=0"); Serial1.println("AT+CIPMODE=0"); Serial1.flush(); delay(1000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("send AT+CIPMUX=1"); Serial1.println("AT+CIPMUX=1"); Serial1.flush(); delay(1000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("Send AT+CIPSERVER=1,80"); Serial1.println("AT+CIPSERVER=1,80"); Serial1.flush(); delay(1000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} Serial.println("Send AT+CIPSTO=120"); Serial1.println("AT+CIPSTO=120"); Serial1.flush(); delay(1000); if (Serial1.find("OK")){Serial.println("answer OK");}else{Serial.println("answer no found OK");} cmd = "AT+CIPSTART=\"TCP\",\""; cmd += DST_IP; cmd += "\",80"; Serial.println("send AT+CIPSTART=TCP"); Serial1.println(cmd); Serial1.flush(); delay(1000); while(Serial1.available()) { character=Serial1.read(); ip.concat(character); } Serial.println(ip); delay(1000000); }Не подскажешь что может быть не так?
Когда AT+CIPMUX=1, команда должна выглядеть как AT+CIPSTART=id,type,addr,port.
Кстати, рекомендую: https://github.com/espressif/esp8266_at/wiki/AT_Description
Когда AT+CIPMUX=1, команда должна выглядеть как AT+CIPSTART=id,type,addr,port.
Кстати, рекомендую: https://github.com/espressif/esp8266_at/wiki/AT_Description
Большое спасибо.
Вроде бы все как-то заработало
https://www.youtube.com/watch?v=CchMpaS6pzQ )))
https://www.youtube.com/watch?v=CchMpaS6pzQ )))
Зачет))))
Дейтвительно алилуя!
А можно ваши нароботки итоговые увидеть?
А можно ваши нароботки итоговые увидеть?
Вот итоговый скетч:
#define SSID "xxx" //им€ сети #define PASS "vfhbyf11111990" //пароль #define DST_IP "192.168.0.10" //ip web сервера const String id="t01"; //id устройства #define START_CHAR '!' //начальный символ принимаемого сообщения #define END_CHAR '$' //конечный символ принимаесого сообщения String WiFiMessage=""; //принимаемое сообщение unsigned int readChar; //переменная для посимвольного чтения сообщения boolean readingWiFi; //флаг чтения сообщения String ip = ""; //переменна€ дл€ хранени€ ip устройства char character; int hardReset = 6; //пин arduino, на котором весит ch_pd boolean connected=false; //флаг соединения WiFi void setup() { pinMode(hardReset, OUTPUT); Serial.begin(9600); Serial.setTimeout(5000); Serial1.begin(9600); Serial1.setTimeout(5000); digitalWrite(hardReset, LOW); delay(100); digitalWrite(hardReset, HIGH); delay(5000); for(int i=0;i<5;i++) { if(connectWiFi()) { connected = true; break; } } if (!connected){while(1); } delay(2000); } void loop() { if (Serial1.available() > 0 && !readingWiFi) { if (Serial1.read() == START_CHAR) { WiFiReadData(); } } } void WiFiReadData() { WiFiMessage = ""; readingWiFi = true; iniReading: if (Serial1.available() > 0) { readChar = Serial1.read(); if (readChar == END_CHAR) { goto endReading; } else { WiFiMessage.concat(readChar); goto iniReading; } } goto iniReading; endReading: readingWiFi = false; ///здесь парсинг сообщения и последующие действия Serial.println(WiFiMessage); } /*функци€ отправки сообщени€ web-серверу*/ boolean sendMSG(String modul_id,String value,boolean startMSG) { String cmd = "AT+CIPSTART=1,\"TCP\",\""; cmd += DST_IP; cmd += "\",80"; //Serial.println("Connecting to WebServer"); Serial1.println(cmd); Serial1.flush(); delay(1000); /*if(Serial1.find("OK")) { Serial.print("OK, Connected to WebServer "); Serial.println(DST_IP); } else { Serial.print("Can not connect to WebServer "); Serial.println(DST_IP); }*/ String msg= "GET /ajax/arduino_read.php?act="; if(startMSG) { msg+="new_w&id="; } else { msg+="s_t_h&id="; } msg+= modul_id; msg+= "&val="; msg+= value; msg+= " HTTP/1.1\r\nHost: "; msg+= DST_IP; msg+= ":80\r\n\r\n"; Serial1.print("AT+CIPSEND=1,"); Serial1.println(msg.length()); Serial.println("Senting MSG"); if (Serial1.find(">")) { //Serial.print("MSG text: "); //Serial.println(msg); Serial1.print(msg); Serial1.flush(); } if(Serial1.find("SEND OK")) { return true; } else { return false; } } /*функци€ конекта к wifi сети*/ boolean connectWiFi() { ip=""; Serial1.println("AT+CWMODE=1"); String cmd="AT+CWJAP=\""; cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; Serial.print("Connecting to "); Serial.println(SSID); Serial1.println(cmd); delay(1000); if(Serial1.find("OK")) { Serial.println("OK, Connected to WiFi."); Serial1.println("AT+CIFSR"); Serial1.flush(); delay(1000); while(Serial1.available()) { character = Serial1.read(); if(character=='.' || character>='0' && character<='9') ip.concat(character); } if(ip != "") { Serial.print("IP Address of ESP8266: "); Serial.println(ip); } ///включаем режим приема/передачи Serial1.println("AT+CIPMODE=0"); Serial1.println("AT+CIPMUX=1"); Serial1.flush(); delay(1000); Serial.println("Starting TCP Server"); Serial1.println("AT+CIPSERVER=1,80"); Serial1.flush(); delay(1000); if (Serial1.find("OK")){Serial.println("OK, Strart TCP Server");}else{Serial.println("Can not start TCP Server");} Serial1.println("AT+CIPSTO=120"); Serial1.flush(); delay(1000); //отправл€ем информацию об устройстве при его старте String msg= "temp_"; msg+= ip; if(sendMSG(id,msg,true)) { Serial.println("Startup info was send"); return true; } else { Serial.println("Startup info was not send"); return false; } } else { Serial.println("Can not connect to the WiFi."); return false; } } String floatToString(float value, byte precision) { int intVal = int(value); unsigned int frac; if(intVal >= 0) { frac = (value - intVal) * precision; } else { frac = (intVal - value) * precision; } return String(intVal) + "." + String(frac); }Спасибо, интересно, кое-что пригодится. WiFiReadData() весьма нестандартно реализована. Переменная readingWiFi явно лишняя в этом скетче.
дополнение к функции WiFIReadData():
void WiFiReadData() { WiFiMessage = ""; readingWiFi = true; iniReading: if (Serial1.available() > 0) { readChar = Serial1.read(); if (readChar == END_CHAR) { goto endReading; } else { WiFiMessage+=char(readChar); goto iniReading; } } goto iniReading; endReading: readingWiFi = false; ///здесь парсинг сообщения и последующие действия Serial.println(WiFiMessage); }Чтобы выводилось символьное представление, а не ascii
Спасибо, интересно, кое-что пригодится. WiFiReadData() весьма нестандартно реализована. Переменная readingWiFi явно лишняя в этом скетче.
А можешь показать пример "стандартного" способа чтения?
Я лишь имел в виду, что обычно чтение порта делают на while и break, а не на if и goto. По сути же разницы не вижу никакой.
Я лишь имел в виду, что обычно чтение порта делают на while и break, а не на if и goto. По сути же разницы не вижу никакой.
Возможно разница есть- в скорости.
Что для меня сейчас является очень критичным. Попробую через while.
Я лишь имел в виду, что обычно чтение порта делают на while и break, а не на if и goto. По сути же разницы не вижу никакой.
Возможно разница есть- в скорости.
Что для меня сейчас является очень критичным. Попробую через while.
Какая может быть тут скорость, когда используется "узкое горлышко" - UART ?
Да, о скорости и я бы не стал беспокоиться, тут в некоторых местах наоборот, подтормаживать приходится.
Чёт не работает. Оно будет работать на ардуино про мини?
А зачем нужно два serial порта? Чтоб в один отладочную инфу выводить? А если она мне не нужна, я могу использовать хардовый для модуля?
Чёт не работает. Оно будет работать на ардуино про мини?
А зачем нужно два serial порта? Чтоб в один отладочную инфу выводить? А если она мне не нужна, я могу использовать хардовый для модуля?
Два serial порта потому что, для arduino pro micro Serial - это usb, а Serial1 - это как раз выводы TX и RX yf плате.
Честно говоря не понял. Разве этот USB-UART распаянный на самой плате ардуино не к тем же единственным RxTx подцеплен?
Тогда я не верно спросил, походу. У меня не совсем Ардуино про мини. У меня голая atmega328p с кварцем, прошитая загрузчиком Arduino Pro mini 5v 8MHz. У неё есть только её выходы, только один RxTx и к нему я цепляюсь UARTом чтоб шить её.
Я могу периписать код, вывинув оттуда софтовый Serial и отладочную инфу, а ESP-01 подцепить к хардварному RxTx моей самопальной ардуины?
Да, конечно. А перед заливкой скетча просто будете отсоединять ESP от RXTX.
Ничё не могу понять. Прошил модуль. Скорость 115200. Поставил её в скетче. Подключил модуль. Модуль моргает, но к сети не подключается. Подцепился терминалом, вроде всё норм, сообщения такие на модуль уходят:
Но он к сети не коннектится. Если терминалом на модуль это самое отправляю, то коннектится к сети нормально.
Ладно. Модуль настроил, к сети он подключается. А дальше что? Должен быть доступен веб сервер на его IP?
Скеч, на всякий случай:
#define SSID "My_AP" //им€ сети #define PASS "pass12345" //пароль #define DST_IP "192.168.1.121" //ip web сервера const String id="t01"; //id устройства #define START_CHAR '!' //начальный символ принимаемого сообщения #define END_CHAR '$' //конечный символ принимаесого сообщения String WiFiMessage=""; //принимаемое сообщение unsigned int readChar; //переменная для посимвольного чтения сообщения boolean readingWiFi; //флаг чтения сообщения String ip = ""; //переменна€ дл€ хранени€ ip устройства char character; int hardReset = 6; //пин arduino, на котором весит ch_pd boolean connected=false; //флаг соединения WiFi void setup() { pinMode(hardReset, OUTPUT); Serial.begin(115200); Serial.setTimeout(5000); digitalWrite(hardReset, LOW); delay(100); digitalWrite(hardReset, HIGH); delay(5000); for(int i=0;i<5;i++) { if(connectWiFi()) { connected = true; break; } } if (!connected){while(1); } delay(2000); } void loop() { if (Serial.available() > 0 && !readingWiFi) { if (Serial.read() == START_CHAR) { WiFiReadData(); } } } void WiFiReadData() { WiFiMessage = ""; readingWiFi = true; iniReading: if (Serial.available() > 0) { readChar = Serial.read(); if (readChar == END_CHAR) { goto endReading; } else { WiFiMessage.concat(readChar); goto iniReading; } } goto iniReading; endReading: readingWiFi = false; ///здесь парсинг сообщения и последующие действия //Serial.println(WiFiMessage); } /*функци€ отправки сообщени€ web-серверу*/ boolean sendMSG(String modul_id,String value,boolean startMSG) { String cmd = "AT+CIPSTART=1,\"TCP\",\""; cmd += DST_IP; cmd += "\",80"; //Serial.println("Connecting to WebServer"); Serial.println(cmd); Serial.flush(); delay(1000); /*if(Serial.find("OK")) { //Serial.print("OK, Connected to WebServer "); //Serial.println(DST_IP); } else { //Serial.print("Can not connect to WebServer "); //Serial.println(DST_IP); }*/ String msg= "GET /ajax/arduino_read.php?act="; if(startMSG) { msg+="new_w&id="; } else { msg+="s_t_h&id="; } msg+= modul_id; msg+= "&val="; msg+= value; msg+= " HTTP/1.1\r\nHost: "; msg+= DST_IP; msg+= ":80\r\n\r\n"; Serial.print("AT+CIPSEND=1,"); Serial.println(msg.length()); //Serial.println("Senting MSG"); if (Serial.find(">")) { //Serial.print("MSG text: "); //Serial.println(msg); Serial.print(msg); Serial.flush(); } if(Serial.find("SEND OK")) { return true; } else { return false; } } /*функци€ конекта к wifi сети*/ boolean connectWiFi() { ip=""; Serial.println("AT+CWMODE=1"); String cmd="AT+CWJAP=\""; cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; //Serial.print("Connecting to "); //Serial.println(SSID); Serial.println(cmd); delay(1000); if(Serial.find("OK")) { //Serial.println("OK, Connected to WiFi."); Serial.println("AT+CIFSR"); Serial.flush(); delay(1000); while(Serial.available()) { character = Serial.read(); if(character=='.' || character>='0' && character<='9') ip.concat(character); } if(ip != "") { //Serial.print("IP Address of ESP8266: "); //Serial.println(ip); } ///включаем режим приема/передачи Serial.println("AT+CIPMODE=0"); Serial.println("AT+CIPMUX=1"); Serial.flush(); delay(1000); //Serial.println("Starting TCP Server"); Serial.println("AT+CIPSERVER=1,80"); Serial.flush(); delay(1000); if (Serial.find("OK")) { //Serial.println("OK, Strart TCP Server"); } else { //Serial.println("Can not start TCP Server"); } Serial.println("AT+CIPSTO=120"); Serial.flush(); delay(1000); //отправл€ем информацию об устройстве при его старте String msg= "temp_"; msg+= ip; if(sendMSG(id,msg,true)) { //Serial.println("Startup info was send"); return true; } else { //Serial.println("Startup info was not send"); return false; } } else { //Serial.println("Can not connect to the WiFi."); return false; } } String floatToString(float value, byte precision) { int intVal = int(value); unsigned int frac; if(intVal >= 0) { frac = (value - intVal) * precision; } else { frac = (intVal - value) * precision; } return String(intVal) + "." + String(frac); }Если раскомментить строку 069 и набрать в браузере IP-адрес из строки 159 , должен показать запрос из браузера.
Ладно. Модуль настроил, к сети он подключается. А дальше что? Должен быть доступен веб сервер на его IP?
Чтобы отправить запрос посредством php, необходимо, как говорилось выше, нужно раскомментировать строку 69 и запустить следующий php скрипт:
<? $fp = fsockopen("ip вашего модуля", 80, $errno, $errstr); if (!$fp) { echo "ERROR: $errno - $errstr<br />\n"; } else { f write($fp, "!my_text$"); fclose($fp); echo "Send OK"; } ?>