Как правильно разобрать UDP пакет ?
- Войдите на сайт для отправки комментариев
В продолжении темы : http://arduino.ru/forum/programmirovanie/soedinenie-2-arduino-nano-cherez-ethernet
Краткое описание железа: 2 arduino nano + 2 ENC28J60
Постепенно, шаг за шагом, удалось добиться того, чтобы сервер принимал от клиента udp пакеты с содержанием в поле data определённого сообщения, true или false в зависимости от того нажата кнопка или нет.
Вот код сервера:
#include <UIPEthernet.h>
EthernetUDP udp;
void setup() {
Serial.begin(9600);
uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05};
Ethernet.begin(mac,IPAddress(192,168,10,227));
int success = udp.begin(5000);
Serial.print("initialize: ");
Serial.println(success ? "success" : "failed");
}
void loop() {
//check for new udp-packet:
int size = udp.parsePacket();
if (size > 0) {
do
{
char* msg = (char*)malloc(size+1);
int len = udp.read(msg,size+1);
msg[len]=0;
Serial.print("received: '");
Serial.print(msg);
free(msg);
}
while ((size = udp.available())>0);
//finish reading this packet:
udp.flush();
Serial.println("'");
int success;
do
{
Serial.print("remote ip: ");
Serial.println(udp.remoteIP());
Serial.print("remote port: ");
Serial.println(udp.remotePort());
//send new packet back to ip/port of client. This also
//configures the current connection to ignore packets from
//other clients!
success = udp.beginPacket(udp.remoteIP(),udp.remotePort());
Serial.print("beginPacket: ");
Serial.println(success ? "success" : "failed");
//beginPacket fails if remote ethaddr is unknown. In this case an
//arp-request is send out first and beginPacket succeeds as soon
//the arp-response is received.
}
while (!success);
success = udp.println("hello world from arduino");
Serial.print("bytes written: ");
Serial.println(success);
success = udp.endPacket();
Serial.print("endPacket: ");
Serial.println(success ? "success" : "failed");
udp.stop();
//restart with new connection to receive packets from other clients
Serial.print("restart connection: ");
Serial.println (udp.begin(5000) ? "success" : "failed");
}
}
Теперь у меня ступор, никак не могу использовать данные из udp пакета. Ещё и пакет разбирается с использованием "наворотов" c++ . Ребята, кто силён , помогите плииззз...Мне нужно чтобы при получении пакетов например "true" любой цифровой выход был в состоянии "0" , как только получаем пакет "false" этот цифровой выход переходил в состояние "1"
Вот код клиента:
#include <UIPEthernet.h>
EthernetUDP udp;
unsigned long next;
int switchPin = 8;
int ledPin = 7;
void setup() {
Serial.begin(9600);
uint8_t mac[6] = {0x01,0xA1,0xB2,0xA3,0x04,0x05};
Ethernet.begin(mac,IPAddress(192,168,10,226));
next = millis()+5000;
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
int success;
int len = 0;
if (((signed long)(millis()-next))>0)
{
do
{
success = udp.beginPacket(IPAddress(192,168,10,227),5000);
Serial.print("beginPacket: ");
Serial.println(success ? "success" : "failed");
//beginPacket fails if remote ethaddr is unknown. In this case an
//arp-request is send out first and beginPacket succeeds as soon
//the arp-response is received.
}
while (!success && ((signed long)(millis()-next))<0);
if (!success )
goto stop;
if (digitalRead(switchPin) == HIGH)
{
success = udp.write("false");
}
else
{
success = udp.write("true");
}
Serial.print("bytes written: ");
Serial.println(success);
success = udp.endPacket();
Serial.print("endPacket: ");
Serial.println(success ? "success" : "failed");
do
{
//check for new udp-packet:
success = udp.parsePacket();
}
while (!success && ((signed long)(millis()-next))<0);
if (!success )
goto stop;
Serial.print("received: '");
do
{
int c = udp.read();
Serial.write(c);
len++;
}
while ((success = udp.available())>0);
Serial.print("', ");
Serial.print(len);
Serial.println(" bytes");
//finish reading this packet:
udp.flush();
stop:
udp.stop();
next = millis()+5000;
}
}
Пока что вышел из положения таким вот образом
код сервера:
void loop() { //check for new udp-packet: int size = udp.parsePacket(); if (size > 0) { do { char* msg = (char*)malloc(size+1); int len = udp.read(msg,size+1); msg[len]=0; Serial.print("received: '"); Serial.println(msg); Serial.print("Len: '"); Serial.println(len); if (len==4) { Serial.print("DLINA PAKETA 4"); digitalWrite(ledPin, LOW); } else if (len == 5) { Serial.print("DLINA PAKETA 5"); digitalWrite(ledPin, HIGH); } else { Serial.print("OTSTOY"); } free(msg); }goto stop;
Не делай так. Это плохо, и в приличном обществе за это бьют канделябром.
goto stop;
Не делай так. Это плохо, и в приличном обществе за это бьют канделябром.
А как делать ? Это было в стандартном примере к библиотеке, ну я так и оставил. Я ещё не силён в программировании Arduino и уж тем более в с++ ))) Если подскажете буду благодарен. И по сабжу, не подскажите, как всё таки воспользоваться содержанием data из пакета udp, а то мне кажется, что с длинной пакета, могу получить глюки ))))
Например так
if (success) { Serial.print("received: '"); do { int c = udp.read(); Serial.write(c); len++; } while ((success = udp.available())>0); Serial.print("', "); Serial.print(len); Serial.println(" bytes"); //finish reading this packet: udp.flush(); } udp.stop(); next = millis()+5000;Последние две строки выполняются в любом случае.
ТС: Ответьте честно - Вы же не понимаете что и почему делает код?
ТС: Ответьте честно - Вы же не понимаете что и почему делает код?
Да, я не понимаю часть кода, где цикл do-while , так как ещё очень мало времени дружу с ардуино. Но я этого и не Скрывал в самом начале топика. Только вот не пойму, к чему этот каверзный вопрос ? Именно для того, чтобы немного разобраться я сюда и написал, если бы я знал всё, думаю врядли бы я задавал вопросы.
А вопрос не каверзный. мне интересно Вам надо разобраться или чтобы заработало? Если разабраться - то читать документацию и спрашивать.
А вопрос не каверзный. мне интересно Вам надо разобраться или чтобы заработало? Если разабраться - то читать документацию и спрашивать.
Мне надо разобраться, чтобы заработало :) Ну на самом деле, всё что требовалось от конструкции (нажал кнопку на одном устройстве, на другом сработало реле) это работает, и в принципе этого было бы достаточно, но именно из-за того, что я хочу разобраться, как это работает я и пришел сюда :) Всё что на данный момент я нашел по ардуино, более или менее нормальную информацию для восприятия, это видеоуроки джереми блума и справочная информация с этого сайта, ну ещё что-то там на амперке. Если вы подскажите ссылки на хорошие ресурсы, где почитать или посмотреть, я не откажусь )
"Почитать или посмотреть" - так Вы научитесь только правильно использовать чужой код :)
Попробуйте разобраться в Вашем коде, попробуйте его переписать по другому, но чтобы также работал. Так понимание и придет :)
Документации тут вполне хватит чтобы разобраться.
Документации тут вполне хватит чтобы разобраться.
Хорошо, вот смотрите, например: Есть библиотека, которую я использую (UIPEthernet), в ней есть классы которые я могу использовать в своём коде, а вот как правильно использовать эти классы я не могу понять :(
"Почитать или посмотреть" - так Вы научитесь только правильно использовать чужой код :)
Я имел ввиду почитать какой либо чебный материал. Документация это хорошо, но нужно ещё чтобы всё разложилось по полочкам )))) На четвертом десятке лет, восприимчивость мозга хромает(надо было в 20 лет учится а в 30 по бабам бегать) )))
Но в целом ваш совет я понял !!!
Хорошо, вот смотрите, например: Есть библиотека, которую я использую (UIPEthernet), в ней есть классы которые я могу использовать в своём коде, а вот как правильно использовать эти классы я не могу понять :(
если библиотека написана грамотно и не "только для себя", то там перед каждым методом будет описание (в комментариях) - что делает, что принимает и что возвращает.
Второй Ваш довод я со смехом отметаю как заблуждения молодого ;)