• Система автоматизации с открытым исходным кодом на базе 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 протокол сам-же на мелкие пакеты не разбивает. Как-бы это протестить. Может кто нибудь знает программу для винды в которой такой пакет можно отправить?
 
Сверху Снизу