CPX MIdi Controller Instructables!
Required items:
- Pizza Box
- White Paint
- Connection cable for CPX
- CPX Board
- Circuit Python
- Mu-Editor
- Laptop
- Midi-city loaded up in a new tab
- Adafruit page loaded up in a new tab
Step1:
https://learn.adafruit.com/cpx-midi-controller
Access this link and view the tutorial of accessing the files
Step2:
Download Circuit Python, the newest version with the library bundles of the newest version as well.
here is the link to start to download CircuitPython
https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython
you click where it says download circuit python then it takes you to another page where you’ll need to click on the board you have, for instance I have a CPX board so I will press that board and it will take me to another page where I can now download circuitpython. After downloading this you’ll want to go download the libraries for the circuit python which will be on the next link.
Step3:
https://learn.adafruit.com/cpx-midi-controller/circuitpython
click on the green button that says library bundle release page, this will take you to a page where you will then be able to download circuit python bundle 5 through the links.
Step4:
Download and install Mu-Editor, this will be your way of writing code, and being able to use the circuit playground express as your midi controller.
https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor
the tutorial is fairly simple on the website to download and run the program.
Step5: Connect ur cpx to your laptop, press the center button twice to load it into cplayboot, then drag the Adafruit-circuitpython file to change it into circuit python mode then drag your libraries into this hard drive.
STep6:
Using Mu Editor, you’ll want to copy and paste the same code that’s on the Adafruit website, which is as follows;
”
### cpx-expressive-midi-controller v1.2
### CircuitPython (on CPX) MIDI controller using the seven touch pads
### and accelerometer for modulation (cc1) and pitch bend
### Left button adjusts octave (switch left) or semitone (switch right)
### Right button adjusts scale, major or chromatic
### Switch right also disables pitch bend and modulation
### Tested with CPX and CircuitPython and 4.0.0-beta.5
### Needs recent adafruit_midi module
### copy this file to CPX as code.py
### MIT License.
### Copyright (c) 2019 Kevin J. Walters
### Permission is hereby granted, free of charge, to any person obtaining a copy
### of this software and associated documentation files (the “Software”), to deal
### in the Software without restriction, including without limitation the rights
### to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
### copies of the Software, and to permit persons to whom the Software is
### furnished to do so, subject to the following conditions:
### The above copyright notice and this permission notice shall be included in all
### copies or substantial portions of the Software.
### THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
### IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
### FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
### AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
### LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
### OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
### SOFTWARE.
import time
import digitalio
import touchio
import busio
import board
import usb_midi
import neopixel
import adafruit_lis3dh
import adafruit_midi
from adafruit_midi.note_on import NoteOn
from adafruit_midi.control_change import ControlChange
from adafruit_midi.pitch_bend import PitchBend
# MIDI defines middle C as 60 and modulation wheel is cc 1 by convention
midi_note_C4 = 60
midi_cc_modwheel = 1 # was const(1)
# 0x19 is the i2c address of the onboard accelerometer
acc_i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
acc_int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT)
acc = adafruit_lis3dh.LIS3DH_I2C(acc_i2c, address=0x19, int1=acc_int1)
acc.range = adafruit_lis3dh.RANGE_2_G
acc.data_rate = adafruit_lis3dh.DATARATE_10_HZ
# brightness 1.0 saves memory by removing need for a second buffer
# 10 is number of NeoPixels on CPX
numpixels = 10 # was const(10)
pixels = neopixel.NeoPixel(board.NEOPIXEL, numpixels, brightness=1.0)
# Turn NeoPixel on to represent a note using RGB x 10
# to represent 30 notes – doesn’t do anything with pitch bend
def noteLED(pix, pnote, pvel):
note30 = (pnote – midi_note_C4) % (3 * numpixels)
pos = note30 % numpixels
r, g, b = pix[pos]
if pvel == 0:
brightness = 0
else:
# max brightness will be 32
brightness = round(pvel / 127 * 30 + 2)
# Pick R/G/B based on range within the 30 notes
if note30 < 10:
r = brightness
elif note30 < 20:
g = brightness
else:
b = brightness
pix[pos] = (r, g, b)
# white pulse used to indicate octave changes
flashbrightness = 20
def flashLED(pix, position):
pos = position % numpixels
t1 = time.monotonic()
oldcolour = pix[pos]
while time.monotonic() – t1 < 0.25:
for i in range(0, flashbrightness, 2):
pix[pos] = (i, i, i)
for i in range(flashbrightness, 0, -2):
pix[pos] = (i, i, i)
pix[pos] = oldcolour
midi_channel = 1
midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1],
out_channel=midi_channel-1)
# CPX counter-clockwise order of touch capable pads (i.e. not A0)
pads = [board.A4,
board.A5,
board.A6,
board.A7,
board.A1,
board.A2,
board.A3]
# The touch pads calibrate themselves as they are created, just once here
touchpads = [touchio.TouchIn(pad) for pad in pads]
del pads # done with that
pb_midpoint = 8192
pitch_bend_value = pb_midpoint # mid point – no bend
min_pb_change = 250
mod_wheel = 0
min_mod_change = 5
# button A is on left (usb at top)
button_left = digitalio.DigitalInOut(board.BUTTON_A)
button_left.switch_to_input(pull=digitalio.Pull.DOWN)
button_right = digitalio.DigitalInOut(board.BUTTON_B)
button_right.switch_to_input(pull=digitalio.Pull.DOWN)
switch_left = digitalio.DigitalInOut(board.SLIDE_SWITCH)
switch_left.switch_to_input(pull=digitalio.Pull.UP)
# some example scales in semitones
scale_st = {“major”: [0, 2, 4, 5, 7, 9, 11],
“chromatic”: [0, 1, 2, 3, 4, 5, 6]}
scales = [“major”, “chromatic”]
scale_idx = 0
base_note = midi_note_C4 # C4 middle C
def make_scale(scale_name):
return [semitone_offset + base_note
for semitone_offset in scale_st[scale_name]]
midi_notes = make_scale(scales[scale_idx])
keydown = [False] * 7
velocity = 127
min_octave = -3
max_octave = +3
octave = 0
min_semitone = -11
max_semitone = +11
semitone = 0
# 1/10 = 10 Hz – review data_rate setting if this is changed
acc_read_t = time.monotonic()
acc_read_period = 1/10
# For accelerometer do nothing between 0 and 1.3 (ms-2)
acc_nullzone = 1.3
acc_range = 4.0
# Convert an accelerometer reading
# from min_msm2 to min_msm2+range to an int from 0 to value_range
# or return 0 or value_range outside those values
# The conversion is applied “symmetrically” to negative numbers
def scale_acc(acc_msm2, min_msm2, range_msm2, value_range):
if acc_msm2 >= 0.0:
sign_a_m = 1
magn_acc_msm2 = acc_msm2
else:
sign_a_m = -1
magn_acc_msm2 = abs(acc_msm2)
adj_msm2 = magn_acc_msm2 – min_msm2
# deal with out of bounds values else scale value
# pylint: disable=no-else-return
if adj_msm2 <= 0:
return 0
elif adj_msm2 >= range_msm2:
return sign_a_m * value_range
else:
return sign_a_m * round(adj_msm2 / range_msm2 * value_range)
# Scan each pad and look for changes by comparing
# with keystate stored in keydown boolean list
# and send note on/off messages accordingly
# Send pitch bend and mod wheel cc based on tilt from accelerometer
# Change octave and semitone based on buttons
while True:
for idx, touchpad in enumerate(touchpads):
if touchpad.value != keydown[idx]:
keydown[idx] = touchpad.value
# 12 semitones in an octave
note = midi_notes[idx] + octave * 12 + semitone
if keydown[idx]:
midi.send(NoteOn(note, velocity))
noteLED(pixels, note, velocity)
else:
midi.send(NoteOn(note, 0)) # Using note on 0 for off
noteLED(pixels, note, 0)
# Perform rate limited checks on the accelerometer
# if switch is to left
now_t = time.monotonic()
if switch_left.value and now_t – acc_read_t > acc_read_period:
acc_read_t = time.monotonic()
ax, ay, az = acc.acceleration
# scale from 0 to 127 (maximum cc 7bit value)
new_mod_wheel = abs(scale_acc(ay, acc_nullzone, acc_range, 127))
if (abs(new_mod_wheel – mod_wheel) > min_mod_change
or (new_mod_wheel == 0 and mod_wheel != 0)):
midi.send(ControlChange(midi_cc_modwheel, new_mod_wheel))
mod_wheel = new_mod_wheel
# scale from 0 to +/- 8191 (almost maximum signed 14bit values)
new_pitch_bend_value = (pb_midpoint
– scale_acc(ax, acc_nullzone, acc_range,
pb_midpoint – 1))
if (abs(new_pitch_bend_value – pitch_bend_value) > min_pb_change
or (new_pitch_bend_value == pb_midpoint
and pitch_bend_value != pb_midpoint)):
midi.send(PitchBend(new_pitch_bend_value))
pitch_bend_value = new_pitch_bend_value
# left button increase octave / semitones shift based on switch
# does not currently clear playing notes (buglet)
if button_left.value:
if switch_left.value:
octave += 1
if octave > max_octave:
octave = min_octave
flashLED(pixels, octave)
else:
semitone += 1
if semitone > max_semitone:
semitone = min_semitone
# semitone range is more than number of pixels!
flashLED(pixels, semitone)
while button_left.value:
pass # wait for button up
# right button cycles through scales
if button_right.value:
scale_idx += 1
if scale_idx >= len(scales):
scale_idx = 0
flashLED(pixels, scale_idx)
midi_notes = make_scale(scales[scale_idx])
while button_right.value:
pass # wait for button up”
copy this into Mu-editor and save it as code.py onto the circuitpython hard drive and let it run.
Step7:
download google chrome and run https://midi.city/
this will allow you to play music on your cpx, unlike safari.
Now how to make the Dj Set using a pizza Box!
step 1:
Make sure you have colored paint, white, black, grey or whatever, make sure you stir the paint before you start to paint the empty pizza box.
Step 2:
start painting the pizza box because we don’t want to be giving out any free promotions.
Step3:
Give the Pizza box a second layer of Paint so we know for certain that there won’t be any free promotions.
STep4:
Let dry
Step 5:
Start drawing using pencil on the painted pizza box, I’d use a wooden pencil to start then trace over the led using a sharpie, get creative and make some new designs!
Step 6: cut out a square from one side of the pizza box, not too big but just enough so the cable of the CPX board can get through it
Step7:
Tape the CPXBoard and cable down to the painted pizza box and plug it into your computer and have fun making some new tunes!