Audio Recording Bracelet

(Continuous Recording, Selective Saving)

The minimum viable product has 4 features.

  1. Continuously recorded audio. The device should have enough battery to continuously record for at least 4 hours — and ideally 10.

  2. Wearable form factor. I want the device to be with me at all times.

  3. Ability to save last 3-5min from audio buffer. The device needs a button to signal when the recording should be saved. The device should have enough storage to save at least 24 hours of audio. Scaling the amount of audio that can be saved should just require buying a more expensive microSD card.

  4. (Easily) export audio files. This is a requirement. Saving audio isn't very useful if I have no way to access it. However, "easily" is in parenthesis because there are a lot of different ways to do the export. The MVP version might be as simple as access to the microSD card.


If I can get this working — and that is a big if — here are 4 of features that would be nice to have.

  1. An LED to signal the device's state. Potentially an RGB diode, so there are more colors to choose from.
  2. A rechargeable battery. It would be great if I could engineer the device in a way so that I don't need to take it apart when it runs out of batteries.
  3. Wireless export. This would be huge. Because I use a Mac, exporting files with microUSB or USB is a pain since I would need to keep track of a dongle. Wireless export can conceivably be be done with either Bluetooth Classic or over Wifi. Based on my research, I think it will be easier to create a wifi access point and a custom iOS/Mac app to facilitate the export. Apple's guidelines are quite strict when it comes to Bluetooth on iOS. Any device that doesn't use one of the default Bluetooth profiles must apply for the MFI program. No thank you!
  4. Water Resistant. The best experience with wearables is when you don't have to think about them. I don't want to worry walking in the rain and electrocuting myself — or, more importantly, breaking my bracelet!

If somehow I have managed to get all of the above working, here are some crazy ideas that would bring this device from a clunky, but useful DIY project into the realm of a consumer wearables.

  1. Entirely Wireless. Never plug a cable into the device. Recharge via induction. Export over wifi.
  2. Custom Charger.

All of these stretch goals go together to create a device that is entirely wireless.



What I Built...

I built a 2-sided ESP-32 board, that interfaces with a microSD card over 4-line SDMMC. The board records audio, sampling at 44k hertz per second, via an analog MEMS microphone and saves it in real-time.

IMG_1740Screen Shot 2019-12-20 at 2.12.04 PMIMG_1736


To retrieve the audio files, the user connects to a soft-access point — a wifi network generated by the device — and can download the files over an HTTP server.

Screen Shot 2019-12-14 at 9.36.34 PM


The board is 28mm x 44mm x 8mm. It is very small (the same size as Neil's hello world example board). Small enough to fit in on a wrist.


I created a 2-part mold out of machinable wax, with a third registration insert 3D printed on a PrusaMK3. I cast the mold with Mold Star 20T. And then 3D printed a cover for the bottom.

What doesn't work:

Screen Shot 2019-12-17 at 1.55.33 AM


Screen Shot 2019-12-20 at 2.20.15 PM

Previous HTM(A)A Projects & Resources:


10/29 | Researching Audio Recording on AVR

In order to capture audio data at an appropriate resolution for human hearing, around 44,000 samples need to be taken per second. For reference, CDs have a 44.1 kHz sampling frequency. Source

11/1 | Battery

Lithium Ion ( 1AH, 50mm x 35mm

11/5 MicroSD Card Characteristics

11/6 How to choose a battery

Charge management controller

Vertical Mount microUSB (6.7mm height)

Vertical Mount microUSB (5.9mm height)


Bottom side is battery / power management + microUSB port for power (either vertical mount or through side). Top Side ESP32, SD Card and microphone + lights?

Writing i2s stream to SD Card

	i2s_config_t i2s_config_rx = {
		mode: (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
		sample_rate: 44100,
		bits_per_sample: I2S_BITS_PER_SAMPLE_32BIT,
		channel_format: I2S_CHANNEL_FMT_RIGHT_LEFT,
		communication_format: (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
		intr_alloc_flags: ESP_INTR_FLAG_LEVEL1,
		dma_buf_count: 14,
		dma_buf_len: 64

	i2s_config_t i2s_config_tx = {
		mode: (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
		sample_rate: 44100,
		bits_per_sample: I2S_BITS_PER_SAMPLE_32BIT,
		channel_format: I2S_CHANNEL_FMT_RIGHT_LEFT,
		communication_format: (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
		intr_alloc_flags: ESP_INTR_FLAG_LEVEL1,
		dma_buf_count: 32,
		dma_buf_len: 64

        i2s_pin_config_t pin_config = {
            .bck_io_num = 21,
            .ws_io_num = 26,
            .data_out_num = 22,//I2S_PIN_NO_CHANGE
            .data_in_num = 23

	//Somehow it's needed. If not, noise!
 	pinMode(23, INPUT);

	//for recording
	i2s_driver_install(I2S_NUM_1, &i2s_config_rx, 0, NULL);
    	i2s_set_pin(I2S_NUM_1, &pin_config);

	//for playback
	i2s_driver_install(I2S_NUM_0, &i2s_config_tx, 0, NULL);
    	i2s_set_pin(I2S_NUM_0, &pin_config);

	uint32_t cnt = 0;
        uint32_t buffer;
   	uint32_t buffer_out = 0;
		buffer = 0;
		int bytes_popped = i2s_pop_sample(I2S_NUM_1, (char*)&buffer, portMAX_DELAY);
		buffer_out = buffer << 5;

		if (buffer_out == 0) {
			//For debugging, if out is zero
			Serial.printf("%d -> %x\n", cnt, (int)buffer_out);
		else {
			//Just playback for now
			i2s_push_sample(I2S_NUM_0, (char*)&buffer_out, portMAX_DELAY);

ES8388 Codec

I2S Pins (Specifically CLK)

SEL is unconnected, i.e. only one channel, apparently left
LRCL to #15
DOUT to #32
BCKL to #14
3V to 3V


11/25 SD Pull Ups

It makes sense to try the 4-bit SD mode rather than SPI because write speed is essential. After making my first dev board, I know realize that the schematic was wrong. I need to connect the pull ups to VCC.

Connecting SD cards with the ESP32 [can be a little bit difficult because the ESP32 uses the same pins for the __ protocol and bootstrapping the micro controller.

There were quite a few problems with my previous circuit besides the pull-ups not being connected properly. I looked into the pinouts for SD cards and realized that I hadn't been connecting ground (VSS) or the power (VDD).

So I need to update the design of my board. Also depending on how difficult it is to set up a 4-bit SD connection, it might make sense to start off with SPI...

Pin Configuration

Pin NumberPin NameIn SD ModeIn SPI Mode
1DAT2/XConnector Data line 2No use
2DAT3/CSConnector Data line 3Chip Select
3CMD/DICommand / Response LineData Input
4VDD/VDDPower supply (+3.3V)Power supply (+3.3V)
5CLK/SCLKClockSerial Clock
7DAT0/D0Connector Data line 0Data Out
8DAT1/XConnector Data line 1No use


In the future, I should flash the device before connecting the microSD card and permanently burn in the voltage that the ESP32 should operate at (3.3V).


12/4 Integrated
Battery Charger

12/5 Small BLE SoCs


12/6 Programming Jib

Now that my development board is mostly working, I need to start thinking about ways to compress the circuit. The various components that are needed to program the board take up a significant amount of space (a button, a switch, and the FTDI header, in addition to all the various traces connecting everything). I can reduce the size of the final circuit a lot if I find a way to remove all of this stuff. Creating a programming jib seems like the right approach.

A programming jib allows you to program a board before soldering it into a circuit. I can separate all of the programming components onto the jig and then only add the necessary components to the product board.

I will need to draw up a schematic. The main different is that there won't be pads for the ESP32 footprint. Instead the chip will be connect with pogo pins.

  1. TX
  2. RX
  3. GPIO 0
  4. EN
  5. GND

Also the ESP32 has the ability to update its firmware over the air (OTA) — once it has been flashed with code enabling this functionality.

10/6 i2s microphone

This really seems like it should be possible and yet it seems like a lot of people have difficulty setting this up.

My contributions to the class / community:

12/9 Flash Memory would probably be better than microSD cards


var consonants = function(s){
	return s.toLowerCase().split('').filter(c => !(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')).join('');

var shiftchar = function(str, shft) {
	return str.split('').map(c => isLetter(c) ? String.fromCharCode(c.charCodeAt()+shft)).join('') : c;

var gematria = function(str, shft) {
	return shiftchar(consonants(str), shft);

function isLetter(str) {
  return /^[a-z]+$/.test(str);


12/12 Through Holes / Vias in KiCad with the SRM-20 & Mods

I am still exporting everything as .svg — I played around with drill files but that didn't seem to be a productive direction to go in. I poked around about in the generated svg and found the <circle> responsible for the hole. The problem with kicad is that the drill holes themselves aren't exported on any layer.

I copy the code for this circle into the Edge-Cuts svg and change the styling to make it black.

Bash command to create a zip of all files in current directory:

zip ${PWD##*/}.zip -r ../${PWD##*/}

I have used sftp to add files to my website and then redownload them on whatever computer I need for the actually fabrication / machining. This has worked well but now that I want to make more complicated PCBs (with 2sides and vias) it is a pain to manually put each file onto the server.

12/14 Things to do

Use breakout board to expedite prototyping of analog / i2s microphone + figure out how to program board without FTDI


Set up environment for esp-idf quickly:

. $HOME/esp/esp-idf/


12/14 Analog MEMS microphone:

I can't seem to get the i2s microphone to work with the ESP32. Very frustrating. I've spent all day in front of the oscilloscope. I really thought this would be the easy part...

Anyway, I need to find a way to get audio so I just created a simple breakout board for the

12/15 Analog Sampling with ADC & ESP32
# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     0x9000,  0x6000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 1M,
storage,  data, fat,     , 2M,

Battery Size is 51mm x 34mm x 5.8mm


Milling a Two-Sided Board in KiCad
The Flip
  1. Make sure to keep the main copper board in place. It is crucial that it stays in the same position so that you can realign your PCB.

  2. Flip your PCB over the vertical axis.

  3. Reposition it snuggly in the bottom left corner.

  4. You will need to adjust your origin to account for the material removed by the 1/32in bit.


12/16 Encoding Audio stream as WAV File


Downloading & playing a WAV file over HTTP (swift)
HEX editor

brew dhex

mDNS on ESP32
void start_mdns_service()
    //initialize mDNS service
    esp_err_t err = mdns_init();
    if (err) {
        printf("MDNS Init failed: %d\n", err);

    //set hostname
    //set default instance
    mdns_instance_name_set("Jhon's ESP32 Thing");
Turn of wifi ESP32 idf (

Scratch Pad



Silicon Rubber





2 Sided Board