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

Arduino и ESP8266 на 0 и 1 ноге

JustACat

Moderator
Команда форума
Emmy, в документации на AT+CIPSTART описано 6 параметров, 2 последних как раз для UDP. Вы пробовали эти 2 последних параметра использовать (у вас в примере только первые 4-ре)?
Документ 4B-AT-Espressif AT Command Examples_v0.4.pdf - есть примеры на 14 и 15 страницах.
Вот, пока номера страниц искал - вы вроде сами разобрались. В любом случае там есть примеры по UDP довольно подробные.

Update: и правильнее все таки испольховать все 6 параметров, либо только первые 4. А не 5, как вы написали.
 

Emmy

Member
если кто нибудь расшифрует что это значит - буду очень благодарен... гугл переводчик не помог
0 : destination peer entity of UDP will not change.
1 : destination peer entity of UDP can change once.
2 : destination peer entity of UDP is allowed to change.
 

Emmy

Member
вот огромное спасибо за 4 или 6. скажите что значит последний параметр. для чего с чем едят
 

JustACat

Moderator
Команда форума
Ну, смотрите, синтаксис такой:
AT+CIPSTART=<id>,"<type>","<addr>",<port>[,<local_port>,<mode>]
Где:
<id> - некий номер (от 0 до 4) внутреннего сокета в ESP, чтобы его можно было потом закрыть (CIPCLOSE), либо данные в него слать (CIPSEND)
<type> - тоже понятнее некуда TCP или UDP
<addr> - IP адрес удаленного узла (не адрес ESP и не маска) - сюда нужно указать именно IP того узла, с которого вы предполагаете получать пакеты и на который будут отправляться пакеты командой CIPSEND=<id>,...
<port> - соответственно это порт удаленного узла (опять же не ESP)
Последние два чисто для UDP:
<local_port> - это уже как раз порт ESP, на котором ESP будет ждать UDP пакеты из внешнего мира
<mode> - режим работы UDP соединения, 3 варианта:
0 - <addr> и <port> не меняются никогда для данного <id>, то есть 1 раз установили в CIPSTART, и такие они и будут вплоть до CIPCLOSE этого <id>
2 - <addr> и <port> для данного <id> будут меняться каждый раз на те, с которых к ESP придет очередной пакет, таким образом ESP сможет отвечать (через CIPSEND) всегда тому узлу, который прислал ей последний пакет
1 - это как 2, но только 1 раз срабатывает... Я так понимаю, это сделано для того, чтобы можно было стартовать, не зная <addr> и <port> удаленного узла (забив от балды, как у вас 255.255.255.255, например), а как только какой-то удаленный узел пошлет на ESP первый пакет, ESP запомнит <addr> и <port> именно этого узла и далее будет слать ответы на него (даже если будут прилетать пакеты с других узлов)

Не знаю, понятно ли объяснил, но сам понял на 100% :)

Update: чуть прояснил еще, и добавил порядка...
 
Последнее редактирование:

Emmy

Member
спасибо. это замечательно и понятно. :)
очень здорово. все как мне нужно
 

Victor

Administrator
Команда форума
синтаксис такой
Зная адрес подсети и маску, можно вычислить (к адресу сети побитово прибавить инверсную маску) broadcast адрес, вот его туда и вставлять вместо 255.255.255.255, а не от балды.
Тогда пакет получат все устройства в подсети до маршрутизатора. Но это теоретически, я на практике не пробовал. У нас тут вроде были люди, кто широковещательные пакеты в сеть слал, лучше спросить у них.
 

JustACat

Moderator
Команда форума
Victor, тогда надо последним параметром обязательно выставить 0 - иначе при первом входящем пакете наши установки перетрутся его отправителем :)
А так да - надо затестить, ибо не факт, что сработает, но я бы попробовал, сейчас просто не в состоянии уже...
А так там делов на 5 мин:
AT+CIPSTART=1,"UDP","192.168.168.255",8080,8081,0
Да потом CIPSEND=1,...
И на ПК словить попробовать этот пакет на порту 8080. Только чтобы там какие-нить антивирусы файрволы не фильтровали...

PS: 192.168.168.255 - это для моей сетки, если что :)
 

Emmy

Member
возник вопрос по пакетам
допустим я пишу while(Serial.available()) { } //пока все что есть не обработаю не выйду, но иногда остатки не успели дойти. есть способ гарантированно дополучить остатки от пакета
 

Emmy

Member
P.S. я ставил 2, посылал в эфир, широковещательно. все норм вроде
 

Victor

Administrator
Команда форума
есть способ гарантированно дополучить остатки от пакета
я делал так (с SimpleFIFO)
Код:
void loop() {
   while (Serial.available() > 0)
   {
      char c = Serial.read();
      if (queue.count() > Q_BUFF)
      {
#ifdef DEBUG
         debugSerial->println("QUEUE IS FULL!");
         queue.flush();
#endif
      }
      queue.enqueue(c);
   }
  processData();
}
Подробнее посмотрите тут https://code.google.com/p/er9x-frsk...APM_Mavlink_to_FrSky/APM_Mavlink_to_FrSky.ino
 
Последнее редактирование:

Emmy

Member
я не настролько хороший программист :(
я так понял существет какой то буфер? или что. мало информации
 

Emmy

Member
сделал сделал бесконечный цикл и if (strstr ( command, "OK")) {break;}
ок бывает в конце пакета.

if (strlen(command)>200) {break;}
//защита от переполнения
 

Victor

Administrator
Команда форума
постоянно опрашиваете порт и если есть данные, то шлете не в переменную, а в очередь.
Если данных в порту нет, то обрабатываете только полные пакеты в очереди (если "недоприняли" пакет, то его "передняя часть" останется в очереди после обработки)
и снова опрашиваете порт и "недопринятый" хвостик принимается. Таким образом ничего не теряется (если конечно, очередь не переполнится)
https://github.com/rambo/SimpleFIFO
 

Emmy

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

Victor

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

Emmy

Member
да, я не верно спросил/думал. такой способ гарантировано ведет в истощение памяти.

если сильны в программировании - не могли бы поправить или подсказать направление в вопросе ПРОПУСКА лишних пакетов и обработки только первого

у меня пока так. если не быстро отправлять пакеты то все нормально. а флуд = принимает больше чем нужно или делятся пополам пакеты.



Код:
  while(Serial.available()) {
delay(2);
//ЕСЛИ УБРАТЬ ТО ВСЕ ПАКЕТЫ ГАРАНТИРОВАНО БУДУТ НЕ ПОЛНОСТЬЮ ПОЛУЧЕНЫ
char c=Serial.read();
  
  
if ((c>=32) and (c<=127)) {
 
  //длинна строки  
  int L = strlen(command);
  command = (char *) realloc(command, L+2); // один символ добавится
  command[L]= c;
  command[L+1]='\0';
}
  //пропускаем все не печатаемые символы для удобства
if (strlen(command)>60) {break;}
//защита от переполнения буфера
  }
 

Victor

Administrator
Команда форума
да не, я не особо силен, но постараюсь помочь
delay - убрать, все символы накапливать в String buf, длину переменной мерять только на предмет переполнения, после Serial.read искать паттерн в буфере
Код:
if (buf.indexOf("то что мы ищем") > -1) {
    ....
    buf="";
}
 

Evgen

New member
А что будет если ESP-шке отправить UDP пакет килобайт так 30-40? UDP протокол сам-же на мелкие пакеты не разбивает. Как-бы это протестить. Может кто нибудь знает программу для винды в которой такой пакет можно отправить?
 
Сверху Снизу