Hardware components | ||||||
![]() |
| × | 1 | |||
Hand tools and fabrication machines | ||||||
![]() |
|
Hello community. Here is a 16-note copper touch keyboard (not enough for flats).
I'm using an Arduino Mega, The notes are linked directly to the Analog PIN and the code "ADCTouchSensor" library, the one that turns your Arduino into MakeyMakey;)
The code adapts to Arduino uno and mega.
For the design, I draw the keyboard and the structure on "Inkscape", then engraved the keyboard with the CNC and the wood in laser cutting.
If you want to help me further develop this project, I threw a bottle in the sea here;)
Good day
Berru
1 / 3
// CAPACITIVE TOUCH BASIC AVEC TESTE POTARD EN ANALOG MARS 2020
// BASE DIFFERENTE EN BAULT | CAPACITIVE A 115200 ET POTARD A 9600
//pas encore trouvé la bonne structure & fonctions
#include <ADCTouchSensor.h>
#ifdef ADCTOUCH_INTERNAL_GROUNDING
# define GROUNDED_PIN -1
#endif
#ifdef ARDUINO_ARCH_AVR
# define SLOW_SAMPLING
# undef FAST_SAMPLING
# undef MEDIUM_SAMPLING
#define LED_OFF 0
#if defined(PIN_A7)
int pins[] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15};
#else
int pins[] = {A0,A1,A2,A3,A4,A5};
#endif
#else // STM32F1
#define USB_MIDI
#include <USBMIDI.h> // https://github.com/arpruss/USBHID_stm32f1
#define LED_BUILTIN PB12 //
#define LED_OFF 1
int pins[] = {PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7};
#ifndef ADCTOUCH_INTERNAL_GROUNDING
# define ADCTOUCH_INTERNAL_GROUNDING PA8
#endif
USBMIDI MidiUSB;
#endif
////NOTE BLANCHE|||||PAS DE BEMOL||||AJOUTER 5 BROCHE ANALOG PAR GAMME
const uint8_t notes[] = {52,54,56,57,59,61,63,64,66,68,69,71,73,75}; //GAMME COMPLETE {64, 65,66, 67,68, 69,70, 71, 72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87};
const int numPins = sizeof(pins)/sizeof(*pins);
const uint8_t NOTE_ON = 0b10010000;
const uint8_t NOTE_OFF = 0b10000000;
int ref[numPins];
uint8_t prev[numPins];
ADCTouchSensor* sensors[numPins];
int val = 0;
void setup()
{
#if defined(ARDUINO_ARCH_AVR)
// default: divide clock by 128
#ifdef FAST_SAMPLING
ADCSRA = (ADCSRA & ~0b111) | 0b100; // 16
#else
#ifdef MEDIUM_SAMPLING
ADCSRA = (ADCSRA & ~0b111) | 0b110; // 64
#endif
#endif
#endif
#ifndef USB_MIDI
Serial.begin(115200);
#else
MidiUSB.begin();
#endif
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, 1^LED_OFF);
for (int i=0; i<numPins; i++) {
sensors[i] = new ADCTouchSensor(pins[i]);
sensors[i]->begin();
prev[i] = 0;
}
digitalWrite(LED_BUILTIN, 0^LED_OFF);
// uint32_t t = micros();
// ADCTouch.read(A0, 10000);
// t = micros() -t;
// Serial.println(t);
}
void midiNote(uint8_t status, uint8_t note, uint8_t velocity) {
#ifdef USB_MIDI
if (status == NOTE_ON)
MidiUSB.sendNoteOn(0, note, velocity);
else if (status == NOTE_OFF)
MidiUSB.sendNoteOff(0, note, velocity);
#else
Serial.write(status);
Serial.write(note);
Serial.write(velocity);
#endif
}
void loop()
{
uint8_t pressed = 0;
for (int i=0; i<numPins; i++) {
if (sensors[i]->read() > 25) {
pressed = 1;
if(!prev[i]) {
midiNote(NOTE_ON, notes[i], 127);
prev[i] = 1;
}
}
else {
if(prev[i]) {
midiNote(NOTE_OFF, notes[i], 127);
prev[i] = 0;
}
}
}
digitalWrite(LED_BUILTIN, pressed^LED_OFF);
}
/*void loop()
{
val = analogRead(0)/8; // Divide by 8 to get range of 0-127 for midi
if (val != lastVal) // If the value does not = the last value the following command is made. This is because the pot has been turned. Otherwise the pot remains the same and no midi message is output.
{
MIDImessage(176,1,val);} // 176 = CC command (channel 1 control change), 1 = Which Control, val = value read from Potentionmeter 1 NOTE THIS SAYS VAL not VA1 (lowercase of course)
lastVal = val;
val1 = analogRead(1)/8; // Divide by 8 to get range of 0-127 for midi
if (val1 != lastVal1)
{
MIDImessage(176,2,val1);} // 176 = CC command, 2 = Which Control, val = value read from Potentionmeter 2
lastVal1 = val1;
val2 = analogRead(2)/8; // Divide by 8 to get range of 0-127 for midi
if (val2 != lastVal2) // If the value does not = the last value the following command is made. This is because the pot has been turned. Otherwise the pot remains the same and no midi message is output.
{
MIDImessage(176,1,val2);} // 176 = CC command (channel 1 control change), 1 = Which Control, val = value read from Potentionmeter 1 NOTE THIS SAYS VAL not VA1 (lowercase of course)
lastVal2 = val2;
val3 = analogRead(3)/8; // Divide by 8 to get range of 0-127 for midi
if (val3 != lastVal3)
{
MIDImessage(176,2,val3);} // 176 = CC command, 2 = Which Control, val = value read from Potentionmeter 2
lastVal3 = val3;
val4 = analogRead(4)/8; // Divide by 8 to get range of 0-127 for midi
if (val4 != lastVal4) // If the value does not = the last value the following command is made. This is because the pot has been turned. Otherwise the pot remains the same and no midi message is output.
{
MIDImessage(176,1,val4);} // 176 = CC command (channel 1 control change), 1 = Which Control, val = value read from Potentionmeter 1 NOTE THIS SAYS VAL not VA1 (lowercase of course)
lastVal4 = val4;
delay(10); //here we add a short delay to help prevent slight fluctuations, knocks on the pots etc. Adding this helped to prevent my pots from jumpin up or down a value when slightly touched or knocked.
}
void MIDImessage(byte command, byte data1, byte data2) //pass values out through standard Midi Command
{
Serial.write(command);
Serial.write(data1);
Serial.write(data2);
}
Comments
Please log in or sign up to comment.