1 x Arduino Uno or Arduino Mega 1 x Seeeduino Touch Shield, ver. 1.0 (2.8" TFT) 1 x 8-Ohm Speaker
// Adapted from the Adafruit Paint application included with the TFT/Touchscreen library package to demonstrate both TFT and Touch Screen // Code modified to draw a piano style keyboard and assign proper pitches to those keys so that they play the correct note when touched // It is recommended to use a PDA type stylus for added touch precision with this sketch, as the piano keys are pretty small // *** BE SURE TO SET THE "speaker" PIN VALUE CORRECTLY FOR YOUR ARDUINO BOARD *** // Ver. 1.0 - Clay Furman 20 DEC 2012
#include <stdint.h>
#include <TouchScreen.h>
#include <TFT.h>
const int speaker=19; //Pin to which the speaker is connected -- use 19 (this is the A5 pin, as a digital output) for Uno or 53 for Mega
//Define frequencies for each of the possible notes #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175
//Measured ADC values for (0,0) and (210-1,320-1) //TS_MINX corresponds to ADC value when X = 0 //TS_MINY corresponds to ADC value when Y = 0 //TS_MAXX corresponds to ADC value when X = 240 -1 //TS_MAXY corresponds to ADC value when Y = 320 -1
static unsigned int TS_MINX, TS_MAXX, TS_MINY, TS_MAXY;
//Touch Screen Co-ordinate mapping register static unsigned int MapX1, MapX2, MapY1, MapY2;
/* Usage: TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); Where, XP = X plus, YP = Y plus, XM = X minus and YM = Y minus */ //init TouchScreen port pins. This would be reinitialized in setup() based on the hardware detected. TouchScreen ts = TouchScreen(17, A2, A1, 14, 300);
int color = BLUE; //Default Paint brush color int duration=250; //Default value for the tone duration int wait=300; //Default time to wait between notes
void setup() { Tft.init(); //init TFT library initTouchScreenParameters(); // initializes Touch Screen parameters based on the detected TFT Touch Shield hardware
// Serial.begin(9600); //debug
//Draw the white keys on the keyboard for (int i=0; i<21; i++) { Tft.fillRectangle(0,i*16,240,15,WHITE); } //Draw the black keys on the keyboard Tft.fillRectangle(0,11,140,11,BLACK); Tft.fillRectangle(0,43,140,11,BLACK); Tft.fillRectangle(0,59,140,11,BLACK); Tft.fillRectangle(0,75,140,11,BLACK); Tft.fillRectangle(0,107,140,11,BLACK); Tft.fillRectangle(0,123,140,11,BLACK); Tft.fillRectangle(0,155,140,11,BLACK); Tft.fillRectangle(0,171,140,11,BLACK); Tft.fillRectangle(0,187,140,11,BLACK); Tft.fillRectangle(0,219,140,11,BLACK); Tft.fillRectangle(0,235,140,11,BLACK); Tft.fillRectangle(0,267,140,11,BLACK); Tft.fillRectangle(0,283,140,11,BLACK); Tft.fillRectangle(0,299,140,11,BLACK);
}
void loop() {
// Serial.println(Tft.IC_CODE,HEX); //debug
// a point object holds x y and z coordinates. Point p = ts.getPoint();
// we have some minimum pressure we consider 'valid' // pressure of 0 means no pressing!
if (p.z > ts.pressureThreshhold) {
//map the ADC value read to into pixel co-ordinates
p.x = map(p.x, TS_MINX, TS_MAXX, MapX1, MapX2); p.y = map(p.y, TS_MINY, TS_MAXY, MapY1, MapY2);
// Determine if the key played is in the potential sharp side or not if(p.x < 140) { Tft.fillCircle(p.x,p.y,2,color); //Key might be a sharp -- split Y axis into black and white keys if (p.y>=0 && p.y<=10) tone(speaker,NOTE_D6, duration); if (p.y>=11 && p.y<=21) tone(speaker,NOTE_CS6, duration); if (p.y>=22 && p.y<=31) tone(speaker,NOTE_C6, duration); if (p.y>=33 && p.y<=42) tone(speaker,NOTE_B5, duration); if (p.y>=43 && p.y<=53) tone(speaker,NOTE_AS5, duration); if (p.y>=54 && p.y<=58) tone(speaker,NOTE_A5, duration); if (p.y>=59 && p.y<=69) tone(speaker,NOTE_GS5, duration); if (p.y>=70 && p.y<=74) tone(speaker,NOTE_G5, duration); if (p.y>=75 && p.y<=85) tone(speaker,NOTE_FS5, duration); if (p.y>=86 && p.y<=95) tone(speaker,NOTE_F5, duration); if (p.y>=97 && p.y<=106) tone(speaker,NOTE_E5, duration); if (p.y>=107 && p.y<=117) tone(speaker,NOTE_DS5, duration); if (p.y>=118 && p.y<=122) tone(speaker,NOTE_D5, duration); if (p.y>=123 && p.y<=133) tone(speaker,NOTE_CS5, duration); if (p.y>=134 && p.y<=143) tone(speaker,NOTE_C5, duration); if (p.y>=145 && p.y<=154) tone(speaker,NOTE_B4, duration); if (p.y>=155 && p.y<=165) tone(speaker,NOTE_AS4, duration); if (p.y>=166 && p.y<=170) tone(speaker,NOTE_A4, duration); if (p.y>=171 && p.y<=181) tone(speaker,NOTE_GS4, duration); if (p.y>=182 && p.y<=186) tone(speaker,NOTE_G4, duration); if (p.y>=187 && p.y<=197) tone(speaker,NOTE_FS4, duration); if (p.y>=198 && p.y<=207) tone(speaker,NOTE_F4, duration); if (p.y>=209 && p.y<=218) tone(speaker,NOTE_E4, duration); if (p.y>=219 && p.y<=229) tone(speaker,NOTE_DS4, duration); if (p.y>=230 && p.y<=234) tone(speaker,NOTE_D4, duration); if (p.y>=235 && p.y<=245) tone(speaker,NOTE_CS4, duration); if (p.y>=246 && p.y<=255) tone(speaker,NOTE_C4, duration); if (p.y>=257 && p.y<=266) tone(speaker,NOTE_B3, duration); if (p.y>=267 && p.y<=277) tone(speaker,NOTE_AS3, duration); if (p.y>=278 && p.y<=282) tone(speaker,NOTE_A3, duration); if (p.y>=283 && p.y<=293) tone(speaker,NOTE_GS3, duration); if (p.y>=294 && p.y<=298) tone(speaker,NOTE_G3, duration); if (p.y>=299 && p.y<=309) tone(speaker,NOTE_FS3, duration); if (p.y>=310 && p.y<=319) tone(speaker,NOTE_F3, duration);
} else { //Key is too far along X axis to be sharp -- split Y axis into white keys only Tft.fillCircle(p.x,p.y,2,color); if (p.y>=0 && p.y<=15) tone(speaker,NOTE_D6, duration); if (p.y>=17 && p.y<=31) tone(speaker,NOTE_C6, duration); if (p.y>=33 && p.y<=47) tone(speaker,NOTE_B5, duration); if (p.y>=49 && p.y<=63) tone(speaker,NOTE_A5, duration); if (p.y>=65 && p.y<=79) tone(speaker,NOTE_G5, duration); if (p.y>=81 && p.y<=95) tone(speaker,NOTE_F5, duration); if (p.y>=97 && p.y<=111) tone(speaker,NOTE_E5, duration); if (p.y>=113 && p.y<=127) tone(speaker,NOTE_D5, duration); if (p.y>=129 && p.y<=143) tone(speaker,NOTE_C5, duration); if (p.y>=145 && p.y<=159) tone(speaker,NOTE_B4, duration); if (p.y>=161 && p.y<=175) tone(speaker,NOTE_A4, duration); if (p.y>=177 && p.y<=191) tone(speaker,NOTE_G4, duration); if (p.y>=193 && p.y<=207) tone(speaker,NOTE_F4, duration); if (p.y>=209 && p.y<=223) tone(speaker,NOTE_E4, duration); if (p.y>=225 && p.y<=239) tone(speaker,NOTE_D4, duration); if (p.y>=241 && p.y<=255) tone(speaker,NOTE_C4, duration); if (p.y>=257 && p.y<=271) tone(speaker,NOTE_B3, duration); if (p.y>=273 && p.y<=287) tone(speaker,NOTE_A3, duration); if (p.y>=289 && p.y<=303) tone(speaker,NOTE_G3, duration); if (p.y>=305 && p.y<=319) tone(speaker,NOTE_F3, duration);
} //Wait for the tone to play -- you can adjust the scalar to make the gap between tones more pronounced -- and then kill the tone output to prepare for the next cycle wait=duration*1; delay(wait); noTone(speaker);
}
}
void initTouchScreenParameters() { //This function initializes Touch Screen parameters based on the detected TFT Touch Schield hardware
if(Tft.IC_CODE == 0x5408) //SPFD5408A TFT driver based Touchscreen hardware detected { #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ts = TouchScreen(54, A1, A2, 57, 300); //init TouchScreen port pins #else ts = TouchScreen(14, A1, A2, 17, 300); //init TouchScreen port pins #endif //Touchscreen parameters for this hardware TS_MINX = 120; TS_MAXX = 910; TS_MINY = 120; TS_MAXY = 950;
MapX1 = 239; MapX2 = 0; MapY1 = 0; MapY2 = 319; } else //ST7781R TFT driver based Touchscreen hardware detected { #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ts = TouchScreen(57, A2, A1, 54, 300); //init TouchScreen port pins #else ts = TouchScreen(17, A2, A1, 14, 300); //init TouchScreen port pins #endif
//Touchscreen parameters for this hardware TS_MINX = 140; TS_MAXX = 900; TS_MINY = 120; TS_MAXY = 940;
MapX1 = 239; MapX2 = 0; MapY1 = 319; MapY2 = 0; } }
Enjoy! cfurman