So uh... This was an interesting project to upload to HackADay. At the time of initially writing this, I was still keeping the general idea secret, but now that it's out I can freely say what it does:
This project was a gift for my BF, and is a wonderfully retro-styled, simplistic audio box.
Hit a button to record a voice message, send it to another box over WiFi, and enjoy the adorable aesthetic of an old tape deck or perhaps an answering machine
Whew! Sorry for the bit of radio silence, we were... Well, we were having a bit of a Christmas Holiday <3
All in all, it were, and still are, a few good days! Presents were exchanged, shenanigans enused, and I am happy to report that the present was well received. In fact, my BF might want to help continue the project, adding a proper wooden casing rather than the 3D printed one I am using now. That would fit the aesthetic beautifully <3
For Christmas itself the present wasn't quite done, it was just about able to play back some music, but we had a few free days since then, and... Well:
All we need now is to solder up a second one, polish the server-side and add a little more audio handling, perhaps a way to use these to directly talk with each other like a DIY intercom :>
Whew, so that was a few eventful last few days working on this present!
I had some extra free time on my paws thanks to a Uni project wrapping up, and I feel like I used it quite well~ Plus, with a slightly adjusted, calmer style of meditation, things actually went by quite smoothly!
Anyhow, let's catch you guys up. First things first, last Thursday I spent the whole afternoon chipping away at the 3D model of the casing. Using Fusion360 and the KiCAD STEP file of the PCB it actually was a very smooth process to design something cute looking! I will want to switch to FreeCAD with Realthunder's changes soon, but for now I can still comfortably use Fusion360, so whatevs. Here's a screenshot of the almost-complete casing, give or take some of the multi-material changes for the buttons:
Apart from just designing this casing, we also put a bit of time into actually printing it - there'll be pics later~
We also finally got the materials for the PCB as well as a time-slot in the Uni laboratory to solder it. Due to the lockdown students have to register for a reserved timeslot, that took a moment. The end result was well worth the wait though!
I did end up leaving out the battery charger and fuel gauge, for the simple reason of having messed up the footprint of the battery. It used the smaller variant of the two QFN footprints available, which frankly scares me a bit because it still does dissipate a fair bit of heat when dropping 5V down to the LiPo voltage to charge it!
Oh well - everything else fit beautifully, and here's the almost-assembled board, sans the ESP32!
The missing charger footprint is the one in the top middle... Oh well. Oh yeah, and the LEDs I'm using to illuminate the key switches? Those are side-mount Inolux WS2812 clones, which can also be mounted in the upright position to create this neat tiny-form-factor directed LED. Works great!
All in all, the PCB + components fit into the casing exactly as I was hoping. After tweaking the program code, checking that everything boots without blowing up etc. etc, I finally ended up with this extremely promising WIP of the assembled unit.
Ain't she a beauty <3
There still are some quirks to sort out. The VU Meter is connected the wrong way around so sadly the needle moves down onto the scale instead of up, aw for that but nothing major.
The speaker and sound is quite good though! I mean, for this setup. I wish I would've taken audio design more into account for this because it's lacking a bit of bass, but for human speech it is very understandable and quite crisp. It also looks like the power design I made supports the WiFi at full power, that'll help keep the stream of MQTT OPUS packets flowing smoothly.
"All" that's left to do now is:
Connect the Microphone
Write a I2S Microphone to Opus stream class (kinda easy tho)
Read out the buttons and write the recording user-interface
Write the Ruby server side that saves and streams the audio recordings.
Hoo boy... Well, it's a lot of fun and we're in no rush, so let's see where this goes!
Since the last progress log, for which I managed to port Opus onto the ESP, a bunch of stuff happened.
First things first, the PCB is here and it looks absolutely stunning! Aisler upped their game a bit, whatever supplier they are using now is making some gorgeous boards and very clean silkscreen. Looks like all the traces are fine too <3
Shiny, just how I like it! Sadly the PCB won't be soldered any time soon. Due to the lockdown my University has made the labs inaccessible unless absolutely necessary, so soldering some hobby stuff is probably not going to work out... What a shame, but we'll still carry on :>
There's enough to do with the Audio backend, in any case! First things first, there was a complete rewrite of our ESP Audio code. Opus needs a large stack and a fairly large amount of processing time, while the ESP's DMA buffer needs to be filled in rather small increments of a few ms. That didn't mix very well...
The new design uses two separate FreeRTOS Threads, one to fill the DMA buffers, and one with a large stack that can be shared between multiple Opus decoders and encoders to conserve resources a bit. We also cleaned up the way we interface with the audio a lot after learning about std::shared_ptr :>
Included in this rewrite was the creation of a dedicated Opus Decoder Stream class. It accepts Opus packets from a coms channel (probably WiFi), and handles decoding and even keeping the playback speed synchronous. With a bit of experimentation, we were even able to register the ESP as Linux Audio Sink, accidentally creating our own WiFi speaker!
You can't quite hear the audio that well, but it still gives a fairly neat demonstration of the audio streaming, and I really look forward to using this in my other projects such as the Lasertag, Smart Home and probably Tap Badge as well <3
Alright, seems like this project is starting to pick up some speed. Over the last few weeks we were perhaps a little busy with the regular stuff... Finishing our bachelor thesis, helping keep a University project just about stay afloat...
But we still managed to make some time to continue the schematic, and last week we finally got around to ordering everything off of Aisler! The PCB could perhaps be a bit smaller, maybe there's a bit of money to save, but this really isn't for mass production. Have a look!
If everything goes well, Aisler will ship it by next Wednesday, and one or two weeks after that and we will hopefully be able to show the hardware in action.
There's LEDs, there's Cherry switches (which also have LEDs), there's WiFi and Audio ... This whole thing has turned into quite a random endeavor, hasn't it? Lovely <3
Oh, speaking of the Audio! This whole project will heavily rely on throwing audio data around from place to place, as can be seen by the MAX Audio Amplifier IC on the board. Since sending raw audio data isn't, perhaps, the smartest idea, and I have noticed that the ESP does not like sending or receiving that much data over MQTT, some form of codec had to be found.
There's the ESP-ADF, but it is way too chunk for what I need, and I don't really like their audio pipelines... I wanted to mess about with my own stuff.
So, after unsuccessfully looking for a nice codec that was available for the ESP, I just decided to make my own! Feel free to add this repo to any of your ESP32 projects if you need a codec :>
Opus is a great voice codec over a huge range of sample- and bitrates, and it's fully open source, so it made for a perfect choice to port to the ESP. The crappy FPU and no good hardware acceleration features mean that encoding data won't work at particularly high qualities, but decoding seems to be very doable.
This also means that now I have Opus for all my other projects - maybe I'll add it to the Lasertag for higher quality weapon sound FX or even background music. Maybe it'll be added to my upcoming smart home rework to add an internal voice coms? And you can bet it'll be added to "TapBadgeV2" once we get around to it~
Anyhow, we'll wait for the PCBs to arrive, solder them up, and see how far we can go from there!