Problems with EEPROM

Hi,

I'm trying to make a sketch that interacts with the user by the serial port. The problem is that when I save a value from the serial port to the EEPROM, sometimes , when I try to read that value from the EEPROM, it returns the value 208. For example, I ask to the user : ID node ? and the users writes 2 in the EEPROM, then when I try to see that value, instead of 2 it returns 208. Anybody know why? Thank you very much.

Post your code (in [code]...[/code] tags).

Pete

Here is my code. The part where is the trouble is in the setup function. Hope u understand its not clena.. Thanks.

#include <RHRouter.h>
#include <RH_RF69.h>
#include <SPI.h>
#include <EEPROM.h>

/*
RED DE NODO LEJANO:
Este nodo se comporta como router, por lo que lo único que hace es recibir 
la información y reenviarla, nada más.
La ruta es la siguiente:
  SENDER_ADDRESS -> ROUTER1_ADDRESS -> ROUTER2_ADDRESS ->MASTER_ADDRESS
*/
/*
#define NODE1_ADDRESS 1
#define NODE2_ADDRESS 2
#define NODE3_ADDRESS 3
#define NODE4_ADDRESS 4
#define NODE5_ADDRESS 5*/


#define ROUTER1_ADDRESS 6
#define ROUTER2_ADDRESS 7
#define ROUTER3_ADDRESS 14
#define ROUTER4_ADDRESS 15 

#define SENDER_ADDRESS 8

#define MASTER_ADDRESS 1

#define LED           9

// Singleton instance of the radio
RH_RF69 driver;

// Class to manage message delivery and receipt, using the driver declared above
RHRouter manager(driver, ROUTER4_ADDRESS);
unsigned long timeOut = 3000;
unsigned int pinA1 = 0;
unsigned int pinA2 = 0;
unsigned int pinA3 = 0;
unsigned int pinA4 = 0;
unsigned int pinA5 = 0;
unsigned int pinA7 = 0; //pin de la bateria 
byte ROUTER_ADDRESS;
byte ROUTER_DIRECTION;



void setup() 
{
  /*
   * Se le pregunta al usuario por el id del nodo y el nodo al que debe ir.
   * En terminos generales se guardan los datos que vienen del serial en la eeprom
   * y luego los datos guardados los usamos para configurar el nodo.
   */
  Serial.begin(115200);
  if (Serial)
  {
    Serial.print("ID del nodo? ");
    delay(3000);
    if (Serial.available()>0)
    {
      
      char id = Serial.read(); // Se lee el id desde el puerto serial
      byte nodo_id = id - 48;
      EEPROM.write(0,nodo_id);
      Serial.println(nodo_id);
      delay(200);
    }
    Serial.print("Siguiente nodo? ");
    delay(3000);
    if (Serial.available()>0)
    {
      
      char dest = Serial.read();
      byte nodo_dest = dest - 48;
      EEPROM.write(1,nodo_dest);
      Serial.println(nodo_dest);
    }
    
  }
  
   //Configuramos el nodo 
  ROUTER_ADDRESS = EEPROM.read(0);//id del nodo
  ROUTER_DIRECTION = EEPROM.read(1); //nodo al que debe ir  
  manager.setThisAddress(ROUTER_ADDRESS);
  delay(200);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 434.0MHz, 0.05MHz AFC pull-in, modulation FSK_Rb2_4Fd36
  
  if (!driver.setFrequency(434.0))
    Serial.println("setFrequency failed");
    
  if (!driver.setModemConfig(RH_RF69::FSK_Rb2_4Fd4_8)) //FSK, Whitening, Rb = 2.4kbs, Rx Bandwidth = 2*4.8kHz.
    Serial.println("SetMode FSK 2.4kbps Failed");
  
  driver.setTxPower(20);
  
  //Tabla de ruteo
  manager.addRouteTo(MASTER_ADDRESS, ROUTER_DIRECTION);
  //manager.addRouteTo(MASTER_ADDRESS, MASTER_ADDRESS);

}


uint8_t data[12];
// Dont put this on the stack:
uint8_t buf[RH_ROUTER_MAX_MESSAGE_LEN];


void loop()
{
  uint8_t len = sizeof(buf);
  uint8_t from;
  

  
  // Leemos los puertos analógicos y luego los guardamos en el arreglo datos 
  pinA1 = analogRead(1);
  data[0] = pinA1;
  data[1] = pinA1>>8;
  //Serial.println(pinA1);
  pinA2 = analogRead(2);
  data[2] = pinA2;
  data[3] = pinA2>>8;
  //Serial.println(pinA2);
  pinA3 = analogRead(3);
  data[4] = pinA3;
  data[5] = pinA3>>8;
  //Serial.println(pinA3);
  pinA4 = analogRead(4);
  data[6] = pinA4;
  data[7] = pinA4>>8;
  //Serial.println(pinA4);
  pinA5 = analogRead(5);
  data[8] = pinA5;
  data[9] = pinA5>>8;
  //Serial.println(pinA5);
  pinA7 = analogRead(7); //Bateria
  data[10] = pinA7;
  data[11] = pinA7>>8;
  //Serial.println(pinA7);
 
  Serial.println("Enviando al nodo Master");
  Serial.println(manager.thisAddress());
  Serial.println(ROUTER_DIRECTION);
  if (manager.sendtoWait(data, sizeof(data), MASTER_ADDRESS) == RH_ROUTER_ERROR_NONE)
  {
    //Si es que el mensaje se envió de manera segura, recibimos un mensaje ACK received.
    //Esto nos dice que el nodo siguiente, recibió el mensaje.
    //Serial.print("ACK recibido de: 0x");Serial.print(from, HEX);Serial.print(" RSSI:");Serial.print(driver.lastRssi(), DEC);
    //Serial.println();
    //Blink(LED,3);
    
  }
   else
  {
    //Serial.println("El dato no se envio correctamente al siguinte nodo");
  }

  
  
  if (manager.recvfromAckTimeout(buf, &len, timeOut, &from))
  {
    //Recibimos un ACK si le llegó el mensaje al nodo siguiente luego de reenviarlo.
    Blink(LED, 3);
   
  }
}

void Blink(byte PIN, int DELAY_MS)
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

You read a character from the serial monitor three seconds after the program starts. There's no guarantee that the user can type a response in that time, but you read a character anyway. If there isn't one there, Serial.read() will return -1. You will then try to store -1-48 =-49 into nodo_dest. But it is an unsigned byte, so it will have a value of 208.
You need to wait until the user has typed something.

Then you will have the problem that the linefeed will be read as the value for nodo_dest.

Change this:

   delay(3000);
    if (Serial.available()>0)
    {
     
      char id = Serial.read(); // Se lee el id desde el puerto serial
      byte nodo_id = id - 48;
      EEPROM.write(0,nodo_id);
      Serial.println(nodo_id);
      delay(200);
    }
    Serial.print("Siguiente nodo? ");
    delay(3000);
    if (Serial.available()>0)
    {
     
      char dest = Serial.read();
      byte nodo_dest = dest - 48;
      EEPROM.write(1,nodo_dest);
      Serial.println(nodo_dest);
    }

to this:

   // wait for input
    while(Serial.available() < 1);
    char id = Serial.read(); // Se lee el id desde el puerto serial
    byte nodo_id = id - 48;
    EEPROM.write(0,nodo_id);
    Serial.println(nodo_id);
    // ignore the rest of the line
    while(Serial.available() > 0);

    Serial.print("Siguiente nodo? ");
    // wait for input
    while(Serial.available() < 1);
    char dest = Serial.read();
    byte nodo_dest = dest - 48;
    EEPROM.write(1,nodo_dest);
    Serial.println(nodo_dest);
    // ignore the rest of the line
    while(Serial.available() > 0);

I haven't tested it, but that should work.

Pete

You're right, my code wasn't good enough. I think that your correction will fix that problem. Now, I'm having another problem, for some reason the part of the code where I send the message is not working with the new code you gave me, Any suggestions? Thank you very much.

These two while statements:

   while(Serial.available() > 0);

should be:

   while(Serial.available() > 0)Serial.read();

Pete

Ok, i changed the while statements. The problem appears when I, instead of connecting the arduino to the serial port, I use a battery instead. Because my idea is to save the values of the ID and de next hop in the EEPROM, so then I don't need to ask again. Then when I connect the Arduino to a battery and connect another Arduino to serial and see if the message was sent correctly, nothing happen. Maybe the problem is with the part:

If (Serial)

Hope the problem understands, thanks for the help.

Marcelo

These two while statements:

Not in my opinion. It would be far better to actually print the data coming in. After all, the response might NOT be OK.

How frequently will you change the value? The EEPROM typically is used to hold values that don't change after a reset, so that this (default) value is read from the EEPROM into a global variable in setup(). When the value shall be changed, the new value is determined in loop() and written both into the variable and the EEPROM. Then your sketch will start with the last value, even if no new input is provided after a reset.

Otherwise, when the value always must be entered after a reset, their is no need nor use for storing that value in the EEPROM.