I have two problems with the PN532 connected with I2C communication in the ESP8266.
The first problem is that sometimes when I connect the board, it throws an error saying that it didn't find the PN53X board
Didn't find PN53x board
0x40237dbc in NfcAdapter::begin(bool) at lib\NDEF/NfcAdapter.cpp:22 (discriminator 1)
0x4023571a in setup at src/main.cpp:34
0x4023a827 in loop_wrapper() at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_main.cpp:198
0x40101229 in cont_wrapper at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/cont.S:81
Then the program restarts, and the same error shows until I disconnect the PN532 from power and connect it again. Only then the program starts. If I hit the RST button from the microprocessor before doing this, it shows the same error. If I hit it after, doing it, it may just start the program, or show the same error. The only constant is that when the error shows, the only way for the program to start is to disconnect and reconnect the PN532.
I thought it may be something with the fact that I am using a protoboard and maybe the cables disconnect just when I connect the board, but the light is on all the time, and if this was the case, then using the RST button should work.
The other problem is that after executing the program without reading for a "long" time, the system throws a VERY long error that has 2 lines related to the PN532, and the system restarts, and the previous problem always presents itself because of the restart.
Here is the error:
0x4023af38 in Twi::read_byte(bool) at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_si2c.cpp:315 (discriminator 2)
0x4023b0a4 in Twi::readFrom(unsigned char, unsigned char*, unsigned int, unsigned char) at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_si2c.cpp:383 (discriminator 2)
0x4023b2e0 in twi_readFrom at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_si2c.cpp:989
0x401061a9 in ets_timer_arm_new at ??:?
0x4023b2e0 in twi_readFrom at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_si2c.cpp:989
0x4023b39c in __delay at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_wiring.cpp:49
0x40237c30 in TwoWire::requestFrom(unsigned char, unsigned int, bool) at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\libraries\Wire/Wire.cpp:129
0x4023b3b5 in __delay at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_wiring.cpp:57
0x40237c63 in TwoWire::requestFrom(int, int) at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\libraries\Wire/Wire.cpp:148
0x40238b36 in PN532_I2C::readResponse(unsigned char*, unsigned char, unsigned short) at lib\PN532_I2C/PN532_I2C.cpp:126
0x40105f25 in wdt_feed at ??:?
0x40248869 in PN532::readPassiveTargetID(unsigned char, unsigned char*, unsigned char*, unsigned short) at lib\PN532/PN532.cpp:393
0x40237e01 in NfcAdapter::tagPresent(unsigned long) at lib\NDEF/NfcAdapter.cpp:42
0x40235904 in readNFC(NfcAdapter*) at src/readNFC.cpp:11
0x401058cd in call_user_start_local at ??:?
0x401058d3 in call_user_start_local at ??:?
0x40100df4 in umm_init at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266\umm_malloc/umm_malloc.cpp:478
0x4010000d in call_user_start at ??:?
0x401000ab in app_entry_redefinable at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_main.cpp:325
0x40269790 in cont_ret at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/cont.S:142
0x402357ab in String::isSSO() const at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/WString.h:262
(inlined by) String::wbuffer() const at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/WString.h:277
(inlined by) String::buffer() const at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/WString.h:276
(inlined by) String::operator bool() const at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/WString.h:139
(inlined by) loop at src/main.cpp:47
0x4023a41a in loop_wrapper() at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_main.cpp:201
0x40101229 in cont_wrapper at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/cont.S:81
0x40212180 in sqlite3VXPrintf at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:25485 (discriminator 1)
0x40212159 in sqlite3VXPrintf at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:25484 (discriminator 1)
0x40212b8d in sqlite3VXPrintf at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:25815
0x40219b9e in lookupName at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:89826
0x4024f0b4 in __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:232
0x4024ad0d in _printf_i at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf_i.c:196 (discriminator 1)
0x4024f0b4 in __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:232
0x4024eff0 in __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:179
0x40219c10 in resolveExprStep at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:89917
0x40219498 in resolveSelectStep at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:90505
0x4024ae3c in _printf_i at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf_i.c:246
0x4027f1af in chip_v6_unset_chanfreq at ??:?
0x4024eff0 in __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:179
0x4024f505 in _svfprintf_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:662
0x4020e8e6 in sqlite3MemFree at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:20819
0x40100e4d in malloc at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266\umm_malloc/umm_malloc.cpp:821
0x402140bc in sqlite3MemMalloc at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:20790
0x402013ac in sqlite3Malloc at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:24497
0x40100e4d in malloc at C:\Users\joaqu\.platformio\packages\framework-arduinoespressif8266\cores\esp8266\umm_malloc/umm_malloc.cpp:821
0x40201618 in dbMallocRawFinish at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:24825
0x4020163d in sqlite3DbMallocRawNN at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:24893
0x4020eb0a in sqlite3DbRealloc at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:24905 (discriminator 1)
0x4020f21a in growOpArray at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:71547
0x4020f26c in growOp3 at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:71585
0x402140bc in sqlite3MemMalloc at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:20790
0x402044da in resolveP2Values at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:72048
0x40207855 in sqlite3VdbeMakeReady at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:73389
0x4020f7a8 in allocVdbe at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:118355
0x4021eccf in sqlite3FinishCoding at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:99926
0x40231006 in yy_reduce at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:137400
0x40231006 in yy_reduce at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:137400
0x402323e8 in sqlite3Parser at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:138590
0x40208cf4 in yy_pop_parser_stack at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:136856
0x40208d0e in sqlite3ParserFinalize at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:136863 (discriminator 1)
0x402325a5 in sqlite3RunParser at .pio\libdeps\esp12e\Sqlite3 for ESP8266\src/sqlite3.c:139431
Just because, here is the code I am running:
// NFC
PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c);
// RTC
RTClib RTC;
void setup() {
Serial.begin(9600);
Wire.begin();
nfc.begin();
// Start the SD Card and the database
SPI.begin();
if (vfs_mount("/SD0", D8) == NULL) {
Serial.println("SD Card Mount Failed");
return;
}
sqlite3_initialize();
Serial.println("System Ready");
}
void loop() {
// Read the NFC tag
String tagId = readNFC(&nfc);
if (tagId && !tagId[0]) return;
// Query the tag
char *message = "";
if (!query_tag(tagId.c_str(), &message)) return;
// Print the message
if (message && !message[0]) {
// If the message is empty, ask the user if they want to save a message
Serial.println("Tag not found\n");
Serial.println("Do you want to save the tag? (y/n)");
// Wait for the user to enter a character
while (Serial.available() == 0) delay(100);
char c = Serial.read();
if (c != 'y') {
Serial.println("Tag not saved");
return;
}
// If the user enters 'y', ask for the message
Serial.println("Enter the message:");
while (Serial.available() == 0) delay(100);
String message = Serial.readString();
if (!message && !message[0]) {
Serial.println("Message cannot be empty\nTag not saved");
}
if (!save_tag(tagId.c_str(), message.c_str())) return;
} else {
Serial.printf("%s\n\n", message);
return;
}
}
byte nuidPICC[6];
String readNFC(NfcAdapter *nfc) {
if (!nfc->tagPresent()) return "";
NfcTag tag = nfc->read();
String tagId = tag.getUidString();
Serial.println(tagId);
return tagId;
}
sqlite3 *db = NULL;
char *db_file_name = "/SD0/sqlite.db";
/**
* Open data.db
*
* @return
*/
bool db_open() {
// Close the database if it's already open
if (db != NULL) sqlite3_close(db);
// Open the database
if (sqlite3_open_v2(db_file_name, &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
NULL) == SQLITE_OK) {
Serial.println(F("Opened database successfully"));
return true;
}
// If the database can't be opened, print an error
Serial.print(F("Can't open database: "));
Serial.println(sqlite3_errmsg(db));
return false;
}
/**
* Query the tag in the database
*
* @param tag The tag to query
* @param db The database
*
* @return 1 if the tag is found, 0 otherwise
*/
bool query_tag(const char *tag, char **message) {
// Open the database
if (!db_open()) return false;
const char *null;
// Prepare the statement
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, "SELECT value FROM nfc_tag WHERE id = ?;", -1,
&statement, &null) != SQLITE_OK) {
Serial.print("Unable to prepare: ");
Serial.println(sqlite3_errmsg(db));
return false;
}
// Bind the value
if (sqlite3_bind_text(statement, 1, tag, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
Serial.print("Unable to bind text: ");
Serial.println(sqlite3_errmsg(db));
sqlite3_finalize(statement);
return false;
}
if (sqlite3_step(statement) != SQLITE_DONE) {
const unsigned char *value = sqlite3_column_text(statement, 0);
// Check value and save it in message
if (value)
*message = const_cast<char *>(reinterpret_cast<const char *>(value));
}
sqlite3_finalize(statement);
// Close the database
db_close();
return true;
}
/**
* Close the database
*/
void db_close() {
if (db != NULL) sqlite3_close(db);
db = NULL;
Serial.println("Closed database successfully");
return;
}
/**
* Save new tags to the database
*
* @param tag The tag to save
* @param message The message to save
*
* @return True if the tag is saved, false otherwise
*/
bool save_tag(const char *tag, const char *message) {
// Open the database
if (!db_open()) return false;
// Prepare the statement
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, "INSERT INTO nfc_tag (id, value) VALUES (?, ?);",
-1, &statement, NULL) != SQLITE_OK) {
Serial.print("Unable to prepare: ");
Serial.println(sqlite3_errmsg(db));
return false;
}
// Bind the values
if (sqlite3_bind_text(statement, 1, tag, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
Serial.print("Unable to bind tag: ");
Serial.println(sqlite3_errmsg(db));
sqlite3_finalize(statement);
return false;
}
if (sqlite3_bind_text(statement, 2, message, -1, SQLITE_TRANSIENT) !=
SQLITE_OK) {
Serial.print("Unable to bind message: ");
Serial.println(sqlite3_errmsg(db));
sqlite3_finalize(statement);
return false;
}
// Execute the statement
sqlite3_step(statement);
sqlite3_finalize(statement);
// Close the database
db_close();
return true;
}