• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь ESP+arduino

Bposter

New member
Доброго, помогите разобраться.

Задача в том чтоб через wi-fi управлять включением и выключением двух свето диодов, когда в браузере ввожу http://192.168.1.103/q то диод включается а W выключается, на второй диод тоже команды E включить R выключить. В проэкте использую Wi-Fi модуль NodeMCU V3 ESP8266 (CH340) и Arduino UNO.

Загвоздка в том что не корректно как то все работает, если включить два свето диода и потом попробывать отключить один из них то могут отключится сразу два, в общем работает как хочет. После рестарта поначалу вроде как норм работает, может где то в памяти храница старые значения и поэтому так работает?

ESP
Код:
#include <ESP8266WiFi.h>

const char* ssid = "Test";
const char* password = "Test";

WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);
 
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
 
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
   
  }
 
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  client.flush();

  // Prepare the response
  String s = "<!DOCTYPE HTML>\r\n<p><a href='/q'>q</a></p><br/><p><a href='/w'>w</a></p><br/><p><a href='/e'>e</a></p><br/><p><a href='/r'>r</a></p><html>\r";
  //s += req;
  s += "</html>\n";

  // Send the response to the client
  client.print(s);
Serial.println(req);

}
Arduino
Код:
int outputPin = 13;
int p = 8;
char val;                          

void setup()
{
  Serial.begin(115200);             
  pinMode(outputPin, OUTPUT);     
  pinMode(p, OUTPUT);
}

void loop()
{ 
  if (Serial.available()) {

      val = Serial.read();
               
    if (val == 'q') {              
      digitalWrite(outputPin, HIGH);
    }
    if(val == 'e'){
      digitalWrite(p, HIGH);
    }
    if (val == 'r') {              
      digitalWrite(p, LOW);    
    }
    if (val == 'w') {              
      digitalWrite(outputPin, LOW);
    }
  }

}
 

CodeNameHawk

Moderator
Команда форума
Так и посылайте в Serial "только свои буквы" управления, а то валите туда все подряд.
Что у вас в req содержится?
 

Юрий Ботов

Moderator
Команда форума
Не "то что ввели в браузере", а "то что браузер послал". Это разные вещи. Браузер обычно (через формы) посылает все поля формы в формате ?name1=value1&name2=value2 и т.д. А при посылке через ajax там может быть вообще что угодно, впрочем скорее всего json - {"name1":"value","name2":"value2"}
 

fandy

Member
Там у него нет никаких форм или аяксов. Там простые ссылки. То есть в req должно быть типа:
GET /q HTTP/1.1

А так, понятно что отладка.
Делаете с помощью SoftwareSerial второй UART на UNO и лупите туда все подряд. Даже думать нечего.
 
Последнее редактирование:

Bposter

New member
Всем спс буду пробывать,
fandy да в мониторинге COM порта приходят данные типа GET /q HTTP/1.1

В справочнике прочитал что когда соединяем по rx tx два устройства то им нужно соединять землю, так ли это?
 
Последнее редактирование:

Bposter

New member
Добрый вечер, помогите в таком вопросе, обращаюсь к веб странице через NodeMCU получаю ответ:

Код:
    String line = client.readStringUntil('\r');
    Serial.print(line);
ответ такого типа:
Код:
HTTP/1.1 200 OK
Server: nginx/1.9.12
Date: Wed, 28 Sep 2016 18:20:06 GMT
Content-Type: text/html
Content-Length: 2
Connection: close
X-Powered-By: PHP/5.3.29-pl0-gentoo

A0
Как вытащить значение A0 ?
 

Юрий Ботов

Moderator
Команда форума
Искать последовательность "\r\n\r\n" (это для C или C++) сразу после нее будет A0

int httpcnt = 0;
char httpprev = ' ';
while (client.available()) {
char c = client.read();

if((httpprev == '\n' && c == '\r') || (httpprev == '\r' && c == '\n')) { httpcnt++;} else {httpcnt = 0;}
httpprev = c;
if(httpcnt == 3) { нашли, дальше куда нибудь сохраняем}
}
 

Юрий Ботов

Moderator
Команда форума
int httpcnt = 0; // счетчик
char httpprev = ' '; // "предыдущий" символ
while (client.available()) { // пока в буфере что то есть
char c = client.read(); // прочесть символ из буфера

if((httpprev == '\n' && c == '\r') || (httpprev == '\r' && c == '\n')) { если предыдйщий символ \n и текущий \r или наоборот
httpcnt++;
} else {
httpcnt = 0; // иначе сбросить счетчик
}
httpprev = c; // запоминаем текущий символ как предыдущий
if(httpcnt == 3) {
//rn+nr+rn нашли, это пустая строка перед нужной нам строкой. Дальнейшие символы куда нибудь сохраняем - это искомый ответ... что то засомневался на счет "3"... возможно "2".
}
}
 

nikolz

Well-known member
можно сделать проще, если учесть что коды управляющих символов, которыми являются и символы /r, /n меньше 32(код пробела)
будет так:
--------------------------
int lenS=32; //размер буфера принятой строки
char str[lenS]; //определить буфер для строки
int count=0; //счетчик длины строки
//~~~~~~~~~~~~~~~~~~~~~~~``
while (client.available()) { // пока в буфере что то есть
char c = client.read(); // прочесть символ из буфера
if ( c>=32) {str[count]=c; count++ ; str[count]=0; } //запоминаем алфавитно-цифровые символы
else { обработать полученную строку в буфере; count=0; }
}
}
 

nikolz

Well-known member
Ваше "проще" работать как надо не будет. Вместо того, чтобы выделить заданную строку, вы пускаете в обработку все строки, в том числе пустые.
согласен, так как не совсем понятно, что же надо найти.
Если надо найти конкретную строку , то это это делается сравнением строк
здесь
else { обработать полученную строку в буфере; count=0; }
------------------
Разница с Вашим решением в том, что я просто убираю все управляющие символы а потом обрабатываю строку по ее содержимому.
При этом можно раскручивать многострочные послания не обращая внимание на управляющие символы.
-----------------------
Если надо найти одну конкретную строку, то тоже нет смысла обнаруживать управляющие символы а сразу искать строку.
 

Bposter

New member
Смысл в том что на веб сервере в базе данных будут храница значения типа A0 и A1 и тд.... A0 выключит определенное реле A1 включить, поэтому если не считать http заголовков до строки будут типа:
A1
B0
C0

искал похожие поделки в нете и пишут что за частые обращения к серверу могут заблокировать ( пишут что лучше использовать MQTT. Кто что думает по этому поводу?
 

Bega5

New member
Спецы помогите новичку. У меня проблема такая когда включать свич LED-1 должен загореца лампочка LED-1 а когда включить свич LED-2 должен LED-2 лампочка. Но у меня не горит лампочки на программе RemoteXY а на подключенном ардуино горит. Вот код :
 

Вложения

Bega5

New member
вот код:


//////////////////////////////////////////////
// RemoteXY include library //
// use library version 2.2.5 or up //
// use ANDROID app version 3.7.1 or up //
//////////////////////////////////////////////

/* определение режима соединения и подключение библиотеки RemoteXY */
[HASHTAG]#define[/HASHTAG] REMOTEXY_MODE__HC05_HARDSERIAL

[HASHTAG]#include[/HASHTAG] <RemoteXY.h>

/* настройки соединения */
[HASHTAG]#define[/HASHTAG] REMOTEXY_SERIAL Serial
[HASHTAG]#define[/HASHTAG] REMOTEXY_SERIAL_SPEED 9600


/* конфигурация интерфейса */
[HASHTAG]#pragma[/HASHTAG] pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 2,2,104,0,6,5,0,2,0,65
,18,22,11,2,79,78,0,79,70,70
,0,2,0,65,41,22,11,2,79,78
,0,79,70,70,0,65,4,15,15,9
,9,2,65,4,15,41,9,9,2,130
,1,63,9,26,46,9,129,0,67,11
,17,6,0,76,69,68,45,49,0,129
,0,67,34,17,6,0,76,69,68,45
,50,0,129,0,28,17,17,6,0,76
,69,68,45,49,0,129,0,28,43,17
,6,0,76,69,68,45,50,0 };

/* структура определяет все переменные вашего интерфейса управления */
struct {

/* input variable */
uint8_t switch_1; /* =1 если переключатель включен и =0 если отключен */
uint8_t switch_2; /* =1 если переключатель включен и =0 если отключен */

/* output variable */
uint8_t Led_1_r; /* =0..255 яркость красного цвета индикатора */
uint8_t Led_2_r; /* =0..255 яркость красного цвета индикатора */

/* other variable */
uint8_t connect_flag; /* =1 if wire connected, else =0 */

} RemoteXY;
[HASHTAG]#pragma[/HASHTAG] pack(pop)

/////////////////////////////////////////////
// END RemoteXY include //
/////////////////////////////////////////////

[HASHTAG]#define[/HASHTAG] PIN_SWITCH_1 12
[HASHTAG]#define[/HASHTAG] PIN_SWITCH_2 13


void setup()
{
RemoteXY_Init ();

pinMode (PIN_SWITCH_1, OUTPUT);
pinMode (PIN_SWITCH_2, OUTPUT);

// TODO you setup code

}

void loop()
{
RemoteXY_Handler ();

digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
digitalWrite(PIN_SWITCH_2, (RemoteXY.switch_2==0)?LOW:HIGH);

// TODO you loop code
// используйте структуру RemoteXY для передачи данных


}
 

tretyakov_sa

Moderator
Команда форума
Спецы помогите новичку. У меня проблема такая когда включать свич LED-1 должен загореца лампочка LED-1 а когда включить свич LED-2 должен LED-2 лампочка. Но у меня не горит лампочки на программе RemoteXY а на подключенном ардуино горит. Вот код :
Сделайте так:
Код:
void loop()
{
RemoteXY_Handler ();

digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
digitalWrite(PIN_SWITCH_2, (RemoteXY.switch_2==0)?LOW:HIGH);
RemoteXY.Led_1_r=RemoteXY.switch_1*255;
RemoteXY.Led_2_r=RemoteXY.switch_2*255;
// TODO you loop code
// используйте структуру RemoteXY для передачи данных


}
 
Последнее редактирование:
Сверху Снизу