Hey guys. i am making a NFC queue system. but the problem is that every time i scan a NFC tag, my arduino runs out of ram very fast. i have made a 2d array, where i wanna store the names in the queue.
532
ok
free ram: 580 ****i start with 580.****
Entering reader
inside UID
Reading
wrote albert at line: 0
1. albert
free ram: 548 ****i scan one time, and it goes down****
Entering reader
inside UID
Reading
wrote aaaaaaaaaaaa at line: 1
1. albert
2. aaaaaaaaaaaa
free ram: 516 ****same here****
Entering reader
inside UID
Reading
wrote balbert at line: 2
1. albert
2. aaaaaaaaaaaa
3. balbert
free ram: 484 ****same here***
Entering reader
inside UID
Reading
wrote bbb at line: 3
1. albert
2. aaaaaaaaaaaa
3. balbert
4. bbb
free ram: 452 ***same here***
Entering reader
so i am gonna run out of ram way too quickly. why do i run out of ram? also, when i remove a name from the list, it still consumes ram.
I think memory is allocated and not returned.
Which library and which example do you use an example for the Mifare ? Please copy a link in the text. Perhaps it is an old one.
A few small other things to optimize:
Use the 'F()' macro to reduce ram use when you print a string, like this : Serial.println(F("error"));
When you use a constant value, use the 'const' keyboard. Perhaps for keyA and keyB : const uint8_t Mifare::keyA[6] = { ....
Peter_n:
I think memory is allocated and not returned.
Which library and which example do you use an example for the Mifare ? Please copy a link in the text. Perhaps it is an old one.
A few small other things to optimize:
Use the 'F()' macro to reduce ram use when you print a string, like this : Serial.println(F("error"));
When you use a constant value, use the 'const' keyboard. Perhaps for keyA and keyB : const uint8_t Mifare::keyA[6] = { ....
Sorry, i am not that good at code yet. where do you wanna use that macro?
Also, the uint8_t mifares next to the defines, isn't my work. i got that from a nfc read example.
econjack:
Which Arduino board are you using and which version of the IDE? Also, what's the purpose of this line?
while (index < ENTRY_SIZE);
If the code gets here, it seems like you'll spend a lot of time here since the loop body doesn't change anything.
I am using arduino uno r3. with ide 1.0.5-r2 (this is what you asked for right?)
Aight, so this was me trying out a theory, i wanted to see if i would get some ram back, if i null terminated all the places in the array, where the chars had to be. it didn't work.
void nameChecker()
{
delay(1000);
for(byte i = 0; i < ENTRY_COUNT; i++)
{
delay(10);
if(strcmp(nameList[i], name) == 0)
{
lineToClear = i;
do
{
nameList[i][index] = 0;
index++;
}
while (index < ENTRY_SIZE); // means that i null terminate the whole string, if i scan a card, which is already ont he list. :)
index = 0;
lineNumberSetDirty = false;
reader();
break;
}
}
writer();
}
if there is memory allocated by mifare.readTarget() it is never freed.
so wrap the call with two freeram() and check if there is the leak
Arduino uno r3.
I think i did as you said. That gave me this.
532
ok
free ram: 522
starting first test
522
522
First test done
inside UID
Reading
starting second test
522
522
Second test done
wrote balbert at line: 0
1. balbert
free ram: 490
starting first test
490
490
First test done
inside UID
Reading
starting second test
490
490
Second test done
wrote bbb at line: 1
1. balbert
2. bbb
free ram: 458
starting first test
458
458
First test done
inside UID
Reading
starting second test
458
458
Second test done
wrote albert at line: 2
1. balbert
2. bbb
3. albert
free ram: 426
starting first test
426
426
First test done
inside UID
Reading
starting second test
426
426
Second test done
2. bbb
3. albert
free ram: 396
starting first test
396
void reader()
{
printer();
Serial.print("free ram: ");
Serial.println(freeRam());
delay(100);
Serial.println("starting first test");
Serial.println(freeRam());
uint8_t * uid = mifare.readTarget();
Serial.println(freeRam());
Serial.println("First test done");
if(uid){
Serial.println("inside UID");
delay(100);
mifare.readPayload(payload, PAYLOAD_SIZE);
Serial.println("Reading");
Serial.println("starting second test");
Serial.println(freeRam());
FOUND_MESSAGE m = NDEF().decode_message(payload);
Serial.println(freeRam());
Serial.println("Second test done");
for(int i = 0; i < PAYLOAD_SIZE; i++) {
inChar = m.payload[i];
name[i] = inChar;
if(inChar == 0) {
memset(payload, 0, PAYLOAD_SIZE);
nameChecker();
break;
}
}
}
}
void printer()
{
for(byte i = 0; i < ENTRY_COUNT; i++)
{
if (nameList[i][0] != 0)
{
Serial.print(i+1);
Serial.print(". ");
Serial.println(nameList[i]);
}
}
index = 0;
}
Peter_n:
I think memory is allocated and not returned.
Which library and which example do you use an example for the Mifare ? Please copy a link in the text. Perhaps it is an old one.
A few small other things to optimize:
Use the 'F()' macro to reduce ram use when you print a string, like this : Serial.println(F("error"));
When you use a constant value, use the 'const' keyboard. Perhaps for keyA and keyB : const uint8_t Mifare::keyA[6] = { ....
robtillaart:
On second examination : it is probably a recursion problem:
namechecker() calls reader()
reader() calls namechecker()
if that happens often enough the stack explodes "
you need to redesign your application logic without the recursion...
Ah i see. i just don't know how. I mean. the reader will always have to call the namechecker, to see if the name already exists on the list, but if the name is already on the list, it will have to go back to the reader, and wait for another card.
is it better to do something like this?
void setup()
{
readerReady = 1
}
void loop()
{
if (readerReady == 1)
{
//Do reader code
nameCheckerReady = 1; //allow namechecker to run
readerReady = 0; //stop reader from running
}
if (nameCheckerReady == 1)
{
//do namechecker code
readerReady = 1; //alow reader to run
namecheckerReady = 0; //stop namechecker from running
}
}
Ah i see. i just don't know how. I mean. the reader will always have to call the namechecker, to see if the name already exists on the list, but if the name is already on the list, it will have to go back to the reader, and wait for another card.
The key there is "go back to". That involves a return, NOT calling the function again.