Week 8: PCB Piano Pt. 2 (Capacitive Touch)

ā† Back to main page

PCB Piano with Capacitive Touch

This week, I built on my previous sensor-reading experience from Week 6 (Bluetooth Computer Mouse), where I read XY data from an IR laser sensor over SPI. However, due to proprietary limitations of that chip, I decided to work on a different type of sensor reading.

The project picks up from Week 5 (Electronics Design), where I designed a SAMD21E-powered piano synthesizer with capacitive sensing pads on the PCB to drive the DAC output, amplified by an LM4871 circuit into an 8-ohm speaker. Thanks to Anthony, the design was ordered from JLCPCB for the Week 6 group assignment after the failed milling attempt at EDS. A few days later, five FR5 boards arrived, ready for assembly.

PCB boards from JLCPCB
FR5 boards from JLCPCB, ready for assembly

After soldering everything together, the PCB looked like this:

Soldered PCB for capacitive touch piano
Completed soldering of the PCB piano with capacitive touch pads

My goal this week was to get capacitive sensing working using the QTouch library, as recommended in the SAMD21E datasheet. I started with self-capacitance, which was straightforward to implement using the AdaFruit FreeTouch library. Here's the code I used:

#include "Adafruit_FreeTouch.h"

#define N_PAD 5
#define PAD_THRESH 600

const int piano_pins[N_PAD] = {3, 4, 5, 6, 7};

Adafruit_FreeTouch qt_array[N_PAD] = {
  Adafruit_FreeTouch(3, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE),
  Adafruit_FreeTouch(4, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE),
  Adafruit_FreeTouch(5, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE),
  Adafruit_FreeTouch(6, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE),
  Adafruit_FreeTouch(7, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE)
};

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Starting capacitive touch readings...");

  for (int i = 0; i < N_PAD; i++) {
    if (!qt_array[i].begin()) {
      Serial.print("Failed to begin FreeTouch on pin ");
      Serial.println(piano_pins[i]);
    }
  }
}

void loop() {
  for (int i = 0; i < N_PAD; i++) {
    int value = qt_array[i].measure();

    Serial.print("Pad");
    Serial.print(i);
    Serial.print(": ");
    Serial.print(value);
    Serial.print(" ");
  }
  Serial.println();
  delay(100);
}

Running this code resulted in the following behavior (with pad readings outputted every 0.1s on Arduino Serial Output):

Testing capacitive touch pads with self-capacitance using AdaFruit FreeTouch

The ultimate goal is to expand this setup from 5 keys to 24 keys by utilizing the SAMD21Eā€™s mutual capacitance capability, which supports more pins through multiplexing. Unfortunately, FreeTouch does not natively support mutual capacitance, and QTouch library installation presented issues on my M-series Mac. I plan to revisit this approach, diving deeper into the SAMD21E datasheet and exploring solutions for more extensive capacitive sensing.


ā† Back to main page