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