Ethernet + XBee + Arduino UNO auto reinicio de la placa

Buenos días,

no sé si estoy escribiendo en el lugar correcto. Cuento un poco un mi caso a ver si me podéis echar un cable.
Veréis tengo apilado sobre una arduino UNO, un escudo ethernet más otro XBee. Además tengo cargada una página web en html usando jquery mu sencilla, que lo que hace es hacer una petición cada x tiempo a la placa tipo GET de manera cuando llega a la placa lee de la tarjeta microSD y responde. Además tengo la posibilidad de hacer un POST, un formulario. De manera que envío datos desde la página web, dos números nada más. A veces llega a la placa, responde y va bien. Pero otras no sé si llegará o no pero la placa se reinicia. Y a partir de llegar ese POST, cuando llega un GET se resetea. Y no sé porqué.

No sé si me podéis dar una pista de por qué se puede resetear la placa. Si queréis pongo código.

He comprobado que utilizar el puerto serie, cualquier instrucción Serial.print como que se vuelve loca la placa.

Pero a parte de eso, ya no sé si es que hay un buffer que se llena, o que dejo alguna instrucción colgando y no sabe que hacer ... no sé ya que puede ser.

gracias de antemano.

Quizá no tenga nada que ver, pero a mi me suena más a falta de alimentación, quizá con determinadas instrucciones consuma un poco más y sea lo suficiente como para que se resetee, intenta cambiar la fuente de alimentación a algo superior.

Un Saludo.

pon el codigo.

es posible que te estes quedando sin memoria RAM, usa la libreria FreeMemory para que te imprima cuanta memoria tienes disponible tras cargar tu programa.

En el último elektor viene un artículo sobre reseteo misterioso del micros AVR.
Al perecer es un "bug hardware" y se produce si llegan datos por la UART a una velocidad elevada superior a cierto valor.
Proponen colocar un pasobajo RC aunque ahora no tengo la revista a mano y no recuerdo valores.

Hola,

primero gracias por vuestras respuestas. Bien os cuento un poco que me ha pasado, dado que mi ethernet shield no me lee la tarjeta microSD pues estoy usando una arduino UNO R3 con su respectiva ethernet shield y por si acaso también tengo una Arduino Ethernet. Antes todo funcionaba no había problemas, pero poco a poco dejó de funcionar... Entonces ahora usando las neuvas me encuentro con otros problemas.

bien si uso unicamente internet. Cuando en un navegador escribo la dirección de la placa pues responde pintando la web que almaceno en html. Luego en la web uso ajax para que cada 20 segundos se pida un refrescos de datos en formato json que también están almacenado sen la microSD. Bien si esto va solo funciona, ahora si simplemente añado :

XBee xbee = XBee();
XBeeResponse response = XBeeResponse(); // paquete tipo respuesta
Rx16Response rx16 = Rx16Response(); // direccion de 16 bits, se puede usar la de 64
TxStatusResponse txStatus = TxStatusResponse();

no pinta la web. O bien me pone ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ continuamente en el navegador. Es como si hubiera una incompatibilidad de librerías, la librería es XBee Arduino Library Version 0.3 - Supports Arduino 1.0 GitHub - andrewrapp/xbee-arduino: Arduino library for communicating with XBee radios in API mode.

Os pego el código. Ahora mismo solo tengo habilitado la parte ethernet que funciona bien pero en cuanto hay una instrucción del xbee no funciona. Tambien he probado a seguir el rastro utilzando Serial.print. Y sino comento xbee.begin() y dejo las instrucciones anteriores ...me sale lo siguiente

GEGET / HTTP/1.1

strange symbols GET / HTTP/1.1
strange symbols GET / HTTP/1.1
strange symbols GET / HTTP/1.1
strange symbols GET / HTTP/1.1
.... forever and ever

como si entrara en un bucle.

Lo curioso es que antes no había problema tenía apiladas una arduino uno r2 con la ethernet shield y la xbee shield y no había problemas. Usar una arduino r2 con una ethernet shield r3 no creo que sea recomendable hay pines que se quedan sueltos. Así que igual tengo que cogerme otra ethernet que encaje para la arduino r2 porque no comprendo lo que está ocurriendo.

// LIBRERIAS
#include <XBee.h>
#include <SPI.h>
#include <Ethernet.h> 
#include <SD.h>  // ocupa 5KB  

#define PACKET_TYPE    0  // data[0]
#define PACKET_LENGTH  1  // data[1]
#define DATA_TYPE      2  // data[2]
#define REQUEST        1
#define RESPONSE       2
#define INFO           3
#define INIT           4

#define CONFIGURATION     0
#define TEMPERATURE_FIELD 3
#define HUMIDITY_FIELD    5
#define SLEEPCYCLE_FIELD  7
#define ASYNCHRONUS_FIELD 9
#define UID_FIELD        11
#define fioMax  30


XBee xbee = XBee();
XBeeResponse response = XBeeResponse();  // paquete tipo respuesta 
Rx16Response rx16 = Rx16Response();      // direccion de 16 bits, se puede usar la de 64
TxStatusResponse txStatus = TxStatusResponse();


byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x09, 0xF1 };
IPAddress ip(193,144,196,6);//casa {192,168,1,4}; laboratorio{ 192, 168, 112, 31 }; CeFoNT {193,144,196,6} // 
EthernetServer server(80); // Puerto 80, HTTP

// VARIABLES GLOBALES

uint8_t fioList[fioMax] = {}, fioNumber = 0, uid[] = {0,0,0,0}, initFrame[] = {REQUEST,1,INIT};

// Ethernet Shield uses pins 10,11,12,13.
#define bufferMax 128
int bufferSize;
char buffer[bufferMax], bufferData[bufferMax];;

// SD
File myFile;
#define ssPin       10
#define chipSelect   4

unsigned long time1, time2;
int sleepCycleCoord = 0, asynchronusCoord = 0;
boolean flag1 = true, flag2 = false;

void setup() {
  pinMode(8,OUTPUT);     // led avisa de llegada de tramas
  pinMode(7,OUTPUT);
  digitalWrite(7, HIGH);
  
  pinMode(ssPin,OUTPUT);  // desactivar w5100 mientras setea la uSD
  digitalWrite(ssPin, HIGH);
  if (!SD.begin(chipSelect)) {  // inicia la tarjeta SD
    //Serial.println("initialization failed!");
    return;
  }
  Ethernet.begin(mac, ip);
  digitalWrite(ssPin, HIGH);
  delay(2000);
  server.begin();
  delay(1000);
  //xbee.begin(9600);
  //delay(1000);
  //Serial.begin(9600);
  //delay(500); 
  //Serial.print("\nCOORDINADOR\n");
  //fioNumber = 0;
  // funcion que borra los ficheros antiguos Fxx.JS y de cambio de ciclo.
  //sendRequest( initFrame, 3, millis()*0xFF ); // BROADCAST INICIAL (puede repetirse para conocer el estado de la red)
  digitalWrite(7,LOW);
}

void loop() {
  //readRequest(); // lee paquetes de entrada continuamente
  listenForClient();
  /*time2 = millis();
  if (flag2 == true) { // si hay pendiente por hacer...
    if (time1-time2 >= sleepCycleCoord)
      sendPendingRequest();   
      time1 = millis(); // una vez alcanzado el tiempo de sueño se tiene que renovar 
  }*/
}
/*
void readRequest() {
  uint8_t fioAddress; // variables locales
  
  if (xbee.readPacket(10)){
    if (xbee.getResponse().isAvailable()) {
      if (xbee.getResponse().getApiId() == RX_16_RESPONSE) { // se trata de un paquete RX 
        xbee.getResponse().getRx16Response(rx16);            // almacena el paquete recibido en el objeto rx16           
        switch (rx16.getData(PACKET_TYPE)) {                                
          case INFO:      // TRAMA INFO
            digitalWrite(8, HIGH);      
            fioAddress = rx16.getRemoteAddress16();
            for ( int k = 0; k < 4; k++ ) 
              uid[k] = rx16.getData(UID_FIELD + k);
            generateJson( fioAddress, rx16.getData(TEMPERATURE_FIELD), rx16.getData(HUMIDITY_FIELD), rx16.getData(SLEEPCYCLE_FIELD), rx16.getData(ASYNCHRONUS_FIELD), uid );  // Renueva los datos de la fio en concreto 
            checkNewAddress(fioAddress); 
            digitalWrite(8, LOW);
          break;                                           
        }  // switch
      }  // getApiId
    }  // available
  }  // readPacket
  
}  // readRequest

void checkNewAddress ( uint8_t address) { // fioNumber, fioList variables globales
      
  for (int i = 0; i <= fioNumber; i++) {
    if (fioNumber == 0) { // TODAVIA NO HAY ELEMENTOS UNIDOS AL COORDINADOR
      fioList[i] = address;
      fioNumber = 1;
      i = fioNumber +1;
    }
    else{  // La lista no está vacía, chequea elemento a elemento
      if ( fioList[i] == address)
        i = fioNumber +1;
      else {  
        if (i == fioNumber) {  // Luego de chequear toda la lista, si no coincide es un elemento nuevo
          fioList[i] = address;
          fioNumber++;
          i = fioNumber +1;
        }
      }  // end else2
    }  // end else1 
  }  // end for    
} // end checkNewAddress

boolean sendRequest(uint8_t data[], uint8_t length, uint8_t frameId) {
  
  uint8_t ack, option = 0, i = 0;
  Tx16Request tx = Tx16Request(0xFFF, option, data, length, frameId);
  do {
    xbee.send(tx); 
    // Tx16Request (uint16_t addr16, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId) (OBLIGATORIO PONERLOS TODOS!!)
    // Tx16Request (uint16_t addr16, uint8_t *payload, uint8_t payloadLength) Creates a Unicast Tx16Request with the ACK option and DEFAULT_FRAME_ID.
    if (xbee.readPacket(1000)) {  // got a response!
      if (xbee.getResponse().getApiId() == TX_STATUS_RESPONSE) {  // should be a znet tx status
        xbee.getResponse().getZBTxStatusResponse(txStatus);
        ack = txStatus.getStatus();  // get the delivery status, the fifth byte
      }  // STATUS:  0 = success, 1 = when all retries are expered and no ACK is received
    }  
    i += 1;
  }while( (i < 3) && (ack != SUCCESS) );

  if (ack == SUCCESS)
    return true;
  else 
    return false;
}
*/
void listenForClient() {
  EthernetClient client = server.available(); // espera a que haya datos disponilbles
  boolean currentLineIsBlank = true, flag = true;
  bufferSize = 0;
  if ( client ) {
    while (client.connected()) {
      while (client.available()) {      
        char c = client.read();  Serial.write(c);
        if (c == '\n' && currentLineIsBlank) {
          while(client.available()) { // Datos si es un POST
            c = client.read();
            bufferData[bufferSize++] = c;
          }
          bufferData[bufferSize] = 0;  //Serial.println(bufferData);
          // flag = true;
          client.println("HTTP/1.1 200 OK");
          client.println();  
          createRequest(bufferData);
          client.flush();
          client.stop();
        }
        else if (c == '\n') { // NEW LINE
          if (flag) {
            buffer[bufferSize] = 0;  // no me pinta salto de linea si bufferSize+1
            bufferSize = 0;  Serial.println(buffer);
            if ( strstr(buffer, "GET / HTTP/1.1") ) {
              filePrint("SRV.txt", client);
              client.flush();
              client.stop();
            }
            else 
              if ( strstr(buffer, "GET /fioList HTTP/1.1") ){
                sendGetResponse(client);      
                client.flush();
                client.stop();
              }
              else 
                if ( !strstr(buffer, "POST /changes HTTP/1.1") ) {
                  client.flush();
                  client.stop();
                }
            flag = false;
          }
          currentLineIsBlank = true;
        } 
        else if (c != '\r') { // caracter de la misma linea
          currentLineIsBlank = false;
          if ( (bufferSize < bufferMax) && flag )
            buffer[bufferSize++] = c;
        }
      }  // client.available
    }  // client.connected
  }  // end if
}  // endListenForClient
  
// Petición recibida del tipo: "GET /192.168.112.31/fio HTTP/1.1"

void sendGetResponse(EthernetClient client) {
  client.println("HTTP/1.1 200 OK\nContent-Type: application/json\nConnection: close");
  client.println(); 
  client.print("{\"fioList\":[\"asynchronus\":\"");
  client.print(asynchronusCoord);
  client.print("\",\"sleepCycle\":\"");
  client.print(sleepCycleCoord);
  client.print("\"},");
  for (int k = 0; k < fioNumber; k++) {
    char filename[9];
    sprintf (filename, "F%d.JS", fioList[k]); // si Fx.js guardado en la microSd como Fx.JS 
    filePrint(filename, client);
    if ( (k+1) != fioNumber)
      client.println(",");
  }
  client.println("]}");
}

// fuente: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1295739118

void filePrint (char filename[10], EthernetClient client){
  if ((myFile = SD.open(filename, FILE_READ))) {  
    while ( myFile.available() )
      client.print( (char) myFile.read() );
    myFile.close();  // CERRAR FICHERO
  }
}

void generateJson (uint8_t address, uint8_t temperature, uint8_t humidity, uint8_t sleepCycle, uint8_t asynchronus, uint8_t uid[]) {
  char filename[9];
  sprintf (filename, "F%d.JS", address);  // String jsonString; Usando string no lo escribe correctamente
  if ( SD.exists(filename) )  // Si ya existía lo borra
    SD.remove(filename);
  // CREACION FICHERO
  if ((myFile = SD.open(filename, FILE_WRITE))) {  // si esta abierto ...
   myFile.print("{\"name\":\"fio");
   myFile.print( address, DEC);
   myFile.print("\",\"address\":\"");
   myFile.print(address, DEC); 
   myFile.print("\",\"temperature\":\"");
   myFile.print(temperature, DEC);
   myFile.print("\",\"humidity\":\"");
   myFile.print(humidity, DEC);
   myFile.print("\",\"asynchronus\":\"");
   myFile.print(asynchronus, DEC);
   myFile.print("\",\"sleepCycle\":\"");
   myFile.print(sleepCycle, DEC);
   myFile.print("\",\"uid\":\"");
   for ( int k = 0; k < 4; k++ ) 
     myFile.print(uid[k], HEX);
   myFile.print("\"}");
   myFile.close();  // CERRAR FICHERO  
  }    
}

void createRequest(char buffer[]) {
  uint8_t frameId = millis()*0x00FF;
  char *param, *equal, sleepCycle[3], asynchronus[2];
  sleepCycle[0] = 0;
  asynchronus[0] = 0;
  //sleepCycle=20&asynchronus=0
  equal = strstr(buffer, "=") + 1;
  param = strstr(equal, "&");
  strncat(sleepCycle, equal, param-equal);  //sleepCycle
  equal = strstr(param, "=") + 1;
  strncat(asynchronus, equal, 1);  //asynchronus
  //Serial.print(atoi(sleepCycle));  Serial.print(atoi(asynchronus));
  uint8_t data[] = {CONFIGURATION, 2, atoi(sleepCycle), atoi(asynchronus)};  // Configuration request: [0,2,SLEEP_CYCLE,ASYNCHRONUS]
  uint8_t length = sizeof(data);
/*
  if ( sendRequest( data, length, frameId) == false ) {
    saveRequest(data, length, frameId); 
    flag2 = true; // al no ser enviada se levanta la bandera de pendientes
  }
  else {  // se consiguió enviar 
    sleepCycleCoord = atoi(sleepCycle);
    asynchronusCoord = atoi(asynchronus);
    if (flag1 == true){ // solo vale true la primera vez que se envía el cambio de ciclo.
      flag1 == false;
      time1 = millis(); // time 1 toma su primer valor
    }
  }*/
}

void saveRequest(uint8_t data[], uint8_t length, uint8_t frameId) { 
  uint8_t k = 0;
  char filename[9];
  sprintf (filename, "%d.txt", 1); 
  SD.remove(filename);  // borrar la anterior
  // CREACION FICHERO 
  if ((myFile = SD.open(filename, FILE_WRITE))) {  // si esta abierto ...
    myFile.print(frameId, HEX); 
    while (k < length) {  
      myFile.println(data[k], HEX);
      k++;
    }
    myFile.close();  // CERRAR FICHERO
  }      
}

void sendPendingRequest() {  
  uint8_t frameId, address, k = 0, data[] = {};
  char filename[9];
  sprintf (filename, "%d.txt", 1); 
  
  if ( SD.exists(filename) ) {
    if ((myFile = SD.open(filename))) {  // ABRIR FICHERO 
      frameId = myFile.read();
      while ( myFile.available() ){
        data[k] = myFile.read();
        k++;
      }
      myFile.close();  // CERRAR FICHERO
 /*    if ( sendRequest( data, sizeof(data), frameId ) == true ){
        flag2 = false;  // baja la bandera de pendientes 
        SD.remove(filename);
      }*/
    }  // myFile
  }  // SD.exists(filename)
}  // sendPendingRequest

ahh en cuanto a vuestras anotaciones, probé la libería para popder saber que memoria me quedaba y eran 200bytes. He alimentado la xbee shield aparte y no compartiendo los puertos de la arduino uno ... Y el código solo con las pocas instrucciones del xbee no alcanzan los 26kb y según estuve leyendo tengo hasta 28kb.

200bytes son muy pocos como memoria libre. yo diria que ahí puede estar el problema.
Intenta liberar algo de memoria y prueba otra vez.

cuando la placa se reinicia sola y el programa esta bien escritor... quiere decir por lo regular es un problema de RAM, se esta agotando... trata de reducir el codigo o compra una arduino con mas capacidad