Как правильно разобрать UDP пакет ?

Dump
Offline
Зарегистрирован: 01.06.2015

В продолжении темы : 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;
    }
}

 

Dump
Offline
Зарегистрирован: 01.06.2015

Пока что вышел из положения таким вот образом

код сервера:

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);

      }

 

Radjah
Offline
Зарегистрирован: 06.08.2014

goto stop;

Не делай так. Это плохо, и в приличном обществе за это бьют канделябром.

 

Dump
Offline
Зарегистрирован: 01.06.2015

Radjah пишет:

goto stop;

Не делай так. Это плохо, и в приличном обществе за это бьют канделябром.

 

А как делать ? Это было в стандартном примере к библиотеке, ну я так и оставил. Я ещё не силён в программировании Arduino и уж тем более в с++ ))) Если подскажете буду благодарен. И по сабжу, не подскажите, как всё таки воспользоваться содержанием data из пакета udp, а то мне кажется, что с длинной пакета, могу получить глюки ))))

Radjah
Offline
Зарегистрирован: 06.08.2014

Например так

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;

Последние две строки выполняются в любом случае.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

ТС: Ответьте честно - Вы же не понимаете что и почему делает код?

Dump
Offline
Зарегистрирован: 01.06.2015

JollyBiber пишет:

ТС: Ответьте честно - Вы же не понимаете что и почему делает код?


Да, я не понимаю часть кода, где цикл do-while , так как ещё очень мало времени дружу с ардуино. Но я этого и не Скрывал в самом начале топика. Только вот не пойму, к чему этот каверзный вопрос ? Именно для того, чтобы немного разобраться я сюда и написал, если бы я знал всё, думаю врядли бы я задавал вопросы.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

А вопрос не каверзный. мне интересно Вам надо разобраться или чтобы заработало? Если разабраться - то читать документацию и спрашивать.

Dump
Offline
Зарегистрирован: 01.06.2015

JollyBiber пишет:

А вопрос не каверзный. мне интересно Вам надо разобраться или чтобы заработало? Если разабраться - то читать документацию и спрашивать.

Мне надо разобраться, чтобы заработало :) Ну на самом деле, всё что требовалось от конструкции (нажал кнопку на одном устройстве, на другом сработало реле) это работает, и в принципе этого было бы достаточно, но именно из-за того, что я хочу разобраться, как это работает я и пришел сюда :) Всё что на данный момент я нашел по ардуино, более или менее нормальную информацию для восприятия, это видеоуроки джереми блума и справочная информация с этого сайта, ну ещё что-то там на амперке. Если вы подскажите ссылки на хорошие ресурсы, где почитать или посмотреть, я не откажусь )

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

"Почитать или посмотреть" - так Вы научитесь только правильно использовать чужой код :)

Попробуйте разобраться в Вашем коде, попробуйте его переписать по другому, но чтобы также работал. Так понимание и придет :)

Документации тут вполне хватит чтобы разобраться.

Dump
Offline
Зарегистрирован: 01.06.2015

JollyBiber пишет:

Документации тут вполне хватит чтобы разобраться.

Хорошо, вот смотрите, например: Есть библиотека, которую я использую (UIPEthernet), в ней есть классы которые я могу использовать в своём коде, а вот как правильно использовать эти классы я не могу понять :(

JollyBiber пишет:

"Почитать или посмотреть" - так Вы научитесь только правильно использовать чужой код :)

Я имел ввиду почитать какой либо чебный материал. Документация это хорошо, но нужно ещё чтобы всё разложилось по полочкам )))) На четвертом десятке лет, восприимчивость мозга хромает(надо было в 20 лет учится а в 30 по бабам бегать) )))

Но в целом ваш совет я понял !!!

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Dump пишет:

Хорошо, вот смотрите, например: Есть библиотека, которую я использую (UIPEthernet), в ней есть классы которые я могу использовать в своём коде, а вот как правильно использовать эти классы я не могу понять :(

если библиотека написана грамотно и не "только для себя", то там перед каждым методом будет описание (в комментариях) - что делает, что принимает и что возвращает.

Второй Ваш довод я со смехом отметаю как заблуждения молодого ;)