First, I would like to say thank you to Vivokey because this has been an intense but wonderful learning experience. I would also like to say thanks to Vivokey for maintaining the api2 endpoints absolutely free of charge.
Recently I have noticed an influx of users asking what they can do with their Spark 2, well this project can now be added to the list of answers! Provided you can solder a few components together and upload a sketch to an Arduino, this project will provide you with the ability to use Vivokey’s api2 server to access the cryptographic functions of your Spark 2.
A successful run through of the sketch(successful mutual verification of the Spark 2) is shown by pin22 of the ESP32 turning on for 1 second. If you would prefer something else to happen, those lines of code can be changed to just about anything. For now, pin22 can be attached to a relay which should mimic the good ol’fashioned xAC.
Sequence of events(to temper everyone’s excitement):
1.User touches capacitive wake-up pin4. (onboard LED turns on)
2.Approx. 3 seconds for WIFI connection.
3.Get-challenge received. (onboard LED turns off)
4.Starts 10s timeout scan. (Scan your Spark 2)
5a.If successful, pin 22 turns on for 1 second
5b.If failed, “Fail!” is printed to console.
6.ESP32 goes to sleep. (rinse and repeat)
Since this project was designed to be battery friendly the ESP32 will sleep between each scan. Every time the ESP32 wakes up, it will need to reconnect to the WIFI which takes most of the programs “awake” time. If you would like a faster process time, the WIFI connection would need to be sustained therefor increasing the power draw significantly.
Required components:
ESP32 DEV-KIT V1 (30pins):
PN532:
https://www.elechouse.com/elechouse/index.php?main_page=product_info&cPath=90_93&products_id=2276
GitHub Repository:
https://github.com/AbbottDSmith/ArduinoVivokey
GitHub - AbbottDSmith/ESP32VivokeyLibrary
Inside the Github repository is an Arduino sketch(.ino), an arduino_sercets file(.h), and a PCB Gerber(.zip) The PCB Gerber is only used to eliminate wires, it is not required.
SET-UP:
1.After wiring the PN532 to the ESP32 by route of the VSPI pins (SS pin = pin5). Download and install each dependency into the Arduino IDE. (ArduinoJson and PN532 Libraries)
2.By default the ESP32’s SPI clock speed will be 30MHz. The PN532’s maximum SPI clock speed is 5MHz. To fix this problem, we can either slow the ESP32’s CPU by using the Arduino IDE, or we can edit the PN532 Library to set a larger clock divider. Since lowering the ESP32’s CPU speed to a suitable speed will disable WIFI/BLE communication, a larger clock divider is the only option. To do this, a change must be made to the PN532 Library. Open PN532_SPI.cpp and change:
_spi->setClockDivider(SPI_CLOCK_DIV8);
To:
_spi->setClockDivider(SPI_CLOCK_DIV64);
Now when the ESP32’s CPU clock speed is 240MHz, the SPI clock speed will be 1/64th = 3.75MHz. Perfect for a PN532.
3.The arduino_secrets file must be edited to add your SSID, PASS, APIKEY, and ROOTCACERT. Only after the initial boot can “VERIFYID”(member-id) be added. The VERIFYID string will be obtained from the initial console’s output. In other words, do not worry about leaving VERIFYID blank for the initial boot up.
4.After running the program once and successfully obtaining VERIFYID, fill in the missing variable in arduino_secrets. It is then recommended, not required, that the user ERASE the lines of code that print VERIFYID to console. These lines will be marked inside the .ino to make them less difficult to find. Finally, reupload the finished files to the ESP32.
Set up is slightly complicated admittedly. If anyone can make sense of what I have written, and then create a tutorial, that would be super appreciated. To say “I have faith in this community” would be an understatement.
Side note:
A reminder to anyone who needs it; check your byte order! This project would have been out a month ago if I knew that my UID needed to have it’s endianness changed. I am sorry to all the lovely patrons of this forum that I bothered for help. I obfuscated my UID in all of my posts that asked for help, which made it impossible for anyone to actually solve my problem, my bad… I am including this line of code because it has had a major impact on me.
uint8_t bigEndianUID[] = {uid[6], uid[5], uid[4], uid[3], uid[2], uid[1], uid[0]};