Piano Scale Trainer Using Elegoo Mega 2560
Piano Scale Practice Aid with Visual Metronome Effect
Components and supplies
1
2.8 Inches TFT Touch Screen For Arduino
1
ELEGOO MEGA R3 Board ATmega 2560 + USB Cable Compatible with Arduino IDE Projects RoHS Compliant
Apps and platforms
1
Amazon Q Developer
1
Arduino IDE 2.0
Project description
Code
PianoScaleVisualizer
cpp
Piano Scale Practice with Visual Metronome Aid
1#include <Elegoo_GFX.h> // Core graphics library 2#include <Elegoo_TFTLCD.h> // Hardware-specific library 3 4// Pin definitions for the LCD screen 5#define LCD_CS A3 // Chip Select goes to Analog 3 6#define LCD_CD A2 // Command/Data goes to Analog 2 7#define LCD_WR A1 // LCD Write goes to Analog 1 8#define LCD_RD A0 // LCD Read goes to Analog 0 9#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin 10 11// Color definitions 12#define BLACK 0x0000 13#define BLUE 0x001F 14#define RED 0xF800 15#define GREEN 0x07E0 16#define CYAN 0x07FF 17#define MAGENTA 0xF81F 18#define YELLOW 0xFFE0 19#define WHITE 0xFFFF 20 21// Initialize the LCD object 22Elegoo_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); 23 24void setup(void) { 25 Serial.begin(9600); 26 Serial.println(F("TFT LCD test")); 27 Serial.println(F("Elegoo 2.8\" TFT Screen")); 28 29 tft.reset(); 30 31 // Identify the LCD driver chip 32 uint16_t identifier = tft.readID(); 33 if(identifier == 0x9325) { 34 Serial.println(F("Found ILI9325 LCD driver")); 35 } else if(identifier == 0x9328) { 36 Serial.println(F("Found ILI9328 LCD driver")); 37 } else if(identifier == 0x4535) { 38 Serial.println(F("Found LGDP4535 LCD driver")); 39 } else if(identifier == 0x7575) { 40 Serial.println(F("Found HX8347G LCD driver")); 41 } else if(identifier == 0x9341) { 42 Serial.println(F("Found ILI9341 LCD driver")); 43 } else if(identifier == 0x8357) { 44 Serial.println(F("Found HX8357D LCD driver")); 45 } else if(identifier==0x0101) { 46 identifier=0x9341; 47 Serial.println(F("Found 0x9341 LCD driver")); 48 } else if(identifier==0x1111) { 49 identifier=0x9328; 50 Serial.println(F("Found 0x9328 LCD driver")); 51 } else { 52 Serial.print(F("Unknown LCD driver chip: ")); 53 Serial.println(identifier, HEX); 54 identifier=0x9341; 55 } 56 57 tft.begin(identifier); 58 tft.setRotation(1); // Set to landscape mode 59} 60 61void loop(void) { 62 // Display all major scales with their corresponding finger numbers 63 displayScaleWithMetronome("C Major", "C,D,E,F,G,A,B,C", "12312345", "54321321"); 64 displayScaleWithMetronome("G Major", "G,A,B,C,D,E,F#,G", "12312345", "54321321"); 65 displayScaleWithMetronome("D Major", "D,E,F#,G,A,B,C#,D", "12312345", "54321321"); 66 displayScaleWithMetronome("A Major", "A,B,C#,D,E,F#,G#,A", "12312345", "54321321"); 67 displayScaleWithMetronome("E Major", "E,F#,G#,A,B,C#,D#,E", "12312345", "54321321"); 68 displayScaleWithMetronome("B/Cb Major", "B,C#,D#,E,F#,G#,A#,B", "12312345", "43214321"); 69 displayScaleWithMetronome("F#/Gb Major", "F#,G#,A#,B,C#,D#,F,F#", "23412312", "43213214"); 70 displayScaleWithMetronome("Db/C# Major", "Db,Eb,F,Gb,Ab,Bb,C,Db", "23123412", "32143213"); 71 displayScaleWithMetronome("Ab Major", "Ab,Bb,C,Db,Eb,F,G,Ab", "34123123", "32143213"); 72 displayScaleWithMetronome("Eb Major", "Eb,F,G,Ab,Bb,C,D,Eb", "31234123", "32143213"); 73 displayScaleWithMetronome("Bb Major", "Bb,C,D,Eb,F,G,A,Bb", "41231234", "32143213"); 74 displayScaleWithMetronome("F Major", "F,G,A,Bb,C,D,E,F", "12341234", "54321321"); 75} 76 77// Function to display a scale with metronome effect 78void displayScaleWithMetronome(const char* scaleName, const char* scaleNotes, const char* rhFingers, const char* lhFingers) { 79 tft.fillScreen(BLACK); 80 81 int16_t startX = 5; 82 int16_t startY = 10; 83 int16_t lineHeight = 30; 84 int16_t itemWidth = 38; 85 86 tft.setTextSize(2); 87 88 // Display scale name 89 tft.setTextColor(YELLOW); 90 tft.setCursor(startX, startY); 91 tft.println(scaleName); 92 93 startY += lineHeight * 2; 94 95 // Display initial scale 96 displayNotes(scaleNotes, startX, startY, itemWidth, WHITE); 97 displayFingers(rhFingers, startX, startY + lineHeight, itemWidth, CYAN); 98 displayFingers(lhFingers, startX, startY + lineHeight * 2, itemWidth, GREEN); 99 100 // Add a 3-second delay before starting the metronome effect 101 delay(3000); 102 103 // Metronome effect 104 for (int repeat = 0; repeat < 3; repeat++) { 105 // Forward (ascending scale) 106 for (int i = 0; i < 8; i++) { 107 highlightNote(scaleNotes, i, startX + i * itemWidth, startY, RED); 108 highlightFinger(rhFingers, i, startX + i * itemWidth, startY + lineHeight, RED); 109 highlightFinger(lhFingers, i, startX + i * itemWidth, startY + lineHeight * 2, RED); 110 delay(1000); 111 highlightNote(scaleNotes, i, startX + i * itemWidth, startY, WHITE); 112 highlightFinger(rhFingers, i, startX + i * itemWidth, startY + lineHeight, CYAN); 113 highlightFinger(lhFingers, i, startX + i * itemWidth, startY + lineHeight * 2, GREEN); 114 } 115 // Backward (descending scale, skipping first and last notes) 116 for (int i = 6; i > 0; i--) { 117 highlightNote(scaleNotes, i, startX + i * itemWidth, startY, RED); 118 highlightFinger(rhFingers, i, startX + i * itemWidth, startY + lineHeight, RED); 119 highlightFinger(lhFingers, i, startX + i * itemWidth, startY + lineHeight * 2, RED); 120 delay(1000); 121 highlightNote(scaleNotes, i, startX + i * itemWidth, startY, WHITE); 122 highlightFinger(rhFingers, i, startX + i * itemWidth, startY + lineHeight, CYAN); 123 highlightFinger(lhFingers, i, startX + i * itemWidth, startY + lineHeight * 2, GREEN); 124 } 125 } 126 127 delay(2000); // Pause before moving to the next scale 128} 129 130// Function to display the notes of a scale 131void displayNotes(const char* notes, int x, int y, int itemWidth, uint16_t color) { 132 tft.setTextColor(color); 133 char note[3]; 134 note[2] = '\0'; 135 int index = 0; 136 for (int i = 0; i < 8; i++) { 137 tft.setCursor(x + i * itemWidth, y); 138 note[0] = notes[index++]; 139 if (notes[index] != ',' && notes[index] != '\0') { 140 note[1] = notes[index++]; 141 } else { 142 note[1] = ' '; 143 } 144 tft.print(note); 145 if (notes[index] == ',') index++; 146 } 147} 148 149// Function to display finger numbers 150void displayFingers(const char* fingers, int x, int y, int itemWidth, uint16_t color) { 151 tft.setTextColor(color); 152 for (int i = 0; i < 8; i++) { 153 tft.setCursor(x + i * itemWidth, y); 154 tft.print(fingers[i]); 155 } 156} 157 158// Function to highlight a specific note during the metronome effect 159void highlightNote(const char* notes, int index, int x, int y, uint16_t color) { 160 char note[3]; 161 note[2] = '\0'; 162 int noteIndex = 0; 163 for (int i = 0; i < index; i++) { 164 noteIndex++; 165 if (notes[noteIndex] != ',' && notes[noteIndex] != '\0') { 166 noteIndex++; 167 } 168 if (notes[noteIndex] == ',') noteIndex++; 169 } 170 note[0] = notes[noteIndex++]; 171 if (notes[noteIndex] != ',' && notes[noteIndex] != '\0') { 172 note[1] = notes[noteIndex]; 173 } else { 174 note[1] = ' '; 175 } 176 tft.setTextColor(color); 177 tft.setCursor(x, y); 178 tft.print(note); 179} 180 181// Function to highlight a specific finger number during the metronome effect 182void highlightFinger(const char* fingers, int index, int x, int y, uint16_t color) { 183 tft.setTextColor(color); 184 tft.setCursor(x, y); 185 tft.print(fingers[index]); 186}
Downloadable files
Piano Scale Visualizer Sketch
Sketch file containing the project code
MetroScale.ino
Documentation
Elegoo 2.8 Inch Touch Screen User Manual
User Manual, libraries and example sketches
https://download.elegoo.com/03%20Other%20Kits/07%202.8-inch%20Screen/Elegoo%202.8%20Inch%20Touch%20Screen%20User%20Manual%20V1.00.2024.04.30.zip
Comments
Only logged in users can leave comments