Forum: Mikrocontroller und Digitale Elektronik AVR Arduino W5100 empfängt zu viele Bytes


von thomas (Gast)


Lesenswert?

Moin,
ich kaue gerade an einem Problem mit einem Arduino Mega mit W5100 im 
ModBus-Modus:
Bei einer TCP-Übertragung werden 10 Bytes gesendet und 65000 Bytes 
kommen an (sagt der W5100).

Ein Arduino sendet über W5100 und Ethernet an einen anderen AVR mit 
W5100.
Wenn der Sender: Client.write(EinByte) mit einem delay versehen wird, 
packt der Arduino ein(ige) EinByte in einen TCP-Frame und schickt es ab.
So kommt das Array mit 10 Bytes in mehreren TCP-Frames an und wird beim 
Empfänger wieder auf die 10 Bytes zusammen gesetzt. Das geht perfekt, 
auch vom PC (ClinetSocket oder Indy) oder mit dem Arduino als normaler 
Ethernet-Client. Auch wenn nur ein Frame gesendet wird.

Ohne das delay meint der empfangende W5100 aber, dass 65291 Bytes (oder 
auch mal 65038) angekommen sind anstatt der 10 gesendeten. Womit er 
definitiv unrecht hat da der Socket-Buffer im W5100 auf 2048 eingestellt 
ist. Im W5100-Buffer steht dann eine Menge Müll, darunter auch irgendwo 
die gesendeten 10 Bytes.

Der Effekt lässt sich bis auf das return (SPDR); herunterbrechen.


Die Funktion
1
W5100_rx_size[Asocket]= w5100_read_int16(W5sRXRSR(Asocket));
packt den Wert 65xxx in W5100_rx_size[Asocket].

Da da jemand eine Idee?
...und vielen Dank für die Tips.
Thomas



Ich habe den Code mal etwas übersichtlicher geschrieben:

Sender: (Arduino Mega mit W5100)
1
//YxModbus.h:
2
#include "Arduino.h"
3
#include <SPI.h>
4
#include <Ethernet.h>
5
6
//YxModbus.cpp:
7
#include "YxModbus.h"
8
EthernetClient Client;
9
10
     for(int i=0; i<10; i++)   
11
      { Client.write(ByteArray[i]); 
12
//      delay(10);
13
      }


Empfänger: (AVR mit W5100)
1
uint8 W5100_TxRx(uint8 cData)
2
{  uint16 n;
3
4
  n=0;
5
  cli();
6
  SPDR = cData;                    // data in TX-register
7
  while(!(SPSR & (1<<SPIF)) && (n++ < gcTxTimeout));      //warte auf transfer ende
8
  sei();
9
  return (SPDR);                    // data aus rx-register
10
}
11
12
13
bool W5100_Tx(uint8 cData)
14
{  uint16 n;
15
16
  n=0;
17
  cli();
18
  SPDR = cData;                    // data in TX-register
19
  while(!(SPSR & (1<<SPIF)) && (n++ < gcTxTimeout));    //warte auf transfer ende
20
  sei();
21
22
  return (n<gcTxTimeout);
23
}
24
25
26
uint8 w5100_read_byte(uint16 addr)
27
{  uint8 inbyte;
28
  
29
  ISR_DISABLE();
30
  CLEARBIT(WIZ_PORT,WIZ_SCS);          //enable W5100
31
  inbyte=0;
32
33
  if (W5100_Tx(0x0F))              //OPcode read 0x0F 
34
  {  if (W5100_Tx((addr & 0xFF00) >> 8))    //adresse hi
35
    {  if (W5100_Tx(addr & 0x00FF))      //adresse lo
36
      {  inbyte=W5100_TxRx(0);      //dummy zum shiften
37
      }
38
    }
39
  }
40
41
      SETBIT(WIZ_PORT,WIZ_SCS);      //disable W5100
42
  ISR_ENABLE();
43
  return(inbyte);
44
}
45
46
47
uint16 w5100_read_int16(uint16 addr)
48
{  uint8  hibyte, lobyte;
49
  uint16   intvalue=0;
50
  
51
  hibyte=w5100_read_byte(addr);
52
  lobyte=w5100_read_byte(addr+1);
53
  intvalue = make16(hibyte,lobyte);
54
55
  return (intvalue);
56
}
57
58
59
#define W5sR(r,n)  ((r)+(n)*0x100)  //  r=register-base-adr, n=socket
60
#define W5sRXRSR(n)  W5sR(0x0426,n)  // 2b - Rx received size
61
Asocket=1;
62
63
bla...
64
W5100_rx_size[Asocket]= w5100_read_int16(W5sRXRSR(Asocket));
65
bla...
66
67
68
69
//=================================================================================
70
//Interrupt vom W5100
71
//W5100_INTERRUPT=INT2_vect  INT2 an PB2(vector No.4)
72
ISR(W5100_INTERRUPT)
73
{  uint8_t int_val, i, n, sreg;  
74
  
75
  sreg = SREG;                      //Save global interrupt flag
76
  cli();
77
  W5100_INTERRUPT_DISABLE();            //disable INT2
78
  int_val = w5100_read_byte(W5IR);        //read Interrupt Register: bits gesetzt
79
  W5100_IntMode=im_Leer;              //W5100 Leer-INT
80
  if (int_val & IR_CONFLICT)  {W5100_IntMode=im_IR_CONFLICT;}  //IR_CONFLICT
81
  if (int_val & IR_UNREACH)  {W5100_IntMode=im_IR_UNREACH;}  //IR_UNREACH
82
  w5100_write_byte(W5IR, 0xf0);         //W5100-interrupt clear
83
  n=0;
84
  do 
85
  {  for (i=0; i<MAX_SOCK_NUM; i++)                //check socket-int
86
    {  if (int_val & IR_SOCK(i))                //check socket interrupt No
87
      {  INT_STATUS[i] |= w5100_read_byte(W5sIR(i));      //save interrupt value, Sn_IR (Socket n Interrupt Register) 
88
        w5100_write_byte(W5sIR(i), INT_STATUS[i]);      //lösche "1"-bits durch writing "1"
89
        W5100_IntMode |= 1<<i;                //W5100 socket-INT
90
        if (INT_STATUS[i]) {LineActionEth=1;};        //=1: Ethernet-Char in Buffer, da kommt etwas rein...        
91
      }
92
    }
93
    int_val = w5100_read_byte(W5IR);              //re-read interrupt value
94
  } while ((int_val != 0) && (n++ < gcIntTimeOut));          //if exist, contiue to process  
95
96
  W5100_INTERRUPT_ENABLE();
97
  SREG = sreg;                      //Restore global interrupt flag  und Enable Ints  
98
}

von The D. (thedaz)


Lesenswert?

Eventuell die Längenangaben byte swappen ?

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.