Problema con UDP

... si, sono ancora io...ma questo progetto mi fa dannare!!!

ho riportato in vita l'arduino...pare impossibile ma ce l'ho fatta :), ora è nato un nuovo probelma devo inviare un pacchetto non ad un solo arduino, ma a 2!
il problema è che se faccio

   Udp.sendPacket( invio, remoteIp, remotePort);

    Udp.sendPacket( invio, remoteIp2, remotePort2);

l'arduino va lentissimo! invece di ciclare normalmente ci mette circa 2 secondi...
come mai?

come posso risolvere?
per ora ho pensato di farlo alternato con un flag, una volta uno e una volta l'altro e raddoppiare la velocità del ciclo (in fondo c'era un delay(200) ora metto delay(100) e alterno, ma non mi sembra una soluzione corretta....vorrei sapere il perchè del motivo per cui si pianta!!!

grazie e scusate per le mie 1000 richieste!

Ho controllato di nuovo! se non c'è il destinatario collegato alla rete, oltre ad andare tutto più lento, fa anche "cose strante" sulla serial print....cioè fa qualcosa di strano in memoria che non riesco a capire, ma comunque non stampa correttamente,,,

fai un piccolo sketch dove usi solo l'UDP pieno di println di debug, e posta anche il link alle librerie UDP che usi.

la libreria è:
ora faccio uno sketch dove l'unica cosa che fa è mandare pacchetti per udp!
la libreria UDP è quella che c'è nel pacchetto arduino UDP.h nella cartella ethernet

Con questo codice: semplicissimo, basta che stacchi uno dei 2 riceventi, e rallenta di circa un fattore 10!

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Udp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,0,202 };
unsigned int localPort = 8888;      // local port to listen on

byte remoteIp[] = { 192,168,0,201 }; 
byte remoteIp2[] = {192,168,0,203 };

unsigned int remotePort = 8888; // holds received packet's originating port
unsigned int remotePort2 = 8889;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,

char invio[3];


int stati = 0;


void setup() {


  

  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop() {

   stati = 10;
   itoa(stati,invio,10); 

   Serial.print("Ho inviato");
   Serial.println(invio);

   Udp.sendPacket( invio, remoteIp, remotePort);

   Udp.sendPacket( invio, remoteIp2, remotePort2);
    
  delay(200);
}

nessuna idea? ho anche provato a guardare la libreria...ma non c'ho capito granchè

Tommaso:
basta che stacchi uno dei 2 riceventi, e rallenta di circa un fattore 10!

il che non mi torna assolutamente... UDP non si cura se non esiste il ricevente... anzi... il pacchetto dovrebbe venir scartato non appena qualche router si accorge di questa cosa...

mi linkeresti la libreria?

infatti è quello che non capisco!!! la libreria è quella che trovi dentro la cartellaEthernet !
però anche con quel semplice programmino, se stacco uno dei 2 rallenta....oh..

risolto il mistero:
in UDP.cpp

/* Send packet contained in buf of length len to peer at specified ip, and port */
/* Use this function to transmit binary data that might contain 0x00 bytes*/
/* This function returns sent data size for success else -1. */
uint16_t UdpClass::sendPacket(uint8_t * buf, uint16_t len,  uint8_t * ip, uint16_t port){
  return sendto(_sock,(const uint8_t *)buf,len,ip,port);
}

/* Send  zero-terminated string str as packet to peer at specified ip, and port */
/* This function returns sent data size for success else -1. */
uint16_t UdpClass::sendPacket(const char str[], uint8_t * ip, uint16_t port){	
  // compute strlen
  const char *s;
  for(s = str; *s; ++s);
  uint16_t len = (s-str);
  // send packet
  return sendto(_sock,(const uint8_t *)str,len,ip,port);
}

quindi in socket.cpp:

/**
 * @brief	This function is an application I/F function which is used to send the data for other then TCP mode. 
 * 		Unlike TCP transmission, The peer's destination address and the port is needed.
 * 		
 * @return	This function return send data size for success else -1.
 */
uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
{
  uint16_t ret=0;

  if (len > W5100.SSIZE) ret = W5100.SSIZE; // check size not to exceed MAX size.
  else ret = len;

  if
    (
  ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
    ((port == 0x00)) ||(ret == 0)
    ) 
  {
    /* +2008.01 [bj] : added return value */
    ret = 0;
  }
  else
  {
    W5100.writeSnDIPR(s, addr);
    W5100.writeSnDPORT(s, port);

    // copy data
    W5100.send_data_processing(s, (uint8_t *)buf, ret);
    W5100.execCmdSn(s, Sock_SEND);

    /* +2008.01 bj */
    while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) 
    {
      if (W5100.readSnIR(s) & SnIR::TIMEOUT)
      {
        /* +2008.01 [bj]: clear interrupt */
        W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */
        return 0;
      }
    }

    /* +2008.01 bj */
    W5100.writeSnIR(s, SnIR::SEND_OK);
  }
  return ret;
}

quindi esiste un time-out, o comunque la conferma di ricezione.
credo che se elimini la parte

/* +2008.01 bj */
    while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) 
    {
      if (W5100.readSnIR(s) & SnIR::TIMEOUT)
      {
        /* +2008.01 [bj]: clear interrupt */
        W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */
        return 0;
      }
    }

dovrebbe andare, però guarda bene cosa combina il codice, io sto andando "a naso"

Ora provo....oppure fargli credere che l'ack sia stato inviato? ciè tipo scrivere dal programma la risposta che lui si aspetta?

no, incasini il codice e comunque credo sia un'errore della libreria

dunque, ho aperto una discussione quì: http://arduino.cc/forum/index.php/topic,56129.new.html
tutti e 3 sono ethernet shield o wifi/xbee?
il router (o meglio il gateway) rimane sempre connesso durante i test?

sono tutti ethernet! 2 sono un pò più vecchie! (dicembre) una è di ora!
non cambia in tutti i casi: sia se stacco il cavo, sia che spenga lo switch, sia che stacci l'altro arduino (o spengendo o staccando il cavo di rete)