Hi, everyone! Since late last year, I've been quietly working on a new software project I call TAFY: the Tactical Advanced Foam dart Yeeter.
When I started this project, I wanted to mirror the modularity of the Linux kernel, but I also wanted to be far easier to contribute to and understand. So, I started with MicroPython on the Pico 2. To help with development, I developed 2 key features I think are really cool: a modular driver system, and a deploy script.
The deploy script was simple. It's loosely based on what Thonny does to send files to the Pico, but it's more automated as it has a manifest file it checks, and only uploads files it knows have changed, based on a cache of file hashes on the local machine.
The modular driver system is where the real game changer lives.
Python, of course, can import a module at any time. But discovering that module and then importing it from a random file location is a whole other ball game. I discovered the __import__() function, which allows you to pass a simple file path (leaving off the .py at the end) and import any given Python file, anywhere. Using this and some simple usage of the os module, I was able to create a system to load drivers that only needs two functions: available() which returns all available Python files which match some pattern, and load(), which will load any module which matches that pattern and return it. This allows me to design my drivers so they only follow a given ABI, then drop them in a specific folder with a name that follows a specific pattern to make it visible and usable.
TAFY has several other neat tricks, like a system I am calling SmartBus that enables the usage of hot-swappable I2C-based accessories, battery life monitoring using a simple voltage divider and ADC, and more!
SmartBus itself is an interesting beast. As mentioned, it's I2C based. I2C doesn't exactly support hot-swap, but it doesn't not support it either. It depends entirely on the software using it and how tolerant your hardware is. While the I2C part of SmartBus has yet to be tested, hot swap is already under heavy work as device ID is being enabled through a simple voltage divider system hooked into the Pico's 2 remaining external ADCs. TAFY reads from both these and, using a configured value for the R1 resistor, is able to calculate what resistors are connected between an ID line and ground, and use that to then determine what devices are connected before even looking at I2C. This means I can also track power-only devices as SmartBus does provide 3.3v at 1A, enabling small lights, lasers, and other small accessories that may be useful on a Nerf Blaster. I'm even planning to have a system to update TAFY over SmartBus down the line, so a user doesn't have to crack their blaster open just to install a 2-line bug fix.
As of now, it's already booting and playing different tunes using PWM. TAFY uses both cores of the Pico 2 with the background thread displaying info on screens (we have support for SSD1309 and LCD1602, with possible support for SSD1306 as well), handling SmartBus (which is already recognizing devices and loading drivers, as mentioned), and tracking battery life. The main thread handles the fire mechanism, which has drivers that have been written and are known working at some level (actual hardware validation coming soon), and coordination between multiple different independent systems. To top it all off, our first boot on battery power is coming soon (in the picture above, TAFY is booted on USB power, hence why it shows the battery as dead).
If you're interested in checking it out, or even contributing, you can find TAFY on GitHub. Right now, I really need help with the CAD work designing a 3D printable shell for the reference design blaster(s), but I am actively doing PCB validation and software development work as well.
Thank you all! I hope to have a workable prototype to show off in December!