Components and supplies
0.1 Inch Right angle pins
LCD Keypad shield
Arduino UNO
0.1 Inch Jumper
Deek Robot data logging shield v1.0
Piezo sounder element
Apps and platforms
Arduino IDE
Project description
Code
GymGeneral software retooled for LCD shield with buttons
c_cpp
1 2//Sports interval timer using SD card to hold intervals data 3 4//CHECK IF LCD SHIELD USES DIGITAL PIN 10 AS THIS IS USED AS CS FOR DATA LOGGING SHIELD 5//CHECK TO SEE IF LCD IS ONE OF THE FAULTY ONES 6//REFERENCE - https://forum.arduino.cc/index.php?topic=96747.0 (Retrieved 27/March/2020) 7 8/* 9 The circuit: 10 * SD card attached to SPI bus as follows: 11 ** MOSI - pin 11 12 ** MISO - pin 12 13 ** CLK - pin 13 14 ** CS - pin 10 for deek robot data logging shield v1.0 15 * 16 * RTC connections (I2C) - Clock not used in this project: 17 * gnd to gnd 18 * + to +5V 19 * SDA to A4 20 * SCL to A5 21 * 22 * LCD shield: 23 * Backlight - pin 10 removed 24 * B4 to D4 25 * B5 to D5 26 * B6 to D6 27 * B7 to D7 28 * RS to D8 29 * E to D9 30 * 31 * LCD shield buttons: 32 * Analog 0 33 * 34 * Buzzer 35 * GND to GND 36 * + to D3 37 */ 38 39#include <SPI.h> 40#include <SD.h> 41 42const int chipSelect=10; 43 44//my_aliases 45const int start_screen=1; 46const int initialization_screen=2; 47const int file_menu_screen=3; 48const int file_wont_open_screen=4; 49 50//my_boolean variables 51volatile bool count_updated=true; 52volatile bool enter_pressed=false; 53volatile bool beep_file_contents=false; 54volatile bool do_update=true; 55 56File root; 57File myFile; 58 59//for the LCD shield 60#include <LiquidCrystal.h> 61 62// select the pins used on the LCD panel 63LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 64// http://www.robotshop.com/content/PDF/dfrobot-lcd-keypad-shield-schematic.pdf 65 66//required to debounce switch 67#define MAX_CHECKS 10 68volatile uint8_t Debounced_State=0;//accessed by isr and main loop code 69uint8_t State[MAX_CHECKS]={0}; 70uint8_t Index=0; 71 72//my_global_variables 73int screen_number=start_screen; 74bool initialization_fail=false; 75bool file_exists=false; 76static String my_filename=""; 77 78const int sounder_pin=3;// the pin we attach our sounder to 79const int duty_cycle=128;//50% duty cycle for analogWrite() 80 81void setup() { 82 83//initial lcd setup 84 lcd.begin(16,2); // initialize the lcd for 16 chars 2 lines 85 lcd.clear(); 86 87 update_display(); 88 delay(5000); 89 screen_number=initialization_screen; 90 91//try to initialize sd card 92 if (!SD.begin(chipSelect)) { 93 initialization_fail=true; 94 update_display(); 95 return; 96 } 97 initialization_fail=false; 98 update_display(); 99 delay(5000); 100 101 102 // initialize digital pin as an output. 103 pinMode(sounder_pin, OUTPUT); 104 105 106 // initialize timer1 107 noInterrupts(); // disable all interrupts 108 TCCR1A = 0; 109 TCCR1B = 0; 110 TCNT1 = 0; 111 112 OCR1A = 625; // compare match register 16MHX/256/100HZ 113 TCCR1B |= (1 << WGM12); // CTC mode 114 TCCR1B |= (1 << CS12); // 256 prescaler 115 TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt 116 interrupts(); 117 118 119}/*end of setup*/ 120 121void loop() { 122 123 root = SD.open("/"); 124 125 int repeats=0; 126 int frequency=0; 127 int on_time=0; 128 int off_time=0; 129 int index=0; 130 131while(1){ 132 133static bool button_up=false; 134static bool chord_ready=false; 135static int Stored_State=0; 136static int Action_Me=0; 137 138 noInterrupts(); // disable all interrupts 139if (Debounced_State>Stored_State){Stored_State=Debounced_State;chord_ready=true;}//store chord and flag as ready 140if (Debounced_State<Stored_State){if(chord_ready){button_up=true;Action_Me=Stored_State;}Stored_State=Debounced_State;} 141 interrupts(); // enable all interrupts 142 143if(button_up && chord_ready) 144{ 145chord_ready=false; 146button_up=false; 147 148if (Action_Me&1<<1){ switch(screen_number){ 149 case file_menu_screen:beep_file_contents=true;break; 150 case file_wont_open_screen:screen_number=file_menu_screen;do_update=true;break;}}//select button 151 152if (Action_Me&1<<0){if (screen_number==file_menu_screen){count_updated=true;}}//down button 153 154} 155 156 if (do_update){do_update=false;update_display();} 157 158 if (count_updated){ 159 160 161 //cycle through the existing files on the SD card 162 count_updated=false; 163 164 File entry = root.openNextFile(); 165 if (! entry) { 166 // no more files -> so go back to beginning 167 entry.close(); 168 root.rewindDirectory(); 169 my_filename="No more"; 170 update_display(); 171 }else 172 { 173 my_filename=entry.name(); 174 screen_number=file_menu_screen; 175 update_display(); 176 entry.close();} 177 } 178 179//beep out the intervals from the chosed file 180if (beep_file_contents){ 181 182 beep_file_contents=false; 183 184 if (SD.exists(my_filename)) {file_exists=true;}else{file_exists=false;} 185 186 update_display(); 187 188 //read data from file 189 // re-open the file for reading: 190 myFile = SD.open(my_filename, FILE_READ); 191 if (myFile) { 192 193 // read from the file until there's nothing else in it: 194 while (myFile.available()) 195 { 196 repeats=myFile.parseInt(); 197 frequency=myFile.parseInt(); 198 on_time=myFile.parseInt(); 199 off_time=myFile.parseInt(); 200 201 for (index=0;index<repeats;index++) 202 { 203 if (frequency==1){TCCR2B = (TCCR2B & 0b11111000) | 0x04;}else{TCCR2B = (TCCR2B & 0b11111000) | 0x02;} 204 205 analogWrite(sounder_pin, duty_cycle); 206 delay(on_time*100); 207 analogWrite(sounder_pin,0); 208 delay(off_time*100); 209 } 210 } 211 212 // close the file: 213 myFile.close(); 214 } else { 215 // if the file didn't open, print an error: 216 screen_number=file_wont_open_screen; 217 update_display(); 218 } 219 220}//end beep out file 221 222} 223 224}/*end of loop*/ 225 226//my_functions 227ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine 228{ 229 230//read buttons 231 uint8_t temp=0x00; 232 233 if (analogRead(0) > 200 && analogRead(0) < 400){temp|=1<<0;} //btnDOWN 234 if (analogRead(0) > 600 && analogRead(0) < 800){temp|=1<<1;} //btnSELECT 235 236//debounce 237 uint8_t i,j; 238 State[Index]= temp; 239 ++Index; 240 j=0xFF; 241 for (i=0;i<MAX_CHECKS;i++){j=j&State[i];} 242 Debounced_State=j; 243 if(Index>=MAX_CHECKS){Index=0;} 244} 245 246//my_screen_functions 247void update_display(void) 248{ 249 switch (screen_number) 250 { 251 case start_screen:lcd.clear(); 252 lcd.setCursor(3,0); 253 lcd.print("GymGeneral"); 254 lcd.setCursor(3,1); 255 lcd.print("Gym timer"); 256 break; 257 case initialization_screen:lcd.clear(); 258 lcd.setCursor(0,0); 259 lcd.print("Init SD..."); 260 if (!initialization_fail){lcd.print("done.");}else{lcd.print("fail!");} 261 break; 262 case file_menu_screen:lcd.clear(); 263 lcd.setCursor(2,0); 264 lcd.print("Select file"); 265 lcd.setCursor(2,1); 266 lcd.print(" ");//clear any previous filename (8.3 character format, so 12 spaces) 267 lcd.setCursor(2,1); 268 lcd.print(my_filename); 269 break; 270 case file_wont_open_screen:lcd.clear(); 271 lcd.print("Can't open file"); 272 break; 273 } 274 } 275
GymGeneral software retooled for LCD shield with buttons
c_cpp
1 2//Sports interval timer using SD card to hold intervals data 3 4//CHECK IF LCD SHIELD USES DIGITAL PIN 10 AS THIS IS USED AS CS FOR DATA LOGGING SHIELD 5//CHECK TO SEE IF LCD IS ONE OF THE FAULTY ONES 6//REFERENCE - https://forum.arduino.cc/index.php?topic=96747.0 (Retrieved 27/March/2020) 7 8/* 9 The circuit: 10 * SD card attached to SPI bus as follows: 11 ** MOSI - pin 11 12 ** MISO - pin 12 13 ** CLK - pin 13 14 ** CS - pin 10 for deek robot data logging shield v1.0 15 * 16 * RTC connections (I2C) - Clock not used in this project: 17 * gnd to gnd 18 * + to +5V 19 * SDA to A4 20 * SCL to A5 21 * 22 * LCD shield: 23 * Backlight - pin 10 removed 24 * B4 to D4 25 * B5 to D5 26 * B6 to D6 27 * B7 to D7 28 * RS to D8 29 * E to D9 30 * 31 * LCD shield buttons: 32 * Analog 0 33 * 34 * Buzzer 35 * GND to GND 36 * + to D3 37 */ 38 39#include <SPI.h> 40#include <SD.h> 41 42const int chipSelect=10; 43 44//my_aliases 45const int start_screen=1; 46const int initialization_screen=2; 47const int file_menu_screen=3; 48const int file_wont_open_screen=4; 49 50//my_boolean variables 51volatile bool count_updated=true; 52volatile bool enter_pressed=false; 53volatile bool beep_file_contents=false; 54volatile bool do_update=true; 55 56File root; 57File myFile; 58 59//for the LCD shield 60#include <LiquidCrystal.h> 61 62// select the pins used on the LCD panel 63LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 64// http://www.robotshop.com/content/PDF/dfrobot-lcd-keypad-shield-schematic.pdf 65 66//required to debounce switch 67#define MAX_CHECKS 10 68volatile uint8_t Debounced_State=0;//accessed by isr and main loop code 69uint8_t State[MAX_CHECKS]={0}; 70uint8_t Index=0; 71 72//my_global_variables 73int screen_number=start_screen; 74bool initialization_fail=false; 75bool file_exists=false; 76static String my_filename=""; 77 78const int sounder_pin=3;// the pin we attach our sounder to 79const int duty_cycle=128;//50% duty cycle for analogWrite() 80 81void setup() { 82 83//initial lcd setup 84 lcd.begin(16,2); // initialize the lcd for 16 chars 2 lines 85 lcd.clear(); 86 87 update_display(); 88 delay(5000); 89 screen_number=initialization_screen; 90 91//try to initialize sd card 92 if (!SD.begin(chipSelect)) { 93 initialization_fail=true; 94 update_display(); 95 return; 96 } 97 initialization_fail=false; 98 update_display(); 99 delay(5000); 100 101 102 // initialize digital pin as an output. 103 pinMode(sounder_pin, OUTPUT); 104 105 106 // initialize timer1 107 noInterrupts(); // disable all interrupts 108 TCCR1A = 0; 109 TCCR1B = 0; 110 TCNT1 = 0; 111 112 OCR1A = 625; // compare match register 16MHX/256/100HZ 113 TCCR1B |= (1 << WGM12); // CTC mode 114 TCCR1B |= (1 << CS12); // 256 prescaler 115 TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt 116 interrupts(); 117 118 119}/*end of setup*/ 120 121void loop() { 122 123 root = SD.open("/"); 124 125 int repeats=0; 126 int frequency=0; 127 int on_time=0; 128 int off_time=0; 129 int index=0; 130 131while(1){ 132 133static bool button_up=false; 134static bool chord_ready=false; 135static int Stored_State=0; 136static int Action_Me=0; 137 138 noInterrupts(); // disable all interrupts 139if (Debounced_State>Stored_State){Stored_State=Debounced_State;chord_ready=true;}//store chord and flag as ready 140if (Debounced_State<Stored_State){if(chord_ready){button_up=true;Action_Me=Stored_State;}Stored_State=Debounced_State;} 141 interrupts(); // enable all interrupts 142 143if(button_up && chord_ready) 144{ 145chord_ready=false; 146button_up=false; 147 148if (Action_Me&1<<1){ switch(screen_number){ 149 case file_menu_screen:beep_file_contents=true;break; 150 case file_wont_open_screen:screen_number=file_menu_screen;do_update=true;break;}}//select button 151 152if (Action_Me&1<<0){if (screen_number==file_menu_screen){count_updated=true;}}//down button 153 154} 155 156 if (do_update){do_update=false;update_display();} 157 158 if (count_updated){ 159 160 161 //cycle through the existing files on the SD card 162 count_updated=false; 163 164 File entry = root.openNextFile(); 165 if (! entry) { 166 // no more files -> so go back to beginning 167 entry.close(); 168 root.rewindDirectory(); 169 my_filename="No more"; 170 update_display(); 171 }else 172 { 173 my_filename=entry.name(); 174 screen_number=file_menu_screen; 175 update_display(); 176 entry.close();} 177 } 178 179//beep out the intervals from the chosed file 180if (beep_file_contents){ 181 182 beep_file_contents=false; 183 184 if (SD.exists(my_filename)) {file_exists=true;}else{file_exists=false;} 185 186 update_display(); 187 188 //read data from file 189 // re-open the file for reading: 190 myFile = SD.open(my_filename, FILE_READ); 191 if (myFile) { 192 193 // read from the file until there's nothing else in it: 194 while (myFile.available()) 195 { 196 repeats=myFile.parseInt(); 197 frequency=myFile.parseInt(); 198 on_time=myFile.parseInt(); 199 off_time=myFile.parseInt(); 200 201 for (index=0;index<repeats;index++) 202 { 203 if (frequency==1){TCCR2B = (TCCR2B & 0b11111000) | 0x04;}else{TCCR2B = (TCCR2B & 0b11111000) | 0x02;} 204 205 analogWrite(sounder_pin, duty_cycle); 206 delay(on_time*100); 207 analogWrite(sounder_pin,0); 208 delay(off_time*100); 209 } 210 } 211 212 // close the file: 213 myFile.close(); 214 } else { 215 // if the file didn't open, print an error: 216 screen_number=file_wont_open_screen; 217 update_display(); 218 } 219 220}//end beep out file 221 222} 223 224}/*end of loop*/ 225 226//my_functions 227ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine 228{ 229 230//read buttons 231 uint8_t temp=0x00; 232 233 if (analogRead(0) > 200 && analogRead(0) < 400){temp|=1<<0;} //btnDOWN 234 if (analogRead(0) > 600 && analogRead(0) < 800){temp|=1<<1;} //btnSELECT 235 236//debounce 237 uint8_t i,j; 238 State[Index]= temp; 239 ++Index; 240 j=0xFF; 241 for (i=0;i<MAX_CHECKS;i++){j=j&State[i];} 242 Debounced_State=j; 243 if(Index>=MAX_CHECKS){Index=0;} 244} 245 246//my_screen_functions 247void update_display(void) 248{ 249 switch (screen_number) 250 { 251 case start_screen:lcd.clear(); 252 lcd.setCursor(3,0); 253 lcd.print("GymGeneral"); 254 lcd.setCursor(3,1); 255 lcd.print("Gym timer"); 256 break; 257 case initialization_screen:lcd.clear(); 258 lcd.setCursor(0,0); 259 lcd.print("Init SD..."); 260 if (!initialization_fail){lcd.print("done.");}else{lcd.print("fail!");} 261 break; 262 case file_menu_screen:lcd.clear(); 263 lcd.setCursor(2,0); 264 lcd.print("Select file"); 265 lcd.setCursor(2,1); 266 lcd.print(" ");//clear any previous filename (8.3 character format, so 12 spaces) 267 lcd.setCursor(2,1); 268 lcd.print(my_filename); 269 break; 270 case file_wont_open_screen:lcd.clear(); 271 lcd.print("Can't open file"); 272 break; 273 } 274 } 275
Downloadable files
Buzzer top view
Buzzer top view
How everything stacks together
How everything stacks together
Piezo sounder connections
Piezo sounder connections
Buzzer top view
Buzzer top view
Buzzer underside view with wiring annotations
Buzzer underside view with wiring annotations
How everything stacks together
How everything stacks together
Piezo sounder connections
Piezo sounder connections
Comments
Only logged in users can leave comments
glennedi
0 Followers
•0 Projects
Table of contents
Intro
0
0