Hardware components | ||||||
| × | 1 |
Teensy3.2 Audio User board was designed to facilitate the construction of simple audio devices based on the Freescale [now NXP] ARM Cortex M4 MK20DX256VLH7 on the Teensy 3.2 application board. The MK20DX256VLH7 has AnalogIO with one DAC pin and many more Digilat IOs than a typical Arduino as well as a more SDRAM and Flash memories. It also runs at 72Mhz meaning you can do so much more in the same time frame . on the board are a footprint for the Teensy 3.2 , a single channel PAM8302M Speaker amp, MicroSD breakout board, and connectors for keyboard, switches and pots.
Originally the board was laid out so a 12 position telephone type keyboard could plug directly into the back. and one small application was done using this keyboard. But the drawbacks to the keyboard are that it is mechanical and could have connection problems as well and not be able to inform the firmware if more than one button was being pressed, disallowing the playing of chords.
For this reason I also included a connector laid out so a direct connection though leads could be made to as MPR121 based keyboard , This Keyboard connects with the I2C port and informs the processor if one or more keypads are being touched [ 12 in all] . So either one octave of chromatic notes can be encoded or 1 and 1/2 octaves of a major/ minor key can be encoded .
ModificationsI modified the existing MPR121 test library as well as adding the code for the original keyboard, to allow for up to 12 simultaneous notes, there are 12 phases that read out data from a sign table. Each phase in incremented by one of the note frequencies in the scale that is chosen. Each key pressed allows for the addition of that sine lookup table into a composite sum which is then put into the on chip DAC.
The DAC output is routed through a volume POT to the Mono amplifier.
I have also used the existing Teensy 3.2 libraries to readout WAV files on the Micro-SD card on to the DAC output.
/*Copyright (c) 2010 bildr community
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.
*/
#include "mpr121.h"
#include "sine1024.c"
#include <i2c_t3.h>
int POT0=0;
int POT1=0;
int POT2=0;
float poti0;
IntervalTimer myTimer;
int phase[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0};
//C,C#,D,D#,E,F,F#,G,G#,A,A#,B,C,C#,D,D#
// scale up each integer to 1024/1000 times raw freq
//int well_tempered[16] ={ 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622}; //cromatic scale
// c,d,e,f,g,a,b,c,d,e,f,g,a,b,c,d
int well_tempered[16] ={ 262, 292, 330, 349, 392, 440, 494, 523, 587, 659, 699, 784, 880, 989, 1047, 1175}; //major scale
int irqpin = 11; // Digital 11
boolean touchStates[12]; //to keep track of the previous touch states
void setup(){
pinMode(irqpin, INPUT);
digitalWrite(irqpin, HIGH); //enable pullup resistor
//Serial.begin(115200);
//Serial.print("Serial Begin.\n");
//Wire.begin();
// Setup for Master mode, pins 18/19, external pullups, 400kHz, 200ms default timeout
Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 400000);
Wire.setDefaultTimeout(200000); // 200ms
analogReadResolution(12);
analogWriteResolution(12);
pinMode (0, OUTPUT);
pinMode (1, OUTPUT);
pinMode (2, OUTPUT);
pinMode (3, OUTPUT);
pinMode (4, OUTPUT);
pinMode (5, OUTPUT);
pinMode (8, OUTPUT);
myTimer.begin(beep, 125); // set up time 8000 times a sec--125 usec
mpr121_setup();
//attachInterrupt(irqpin, isrService, FALLING); // interrrupt 1 is data ready
}
void loop(){
readTouchInputs();
}
void readTouchInputs(){
if(!checkInterrupt()){
//read the touch state from the MPR121
Wire.requestFrom(0x5A,2);
byte LSB = Wire.read();
byte MSB = Wire.read();
uint16_t touched = ((MSB << 8) | LSB); //16bits that make up the touch states
for (int i=0; i < 12; i++){ // Check what electrodes were pressed
if(touched & (1<<i)){
if(touchStates[i] == 0){
//pin i was just touched
//Serial.print("pin ");
//Serial.print(i);
//Serial.println(" was just touched");
digitalWrite(1, 1);
}else if(touchStates[i] == 1){
//pin i is still being touched
}
touchStates[i] = 1;
}else{
if(touchStates[i] == 1){
//Serial.print("pin ");
//Serial.print(i);
//Serial.println(" is no longer being touched");
digitalWrite(1, 0);
//pin i is no longer being touched
}
touchStates[i] = 0;
}
}
}
}
void mpr121_setup(void){
set_register(0x5A, ELE_CFG, 0x00);
// Section A - Controls filtering when data is > baseline.
set_register(0x5A, MHD_R, 0x01);
set_register(0x5A, NHD_R, 0x01);
set_register(0x5A, NCL_R, 0x00);
set_register(0x5A, FDL_R, 0x00);
// Section B - Controls filtering when data is < baseline.
set_register(0x5A, MHD_F, 0x01);
set_register(0x5A, NHD_F, 0x01);
set_register(0x5A, NCL_F, 0xFF);
set_register(0x5A, FDL_F, 0x02);
// Section C - Sets touch and release thresholds for each electrode
set_register(0x5A, ELE0_T, TOU_THRESH);
set_register(0x5A, ELE0_R, REL_THRESH);
set_register(0x5A, ELE1_T, TOU_THRESH);
set_register(0x5A, ELE1_R, REL_THRESH);
set_register(0x5A, ELE2_T, TOU_THRESH);
set_register(0x5A, ELE2_R, REL_THRESH);
set_register(0x5A, ELE3_T, TOU_THRESH);
set_register(0x5A, ELE3_R, REL_THRESH);
set_register(0x5A, ELE4_T, TOU_THRESH);
set_register(0x5A, ELE4_R, REL_THRESH);
set_register(0x5A, ELE5_T, TOU_THRESH);
set_register(0x5A, ELE5_R, REL_THRESH);
set_register(0x5A, ELE6_T, TOU_THRESH);
set_register(0x5A, ELE6_R, REL_THRESH);
set_register(0x5A, ELE7_T, TOU_THRESH);
set_register(0x5A, ELE7_R, REL_THRESH);
set_register(0x5A, ELE8_T, TOU_THRESH);
set_register(0x5A, ELE8_R, REL_THRESH);
set_register(0x5A, ELE9_T, TOU_THRESH);
set_register(0x5A, ELE9_R, REL_THRESH);
set_register(0x5A, ELE10_T, TOU_THRESH);
set_register(0x5A, ELE10_R, REL_THRESH);
set_register(0x5A, ELE11_T, TOU_THRESH);
set_register(0x5A, ELE11_R, REL_THRESH);
// Section D
// Set the Filter Configuration
// Set ESI2
set_register(0x5A, FIL_CFG, 0x04);
// Section E
// Electrode Configuration
// Set ELE_CFG to 0x00 to return to standby mode
set_register(0x5A, ELE_CFG, 0x0C); // Enables all 12 Electrodes
// Section F
// Enable Auto Config and auto Reconfig
/*set_register(0x5A, ATO_CFG0, 0x0B);
set_register(0x5A, ATO_CFGU, 0xC9); // USL = (Vdd-0.7)/vdd*256 = 0xC9 @3.3V set_register(0x5A, ATO_CFGL, 0x82); // LSL = 0.65*USL = 0x82 @3.3V
set_register(0x5A, ATO_CFGT, 0xB5);*/ // Target = 0.9*USL = 0xB5 @3.3V
set_register(0x5A, ELE_CFG, 0x0C);
}
boolean checkInterrupt(void){
return digitalRead(irqpin);
}
void set_register(int address, unsigned char r, unsigned char v){
Wire.beginTransmission(address);
Wire.write(r);
Wire.write(v);
Wire.endTransmission();
}
// interrupt from timer
void beep(void) {
digitalWrite(5, 1);
int val = 0;
int valadd = 0;
for (int i=0; i < 12; i++){
if (touchStates[i] == 1) {
// valadd = TableS1024[((int)phase[i]>>3)&0x3ff];
valadd = TableS1024[(phase[i]>>3)&0x3ff];
digitalWrite(0, 1);
}
else {
valadd = 0;
digitalWrite(0, 0);
}
val = val + valadd ;
phase[i] = phase[i] + 2*well_tempered[i];
}
//Serial.println(val);
analogWrite(A14, (int)val/4);
digitalWrite(5, 0);
}
const int TableS1024[1024] = {
0x800,0x80c,0x819,0x825,0x832,0x83e,0x84b,0x857,
0x864,0x871,0x87d,0x88a,0x896,0x8a3,0x8af,0x8bc,
0x8c8,0x8d5,0x8e1,0x8ee,0x8fa,0x907,0x913,0x91f,
0x92c,0x938,0x945,0x951,0x95e,0x96a,0x976,0x983,
0x98f,0x99b,0x9a8,0x9b4,0x9c0,0x9cc,0x9d9,0x9e5,
0x9f1,0x9fd,0xa09,0xa15,0xa22,0xa2e,0xa3a,0xa46,
0xa52,0xa5e,0xa6a,0xa76,0xa82,0xa8e,0xa9a,0xaa5,
0xab1,0xabd,0xac9,0xad5,0xae0,0xaec,0xaf8,0xb03,
0xb0f,0xb1b,0xb26,0xb32,0xb3d,0xb49,0xb54,0xb60,
0xb6b,0xb76,0xb82,0xb8d,0xb98,0xba3,0xbae,0xbba,
0xbc5,0xbd0,0xbdb,0xbe6,0xbf1,0xbfc,0xc06,0xc11,
0xc1c,0xc27,0xc32,0xc3c,0xc47,0xc52,0xc5c,0xc67,
0xc71,0xc7b,0xc86,0xc90,0xc9a,0xca5,0xcaf,0xcb9,
0xcc3,0xccd,0xcd7,0xce1,0xceb,0xcf5,0xcff,0xd09,
0xd12,0xd1c,0xd26,0xd2f,0xd39,0xd42,0xd4c,0xd55,
0xd5f,0xd68,0xd71,0xd7a,0xd83,0xd8c,0xd95,0xd9e,
0xda7,0xdb0,0xdb9,0xdc2,0xdca,0xdd3,0xddc,0xde4,
0xded,0xdf5,0xdfd,0xe06,0xe0e,0xe16,0xe1e,0xe26,
0xe2e,0xe36,0xe3e,0xe46,0xe4e,0xe55,0xe5d,0xe65,
0xe6c,0xe74,0xe7b,0xe82,0xe8a,0xe91,0xe98,0xe9f,
0xea6,0xead,0xeb4,0xebb,0xec1,0xec8,0xecf,0xed5,
0xedc,0xee2,0xee8,0xeef,0xef5,0xefb,0xf01,0xf07,
0xf0d,0xf13,0xf19,0xf1f,0xf24,0xf2a,0xf30,0xf35,
0xf3a,0xf40,0xf45,0xf4a,0xf4f,0xf54,0xf59,0xf5e,
0xf63,0xf68,0xf6d,0xf71,0xf76,0xf7a,0xf7f,0xf83,
0xf87,0xf8c,0xf90,0xf94,0xf98,0xf9c,0xf9f,0xfa3,
0xfa7,0xfaa,0xfae,0xfb1,0xfb5,0xfb8,0xfbb,0xfbf,
0xfc2,0xfc5,0xfc8,0xfca,0xfcd,0xfd0,0xfd3,0xfd5,
0xfd8,0xfda,0xfdc,0xfdf,0xfe1,0xfe3,0xfe5,0xfe7,
0xfe9,0xfeb,0xfec,0xfee,0xff0,0xff1,0xff3,0xff4,
0xff5,0xff6,0xff7,0xff8,0xff9,0xffa,0xffb,0xffc,
0xffd,0xffd,0xffe,0xffe,0xffe,0xfff,0xfff,0xfff,
0xfff,0xfff,0xfff,0xfff,0xffe,0xffe,0xffe,0xffd,
0xffd,0xffc,0xffb,0xffa,0xff9,0xff8,0xff7,0xff6,
0xff5,0xff4,0xff3,0xff1,0xff0,0xfee,0xfec,0xfeb,
0xfe9,0xfe7,0xfe5,0xfe3,0xfe1,0xfdf,0xfdc,0xfda,
0xfd8,0xfd5,0xfd3,0xfd0,0xfcd,0xfca,0xfc8,0xfc5,
0xfc2,0xfbf,0xfbb,0xfb8,0xfb5,0xfb1,0xfae,0xfaa,
0xfa7,0xfa3,0xf9f,0xf9c,0xf98,0xf94,0xf90,0xf8c,
0xf87,0xf83,0xf7f,0xf7a,0xf76,0xf71,0xf6d,0xf68,
0xf63,0xf5e,0xf59,0xf54,0xf4f,0xf4a,0xf45,0xf40,
0xf3a,0xf35,0xf30,0xf2a,0xf24,0xf1f,0xf19,0xf13,
0xf0d,0xf07,0xf01,0xefb,0xef5,0xeef,0xee8,0xee2,
0xedc,0xed5,0xecf,0xec8,0xec1,0xebb,0xeb4,0xead,
0xea6,0xe9f,0xe98,0xe91,0xe8a,0xe82,0xe7b,0xe74,
0xe6c,0xe65,0xe5d,0xe55,0xe4e,0xe46,0xe3e,0xe36,
0xe2e,0xe26,0xe1e,0xe16,0xe0e,0xe06,0xdfd,0xdf5,
0xded,0xde4,0xddc,0xdd3,0xdca,0xdc2,0xdb9,0xdb0,
0xda7,0xd9e,0xd95,0xd8c,0xd83,0xd7a,0xd71,0xd68,
0xd5f,0xd55,0xd4c,0xd42,0xd39,0xd2f,0xd26,0xd1c,
0xd12,0xd09,0xcff,0xcf5,0xceb,0xce1,0xcd7,0xccd,
0xcc3,0xcb9,0xcaf,0xca5,0xc9a,0xc90,0xc86,0xc7b,
0xc71,0xc67,0xc5c,0xc52,0xc47,0xc3c,0xc32,0xc27,
0xc1c,0xc11,0xc06,0xbfc,0xbf1,0xbe6,0xbdb,0xbd0,
0xbc5,0xbba,0xbae,0xba3,0xb98,0xb8d,0xb82,0xb76,
0xb6b,0xb60,0xb54,0xb49,0xb3d,0xb32,0xb26,0xb1b,
0xb0f,0xb03,0xaf8,0xaec,0xae0,0xad5,0xac9,0xabd,
0xab1,0xaa5,0xa9a,0xa8e,0xa82,0xa76,0xa6a,0xa5e,
0xa52,0xa46,0xa3a,0xa2e,0xa22,0xa15,0xa09,0x9fd,
0x9f1,0x9e5,0x9d9,0x9cc,0x9c0,0x9b4,0x9a8,0x99b,
0x98f,0x983,0x976,0x96a,0x95e,0x951,0x945,0x938,
0x92c,0x91f,0x913,0x907,0x8fa,0x8ee,0x8e1,0x8d5,
0x8c8,0x8bc,0x8af,0x8a3,0x896,0x88a,0x87d,0x871,
0x864,0x857,0x84b,0x83e,0x832,0x825,0x819,0x80c,
0x800,0x7f3,0x7e6,0x7da,0x7cd,0x7c1,0x7b4,0x7a8,
0x79b,0x78e,0x782,0x775,0x769,0x75c,0x750,0x743,
0x737,0x72a,0x71e,0x711,0x705,0x6f8,0x6ec,0x6e0,
0x6d3,0x6c7,0x6ba,0x6ae,0x6a1,0x695,0x689,0x67c,
0x670,0x664,0x657,0x64b,0x63f,0x633,0x626,0x61a,
0x60e,0x602,0x5f6,0x5ea,0x5dd,0x5d1,0x5c5,0x5b9,
0x5ad,0x5a1,0x595,0x589,0x57d,0x571,0x565,0x55a,
0x54e,0x542,0x536,0x52a,0x51f,0x513,0x507,0x4fc,
0x4f0,0x4e4,0x4d9,0x4cd,0x4c2,0x4b6,0x4ab,0x49f,
0x494,0x489,0x47d,0x472,0x467,0x45c,0x451,0x445,
0x43a,0x42f,0x424,0x419,0x40e,0x403,0x3f9,0x3ee,
0x3e3,0x3d8,0x3cd,0x3c3,0x3b8,0x3ad,0x3a3,0x398,
0x38e,0x384,0x379,0x36f,0x365,0x35a,0x350,0x346,
0x33c,0x332,0x328,0x31e,0x314,0x30a,0x300,0x2f6,
0x2ed,0x2e3,0x2d9,0x2d0,0x2c6,0x2bd,0x2b3,0x2aa,
0x2a0,0x297,0x28e,0x285,0x27c,0x273,0x26a,0x261,
0x258,0x24f,0x246,0x23d,0x235,0x22c,0x223,0x21b,
0x212,0x20a,0x202,0x1f9,0x1f1,0x1e9,0x1e1,0x1d9,
0x1d1,0x1c9,0x1c1,0x1b9,0x1b1,0x1aa,0x1a2,0x19a,
0x193,0x18b,0x184,0x17d,0x175,0x16e,0x167,0x160,
0x159,0x152,0x14b,0x144,0x13e,0x137,0x130,0x12a,
0x123,0x11d,0x117,0x110,0x10a,0x104,0xfe,0xf8,
0xf2,0xec,0xe6,0xe0,0xdb,0xd5,0xcf,0xca,
0xc5,0xbf,0xba,0xb5,0xb0,0xab,0xa6,0xa1,
0x9c,0x97,0x92,0x8e,0x89,0x85,0x80,0x7c,
0x78,0x73,0x6f,0x6b,0x67,0x63,0x60,0x5c,
0x58,0x55,0x51,0x4e,0x4a,0x47,0x44,0x40,
0x3d,0x3a,0x37,0x35,0x32,0x2f,0x2c,0x2a,
0x27,0x25,0x23,0x20,0x1e,0x1c,0x1a,0x18,
0x16,0x14,0x13,0x11,0xf,0xe,0xc,0xb,
0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,
0x2,0x2,0x1,0x1,0x1,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x2,
0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,
0xa,0xb,0xc,0xe,0xf,0x11,0x13,0x14,
0x16,0x18,0x1a,0x1c,0x1e,0x20,0x23,0x25,
0x27,0x2a,0x2c,0x2f,0x32,0x35,0x37,0x3a,
0x3d,0x40,0x44,0x47,0x4a,0x4e,0x51,0x55,
0x58,0x5c,0x60,0x63,0x67,0x6b,0x6f,0x73,
0x78,0x7c,0x80,0x85,0x89,0x8e,0x92,0x97,
0x9c,0xa1,0xa6,0xab,0xb0,0xb5,0xba,0xbf,
0xc5,0xca,0xcf,0xd5,0xdb,0xe0,0xe6,0xec,
0xf2,0xf8,0xfe,0x104,0x10a,0x110,0x117,0x11d,
0x123,0x12a,0x130,0x137,0x13e,0x144,0x14b,0x152,
0x159,0x160,0x167,0x16e,0x175,0x17d,0x184,0x18b,
0x193,0x19a,0x1a2,0x1aa,0x1b1,0x1b9,0x1c1,0x1c9,
0x1d1,0x1d9,0x1e1,0x1e9,0x1f1,0x1f9,0x202,0x20a,
0x212,0x21b,0x223,0x22c,0x235,0x23d,0x246,0x24f,
0x258,0x261,0x26a,0x273,0x27c,0x285,0x28e,0x297,
0x2a0,0x2aa,0x2b3,0x2bd,0x2c6,0x2d0,0x2d9,0x2e3,
0x2ed,0x2f6,0x300,0x30a,0x314,0x31e,0x328,0x332,
0x33c,0x346,0x350,0x35a,0x365,0x36f,0x379,0x384,
0x38e,0x398,0x3a3,0x3ad,0x3b8,0x3c3,0x3cd,0x3d8,
0x3e3,0x3ee,0x3f9,0x403,0x40e,0x419,0x424,0x42f,
0x43a,0x445,0x451,0x45c,0x467,0x472,0x47d,0x489,
0x494,0x49f,0x4ab,0x4b6,0x4c2,0x4cd,0x4d9,0x4e4,
0x4f0,0x4fc,0x507,0x513,0x51f,0x52a,0x536,0x542,
0x54e,0x55a,0x565,0x571,0x57d,0x589,0x595,0x5a1,
0x5ad,0x5b9,0x5c5,0x5d1,0x5dd,0x5ea,0x5f6,0x602,
0x60e,0x61a,0x626,0x633,0x63f,0x64b,0x657,0x664,
0x670,0x67c,0x689,0x695,0x6a1,0x6ae,0x6ba,0x6c7,
0x6d3,0x6e0,0x6ec,0x6f8,0x705,0x711,0x71e,0x72a,
0x737,0x743,0x750,0x75c,0x769,0x775,0x782,0x78e,
0x79b,0x7a8,0x7b4,0x7c1,0x7cd,0x7da,0x7e6,0x7f3
};
/*
MPR121.h
April 8, 2010
by: Jim Lindblom
*/
// MPR121 Register Defines
#define MHD_R 0x2B
#define NHD_R 0x2C
#define NCL_R 0x2D
#define FDL_R 0x2E
#define MHD_F 0x2F
#define NHD_F 0x30
#define NCL_F 0x31
#define FDL_F 0x32
#define ELE0_T 0x41
#define ELE0_R 0x42
#define ELE1_T 0x43
#define ELE1_R 0x44
#define ELE2_T 0x45
#define ELE2_R 0x46
#define ELE3_T 0x47
#define ELE3_R 0x48
#define ELE4_T 0x49
#define ELE4_R 0x4A
#define ELE5_T 0x4B
#define ELE5_R 0x4C
#define ELE6_T 0x4D
#define ELE6_R 0x4E
#define ELE7_T 0x4F
#define ELE7_R 0x50
#define ELE8_T 0x51
#define ELE8_R 0x52
#define ELE9_T 0x53
#define ELE9_R 0x54
#define ELE10_T 0x55
#define ELE10_R 0x56
#define ELE11_T 0x57
#define ELE11_R 0x58
#define FIL_CFG 0x5D
#define ELE_CFG 0x5E
#define GPIO_CTRL0 0x73
#define GPIO_CTRL1 0x74
#define GPIO_DATA 0x75
#define GPIO_DIR 0x76
#define GPIO_EN 0x77
#define GPIO_SET 0x78
#define GPIO_CLEAR 0x79
#define GPIO_TOGGLE 0x7A
#define ATO_CFG0 0x7B
#define ATO_CFGU 0x7D
#define ATO_CFGL 0x7E
#define ATO_CFGT 0x7F
// Global Constants
#define TOU_THRESH 0x06
#define REL_THRESH 0x0A
Comments