Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
150422f5dThis file is pinned to the selected release. Download the original to open it in your design tool.
#
# picotouch_aftertouch.py -- Tiny capsense MIDI slider controller using Pico
# 28 Feb 2023 - @todbot / Tod Kurt - github.com/todbot/picotouch
#
# A touch-sensitive MIDI controller where pressing harder sends MIDI CC
#
# NOTE: This does not work very well.
#
# picotouch board
# ┌──────────────────────────────────────────────────────────────────────────────────────────┐
# │ .─. .─. .─. .─. .─. .─. .─. │
# │ ( 1 ) ( 3 ) ( 6 ) ( 8 ) ( 10) ( 13) ( 15) │
# │ `─' `─' `─' `─' `─' `─' `─' │
# │ .─. .─. .─. .─. .─. .─. .─. .─. .─. .─. │
# │ ( 0 ) ( 2 ) ( 4 ) ( 5 ) ( 7 ) ( 9 ) ( 11) ( 12) ( 14) ( 16) │
# │ `─' `─' `─' `─' `─' `─' `─' `─' `─' `─' │
# └──────────────────────────────────────────────────────────────────────────────────────────┘
#
# To use:
#
# 1. Install needed libraries:
# circup install adafruit_midi adafruit_debouncer adafruit_ticks
#
# 2. Copy over this file as code.py:
# cp code.py /Volumes/CIRCUITPY/code.py
#
# on Pico / RP2040, need 1M pull-down on each input
import time
import board, pwmio
import touchio
import digitalio
import usb_midi
import adafruit_midi
from adafruit_midi.note_on import NoteOn
from adafruit_midi.pitch_bend import PitchBend
from adafruit_midi.control_change import ControlChange
from adafruit_debouncer import Debouncer, Button
debug = False
octave = 4
midi_velocity = 100
midi_channel = 0 # 0-15
midi_cc_num = 1 # standard modwheel
touch_threshold_adjust = 10
midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1])
touch_pins = (
board.GP0, board.GP1, board.GP2, board.GP3, board.GP4, board.GP5,
board.GP6, board.GP7, board.GP8, board.GP9, board.GP10, board.GP11,
board.GP12, board.GP13, board.GP14, board.GP15, board.GP16, board.GP17,
board.GP18, board.GP19, board.GP20, board.GP21,
board.GP22,
)
led = pwmio.PWMOut(board.LED, frequency=25000, duty_cycle=0)
# special keys that aren't notes
pitch_up_key = 22
pitch_dn_key = 21
mod_up_key = 19
mod_mid_key = 18
oct_up_key = 20
oct_dn_key = 17
time.sleep(1)
td_scale_factor = 18
def td_scale(v):
v = int( v*v ) >> td_scale_factor
return v
touchs = [] # for debug
touchpads = []
for pin in touch_pins:
touchin = touchio.TouchIn(pin)
touchin.threshold += touch_threshold_adjust
touchs.append(touchin)
touchpads.append( Debouncer(touchin) )
num_touchs = len(touchs)
notes_on = [0] * num_touchs # list of notes currently sounding
print("\n----------")
print("picotouch hello")
touchs_smooth = [0] * num_touchs
touchs_delta = [0] * num_touchs
touchs_start = [0] * num_touchs
sm_amount = 0.95
cc_sending_id = -1
key_down_time = time.monotonic()
while True:
for i in range(num_touchs):
touch = touchpads[i]
touch.update()
touchs_smooth[i] = touchs_smooth[i] * sm_amount + (1-sm_amount) * touchs[i].raw_value
touchs_delta[i] = touchs[i].raw_value - touchs[i].threshold; # + 200
#print("%+05x" % int(touchs_delta[i]), " ", end='')
if touch.rose:
led.duty_cycle = 65535
if debug: print('key press %2d' % i)
noteOn = NoteOn((12*octave) + i, midi_velocity)
notes_on[i] = noteOn
midi.send( noteOn, channel=midi_channel )
cc_sending_id = i
key_down_time = time.monotonic()
touchs_start[i] = touchs_smooth[i]
if touch.fell:
led.duty_cycle = 0
if debug: print("key release %2d" % i)
noteOn = notes_on[i]
notes_on[i] = 0
noteOn.velocity = 0 # noteOff == noteOn w/ zero velocity (as well as NoteOff)
midi.send( noteOn, channel=midi_channel )
cc_sending_id = -1
#print()
for i in range(num_touchs):
td = int(touchs_smooth[i]) - touchs[i].threshold
#td = int(touchs_smooth[i] - touchs_start[i])
if td > 0 and notes_on[i] and i == cc_sending_id and time.monotonic() - key_down_time > 0.4:
v = td_scale(td)
v = min(max( v, 0 ), 127 )
midi.send( ControlChange(midi_cc_num, v), channel=midi_channel)
led.duty_cycle = v * 512
print( "*" * (v//2), v,td)