Forum: Mikrocontroller und Digitale Elektronik Probleme mit Arduino und UDP


von Sylvia H. (sandy)


Lesenswert?

Hallo,
ich besitze einen Arduino Ethernet Shield mit dem WIZ 5100, welches von 
meinem Arduino 2560 angesteuert wird.

Nun möchte ich gerne an ein Interface ein ByteArry per Ethernet senden 
und muss dabei das UDP Protokoll nutzen.

Das Problem ist folgendes:

Ich schicke das Bytearry mit folgender Funktion auf den Bus:
1
/**
2
 * Funkion sendet ein Datagrama auf den Ethernet Bus per UDP
3
 *
4
 * @param data  Das zu sendende Datagram als Bytearray
5
 * @param size  Die Groesse des Bytearray
6
 */
7
void Ardu_CAPL::sendDatagram(byte* data, int size){
8
   Serial.println("Send datagram");
9
    Serial.print("Udp.beginPacket(");
10
11
    Serial.print(remoteIP);
12
    Serial.print(", ");
13
    Serial.print(remotePort);
14
    Serial.print(") --> ");
15
    Serial.println(udp.beginPacket(remoteIP, remotePort)); //1 = ok
16
17
    Serial.print("Udp.write([");
18
    for (int i=0; i < size; i++) {
19
      Serial.print(data[i], HEX);
20
      Serial.print(" ");
21
    }
22
    Serial.print("], ");
23
    Serial.print(size);
24
    Serial.print(") --> ");
25
    Serial.println(udp.write(data, size)); // Anzeige ist Anzahl der gesendeten Bytes
26
27
    //wait until Sn_Tx_WR amd Sn_TX_Rd are the same
28
    delay(10);
29
30
    Serial.print("Udp.endPacket() --> ");
31
    Serial.println(udp.endPacket()); // 1 = ok 0 = Timeout
32
33
}

Danach warte ich auf eine Antwort:
1
void Ardu_CAPL::readDatagram(char* receiveBuffer){
2
3
  // if there's data available, read a packet
4
     int packetSize = udp.parsePacket();
5
     Serial.print("wait for answer ");
6
7
     if(packetSize){
8
9
       Serial.print("Received packet of size ");
10
       Serial.println(packetSize);
11
       Serial.print("From ");
12
       IPAddress remote = udp.remoteIP();
13
14
       //show tranceiver ip and prot
15
       for (int i =0; i < 4; i++)
16
            {
17
              Serial.print(remote[i], DEC);
18
              if (i < 3)
19
              {
20
                Serial.print(".");
21
              }
22
            }
23
            Serial.print(", port ");
24
            Serial.println(udp.remotePort());
25
26
27
         // read the packet into packetBufffer
28
        // udp.read(receiveBuffer,UDP_TX_PACKET_MAX_SIZE);
29
         udp.read(receiveBuffer,32);
30
31
         //show the packet Buffer
32
         //char temp[UDP_TX_PACKET_MAX_SIZE];
33
         char temp[32];
34
        // receiveBuffer -= UDP_TX_PACKET_MAX_SIZE;
35
         receiveBuffer -= 32;
36
37
       //  for (int i=0; i< UDP_TX_PACKET_MAX_SIZE; i++){
38
         for (int i=0; i< 32; i++){
39
           temp[i] = *receiveBuffer;
40
           receiveBuffer++;
41
42
         }
43
44
45
         Serial.println("Contents:");
46
         Serial.println(temp);
47
48
     }else{
49
       Serial.print("no data receivced ");
50
     }
51
}

Leider bekomme ich keine Antwort! Die Anzeige meines Seriellen Monitors 
zeigt:

Udp.beginPacket(169.254.11.39, 2809) --> 1
Udp.write([43 41 4E 6F 65 46 44 58 1 0 1 0 0 80 0 0 4 0 A 0 ], 20) --> 
20
Udp.endPacket() --> 0
wait for answer no data receivced


Im Errata Sheet des WIZ 5100 habe ich gelesen :

Unable to complete SEND/SENDMAC command in UDP/IP-Raw mode. That is, do 
not assert SEND_OK interrupt and do not equal the values of Socket n Tx 
Read Pointer Register (Sn_TX_RD) and Socket n Tx Write Pointer Register 
(Sn_TX_WR).

Der Grund wäre:

Generally, the Sn_TX_RD value is equal to the Sn_TX_WR value and asserts 
SEND_OK interrupt when a transmission process was completed. But the 
case of errata which the Sn_TX_RD and Sn_TX_WR values are different and 
do not assert SEND_OK interrupt in UDP/IP-Raw mode. This phenomenon is 
occurred when our chip receive data in opened socket (i.e. assert RECV 
interrupt) and simultaneously the application program (Host MCU) 
executes SEND/SENDMAC command on that socket.

Der Lösungsvorschlag ist darauf zu warten, dass Sn_TX_WR und Sn_TX_RD 
bis den gleichen wert annehmen, und dann den Socket zu schliessen
Pseudocode:
/* Complete Sending */
/* wait until Sn_TX_WR and Sn_TX_RD are same */
 While (Sn_TX_WR != Sn_TX_RD)
{ wait some time; loop_cnt++;
if (loop_cnt > CONST_BLOCK_CNT) goto RESET }

Leider bekomme ich es nicht hin, diesen Pseudocode in C++ zu backen...

Kennt jemand dieses Problem? Hat da schon jemand eine Lösung?

Vielen Dank und Grüße von
Sandy

von PittyJ (Gast)


Lesenswert?

Wird die Antwort überhaupt geschickt? Wird sie richtig geschickt? Was 
sagt Wireshark?

Könnte man nicht dem Arduino eine IP-Adresse geben, dass der Raw-Mode 
nicht notwendig ist?

von Sylvia H. (sandy)


Lesenswert?

Ich habe leider keinen Router zur Hand, um mich in die Kommunikation 
zwischen den Arduino und dem Interface mit meinem PC hineinzuschalten.

Der Hinweis mit der IP Adresse hat geholfen, nun empfange ich eine 
Antwort.
 Leider muss ich aber zuerst 2 dummy Pakete an die IP Adresse des 
Interfaces senden bevor ich korrekte Antworten erhalte.

Kennt jemand dieses Phänomen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.