• Система автоматизации с открытым исходным кодом на базе 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 для передачи данных


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