Пользует ли кто WiFi-модули ESP8266 ? Поделитесь впечатлениями.

boban_
Offline
Зарегистрирован: 09.10.2013

Ты устройству, устройство по сом порту на ардуино, ардуино обрабатывает команду.

Только так.

Araris
Offline
Зарегистрирован: 09.11.2012

Я для пересылки данных между Ардуинами пользуюсь 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. Парсим строку всячески.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

NEGr пишет:

Вопрос в том как можно отработать обратную связь: делать запрос из php устройсту, чтобы то запустило какой-то набор действий на arduino? Или это только путем поднятия web-сервера на arduino?

Тут два момента: кто должен быть инициатором соединения? Может ардуина обратиться к серверу и получить ответ, который будет содержать какие-то команды на исполнение. Или же php (curl) будет инициировать запрос к ардуине и тоже передавать ей какие-то  GET-параметры...

У меня примерно так дистанционно включается и выключается генерация на grid-tie инверторе: если в параметрах строки запроса к ардуине переменная a=6 то ардуина дергает ножкой и включает мосфет.

NEGr
Offline
Зарегистрирован: 12.05.2014

Andrey_Y_Ostanovsky пишет:

NEGr пишет:

Вопрос в том как можно отработать обратную связь: делать запрос из php устройсту, чтобы то запустило какой-то набор действий на arduino? Или это только путем поднятия web-сервера на arduino?

Тут два момента: кто должен быть инициатором соединения? Может ардуина обратиться к серверу и получить ответ, который будет содержать какие-то команды на исполнение. Или же php (curl) будет инициировать запрос к ардуине и тоже передавать ей какие-то  GET-параметры...

У меня примерно так дистанционно включается и выключается генерация на grid-tie инверторе: если в параметрах строки запроса к ардуине переменная a=6 то ардуина дергает ножкой и включает мосфет.

php инициирует  get запросы, а arduino их должна принять и обрабаотать. и в случае если что-то произошло на самой arduino отправить в другую сторону новой статус или значение.

до этого все было построенно на nrf24, а хочется на wifi(универсальнее).

да web сервер развернут на компе с встроенным wifi

NEGr
Offline
Зарегистрирован: 12.05.2014

ты имееш в виду типа этого:

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 команду выполнить)? Кто-нибудь пробовал подобное провернуть?

Araris
Offline
Зарегистрирован: 09.11.2012

NEGr пишет:

...как послать данные устройству с сервера(через 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

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

Ардуино "слушает" в этот момент 80-й порт ?

Я имею в виду AT+CIPSERVER=1,80

Пробовал и AT+CIPSERVER=1,80 и AT+CIPSTART режимы. Одно и тоже - не может достучаться. не php не telnet. Есть еще какие-нибудь предположения?

Araris
Offline
Зарегистрирован: 09.11.2012

А кто-то другой, кроме php / telnet, может достучаться ? В WiFiMessage хоть из браузера можно что-нибудь получить ?

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

А кто-то другой, кроме php / telnet, может достучаться ? В WiFiMessage хоть из браузера можно что-нибудь получить ?

не понял... что значит из браузера?

Araris
Offline
Зарегистрирован: 09.11.2012

В адресной строке браузера вводим http://192.168.1.111/ , IP соответствующий. В этот момент уже что-то (GET) будет отправлено. Сможете ли Вы принять "что-то" ?

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

В адресной строке браузера вводим 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;
    }
}

после подключения выводит следующие значения:

Araris
Offline
Зарегистрирован: 09.11.2012

1. К коду претензий не имею, мы явно брали код-основу из одного источника. Я еще AT+RST посылаю вначале, а так все один в один почти. А вот почему ничего не принимает, вряд ли догадаюсь, дальше я иду другим путем (ловлю бродкастные UDP-пакеты)

2. А что это за длинный ряд цифр в окне монитора порта ?

Araris
Offline
Зарегистрирован: 09.11.2012

Вот, для сравнения



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(); }
} 

 

NEGr
Offline
Зарегистрирован: 12.05.2014

длинный ряд - это то что ловится в serial1 после того как произошло подключение к wifi. Что это за фигня- фиг знает.

Araris
Offline
Зарегистрирован: 09.11.2012

NEGr пишет:

длинный ряд - это то что ловится в serial1 после того как произошло подключение к wifi. Что это за фигня- фиг знает.

Ага. Я, кстати, на всякий случай даю паузу и чищу буфер после каждой команды ( ESPFlushSerial(delay) )

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

NEGr пишет:

длинный ряд - это то что ловится в serial1 после того как произошло подключение к wifi. Что это за фигня- фиг знает.

Ага. Я, кстати, на всякий случай даю паузу и чищу буфер после каждой команды ( ESPFlushSerial(delay) )

А у тебя при обращении из браузера - что-то отлавливается на arduino????

 

Araris
Offline
Зарегистрирован: 09.11.2012

Отлавливалось +IPD,id,len:data , но потом я ушел с TCP на UDP.

Впрочем, неважно, там та же +IPD приходит.

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

Отлавливалось +IPD,id,len:data , но потом я ушел с TCP на UDP.

Впрочем, неважно, там та же +IPD приходит.

А какую arduino ты использовал для тестов???

Araris
Offline
Зарегистрирован: 09.11.2012

Нано (SoftwareSerial) и Мега (Hardware Serial). Какую - неважно.

Я бы посоветовал посмотреть в connectWiFi(), что отвечает Ардуина на команды AT+CWMODE=1 , AT+CIPMODE=0 , AT+CIPSERVER=1,80 ,  AT+CIPSTO=120.

NEGr
Offline
Зарегистрирован: 12.05.2014

Спасибо. так и сделаю, но теперь уже дома.

посмотрю выводы после каждой команды! может станет что-то яснее.

Если нет то попробую поднять web сервер на arduino и с ним работать

MaksMS
Offline
Зарегистрирован: 11.03.2013

NEGr пишет:

Если нет то попробую поднять web сервер на arduino и с ним работать

Даже не пытайтесь сделать веб сервер на ардуине с 1кб ОЗУ - максимум пару строк вывести реально. Памяти не хватит. На МЕГЕ заработает.

Тут так получается, что надо размер знать странички и для этого поместить её сначала в буфер..

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

Нано (SoftwareSerial) и Мега (Hardware Serial). Какую - неважно.

Я бы посоветовал посмотреть в connectWiFi(), что отвечает Ардуина на команды AT+CWMODE=1 , AT+CIPMODE=0 , AT+CIPSERVER=1,80 ,  AT+CIPSTO=120.

посмотрел ответы на все AT  команды. одни кракозябры. причем если искать Serial.find  то находит что нужно. Почему же в монитор порта выводится всякая аброкодабра?

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

NEGr пишет:

посмотрел ответы на все AT  команды. одни кракозябры. причем если искать Serial.find  то находит что нужно. Почему же в монитор порта выводится всякая аброкодабра?

Не совпадают скорость, битность, сама программа "монитора порта" кривая... Причем, иногда скорость на порту выставляешь, а она не выставляется - бывают и такие глюки.

NEGr
Offline
Зарегистрирован: 12.05.2014

Прогнал вот так : 

  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. не понятно что не так....

NEGr
Offline
Зарегистрирован: 12.05.2014

Как ни странно - прям мистика, но при обращении из браузера появился ответ, да и через сокеты тоже все ок. урааааааа!!!!!

Araris
Offline
Зарегистрирован: 09.11.2012

Вот и славно. delay(2000); - многовато, можно сильно уменьшить.

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

Вот и славно. delay(2000); - многовато, можно сильно уменьшить.

Еще один маленький вопросик: правильно ли я понимаю, чтобы отправить сообщение web-серверу, находясь в режиме tcp сервера, вначале перейти в режим tcp клиента и потом только отправлять сообщения. затем чтобы снова иметь возможность получать сообщения от web-сервера - снова перейти в режим tcp сервера????

Araris
Offline
Зарегистрирован: 09.11.2012

Почти правильно, режим сервера (AT+CIPSERVER=) включается при старте/рестарте модуля (на самом деле модуль помнит его и без этого, но это уже другая история), режим клиента запускаем (AT+CIPSTART=) перед отправкой (AT+CIPSEND=) и закрываем после отправки (AT+CIPCLOSE=). Можно и не закрывать, я пробовал, и без закрытия работает. Интуиция подсказывает, что AT+CIPSTART= перед каждой отправкой тоже можно не делать, но так я не пробовал.

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

Почти правильно, режим сервера (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);
  
}

Не подскажешь что может быть не так?

 

Araris
Offline
Зарегистрирован: 09.11.2012

Когда AT+CIPMUX=1, команда должна выглядеть как AT+CIPSTART=id,type,addr,port.

Кстати, рекомендую: https://github.com/espressif/esp8266_at/wiki/AT_Description

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

Когда AT+CIPMUX=1, команда должна выглядеть как AT+CIPSTART=id,type,addr,port.

Кстати, рекомендую: https://github.com/espressif/esp8266_at/wiki/AT_Description

Большое спасибо. 

NEGr
Offline
Зарегистрирован: 12.05.2014

Вроде бы все как-то заработало

 
Araris
Offline
Зарегистрирован: 09.11.2012
NEGr
Offline
Зарегистрирован: 12.05.2014

Зачет)))) 

Дейтвительно алилуя!

Sirocco
Offline
Зарегистрирован: 28.09.2013

NEGr пишет:
Вроде бы все как-то заработало

А можно ваши нароботки итоговые увидеть? 

NEGr
Offline
Зарегистрирован: 12.05.2014

Sirocco пишет:

NEGr пишет:
Вроде бы все как-то заработало

А можно ваши нароботки итоговые увидеть? 

Вот итоговый скетч:

#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);
}

 

Araris
Offline
Зарегистрирован: 09.11.2012

Спасибо, интересно, кое-что пригодится. WiFiReadData() весьма нестандартно реализована. Переменная readingWiFi явно лишняя в этом скетче.

NEGr
Offline
Зарегистрирован: 12.05.2014

дополнение к функции 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

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

Спасибо, интересно, кое-что пригодится. WiFiReadData() весьма нестандартно реализована. Переменная readingWiFi явно лишняя в этом скетче.

А можешь показать пример "стандартного" способа чтения?

Araris
Offline
Зарегистрирован: 09.11.2012

Я лишь имел в виду, что обычно чтение порта делают на while и break, а не на if и goto. По сути же разницы не вижу никакой.

NEGr
Offline
Зарегистрирован: 12.05.2014

Araris пишет:

Я лишь имел в виду, что обычно чтение порта делают на while и break, а не на if и goto. По сути же разницы не вижу никакой.

Возможно разница есть- в скорости.

Что для меня сейчас является очень критичным. Попробую через while.

MaksMS
Offline
Зарегистрирован: 11.03.2013

NEGr пишет:

Araris пишет:

Я лишь имел в виду, что обычно чтение порта делают на while и break, а не на if и goto. По сути же разницы не вижу никакой.

Возможно разница есть- в скорости.

Что для меня сейчас является очень критичным. Попробую через while.

Какая может быть тут скорость, когда используется "узкое горлышко" - UART ?

Araris
Offline
Зарегистрирован: 09.11.2012

Да, о скорости и я бы не стал беспокоиться, тут в некоторых местах наоборот, подтормаживать приходится.

Sirocco
Offline
Зарегистрирован: 28.09.2013

Чёт не работает. Оно будет работать на ардуино про мини?

А зачем нужно два serial порта? Чтоб в один отладочную инфу выводить? А если она мне не нужна, я могу использовать хардовый для модуля?

NEGr
Offline
Зарегистрирован: 12.05.2014

Sirocco пишет:

Чёт не работает. Оно будет работать на ардуино про мини?

А зачем нужно два serial порта? Чтоб в один отладочную инфу выводить? А если она мне не нужна, я могу использовать хардовый для модуля?

Два serial порта потому что, для arduino pro micro Serial - это usb, а Serial1 - это как раз выводы TX и RX yf плате.

 

Sirocco
Offline
Зарегистрирован: 28.09.2013

NEGr пишет:
Два 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 моей самопальной ардуины?

Araris
Offline
Зарегистрирован: 09.11.2012

Да, конечно. А перед заливкой скетча просто будете отсоединять ESP от RXTX.

Sirocco
Offline
Зарегистрирован: 28.09.2013

Ничё не могу понять. Прошил модуль. Скорость 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);
}

 

Araris
Offline
Зарегистрирован: 09.11.2012

Если раскомментить строку 069 и набрать в браузере IP-адрес из строки 159 , должен показать запрос из браузера.

NEGr
Offline
Зарегистрирован: 12.05.2014

Sirocco пишет:

Ладно. Модуль настроил, к сети он подключается. А дальше что? Должен быть доступен веб сервер на его 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";
}
?>