Based on my prototyping and testing, I designed and built a first prototype. This version used an ESP32 as the microcontroller and wireless connectivity, a LIS3DH accelerometer for impact sensing, and a AAA size lithium ion cylindrical cell for power. A USB micro port was included for charging. A 3-position DIP switch allows for setting the device index (the firmware for all will be identical, with indexing handled based on those settings.) A high power RGB common anode LED is used for indication. The PCB would be mounted into a COTS polycarbonate case, which would then be bolted onto a sheet of 1/4" thick HDPE or LDPE. To help resist impact, the coin cell is strapped down into its holder with zipties. The image below shows the setup once installed.
Upon receipt of the PCBs, I noticed I made a few critical design flaws that somehow slipped my mind. First and foremost I had forgot to add a power switch interface. I was so used to building always-on hardware (see another of my ESP32 projects) that I didn't even think about it. Second, I added a push button that was to be used to switch between various game modes. The button was supposed to be accessible from the backside of the polycarbonate enclosure, but I placed it on the wrong side without thinking too much. This doesn't cause basic functionality issues, but is still wrong.
Nonetheless, a lot did work on the first try. USB charging of the coin cell works, programming of the ESP-WROOM-32 modules works, interfacing with the accelerometer over I2C works, and accelerometer interrupts on high acceleration works. The DIP switches to choose mode also function as desired as well. The LED is very bright, uncomfortable to have on without a diffuser.
The power system is designed similar to the layout for Adafruit's M0 feather boards. The USB power is connected to the 3.3V system voltage regulator directly, and a schottky diode prevents overvoltage to the battery. This implies that when on battery power, all current flows through that diode. I had chosen one with a low forward voltage drop of around 0.25V, but I had failed to look closely at its voltage drop over current. The ESP32 is power hungry, and can pull over 110mA easily. When on battery power, the system would not boot and was making an audible noise. I connected a power supply to the battery terminals, and was able to boot the system at around 4.5V. Of course with a max single cell voltage of 4.2V, this would never work. As a first test, a soldered a jumper over the diode to eliminate its voltage drop. The image below shows the setup. This booted up fine at all reasonable battery voltage levels!
However, the problem remained that if I simply short across the diode, the system cannot be connected to USB power if a battery is installed. Therefore, it cannot be charged. With an expected battery life of only a few hours, no power switch, and the design calling for the battery to be strapped down and embedded deeply, this would be a major hassle. I needed a solution to allow both operation and charging. I dug deeper into what was actually happening. To protect the battery from complete discharge, I had included a supervisor which shut off the regulator if input voltage dropped below 3.3V. I hooked up my scope to both the input voltage and the enable pin of the regulator to see if this was the issue.
In the image below, the purple trace is the input voltage, and the yellow trace is the voltage regulator enable pin. Clearly, the system was repeatedly rebooting. This was the audible signal I could hear.
Zooming in and measuring, it is clear that the input voltage drops to just barely below 3.3V, causing the supervisor to shut off power to the system.
Without a way to have charging, normal battery powered operation, and battery protection working, I chose to eliminate battery protection for now, in order to show a full demo. I hooked up the voltage regulator enable pin directly to the input, so it is always on, and the system no longer reboots, and can operate on battery power alone.
With that done, I installed the PCBs into the polycarbonate cases, and then bolted those onto the HDPE plate. This design is not the most aesthetic, but is a quick way to test out the concept.
For the next hardware revision, I will make a few fixes:
- Add a power switch
- Solve the repeated shutdown issues. There are some options, and I will likely use some combination:
- Use a schottky diode rated for higher current with lower drop
- Attach the supervisor voltage in pin directly to the battery terminal to measure the correct voltage
- Always power the system from the battery, without USB power passthrough (no protection diode needed, but must have a battery installed to work)
- Move the mode change change button to the opposite side of the PCB
For the wireless interfacing stack, I used ESP-NOW. I started with my example code, and built a game state machine on top of that. The overall layout consists of one main target (index 0), and up to 7 other "satellite " targets. Their indices are selected via the DIP switches, so all the firmware is identical. The first game I set up simply lights up a randomly selected target for N seconds, then if that target is hit it tells the main target how long it took to get hit. This will train reaction time and accuracy.
There are some sections of code that work, but need to be better. With ESP-NOW, I cannot guarantee message success, so I have to set up the code to handle a lack of a response safely. That is implemented, but in a poor way for now. I am thinking of using FreeRTOS's timers to make this more reliable and general.
This software is working well, although due to some hardware issues, the entire system isn't quite working yet.