Problema al leer de la EEPROM

Estoy intentando almacenar y después leer un valor de 32 bits pero no hay manera de que funcione. Sólo funciona hasta 16, a partir de ahí ya no los guarda bien. Aquí el código:

#include "EEPROM.h"

uint32_t valor;
uint32_t addr;

void setup() {
  valor = 0;
  addr = 0;
  Serial.begin(9600);
  delay(25);

Serial.print("Numero: ");
while(!Serial.available()) ;
if(Serial.available())
	valor = Serial.parseInt();
Serial.print("Has escrito: ");
Serial.println(valor);
Serial.println();

delay(500);

Serial.println("Guardando valor...");

EEPROMWriteBits(addr, valor);

Serial.println("Valor guardado!");
	Serial.println();
	Serial.println("------------------------");

	delay(2000);
	addr = 0;

	Serial.println("Recuperando valor...");

	valor = EEPROMReadBits(addr);

	Serial.println("\nValor recuperado: ");
	Serial.println(valor);

}

void loop() {
	
}


//EEPROM -> 512 bytes de memoria
void EEPROMWriteBits(uint32_t p_address, uint32_t p_value){
  uint8_t primero = ((p_value >> 0) & 0xFF);
  uint8_t segundo = ((p_value >> 8) & 0xFF);
  uint8_t tercero = ((p_value >> 16) & 0xFF);
  uint8_t cuarto = ((p_value >> 24) & 0xFF);

  Serial.print("primero: ");
  Serial.println(primero);
  Serial.print("segundo: ");
  Serial.println(segundo);
  Serial.print("tercero: ");
  Serial.println(tercero);
  Serial.print("cuarto: ");
  Serial.println(cuarto);

  EEPROM.write(p_address, primero);
  EEPROM.write(p_address + 1, segundo);
  EEPROM.write(p_address + 2, tercero);
  EEPROM.write(p_address + 3, cuarto);
}

uint32_t EEPROMReadBits(uint32_t p_address){
  uint8_t primero = EEPROM.read(p_address);
  uint8_t segundo = EEPROM.read(p_address + 1);
  uint8_t tercero = EEPROM.read(p_address + 2);
  uint8_t cuarto = EEPROM.read(p_address + 3);

  Serial.print("primero: ");
  Serial.println(primero);
  Serial.print("segundo: ");
  Serial.println(segundo);
  Serial.print("tercero: ");
  Serial.println(tercero);
  Serial.print("cuarto: ");
  Serial.println(cuarto);

  uint32_t val = ((primero << 0) & 0xFF) + 
    		((segundo << 8) & 0xFF00) +
    		((tercero << 16) & 0xFF0000) +
    		((cuarto << 24) & 0xFF000000);

	return val;
}

Lo que intento es separar la palabra en 4 partes de 8 bits cada una para almacenar cada parte en un bloque de memoria de la EEPROM y despues leer y juntar cada bloque mediante desplazamientos para retornar el valor.

Hola:

Yo le veo dos cosas, pero no se si es ese el error.

1 - valor = Serial.parseInt(); es un Int (16 bits con signo) , y no uint32_t 2 - en EEPROM.write(address, value) address también es Int (16 bits con signo) , y no uint32_t.

Respecto al primero porque no probas de sacar la parte de introducir por Serial el numero y directamente lo fijas en el código (algo como valor = 0x12345678 ) para ver que pasa.

Saludos.

perrociego: Hola:

Yo le veo dos cosas, pero no se si es ese el error.

1 - valor = Serial.parseInt(); es un Int (16 bits con signo) , y no uint32_t 2 - en EEPROM.write(address, value) address también es Int (16 bits con signo) , y no uint32_t.

Respecto al primero porque no probas de sacar la parte de introducir por Serial el numero y directamente lo fijas en el código (algo como valor = 0x12345678 ) para ver que pasa.

Saludos.

Ya tengo el por qué.

Era tan simple como que en EEPROMReadBits a "tercero" y "cuarto" les había asignado el tipo uint8_t cuando debían ser uint32_t, sino es imposible desplazar sobre ellos más de 16 bits (totalmente lógico).

Gracias!

Subo el código correcto por si a alguien le interesa.

#include "EEPROM.h"

uint32_t valor;
int addr;


void setup() {
	valor = 0;
	addr = 0;
	Serial.begin(9600);
	delay(25);

	Serial.print("Numero: ");
	while(!Serial.available()) ;

	if(Serial.available())
		valor = Serial.parseInt();

	Serial.print("Has escrito: ");
	Serial.println(valor);
	Serial.println();

	delay(500);

	Serial.println("Guardando valor...");

	EEPROMWriteLong(addr, valor);

	Serial.println("Valor guardado!");

	Serial.println();
	Serial.println("------------------------");

	delay(2000);

	Serial.println("Recuperando valor...");

	valor = EEPROMReadLong(addr);

	Serial.println("\nValor recuperado: ");
	Serial.println(valor);

}

void loop() {
	
}


//EEPROM -> 512 bytes de memoria
void EEPROMWriteLong(int p_address, uint32_t p_value){
  uint8_t primero = ((p_value >> 0) & 0xFF);
  uint8_t segundo = ((p_value >> 8) & 0xFF);
  uint8_t tercero = ((p_value >> 16) & 0xFF);
  uint8_t cuarto = ((p_value >> 24) & 0xFF);

  Serial.print("0 - 7 bits (dec): ");
  Serial.println(primero);
  Serial.print("8 - 15 bits (dec): ");
  Serial.println(segundo);
  Serial.print("16 - 23 bits (dec): ");
  Serial.println(tercero);
  Serial.print("24 - 31 bits (dec): ");
  Serial.println(cuarto);

  EEPROM.write(p_address, primero);
  EEPROM.write(p_address + 1, segundo);
  EEPROM.write(p_address + 2, tercero);
  EEPROM.write(p_address + 3, cuarto);
}

uint32_t EEPROMReadLong(uint32_t p_address){
	uint8_t primero = EEPROM.read(p_address);
  uint8_t segundo = EEPROM.read(p_address + 1);
  uint32_t tercero = EEPROM.read(p_address + 2);
  uint32_t cuarto = EEPROM.read(p_address + 3);

  Serial.print("0 - 7 bits (dec): ");
  Serial.println(primero);
  Serial.print("8 - 15 bits (dec): ");
  Serial.println(segundo);
  Serial.print("16 - 23 bits (dec): ");
  Serial.println(tercero);
  Serial.print("24 - 31 bits (dec): ");
  Serial.println(cuarto);

  uint32_t val = ((primero << 0) & 0xFF) + 
    		         ((segundo << 8) & 0xFF00) +
    		         ((tercero << 16) & 0xFF0000) +
    		         ((cuarto << 24) & 0xFF000000);

	return val;
}