
Having gotten over a fear of hardware with the early easy success of the Decision Slug, and having proven out the simplicity of even the block interface for software with my Arc Reactor POTS Sensor, I wanted to explore more of the input sensors. Ever since playing at Meow Wolf in Santa Fe this summer, touch capacitance has been dancing in my brain. I made some progress on it, but have to tell you that there is something glitchy in getting it going all the way with Adafruit’s Circuit Playground Express (CPE) and this is not yet whole.
The CPE has 7 pads that can act as touch capacitive inputs, there are 7 main colors in a rainbow ( ROYGBIV) and there are 7 notes in a scale. Seems like it is time to make a rainbox piano. I should be able to set it up so that there are strips of copper tape that make the inputs conductive, I should be able to build something fun.
It seemed like a super simple coding project- touch input here, change the color, play a sound. Easy, right? Sure, unless you try to get all software-y on it. I thought. Hey- have one variable, set the value of the variable according to where the input came from. Then have an evaluation of the variable and do different things depending on the value of the variable. Perfectly logical software application approach. The code looked something like this:
let touchMe = 0
input.pinA1.onEvent(ButtonEvent.Click, function () {
touchMe = 1
})
input.pinA2.onEvent(ButtonEvent.Click, function () {
touchMe = 2
})
input.pinA3.onEvent(ButtonEvent.Click, function () {
touchMe = 3
})
input.pinA4.onEvent(ButtonEvent.Click, function () {
touchMe = 4
})
input.pinA5.onEvent(ButtonEvent.Click, function () {
touchMe = 5
})
input.pinA6.onEvent(ButtonEvent.Click, function () {
touchMe = 6
})
input.pinA7.onEvent(ButtonEvent.Click, function () {
touchMe = 7
})
forever(function () {
if (touchMe == 1) {
light.setAll(0xff0000)
music.playTone(262, music.beat(BeatFraction.Half))
touchMe = 0
music.stopAllSounds()
light.clear()
} else if (touchMe == 2) {
light.setAll(0xff8000)
music.playTone(294, music.beat(BeatFraction.Half))
touchMe = 0
music.stopAllSounds()
light.clear()
} else if (touchMe == 3) {
light.setAll(0xffff00)
music.playTone(330, music.beat(BeatFraction.Half))
touchMe = 0
music.stopAllSounds()
light.clear()
} else if (touchMe == 4) {
light.setAll(0x00ff00)
music.playTone(349, music.beat(BeatFraction.Half))
touchMe = 0
music.stopAllSounds()
light.clear()
} else if (touchMe == 5) {
light.setAll(0x00ffff)
music.playTone(392, music.beat(BeatFraction.Half))
touchMe = 0
music.stopAllSounds()
light.clear()
} else if (touchMe == 6) {
light.setAll(0x0000ff)
music.playTone(440, music.beat(BeatFraction.Half))
touchMe = 0
music.stopAllSounds()
light.clear()
} else if (touchMe == 7) {
light.setAll(0x7f00ff)
music.playTone(494, music.beat(BeatFraction.Half))
touchMe = 0
music.stopAllSounds()
light.clear()
} else {
touchMe = 0
light.setAll(0xffffff)
}
})
Lesson One: the hardware and hardware interactions were way faster than the software evaluation of that long if/else statement. So sometimes it would do the right thing, but sometimes it would miss and sometimes I would get the input from the last touch. I had to think about code differently for hardware/human interactions. It was direct and so the code needed to be more direct.
forever(function () {
light.setBrightness(107)
music.setVolume(175)
if (input.pinA1.isPressed()) {
music.playTone(262, music.beat(BeatFraction.Half))
light.setPixelColor(6, 0xff0000)
} else if (input.pinA2.isPressed()) {
music.playTone(294, music.beat(BeatFraction.Half))
light.setPixelColor(8, 0xff8000)
} else if (input.pinA3.isPressed()) {
music.playTone(330, music.beat(BeatFraction.Half))
light.setPixelColor(9, 0xffff00)
} else if (input.pinA4.isPressed()) {
music.playTone(349, music.beat(BeatFraction.Half))
light.setPixelColor(1, 0x00ff00)
} else if (input.pinA5.isPressed()) {
music.playTone(392, music.beat(BeatFraction.Half))
light.setPixelColor(2, 0x00ffff)
} else if (input.pinA6.isPressed()) {
music.playTone(440, music.beat(BeatFraction.Half))
light.setPixelColor(3, 0x0000ff)
} else if (input.pinA7.isPressed()) {
music.playTone(523, music.beat(BeatFraction.Half))
light.setPixelColor(4, 0x7f00ff)
} else {
light.setAll(0x000000)
music.stopAllSounds()
}
})
This code does the same thing as the first block, but is much more responsive and gives us a tone and color change correctly every time.
Since I knew the code and hardware were working reliably, I started to build out the actual human interface for the piano.
Lesson 2: Notice the table in that video. Yep.. a metal table. LOL. D’oh. when working with touch inputs, working with leads on a metal table through paper gives interesting mixed up spaghetti results.
I decided to move the base of the project onto a 6X6 square of polycarb and started marking out and running copper tape and wire where I want the touch spots to be for this handheld rainbow piano.
Debug Issue: Everything is lovely with the first touch sensor or two, but after that, the entire thing goes nuts. Sometimes when you touch pad #3 you get the code for 3 to play, but sometimes it plays 1 or 7 or… It is like a crazy ghost in the machine.
I banged my head on this for about 20 minutes, and then I hit time for SHAK open house, so it is a pause and then regroup on this in the future. Note: I got to the bottom of this mystery a few weeks later and wrote it up.