Components and supplies
Arduino UNO
Resistor 10k ohm
20 x 4 RGB LCD Display
Pushbutton Switch, Momentary
Micro SD Card Adapter
Project description
Code
Poetry Clock Files
Zip file containing 526 poems used in the clock and the python script used to download them.
Poetry Clock Code
c_cpp
The Arduino Code for the Poetry Clock. Note you will need to download the SD fat library (version 1.1.4) to run this code. Download it here: https://github.com/greiman/SdFat
1// SPI library to communicate with SD card 2#include <SPI.h> 3 4// SD card chip select pin. 5const byte chipSelect = 10; 6 7// File system object. Make SdFat compatible with SD. 8#include <SdFat.h> 9SdFat SD; 10 11// Directory file. 12File root; 13// Text file 14File entry; 15//number of files in root 16int rootFileCount = 0; 17 18// initialize the LCD library by associating any LCD interface pin 19// with the arduino pin number it is connected to 20#include <LiquidCrystal.h> 21const int rs = A4, en = 2, d4 = 6, d5 = 7, d6 = 4, d7 = 8; 22LiquidCrystal lcd(rs, en, d4, d5, d6, d7); 23// number of LCD columns and rows 24const byte lcdCols = 20; 25const byte lcdRows = 4; 26// colour pins of LCD display 27const byte redLed = 3; 28const byte greenLed = 5; 29const byte blueLed = 9; 30// colour values of the backlight 31int red = 30; 32int green = 160; 33int blue = 40; 34// brightness of LCD display 35int brightness = 180; // you can change the overall brightness by range 0 -> 255 36 37//operating mode switch pin 38const byte switchPin = A1; 39int switchState; 40 41// operating mode; 42bool mode2 = false; 43 44// timekeeping variables 45int currentMin = 0; 46int currentHour = 0; 47int currentDay = 1; 48int currentMonth = 1; 49int currentYear = 2020; 50int daysinMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 51unsigned long previousTime = 0; 52 53// time switch pin 54const byte timePin = A2; 55int timeState; 56// select switch pin 57const byte selectPin = A3; 58int selectState; 59int selectCounter = 0; 60char selectToken = 'T'; 61 62// determine whether to display poem of the day 63bool potd = false; 64// the potd number 65int potd_n; 66// index of poetry file to read on SD card 67int threshold; 68 69 70void setup() { 71 Serial.begin(9600); 72 // Wait for USB Serial 73 while (!Serial) { 74 SysCall::yield(); 75 } 76 Serial.println("Serial initialized. Initializing LCD display..."); 77 // set up the LCD's number of columns and rows: 78 lcd.begin(lcdCols, lcdRows); 79 // turn off LCD autoscrolling 80 lcd.noAutoscroll(); 81 // set up LCD backlight pins 82 pinMode(redLed, OUTPUT); 83 pinMode(greenLed, OUTPUT); 84 pinMode(blueLed, OUTPUT); 85 // set up switch pins 86 pinMode(switchPin, INPUT); 87 pinMode(timePin, INPUT); 88 pinMode(selectPin, INPUT); 89 Serial.println("LCD initialized. Initializing SD card..."); 90 // Initialize at the highest speed supported by the board that is 91 // not over 50 MHz. Try a lower speed if SPI errors occur. 92 delay(1000); 93 while (!SD.begin(chipSelect, SD_SCK_MHZ(50))) { 94 SD.initErrorHalt(); 95 } 96 Serial.println("SD card initialized. Opening root directory..."); 97 if (!root.open("/")) { 98 Serial.println("Opening root directory failed."); 99 } 100 //Serial.println("Root directory opened. Counting files..."); 101 while (root.openNextFile()) { 102 rootFileCount++; 103 } 104 Serial.print(rootFileCount); 105 Serial.println(" files counted."); 106 // generate a seed for the RNG and random starting colours 107 randomSeed(analogRead(0)); 108 // initialise potd_n value 109 potd_n = random(rootFileCount); 110 // set the LCD display backlight based on currentTime 111 setBacklight(red,green,blue); 112} 113 114void loop() { 115 // time keeping 116 unsigned long currentTime = millis(); 117 // calculate minutes, hours, days, months and years 118 if (currentTime - previousTime > 60000){ 119 currentMin++; 120 previousTime = currentTime; 121 } 122 if (currentMin >= 60){ 123 currentMin = 0; 124 currentHour ++; 125 } 126 if (currentHour >= 24){ 127 currentHour = 0; 128 currentDay ++; 129 potd_n = random(rootFileCount); 130 } 131 if (currentDay >= daysinMonth[currentMonth]){ 132 currentDay = 1; 133 currentMonth ++; 134 } 135 if (currentMonth >= 13){ 136 currentMonth = 1; 137 currentYear ++; 138 } 139 // read the select state to determine what time parameter is to be changed 140 selectState = digitalRead(selectPin); 141 if (selectState == HIGH){ 142 selectCounter ++; 143 if (selectCounter == 5){ 144 selectCounter = 0; 145 } 146 switch(selectCounter){ 147 case 0: 148 selectToken = 'T'; 149 break; 150 case 1: 151 selectToken = 'H'; 152 break; 153 case 2: 154 selectToken = 'D'; 155 break; 156 case 3: 157 selectToken = 'M'; 158 break; 159 case 4: 160 selectToken = 'Y'; 161 } 162 delay(250); 163 } 164 // read the time state to determine time 165 timeState = digitalRead(timePin); 166 if (timeState == HIGH){ 167 switch(selectCounter){ 168 case 0: 169 currentMin ++; 170 break; 171 case 1: 172 currentHour ++; 173 break; 174 case 2: 175 currentDay ++; 176 break; 177 case 3: 178 currentMonth ++; 179 break; 180 case 4: 181 currentYear ++; 182 } 183 delay(250); 184 } 185 // read the switch state to determine operating mode 186 switchState = digitalRead(switchPin); 187 if (switchState == HIGH){ 188 mode2 = true; 189 } 190 if (mode2 == true){ 191 // 192 // MODE 2: RANDOM POEM 193 // display a random poem from the SD card line by line 194 // 195 // initialise backlight with random r,g,b values; 196 red = random(256); 197 green = random(256); 198 blue = random(256); 199 setBacklight(red,green,blue); 200 //if (!SD.begin(chipSelect, SD_SCK_MHZ(50))) { 201 // SD.initErrorHalt(); 202 //} 203 //if (!root.open("/")) { 204 // Serial.println("Opening root directory failed."); 205 //} 206 // rewind root directory to begining 207 root.rewindDirectory(); 208 // generate random number up to file count and open the corresponding file 209 if (potd == false){ 210 threshold = random(0,rootFileCount); 211 // use potd_n as the threshold value 212 } else { 213 threshold = potd_n; 214 } 215 int i = 0; 216 while (i < threshold) { 217 entry = root.openNextFile(); 218 i++; 219 } 220 // arrays with characters to display on each row of lcd screen 221 char row0[lcdCols]; 222 char row1[lcdCols]; 223 char row2[lcdCols]; 224 char row3[lcdCols]; 225 // initialise as empty otherwise problems will occur when reading first line 226 memset(row0, ' ', lcdCols); 227 memset(row1, ' ', lcdCols); 228 memset(row2, ' ', lcdCols); 229 memset(row3, ' ', lcdCols); 230 // read the file byte by byte and display it on the LCD screen 231 byte b = 0; 232 byte le; 233 bool leFlag = false; 234 while (entry.available()){ 235 //if the next byte is a carriage return 236 if (entry.peek() == 13){ 237 leFlag = true; 238 //ignore carriage return and line end symbols 239 entry.read(); 240 entry.read(); 241 } 242 else { 243 // ignore any non basic ascii symbols 244 while (entry.peek() < 32 || entry.peek() > 126) { 245 entry.read(); 246 } 247 //first row 248 if (b < lcdCols){ 249 row0[b] = entry.read(); 250 // prevent words from splitting over lines 251 if (b == lcdCols - 1 && entry.peek() != ' '){ 252 //find the last instance of space in row0 253 le = lineEnd(row0,lcdCols); 254 //shift all text after the last space to the row beneath 255 for (byte c = le; c < lcdCols; c++){ 256 row1[c-le] = row0[c]; 257 row0[c] = ' '; 258 } 259 //update the index position to account for the shift; 260 b = 2 * lcdCols - 1 - le; 261 } 262 //second row 263 } else if (b < lcdCols * 2) { 264 row1[b-lcdCols] = entry.read(); 265 // prevent words from splitting over lines 266 if (b == lcdCols * 2 - 1 && entry.peek() != ' '){ 267 //find the last instance of space in row1 268 le = lineEnd(row1,lcdCols); 269 //shift all text after the last space to the row beneath 270 for (byte c = le; c < lcdCols; c++){ 271 row2[c-le] = row1[c]; 272 row1[c] = ' '; 273 } 274 //update the index position to account for the shift; 275 b = 3 * lcdCols - 1 - le; 276 } 277 //third row 278 } else if (b < lcdCols * 3) { 279 row2[b-lcdCols*2] = entry.read(); 280 // prevent words from splitting over lines 281 if (b == lcdCols * 3 - 1 && entry.peek() != ' '){ 282 //find the last instance of space in row2 283 le = lineEnd(row2,lcdCols); 284 //shift all text after the last space to the row beneath 285 for (byte c = le; c < lcdCols; c++){ 286 row3[c-le] = row2[c]; 287 row2[c] = ' '; 288 } 289 //update the index position to account for the shift; 290 b = 4 * lcdCols - 1 - le; 291 } 292 //fourth row 293 } else if (b < lcdCols * 4) { 294 row3[b-lcdCols*3] = entry.read(); 295 } 296 b++; 297 } 298 // write the row bytes to the display 299 if (b > lcdCols * 4 || leFlag == true) { 300 lcd.clear(); 301 lcd.home(); 302 lcd.write(row0); 303 lcd.setCursor(0,1); 304 lcd.write(row1); 305 lcd.setCursor(0,2); 306 lcd.write(row2); 307 lcd.setCursor(0,3); 308 lcd.write(row3); 309 // time to wait between displaying lines 310 delay(2500); 311 memset(row0, ' ', lcdCols); 312 memset(row1, ' ', lcdCols); 313 memset(row2, ' ', lcdCols); 314 memset(row3, ' ', lcdCols); 315 b = 0; 316 leFlag = false; 317 } 318 } 319 // clear the screen and reset the cursor 320 lcd.clear(); 321 lcd.home(); 322 entry.close(); 323 mode2 = false; 324 } 325 else { 326 // 327 // MODE 1: Clock 328 // LCD display functions as a clock, displaying time and date. 329 // Time and date are adjustable using PTM switches. 330 // Every 15 minutes a random poem is displayed. 331 // 332 lcd.home(); 333 //Print time and date 334 printDate(currentDay,currentMonth,currentYear); 335 lcd.print(" "); 336 printTime(currentMin,currentHour); 337 lcd.print(" "); 338 // print character to show which parameter is changed by timeSwitch; 339 lcd.print(selectToken); 340 lcd.setCursor(0,1); 341 if(currentHour >= 4 and currentHour < 12){ 342 lcd.print("Good morning, "); 343 }else if (currentHour >= 12 and currentHour < 19){ 344 lcd.print("Good afternoon,"); 345 } else { 346 lcd.print("Good evening, "); 347 } 348 lcd.setCursor(0,2); 349 lcd.print("Press red button"); 350 lcd.setCursor(0,3); 351 lcd.print(" for a poem."); 352 // display poem of the day every 15 minutes 353 if (currentMin % 15 == 0 and potd == false){ 354 mode2 = true; 355 potd = true; 356 // untill the minute is up pressing the red button will read poem of the day 357 } else if (currentMin % 15 != 0){ 358 potd = false; 359 } 360 } 361} 362// determine the position of where to break the display in a row of characters 363byte lineEnd(char row[], byte rowLength){ 364 byte le = 0; 365 for (byte c = 0; c < rowLength; c++){ 366 if (row[c] == ' '){ 367 le = c; 368 } 369 } 370 return le; 371} 372// set the LED backlight 373void setBacklight(uint8_t r, uint8_t g, uint8_t blue) { 374 // from https://learn.adafruit.com/character-lcds/rgb-backlit-lcds 375 // normalize the red LED - its brighter than the rest! 376 r = map(r, 0, 255, 0, 100); 377 g = map(g, 0, 255, 0, 150); 378 379 r = map(r, 0, 255, 0, brightness); 380 g = map(g, 0, 255, 0, brightness); 381 blue = map(blue, 0, 255, 0, brightness); 382 383 // common anode so invert! 384 r = map(r, 0, 255, 255, 0); 385 g = map(g, 0, 255, 255, 0); 386 blue = map(blue, 0, 255, 255, 0); 387 Serial.print("R = "); Serial.print(r, DEC); 388 Serial.print(" G = "); Serial.print(g, DEC); 389 Serial.print(" B = "); Serial.println(blue, DEC); 390 analogWrite(redLed, r); 391 analogWrite(greenLed, g); 392 analogWrite(blueLed, blue); 393} 394//print time (hours:minutes) 395void printTime(int currentMin,int currentHour){ 396 if (currentHour < 10){ 397 lcd.print("0"); 398 } 399 lcd.print(currentHour); 400 lcd.print(":"); 401 if (currentMin < 10){ 402 lcd.print("0"); 403 } 404 lcd.print(currentMin); 405} 406//print date(day:month:year) 407void printDate(int currentDay, int currentMonth, int currentYear){ 408 if (currentDay < 10){ 409 lcd.print("0"); 410 } 411 lcd.print(currentDay); 412 lcd.print("/"); 413 if (currentMonth < 10){ 414 lcd.print("0"); 415 } 416 lcd.print(currentMonth); 417 lcd.print("/"); 418 lcd.print(currentYear); 419} 420
Poetry Clock Files
Zip file containing 526 poems used in the clock and the python script used to download them.
Poetry Clock Code
c_cpp
The Arduino Code for the Poetry Clock. Note you will need to download the SD fat library (version 1.1.4) to run this code. Download it here: https://github.com/greiman/SdFat
1// SPI library to communicate with SD card 2#include <SPI.h> 3 4// 5 SD card chip select pin. 6const byte chipSelect = 10; 7 8// File system object. 9 Make SdFat compatible with SD. 10#include <SdFat.h> 11SdFat SD; 12 13// Directory 14 file. 15File root; 16// Text file 17File entry; 18//number of files in root 19int 20 rootFileCount = 0; 21 22// initialize the LCD library by associating any LCD interface 23 pin 24// with the arduino pin number it is connected to 25#include <LiquidCrystal.h> 26const 27 int rs = A4, en = 2, d4 = 6, d5 = 7, d6 = 4, d7 = 8; 28LiquidCrystal lcd(rs, en, 29 d4, d5, d6, d7); 30// number of LCD columns and rows 31const byte lcdCols = 20; 32const 33 byte lcdRows = 4; 34// colour pins of LCD display 35const byte redLed = 3; 36const 37 byte greenLed = 5; 38const byte blueLed = 9; 39// colour values of the backlight 40int 41 red = 30; 42int green = 160; 43int blue = 40; 44// brightness of LCD display 45int 46 brightness = 180; // you can change the overall brightness by range 0 -> 255 47 48//operating 49 mode switch pin 50const byte switchPin = A1; 51int switchState; 52 53// operating 54 mode; 55bool mode2 = false; 56 57// timekeeping variables 58int currentMin 59 = 0; 60int currentHour = 0; 61int currentDay = 1; 62int currentMonth = 1; 63int 64 currentYear = 2020; 65int daysinMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 66unsigned 67 long previousTime = 0; 68 69// time switch pin 70const byte timePin = A2; 71int 72 timeState; 73// select switch pin 74const byte selectPin = A3; 75int selectState; 76int 77 selectCounter = 0; 78char selectToken = 'T'; 79 80// determine whether to display 81 poem of the day 82bool potd = false; 83// the potd number 84int potd_n; 85// 86 index of poetry file to read on SD card 87int threshold; 88 89 90void setup() 91 { 92 Serial.begin(9600); 93 // Wait for USB Serial 94 while (!Serial) { 95 96 SysCall::yield(); 97 } 98 Serial.println("Serial initialized. Initializing 99 LCD display..."); 100 // set up the LCD's number of columns and rows: 101 lcd.begin(lcdCols, 102 lcdRows); 103 // turn off LCD autoscrolling 104 lcd.noAutoscroll(); 105 // set 106 up LCD backlight pins 107 pinMode(redLed, OUTPUT); 108 pinMode(greenLed, OUTPUT); 109 110 pinMode(blueLed, OUTPUT); 111 // set up switch pins 112 pinMode(switchPin, INPUT); 113 114 pinMode(timePin, INPUT); 115 pinMode(selectPin, INPUT); 116 Serial.println("LCD 117 initialized. Initializing SD card..."); 118 // Initialize at the highest speed 119 supported by the board that is 120 // not over 50 MHz. Try a lower speed if SPI 121 errors occur. 122 delay(1000); 123 while (!SD.begin(chipSelect, SD_SCK_MHZ(50))) 124 { 125 SD.initErrorHalt(); 126 } 127 Serial.println("SD card initialized. Opening 128 root directory..."); 129 if (!root.open("/")) { 130 Serial.println("Opening 131 root directory failed."); 132 } 133 //Serial.println("Root directory opened. 134 Counting files..."); 135 while (root.openNextFile()) { 136 rootFileCount++; 137 138 } 139 Serial.print(rootFileCount); 140 Serial.println(" files counted."); 141 142 // generate a seed for the RNG and random starting colours 143 randomSeed(analogRead(0)); 144 145 // initialise potd_n value 146 potd_n = random(rootFileCount); 147 // 148 set the LCD display backlight based on currentTime 149 setBacklight(red,green,blue); 150 151} 152 153void loop() { 154 // time keeping 155 unsigned long currentTime 156 = millis(); 157 // calculate minutes, hours, days, months and years 158 if (currentTime 159 - previousTime > 60000){ 160 currentMin++; 161 previousTime = currentTime; 162 163 } 164 if (currentMin >= 60){ 165 currentMin = 0; 166 currentHour ++; 167 168 } 169 if (currentHour >= 24){ 170 currentHour = 0; 171 currentDay ++; 172 173 potd_n = random(rootFileCount); 174 } 175 if (currentDay >= daysinMonth[currentMonth]){ 176 177 currentDay = 1; 178 currentMonth ++; 179 } 180 if (currentMonth >= 13){ 181 182 currentMonth = 1; 183 currentYear ++; 184 } 185 // read the select state 186 to determine what time parameter is to be changed 187 selectState = digitalRead(selectPin); 188 189 if (selectState == HIGH){ 190 selectCounter ++; 191 if (selectCounter == 192 5){ 193 selectCounter = 0; 194 } 195 switch(selectCounter){ 196 case 197 0: 198 selectToken = 'T'; 199 break; 200 case 1: 201 selectToken 202 = 'H'; 203 break; 204 case 2: 205 selectToken = 'D'; 206 break; 207 208 case 3: 209 selectToken = 'M'; 210 break; 211 case 4: 212 selectToken 213 = 'Y'; 214 } 215 delay(250); 216 } 217 // read the time state to determine 218 time 219 timeState = digitalRead(timePin); 220 if (timeState == HIGH){ 221 switch(selectCounter){ 222 223 case 0: 224 currentMin ++; 225 break; 226 case 1: 227 currentHour 228 ++; 229 break; 230 case 2: 231 currentDay ++; 232 break; 233 234 case 3: 235 currentMonth ++; 236 break; 237 case 4: 238 currentYear 239 ++; 240 } 241 delay(250); 242 } 243 // read the switch state to determine 244 operating mode 245 switchState = digitalRead(switchPin); 246 if (switchState == 247 HIGH){ 248 mode2 = true; 249 } 250 if (mode2 == true){ 251 // 252 253 // MODE 2: RANDOM POEM 254 // display a random poem from the SD card line 255 by line 256 // 257 // initialise backlight with random r,g,b values; 258 259 red = random(256); 260 green = random(256); 261 blue = random(256); 262 263 setBacklight(red,green,blue); 264 //if (!SD.begin(chipSelect, SD_SCK_MHZ(50))) 265 { 266 // SD.initErrorHalt(); 267 //} 268 //if (!root.open("/")) { 269 270 // Serial.println("Opening root directory failed."); 271 //} 272 // 273 rewind root directory to begining 274 root.rewindDirectory(); 275 // generate 276 random number up to file count and open the corresponding file 277 if (potd == 278 false){ 279 threshold = random(0,rootFileCount); 280 // use potd_n as the 281 threshold value 282 } else { 283 threshold = potd_n; 284 } 285 int 286 i = 0; 287 while (i < threshold) { 288 entry = root.openNextFile(); 289 290 i++; 291 } 292 // arrays with characters to display on each row of lcd 293 screen 294 char row0[lcdCols]; 295 char row1[lcdCols]; 296 char row2[lcdCols]; 297 298 char row3[lcdCols]; 299 // initialise as empty otherwise problems will occur 300 when reading first line 301 memset(row0, ' ', lcdCols); 302 memset(row1, ' 303 ', lcdCols); 304 memset(row2, ' ', lcdCols); 305 memset(row3, ' ', lcdCols); 306 307 // read the file byte by byte and display it on the LCD screen 308 byte b 309 = 0; 310 byte le; 311 bool leFlag = false; 312 while (entry.available()){ 313 314 //if the next byte is a carriage return 315 if (entry.peek() == 13){ 316 317 leFlag = true; 318 //ignore carriage return and line end symbols 319 320 entry.read(); 321 entry.read(); 322 } 323 else { 324 325 // ignore any non basic ascii symbols 326 while (entry.peek() < 32 327 || entry.peek() > 126) { 328 entry.read(); 329 } 330 //first 331 row 332 if (b < lcdCols){ 333 row0[b] = entry.read(); 334 // 335 prevent words from splitting over lines 336 if (b == lcdCols - 1 && entry.peek() 337 != ' '){ 338 //find the last instance of space in row0 339 le 340 = lineEnd(row0,lcdCols); 341 //shift all text after the last space to 342 the row beneath 343 for (byte c = le; c < lcdCols; c++){ 344 345 row1[c-le] = row0[c]; 346 row0[c] = ' '; 347 } 348 349 //update the index position to account for the shift; 350 b 351 = 2 * lcdCols - 1 - le; 352 } 353 //second row 354 } else 355 if (b < lcdCols * 2) { 356 row1[b-lcdCols] = entry.read(); 357 // 358 prevent words from splitting over lines 359 if (b == lcdCols * 2 - 1 && 360 entry.peek() != ' '){ 361 //find the last instance of space in row1 362 363 le = lineEnd(row1,lcdCols); 364 //shift all text after the 365 last space to the row beneath 366 for (byte c = le; c < lcdCols; c++){ 367 368 row2[c-le] = row1[c]; 369 row1[c] = ' 370 '; 371 } 372 //update the index position to account for the 373 shift; 374 b = 3 * lcdCols - 1 - le; 375 } 376 //third 377 row 378 } else if (b < lcdCols * 3) { 379 row2[b-lcdCols*2] = entry.read(); 380 381 // prevent words from splitting over lines 382 if (b == lcdCols 383 * 3 - 1 && entry.peek() != ' '){ 384 //find the last instance of space 385 in row2 386 le = lineEnd(row2,lcdCols); 387 //shift all text 388 after the last space to the row beneath 389 for (byte c = le; c < lcdCols; 390 c++){ 391 row3[c-le] = row2[c]; 392 row2[c] 393 = ' '; 394 } 395 //update the index position to account for 396 the shift; 397 b = 4 * lcdCols - 1 - le; 398 } 399 //fourth 400 row 401 } else if (b < lcdCols * 4) { 402 row3[b-lcdCols*3] = entry.read(); 403 404 } 405 b++; 406 } 407 // write the row bytes to the display 408 409 if (b > lcdCols * 4 || leFlag == true) { 410 lcd.clear(); 411 lcd.home(); 412 413 lcd.write(row0); 414 lcd.setCursor(0,1); 415 lcd.write(row1); 416 417 lcd.setCursor(0,2); 418 lcd.write(row2); 419 lcd.setCursor(0,3); 420 421 lcd.write(row3); 422 // time to wait between displaying lines 423 424 delay(2500); 425 memset(row0, ' ', lcdCols); 426 memset(row1, 427 ' ', lcdCols); 428 memset(row2, ' ', lcdCols); 429 memset(row3, ' 430 ', lcdCols); 431 b = 0; 432 leFlag = false; 433 } 434 } 435 436 // clear the screen and reset the cursor 437 lcd.clear(); 438 lcd.home(); 439 440 entry.close(); 441 mode2 = false; 442 } 443 else { 444 // 445 // 446 MODE 1: Clock 447 // LCD display functions as a clock, displaying time and 448 date. 449 // Time and date are adjustable using PTM switches. 450 // Every 451 15 minutes a random poem is displayed. 452 // 453 lcd.home(); 454 //Print 455 time and date 456 printDate(currentDay,currentMonth,currentYear); 457 lcd.print(" 458 "); 459 printTime(currentMin,currentHour); 460 lcd.print(" "); 461 // 462 print character to show which parameter is changed by timeSwitch; 463 lcd.print(selectToken); 464 465 lcd.setCursor(0,1); 466 if(currentHour >= 4 and currentHour < 12){ 467 lcd.print("Good 468 morning, "); 469 }else if (currentHour >= 12 and currentHour < 19){ 470 lcd.print("Good 471 afternoon,"); 472 } else { 473 lcd.print("Good evening, "); 474 } 475 476 lcd.setCursor(0,2); 477 lcd.print("Press red button"); 478 lcd.setCursor(0,3); 479 480 lcd.print(" for a poem."); 481 // display poem of the day every 482 15 minutes 483 if (currentMin % 15 == 0 and potd == false){ 484 mode2 = 485 true; 486 potd = true; 487 // untill the minute is up pressing the red button 488 will read poem of the day 489 } else if (currentMin % 15 != 0){ 490 potd 491 = false; 492 } 493 } 494} 495// determine the position of where to break 496 the display in a row of characters 497byte lineEnd(char row[], byte rowLength){ 498 499 byte le = 0; 500 for (byte c = 0; c < rowLength; c++){ 501 if (row[c] 502 == ' '){ 503 le = c; 504 } 505 } 506 return le; 507} 508// set the 509 LED backlight 510void setBacklight(uint8_t r, uint8_t g, uint8_t blue) { 511 // 512 from https://learn.adafruit.com/character-lcds/rgb-backlit-lcds 513 // normalize 514 the red LED - its brighter than the rest! 515 r = map(r, 0, 255, 0, 100); 516 g 517 = map(g, 0, 255, 0, 150); 518 519 r = map(r, 0, 255, 0, brightness); 520 g = 521 map(g, 0, 255, 0, brightness); 522 blue = map(blue, 0, 255, 0, brightness); 523 524 525 // common anode so invert! 526 r = map(r, 0, 255, 255, 0); 527 g = map(g, 528 0, 255, 255, 0); 529 blue = map(blue, 0, 255, 255, 0); 530 Serial.print("R = 531 "); Serial.print(r, DEC); 532 Serial.print(" G = "); Serial.print(g, DEC); 533 534 Serial.print(" B = "); Serial.println(blue, DEC); 535 analogWrite(redLed, r); 536 537 analogWrite(greenLed, g); 538 analogWrite(blueLed, blue); 539} 540//print time 541 (hours:minutes) 542void printTime(int currentMin,int currentHour){ 543 if (currentHour 544 < 10){ 545 lcd.print("0"); 546 } 547 lcd.print(currentHour); 548 lcd.print(":"); 549 550 if (currentMin < 10){ 551 lcd.print("0"); 552 } 553 lcd.print(currentMin); 554} 555//print 556 date(day:month:year) 557void printDate(int currentDay, int currentMonth, int currentYear){ 558 559 if (currentDay < 10){ 560 lcd.print("0"); 561 } 562 lcd.print(currentDay); 563 564 lcd.print("/"); 565 if (currentMonth < 10){ 566 lcd.print("0"); 567 } 568 569 lcd.print(currentMonth); 570 lcd.print("/"); 571 lcd.print(currentYear); 572} 573
Downloadable files
LCD Poetry Clock Breadboard Layout
LCD Poetry Clock Breadboard Layout
LCD Poetry Clock Breadboard Layout
LCD Poetry Clock Breadboard Layout
Poetry Clock Breadboard Fritzing File
Poetry Clock Breadboard Fritzing File
Comments
Only logged in users can leave comments
kzra
0 Followers
•0 Projects
Table of contents
Intro
2
0