Hi everyone, I'm fairly new in the Arduino world, I have a small project which requires to store amounts of data that are too high to be stored on the internal Arduino's EEPROM.
So I bought an EEPROM chip, the 24LC256, and implemented an abstraction class that stores data on it regardless of the length, so the class can handle as much page writes as required on the chip.
Here's the code for the write method (I've cleaned up debug messages):
bool E2PRM24LC256::write(unsigned short address, byte* data, unsigned short length) {
byte ACK;
byte* page = data;
unsigned short written, writeLength = 0;
unsigned short pageAddress = address;
while (written < length) {
//Initiate IC2 channel with device of given address, this will send start condition byte
Wire.beginTransmission(this->deviceAddress);
//Send the first byte of the page start address
Wire.write((byte)(pageAddress >> 8));
//Send the last byte of the page start address
Wire.write((byte)pageAddress);
//Because of page boundaries we can't always write as much as we want
//for instance if the write address is 155
//then the page boundaries are 128-192, if we try to write
//64 bytes the device will roll over and overwrite data stored
//at the beginning of the page (from the address 128)
//Hence we need to find out how much data we can write on this page,
//to do that we compute the mod of address divided by the page buffer size (64)
//and substract the result to the page buffer size: 64 - (pageAddress % 64) = available writing length
writeLength = PAGE_BUFFER_SIZE - (pageAddress % PAGE_BUFFER_SIZE);
if (writeLength > WIRE_BUFFER_LENGTH) {
writeLength = WIRE_BUFFER_LENGTH;
}
if (writeLength > length - written) {
writeLength = length - written;
}
//Prevent overflow
if (written >= 0) {
//Add written bytes to the counter
written += Wire.write(&data[written], writeLength);
} else {
return written > 0;
}
pageAddress += writeLength;
ACK = Wire.endTransmission();
if (ACK > 0) {
Serial.print("ACK problem ");
Serial.println(ACK);
return false;
}
delay(5);//Wait 5ms for the page to be fully written on the device
}
return true;
}
It works quite fine, and to be sure I've designed a small test:
- Generate a byte sequence of random length (between 8 and 128 bytes actually)
- Store the bytes at a random address on the device
- Read the data from the same address
- Compare both and return false if there is a difference
- Repeat
So, I've runned the test 5 times with 10 or 20 repetitions, it helped me detect flaws in the allocation algorithm that I have fixed, but after a while the endTransmission method returns the error code 2, here's the test output :
Free memory 1041 B
Writing 85 bytes -> (0) (1) (2) (3) (4) (5) (6) a(7) (8) (9)
(10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) e(27) (28) (29) (30) (31) (32) !(33) "(34) #(35) $(36) %(37) &(38) '(39) ((40) )(41) *(42) +(43) ,(44) -(45) .(46) /(47) 0(48) 1(49) 2(50) 3(51) 4(52) 5(53) 6(54) 7(55) 8(56) 9(57) :(58) ;(59) <(60) =(61) >(62) ?(63) @(64) A(65) B(66) C(67) D(68) E(69) F(70) G(71) H(72) I(73) J(74) K(75) L(76) M(77) N(78) O(79) P(80) Q(81) R(82) S(83) T(84)
To address 25161
Page address 25161 written 0 writeLength 30 pointer address 2101
(0) (1) (2) (3) (4) (5) (6) a(7) (8) (9)
(10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) e(27) (28) (29)
Page address 25191 written 30 writeLength 25 pointer address 2131
(30) (31) (32) !(33) "(34) #(35) $(36) %(37) &(38) '(39) ((40) )(41) *(42) +(43) ,(44) -(45) .(46) /(47) 0(48) 1(49) 2(50) 3(51) 4(52) 5(53) 6(54)
Page address 25216 written 55 writeLength 30 pointer address 2156
7(55) 8(56) 9(57) :(58) ;(59) <(60) =(61) >(62) ?(63) @(64) A(65) B(66) C(67) D(68) E(69) F(70) G(71) H(72) I(73) J(74) K(75) L(76) M(77) N(78) O(79) P(80) Q(81) R(82) S(83) T(84)
Read 85 bytes -> (0) (1) (2) (3) (4) (5) (6) a(7) (8) (9)
(10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) e(27) (28) (29) (30) (31) (32) !(33) "(34) #(35) $(36) %(37) &(38) '(39) ((40) )(41) *(42) +(43) ,(44) -(45) .(46) /(47) 0(48) 1(49) 2(50) 3(51) 4(52) 5(53) 6(54) 7(55) 8(56) 9(57) :(58) ;(59) <(60) =(61) >(62) ?(63) @(64) A(65) B(66) C(67) D(68) E(69) F(70) G(71) H(72) I(73) J(74) K(75) L(76) M(77) N(78) O(79) P(80) Q(81) R(82) S(83) T(84)
From address 25161
[......................................]
Test number 1
Free memory -8431 B
Writing 79 bytes -> (0) (1) (2) (3) (4) (5) (6) a(7) (8) (9)
(10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) e(27) (28) (29) (30) (31) (32) !(33) "(34) #(35) $(36) %(37) &(38) '(39) ((40) )(41) *(42) +(43) ,(44) -(45) .(46) /(47) 0(48) 1(49) 2(50) 3(51) 4(52) 5(53) 6(54) 7(55) 8(56) 9(57) :(58) ;(59) <(60) =(61) >(62) ?(63) @(64) A(65) B(66) C(67) D(68) E(69) F(70) G(71) H(72) I(73) J(74) K(75) L(76) M(77) N(78)
To address 5539
Page address 5539 written 0 writeLength 29 pointer address 2101
(0) (1) (2) (3) (4) (5) (6) a(7) (8) (9)
(10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) e(27) (28)
Page address 5568 written 29 writeLength 30 pointer address 2130
(29) (30) (31) (32) !(33) "(34) #(35) $(36) %(37) &(38) '(39) ((40) )(41) *(42) +(43) ,(44) -(45) .(46) /(47) 0(48) 1(49) 2(50) 3(51) 4(52) 5(53) 6(54) 7(55) 8(56) 9(57) :(58)
Page address 5598 written 59 writeLength 20 pointer address 2160
;(59) <(60) =(61) >(62) ?(63) @(64) A(65) B(66) C(67) D(68) E(69) F(70) G(71) H(72) I(73) J(74) K(75) L(76) M(77) N(78)
Read 79 bytes -> (0) (1) (2) (3) (4) (5) (6) a(7) (8) (9)
(10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) e(27) (28) (29) (30) (31) (32) !(33) "(34) #(35) $(36) %(37) &(38) '(39) ((40) )(41) *(42) +(43) ,(44) -(45) .(46) /(47) 0(48) 1(49) 2(50) 3(51) 4(52) 5(53) 6(54) 7(55) 8(56) 9(57) :(58) ;(59) <(60) =(61) >(62) ?(63) @(64) A(65) B(66) C(67) D(68) E(69) F(70) G(71) H(72) I(73) J(74) K(75) L(76) M(77) N(78)
From address 5539
Free ram -8431
Test number 10
Free memory -8431 B
Writing 125 bytes -> (0) (1) (2) (3) (4) (5) (6) a(7) (8) (9)
(10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) e(27) (28) (29) (30) (31) (32) !(33) "(34) #(35) $(36) %(37) &(38) '(39) ((40) )(41) *(42) +(43) ,(44) -(45) .(46) /(47) 0(48) 1(49) 2(50) 3(51) 4(52) 5(53) 6(54) 7(55) 8(56) 9(57) :(58) ;(59) <(60) =(61) >(62) ?(63) @(64) A(65) B(66) C(67) D(68) E(69) F(70) G(71) H(72) I(73) J(74) K(75) L(76) M(77) N(78) O(79) P(80) Q(81) R(82) S(83) T(84) U(85) V(86) W(87) X(88) Y(89) Z(90) [(91) \(92) ](93) ^(94) _(95) `(96) a(97) b(98) c(99) d(100) e(101) f(102) g(103) h(104) i(105) j(106) k(107) l(108) m(109) n(110) o(111) p(112) q(113) r(114) s(115) t(116) u(117) v(118) w(119) x(120) y(121) z(122) {(123) |(124)
To address 29689
Page address 29689 written 0 writeLength 7 pointer address 2101
(0) (1) (2) (3) (4) (5) (6) ACK problem 2
And the arduino freezes after that
I've tried tweaking the options passed to the test methods (run count and executions count) but nothing solved the problem, and I can't figure out where it comes from......
Any help would be greatly appreciated, thanks !