ATrappmann / PN5180-Library

PN5180 library for Arduino
GNU Lesser General Public License v2.1
105 stars 92 forks source link

Reducing SRAM footprint / enabling PN5180 reader array? #5

Closed alastaira closed 5 years ago

alastaira commented 5 years ago

Testing the library seems to be working great at detecting ISO15693 cards using a simple, single reader - thanks!

I'm now trying to upgrade an existing system that uses an array of four RFID readers - currently these are using ISO14443 tags on MFRC522 readers attached via SPI interface to a single Arduino UNO , which I'd like to replace with ISO15693 tags on PN5180s to benefit from the significantly improved read range.

Hardware-wise, it's trivial to swap out of the readers. The problem I've encountered is that, on the software side, using an empty sketch that does nothing more than instantiate four PN5180ISO15693 objects assigns 2236bytes of global memory - exceeding the 2kb available on an ATMega328-based board. By comparison, the MFRC522 library I'm using currently requires only 258bytes to instantiate an array of 4 readers.

I wondered if you had any ideas on how to reduce the memory footprint, or a different approach to polling multiple readers from a single sketch? I've been able to trim a couple of bytes out - moving some variables to PROGMEM, and correcting a couple of cases where string literals were not using the F() macro etc., but not made any significant difference. Or do you think it will not be possible with the current architecture and I should look to, perhaps, assign a separate Arduino Nano to monitor each PN5180 board, and then poll those via I2C from a master controller or similar?

Any thoughts much appreciated!

ATrappmann commented 5 years ago

Hi alastaira, thank you for your interest and your feedback. I can reproduce your problem exactly. My first thought was, that not all the debugging output was disabled, but that is not the case. Looking into the code, the PN5180 class has a readBuffer with 508 bytes in size. If you instantiate the classes 4 times, you have 4 readBuffers with 2032 bytes of global space. This buffer is only used by PN5180::readData function. So if you instantiate 4 instances, I don't think you need 4 buffers in each class. Simply by making the readBuffer a static instance variable, you reduce the amount of memory from 2032 to 204 bytes only and there should not be any difference in behavior as long as you don't call readData in parallel (somehow). Please add a "static" in front of the declaration of the header of PN5180.h: static uint8_t readBuffer[508]; This should solve it. --Andreas.

alastaira commented 5 years ago

Excellent, that seemed to do the trick, thanks! I've just tested it with an array of two readers and it seemed fine. Will try extending that to 4 or more readers and let you know how I get on.

For the benefit of future readers who might want to make this same modification, in addition to modifying the declaration of readBuffer in PN5180.h (line 76) as follows: static uint8_t readBuffer[508]; I also had to add a definition of the variable into PN5180.cpp (I placed it just before the READ_DATA function as that's where it's used, but you can put it anywhere in the main body of the file) uint8_t PN5180::readBuffer[508];

Other than slightly messing up your otherwise very nicely-encapsulated library code, would there be any reasons for not declaring a static readbuffer as a matter of course?

ATrappmann commented 5 years ago

Thank you for your feedback. I will prepare a minor version with this. Please let me know if everything works with your array of 4 readers.