Components and supplies
PIR Motion Sensor (generic)
AM2320 Temperature and humidity sensor
MAX7219 8x8 LED matrix
Arduino Nano R3
DS1302 Real Time Clock
Apps and platforms
Arduino IDE
Project description
Code
Link to library: LedControlMS
Link to library: LedControlMS
Link to library: AM2320-master
Link to library: arduino-ds1302-master
20171103 enhanced 32x8 LED matrix Sketch code with the 5V input of the AM2320 on pin D8
arduino
The code will check if the AM2320 gives an error and reset it.
1/* 2*************************************************************************** 3* 32 x 8 LED matrix date-clock-temperature-humidity display by ericBcreator 4* 5* enhanced version with the AM2320 powered by a delayed output pin D8 and 6* reset function when there is an error 7* 8* components: 9* - DS1302 real time clock 10* - AM2320 temperature and humidity sensor 11* - PIR Motion Sensor 12* - 4 x MAX7219 8x8 LED matrix 13* - Arduino Nano 14* 15*************************************************************************** 16* last updated 20171103 by ericBcreator 17* 18* This code is free for personal use, not for commercial purposes. 19* Please leave this header intact. 20* 21* contact: ericBcreator@gmail.com 22*************************************************************************** 23*/ 24 25// 26// Include libraries 27// 28 29#include <stdio.h> 30#include <DS1302.h> // library for DS1302 RealTimeClock 31#include <LedControlMS.h> // library for 8x8 LED matrix 32 33#include <LowPower.h> // library to turn the Arduino into sleep mode when no motion is detected 34 35#include <Wire.h> 36#include <AM2320.h> // library for AM2320 temperature-humidity sensor 37AM2320 th; // pins connections: 1 to 5V, 2 (SDA) to A4, 3 to GND and 4 (SCL) A5 38 39// 40// Define pins 41// 42 43#define TEMPPIN A6 // temperature sensor pin 44#define AM2320POWERPIN 8 // output pin to power the AM2320 with a delay 45 46#define PIRPIN 2 // PIR sensor interrupt pin (2 or 3 for Arduino Nano) 47 48#define CLOCKCEPIN 5 // DS1302 Chip Enable pin 49#define CLOCKIOPIN 6 // DS1302 Input/Output pin 50#define CLOCKCLKPIN 7 // DS1302 Serial Clock pin 51 52#define LCLOADPIN 10 // LC LOAD pin 53#define LCCLKPIN 11 // LC CLK pin 54#define LCDINPIN 12 // LC DataIn pin 55 56// 57// Setup objects 58// 59 60// DataIn, CLK, LOAD, numOfDevices (fixed at 4) 61LedControl lc = LedControl(LCDINPIN, LCCLKPIN, LCLOADPIN, 4); 62 63// Create a DS1302 clock object 64DS1302 rtc(CLOCKCEPIN, CLOCKIOPIN, CLOCKCLKPIN); 65 66// 67// Initialize variables 68// 69 70int ledBrightness = 0; // 0 -15 71int timeBlinkDelay = 500; // blink speed of the colon 72int numOfTimeLoops = 10; // num of 2 second loops the time will display 73int delayTimeStatic = 4000; // display time for the static texts 74int animDelay = 55; // delay time during animations 75int clearLedDisplay = false; // not used 76int ledUpdateDelay = 20; // delay time between drawing LED columns 77int nextLineDelay = 1500; // delay time between multiple line displays 78int numOfLoopsUntilSleep = 5; // number of times the main loop will run before going into sleep mode 79int AM2320powerDelay = 2000; // delay time before powering the AM2320 sensor 80 81int destMatrix, destCol; 82int animType = 0; 83int sleeping = true; 84int firstLoop = true; 85 86volatile int sleepLoopCounter = 0; 87 88const char * DS1302ErrorMessage = "*RTC ERROR"; 89const char * AM2320ErrorMessage = "*TEMPERROR"; 90 91// 92// Setup 93// 94 95void setup() { 96 //Serial.begin(9600); // for debugging 97 98 //setTime(); // run once to initialize the date and time of the rtc 99 100 int devices = lc.getDeviceCount(); 101 for(int address = 0; address < devices; address++) { 102 lc.shutdown(address, false); 103 // Set the brightness 104 lc.setIntensity(address, ledBrightness); 105 lc.clearDisplay(address); 106 } 107 108 pinMode (PIRPIN, INPUT); 109 digitalWrite (PIRPIN, LOW); 110 attachInterrupt(digitalPinToInterrupt(PIRPIN), PIRmotionDetected, RISING); 111 112 pinMode (AM2320POWERPIN, OUTPUT); 113 resetAM2320(); 114 115 powerOnTest(); // check the sensors 116} 117 118// 119// Main loop 120// 121 122void loop() { 123 if (sleepLoopCounter == 0 && sleeping == true) { 124 displayAnim(); 125 if (firstLoop != true) { // when waking up, first display the time, then do the regular loop 126 displayTime(); 127 displayAnim(); 128 } 129 130 sleeping = false; 131 firstLoop = false; 132 } 133 134 if (sleepLoopCounter < numOfLoopsUntilSleep) { 135 sleepLoopCounter++; 136 displayDate(); 137 displayTime(); 138 displayTemp(); 139 displayAnim(); 140 } 141 else if (sleepLoopCounter == numOfLoopsUntilSleep) { 142 displayAnimClear(); 143 sleeping = true; 144 sleepLoopCounter++; 145 146 // Enter power down state with ADC and BOD module disabled. 147 // When the PIR detects motion, an interrupt calls the PIRmotionDetected() function and the script continue 148 LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 149 } 150} 151 152// 153// Functions 154// 155 156void setTime() { 157 // Initialize a new chip by turning off write protection and clearing the 158 // clock halt flag. These methods needn't always be called. See the DS1302 159 // datasheet for details. 160 rtc.writeProtect(false); 161 rtc.halt(false); 162 163 // Make a new time object to set the date and time. 164 // yy, mm, dd, hr, min, sec, day of week 165 Time t(2017, 10, 29, 6, 45, 0, Time::kSunday); 166 167 // Set the time and date on the chip. 168 rtc.time(t); 169} 170 171void powerOnTest() { 172 displayStringCondensed(2, "INIT..."); 173 delay (AM2320powerDelay); 174 175 Time t = rtc.time(); 176 int readTH; 177 178 for (int i = 0; i < 1; i++) { 179 readTH = th.Read(); 180 if (readTH == 1 or readTH == 2) { 181 //if (i == 1) displayStringCondensed(0, AM2320ErrorMessage); 182 resetAM2320(); 183 } 184 } 185 186 if (dayAsString(t.day) == DS1302ErrorMessage ) { 187 displayStringCondensed(0, DS1302ErrorMessage); 188 } 189} 190 191void PIRmotionDetected() { 192 if (digitalRead(PIRPIN) == HIGH) { 193 //Serial.println("Motion detected"); 194 195 sleepLoopCounter = 0; 196 197 lc.setLed(3,0,0,true); 198 lc.setLed(3,0,0,false); 199 } 200} 201 202void displayDate() { 203 Time t = rtc.time(); 204 205 String day = dayAsString(t.day); 206 char dayString[20]; 207 snprintf(dayString, sizeof(dayString), "%s ", day.c_str()); 208 displayStringCondensed(1, dayString); 209 delayAndClearLed(); 210 211 String month = monthAsString(t.mon); 212 char dateString[8]; 213 snprintf(dateString, sizeof(dateString), "%02d||%s", t.date, month.c_str()); 214 displayStringCondensed(1, dateString); 215 delayAndClearLed(); 216 217 char yearString[5]; 218 snprintf(yearString, sizeof(yearString), "%04d", t.yr); 219 displayStringCondensed(4, yearString); 220 delayAndClearLed(); 221} 222 223void displayTime() { 224 for (int i = 0; i <= numOfTimeLoops; i++) { 225 Time t = rtc.time(); 226 char timeString[9]; 227 snprintf(timeString, sizeof(timeString), "%02d||||%02d", t.hr, t.min); 228 displayStringCondensed(2, timeString); 229 230 lc.setLed(1,5,0,false); 231 lc.setLed(1,2,0,false); 232 delay(timeBlinkDelay); 233 lc.setLed(1,5,0,true); 234 lc.setLed(1,2,0,true); 235 delay(timeBlinkDelay); 236 } 237 238 if (clearLedDisplay) 239 lc.clearAll(); 240} 241 242void displayTemp () { 243 int intValue, fracValue; 244 245 if(th.Read() == 0) { 246 char tempString[10]; 247 intValue = th.t; 248 fracValue = th.t * 10 - intValue * 10; 249 250 snprintf(tempString, sizeof(tempString), "%02d.|%01d||C", intValue, fracValue); 251 displayStringCondensed(2, tempString); 252 delayAndClearLed(); 253 } 254 else { 255 displayStringCondensed(0, AM2320ErrorMessage); 256 resetAM2320(); 257 } 258 259 if(th.Read() == 0) { 260 char humString[10]; 261 intValue = th.h; 262 263 snprintf(humString, sizeof(humString), "%02d||/ ", intValue); 264 displayStringCondensed(7, humString); 265 delayAndClearLed(); 266 } 267 else { 268 displayStringCondensed(0, AM2320ErrorMessage); 269 resetAM2320(); 270 } 271} 272 273void displayAnim() { 274 switch (animType) { 275 case 0: 276 for (int row = 0; row <= 7; row++) { 277 for (int matrix = 0; matrix <= 3; matrix++) { 278 lc.setRow(matrix, 7 - row, B11111111); 279 } 280 delay(animDelay); 281 } 282 break; 283 284 case 1: 285 for (int row = 0; row <= 7; row++) { 286 for (int matrix = 0; matrix <= 3; matrix++) { 287 lc.setRow(matrix, row, B11111111); 288 } 289 delay(animDelay); 290 } 291 break; 292 } 293 294 animType++; 295 if (animType > 1) 296 animType = 0; 297 298 if (clearLedDisplay) 299 lc.clearAll(); 300} 301 302void displayAnimClear() { 303 for (int row = 0; row <= 7; row++) { 304 for (int matrix = 0; matrix <= 3; matrix++) { 305 lc.setRow(matrix, 7 - row, B00000000); 306 } 307 delay(animDelay); 308 } 309} 310 311void displayStringCondensed (int startCol, char * displayString) { 312 int i; 313 char c; 314 destMatrix = 0; 315 destCol = 7 - startCol; 316 317 for (i = 7; i > (7 - startCol); i--) // clear first columns if the startCol > 0 318 lc.setColumn(destMatrix, i, B00000000); 319 320 while (displayString[0] != 0) { 321 c = displayString[0]; 322 323 if (destMatrix == 4 || displayString[0] == '~') { // next line when we're out of matrices or a newline character is sent: ~ 324 clearLastColumns(); 325 destMatrix = 0; 326 destCol = 7 - startCol; 327 328 if (displayString[0] == '~') { 329 displayString++; 330 c = displayString[0]; 331 } 332 delay(nextLineDelay); 333 } 334 335 if (displayString[0] == '|') { // display one blank column 336 lc.setColumn(destMatrix, destCol, B00000000); 337 increaseColCounter(); 338 } 339 else if (displayString[0] == '.') { // display a point in a single column 340 lc.setColumn(destMatrix, destCol, B10000000); 341 increaseColCounter(); 342 } 343 else if (displayString[0] == '!') { // display a ! 344 lc.setColumn(destMatrix, destCol, B10111111); 345 increaseColCounter(); 346 } 347 else if (displayString[0] == '/') { // display a % sign, % sign won't work because of the snprintf function 348 lc.setColumn(destMatrix, destCol, B11000011); 349 increaseColCounter(); 350 lc.setColumn(destMatrix, destCol, B00110011); 351 increaseColCounter(); 352 lc.setColumn(destMatrix, destCol, B11001100); 353 increaseColCounter(); 354 lc.setColumn(destMatrix, destCol, B11000011); 355 increaseColCounter(); 356 } 357 else if (displayString[0] == '*') { // display a * 358 lc.setColumn(destMatrix, destCol, B00100010); 359 increaseColCounter(); 360 lc.setColumn(destMatrix, destCol, B00010100); 361 increaseColCounter(); 362 lc.setColumn(destMatrix, destCol, B01111111); 363 increaseColCounter(); 364 lc.setColumn(destMatrix, destCol, B00010100); 365 increaseColCounter(); 366 lc.setColumn(destMatrix, destCol, B00100010); 367 increaseColCounter(); 368 lc.setColumn(destMatrix, destCol, B00000000); 369 increaseColCounter(); 370 } 371 else { 372 if (destMatrix == 3 && destCol < 4) { // the character does not fit so enforce a new line 373 clearLastColumns(); 374 destMatrix = 0; 375 destCol = 7 - startCol; 376 displayString--; 377 delay(nextLineDelay); 378 } 379 else { 380 int pos = lc.getCharArrayPosition(c); 381 382 for (i = 0; i < 6; i++) { 383 lc.setColumn(destMatrix, destCol, alphabetBitmap[pos][i]); 384 increaseColCounter(); 385 } 386 } 387 } 388 389 displayString++; 390 } 391 392 clearLastColumns(); 393} 394 395void increaseColCounter() { 396 destCol--; 397 398 if (destCol < 0) { 399 destMatrix++; 400 destCol = 7; 401 } 402 403 delay(ledUpdateDelay); 404} 405 406void clearLastColumns() { 407 for (int i = destMatrix * 8 + destCol; i < 4 * 8; i++) { 408 lc.setColumn(destMatrix, destCol, B00000000); 409 increaseColCounter(); 410 } 411} 412 413void delayAndClearLed() { 414 delay(delayTimeStatic); 415 416 if (clearLedDisplay) 417 lc.clearAll(); 418} 419 420String dayAsString(const Time::Day day) { 421 switch (day) { 422 case Time::kSunday: return "|||Sun- day"; 423 case Time::kMonday: return "|||Mon- day"; 424 case Time::kTuesday: return "Tues- day"; 425 case Time::kWednesday: return "|||Wed-ness- day"; 426 case Time::kThursday: return "Thurs|||-day"; 427 case Time::kFriday: return "|||Fri- day"; 428 case Time::kSaturday: return "Satur|||-day"; 429 } 430 return DS1302ErrorMessage ; 431} 432 433String monthAsString(int month) { 434 switch (month) { 435 case 1: return "Jan"; 436 case 2: return "Feb"; 437 case 3: return "Mar"; 438 case 4: return "Apr"; 439 case 5: return "May"; 440 case 6: return "Jun"; 441 case 7: return "Jul"; 442 case 8: return "Aug"; 443 case 9: return "Sep"; 444 case 10: return "Oct"; 445 case 11: return "Nov"; 446 case 12: return "Dec"; 447 } 448 return DS1302ErrorMessage ; 449} 450 451void resetAM2320() { 452 digitalWrite (AM2320POWERPIN, LOW); 453 delay (AM2320powerDelay); 454 digitalWrite (AM2320POWERPIN, HIGH); 455} 456 457
Link to library: Low-Power-master
Link to library: AM2320-master
Link to library: Low-Power-master
20171103 enhanced 32x8 LED matrix Sketch code with the 5V input of the AM2320 on pin D8
arduino
The code will check if the AM2320 gives an error and reset it.
1/* 2*************************************************************************** 3* 32 x 8 LED matrix date-clock-temperature-humidity display by ericBcreator 4* 5* enhanced version with the AM2320 powered by a delayed output pin D8 and 6* reset function when there is an error 7* 8* components: 9* - DS1302 real time clock 10* - AM2320 temperature and humidity sensor 11* - PIR Motion Sensor 12* - 4 x MAX7219 8x8 LED matrix 13* - Arduino Nano 14* 15*************************************************************************** 16* last updated 20171103 by ericBcreator 17* 18* This code is free for personal use, not for commercial purposes. 19* Please leave this header intact. 20* 21* contact: ericBcreator@gmail.com 22*************************************************************************** 23*/ 24 25// 26// Include libraries 27// 28 29#include <stdio.h> 30#include <DS1302.h> // library for DS1302 RealTimeClock 31#include <LedControlMS.h> // library for 8x8 LED matrix 32 33#include <LowPower.h> // library to turn the Arduino into sleep mode when no motion is detected 34 35#include <Wire.h> 36#include <AM2320.h> // library for AM2320 temperature-humidity sensor 37AM2320 th; // pins connections: 1 to 5V, 2 (SDA) to A4, 3 to GND and 4 (SCL) A5 38 39// 40// Define pins 41// 42 43#define TEMPPIN A6 // temperature sensor pin 44#define AM2320POWERPIN 8 // output pin to power the AM2320 with a delay 45 46#define PIRPIN 2 // PIR sensor interrupt pin (2 or 3 for Arduino Nano) 47 48#define CLOCKCEPIN 5 // DS1302 Chip Enable pin 49#define CLOCKIOPIN 6 // DS1302 Input/Output pin 50#define CLOCKCLKPIN 7 // DS1302 Serial Clock pin 51 52#define LCLOADPIN 10 // LC LOAD pin 53#define LCCLKPIN 11 // LC CLK pin 54#define LCDINPIN 12 // LC DataIn pin 55 56// 57// Setup objects 58// 59 60// DataIn, CLK, LOAD, numOfDevices (fixed at 4) 61LedControl lc = LedControl(LCDINPIN, LCCLKPIN, LCLOADPIN, 4); 62 63// Create a DS1302 clock object 64DS1302 rtc(CLOCKCEPIN, CLOCKIOPIN, CLOCKCLKPIN); 65 66// 67// Initialize variables 68// 69 70int ledBrightness = 0; // 0 -15 71int timeBlinkDelay = 500; // blink speed of the colon 72int numOfTimeLoops = 10; // num of 2 second loops the time will display 73int delayTimeStatic = 4000; // display time for the static texts 74int animDelay = 55; // delay time during animations 75int clearLedDisplay = false; // not used 76int ledUpdateDelay = 20; // delay time between drawing LED columns 77int nextLineDelay = 1500; // delay time between multiple line displays 78int numOfLoopsUntilSleep = 5; // number of times the main loop will run before going into sleep mode 79int AM2320powerDelay = 2000; // delay time before powering the AM2320 sensor 80 81int destMatrix, destCol; 82int animType = 0; 83int sleeping = true; 84int firstLoop = true; 85 86volatile int sleepLoopCounter = 0; 87 88const char * DS1302ErrorMessage = "*RTC ERROR"; 89const char * AM2320ErrorMessage = "*TEMPERROR"; 90 91// 92// Setup 93// 94 95void setup() { 96 //Serial.begin(9600); // for debugging 97 98 //setTime(); // run once to initialize the date and time of the rtc 99 100 int devices = lc.getDeviceCount(); 101 for(int address = 0; address < devices; address++) { 102 lc.shutdown(address, false); 103 // Set the brightness 104 lc.setIntensity(address, ledBrightness); 105 lc.clearDisplay(address); 106 } 107 108 pinMode (PIRPIN, INPUT); 109 digitalWrite (PIRPIN, LOW); 110 attachInterrupt(digitalPinToInterrupt(PIRPIN), PIRmotionDetected, RISING); 111 112 pinMode (AM2320POWERPIN, OUTPUT); 113 resetAM2320(); 114 115 powerOnTest(); // check the sensors 116} 117 118// 119// Main loop 120// 121 122void loop() { 123 if (sleepLoopCounter == 0 && sleeping == true) { 124 displayAnim(); 125 if (firstLoop != true) { // when waking up, first display the time, then do the regular loop 126 displayTime(); 127 displayAnim(); 128 } 129 130 sleeping = false; 131 firstLoop = false; 132 } 133 134 if (sleepLoopCounter < numOfLoopsUntilSleep) { 135 sleepLoopCounter++; 136 displayDate(); 137 displayTime(); 138 displayTemp(); 139 displayAnim(); 140 } 141 else if (sleepLoopCounter == numOfLoopsUntilSleep) { 142 displayAnimClear(); 143 sleeping = true; 144 sleepLoopCounter++; 145 146 // Enter power down state with ADC and BOD module disabled. 147 // When the PIR detects motion, an interrupt calls the PIRmotionDetected() function and the script continue 148 LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 149 } 150} 151 152// 153// Functions 154// 155 156void setTime() { 157 // Initialize a new chip by turning off write protection and clearing the 158 // clock halt flag. These methods needn't always be called. See the DS1302 159 // datasheet for details. 160 rtc.writeProtect(false); 161 rtc.halt(false); 162 163 // Make a new time object to set the date and time. 164 // yy, mm, dd, hr, min, sec, day of week 165 Time t(2017, 10, 29, 6, 45, 0, Time::kSunday); 166 167 // Set the time and date on the chip. 168 rtc.time(t); 169} 170 171void powerOnTest() { 172 displayStringCondensed(2, "INIT..."); 173 delay (AM2320powerDelay); 174 175 Time t = rtc.time(); 176 int readTH; 177 178 for (int i = 0; i < 1; i++) { 179 readTH = th.Read(); 180 if (readTH == 1 or readTH == 2) { 181 //if (i == 1) displayStringCondensed(0, AM2320ErrorMessage); 182 resetAM2320(); 183 } 184 } 185 186 if (dayAsString(t.day) == DS1302ErrorMessage ) { 187 displayStringCondensed(0, DS1302ErrorMessage); 188 } 189} 190 191void PIRmotionDetected() { 192 if (digitalRead(PIRPIN) == HIGH) { 193 //Serial.println("Motion detected"); 194 195 sleepLoopCounter = 0; 196 197 lc.setLed(3,0,0,true); 198 lc.setLed(3,0,0,false); 199 } 200} 201 202void displayDate() { 203 Time t = rtc.time(); 204 205 String day = dayAsString(t.day); 206 char dayString[20]; 207 snprintf(dayString, sizeof(dayString), "%s ", day.c_str()); 208 displayStringCondensed(1, dayString); 209 delayAndClearLed(); 210 211 String month = monthAsString(t.mon); 212 char dateString[8]; 213 snprintf(dateString, sizeof(dateString), "%02d||%s", t.date, month.c_str()); 214 displayStringCondensed(1, dateString); 215 delayAndClearLed(); 216 217 char yearString[5]; 218 snprintf(yearString, sizeof(yearString), "%04d", t.yr); 219 displayStringCondensed(4, yearString); 220 delayAndClearLed(); 221} 222 223void displayTime() { 224 for (int i = 0; i <= numOfTimeLoops; i++) { 225 Time t = rtc.time(); 226 char timeString[9]; 227 snprintf(timeString, sizeof(timeString), "%02d||||%02d", t.hr, t.min); 228 displayStringCondensed(2, timeString); 229 230 lc.setLed(1,5,0,false); 231 lc.setLed(1,2,0,false); 232 delay(timeBlinkDelay); 233 lc.setLed(1,5,0,true); 234 lc.setLed(1,2,0,true); 235 delay(timeBlinkDelay); 236 } 237 238 if (clearLedDisplay) 239 lc.clearAll(); 240} 241 242void displayTemp () { 243 int intValue, fracValue; 244 245 if(th.Read() == 0) { 246 char tempString[10]; 247 intValue = th.t; 248 fracValue = th.t * 10 - intValue * 10; 249 250 snprintf(tempString, sizeof(tempString), "%02d.|%01d||C", intValue, fracValue); 251 displayStringCondensed(2, tempString); 252 delayAndClearLed(); 253 } 254 else { 255 displayStringCondensed(0, AM2320ErrorMessage); 256 resetAM2320(); 257 } 258 259 if(th.Read() == 0) { 260 char humString[10]; 261 intValue = th.h; 262 263 snprintf(humString, sizeof(humString), "%02d||/ ", intValue); 264 displayStringCondensed(7, humString); 265 delayAndClearLed(); 266 } 267 else { 268 displayStringCondensed(0, AM2320ErrorMessage); 269 resetAM2320(); 270 } 271} 272 273void displayAnim() { 274 switch (animType) { 275 case 0: 276 for (int row = 0; row <= 7; row++) { 277 for (int matrix = 0; matrix <= 3; matrix++) { 278 lc.setRow(matrix, 7 - row, B11111111); 279 } 280 delay(animDelay); 281 } 282 break; 283 284 case 1: 285 for (int row = 0; row <= 7; row++) { 286 for (int matrix = 0; matrix <= 3; matrix++) { 287 lc.setRow(matrix, row, B11111111); 288 } 289 delay(animDelay); 290 } 291 break; 292 } 293 294 animType++; 295 if (animType > 1) 296 animType = 0; 297 298 if (clearLedDisplay) 299 lc.clearAll(); 300} 301 302void displayAnimClear() { 303 for (int row = 0; row <= 7; row++) { 304 for (int matrix = 0; matrix <= 3; matrix++) { 305 lc.setRow(matrix, 7 - row, B00000000); 306 } 307 delay(animDelay); 308 } 309} 310 311void displayStringCondensed (int startCol, char * displayString) { 312 int i; 313 char c; 314 destMatrix = 0; 315 destCol = 7 - startCol; 316 317 for (i = 7; i > (7 - startCol); i--) // clear first columns if the startCol > 0 318 lc.setColumn(destMatrix, i, B00000000); 319 320 while (displayString[0] != 0) { 321 c = displayString[0]; 322 323 if (destMatrix == 4 || displayString[0] == '~') { // next line when we're out of matrices or a newline character is sent: ~ 324 clearLastColumns(); 325 destMatrix = 0; 326 destCol = 7 - startCol; 327 328 if (displayString[0] == '~') { 329 displayString++; 330 c = displayString[0]; 331 } 332 delay(nextLineDelay); 333 } 334 335 if (displayString[0] == '|') { // display one blank column 336 lc.setColumn(destMatrix, destCol, B00000000); 337 increaseColCounter(); 338 } 339 else if (displayString[0] == '.') { // display a point in a single column 340 lc.setColumn(destMatrix, destCol, B10000000); 341 increaseColCounter(); 342 } 343 else if (displayString[0] == '!') { // display a ! 344 lc.setColumn(destMatrix, destCol, B10111111); 345 increaseColCounter(); 346 } 347 else if (displayString[0] == '/') { // display a % sign, % sign won't work because of the snprintf function 348 lc.setColumn(destMatrix, destCol, B11000011); 349 increaseColCounter(); 350 lc.setColumn(destMatrix, destCol, B00110011); 351 increaseColCounter(); 352 lc.setColumn(destMatrix, destCol, B11001100); 353 increaseColCounter(); 354 lc.setColumn(destMatrix, destCol, B11000011); 355 increaseColCounter(); 356 } 357 else if (displayString[0] == '*') { // display a * 358 lc.setColumn(destMatrix, destCol, B00100010); 359 increaseColCounter(); 360 lc.setColumn(destMatrix, destCol, B00010100); 361 increaseColCounter(); 362 lc.setColumn(destMatrix, destCol, B01111111); 363 increaseColCounter(); 364 lc.setColumn(destMatrix, destCol, B00010100); 365 increaseColCounter(); 366 lc.setColumn(destMatrix, destCol, B00100010); 367 increaseColCounter(); 368 lc.setColumn(destMatrix, destCol, B00000000); 369 increaseColCounter(); 370 } 371 else { 372 if (destMatrix == 3 && destCol < 4) { // the character does not fit so enforce a new line 373 clearLastColumns(); 374 destMatrix = 0; 375 destCol = 7 - startCol; 376 displayString--; 377 delay(nextLineDelay); 378 } 379 else { 380 int pos = lc.getCharArrayPosition(c); 381 382 for (i = 0; i < 6; i++) { 383 lc.setColumn(destMatrix, destCol, alphabetBitmap[pos][i]); 384 increaseColCounter(); 385 } 386 } 387 } 388 389 displayString++; 390 } 391 392 clearLastColumns(); 393} 394 395void increaseColCounter() { 396 destCol--; 397 398 if (destCol < 0) { 399 destMatrix++; 400 destCol = 7; 401 } 402 403 delay(ledUpdateDelay); 404} 405 406void clearLastColumns() { 407 for (int i = destMatrix * 8 + destCol; i < 4 * 8; i++) { 408 lc.setColumn(destMatrix, destCol, B00000000); 409 increaseColCounter(); 410 } 411} 412 413void delayAndClearLed() { 414 delay(delayTimeStatic); 415 416 if (clearLedDisplay) 417 lc.clearAll(); 418} 419 420String dayAsString(const Time::Day day) { 421 switch (day) { 422 case Time::kSunday: return "|||Sun- day"; 423 case Time::kMonday: return "|||Mon- day"; 424 case Time::kTuesday: return "Tues- day"; 425 case Time::kWednesday: return "|||Wed-ness- day"; 426 case Time::kThursday: return "Thurs|||-day"; 427 case Time::kFriday: return "|||Fri- day"; 428 case Time::kSaturday: return "Satur|||-day"; 429 } 430 return DS1302ErrorMessage ; 431} 432 433String monthAsString(int month) { 434 switch (month) { 435 case 1: return "Jan"; 436 case 2: return "Feb"; 437 case 3: return "Mar"; 438 case 4: return "Apr"; 439 case 5: return "May"; 440 case 6: return "Jun"; 441 case 7: return "Jul"; 442 case 8: return "Aug"; 443 case 9: return "Sep"; 444 case 10: return "Oct"; 445 case 11: return "Nov"; 446 case 12: return "Dec"; 447 } 448 return DS1302ErrorMessage ; 449} 450 451void resetAM2320() { 452 digitalWrite (AM2320POWERPIN, LOW); 453 delay (AM2320powerDelay); 454 digitalWrite (AM2320POWERPIN, HIGH); 455} 456 457
32x8 LED matrix Sketch code
arduino
1/* 2* 32 x 8 LED matrix date-clock-temperature-humidity display by ericBcreator 3* 4* components: 5* - DS1302 real time clock 6* - AM2320 temperature and humidity sensor 7* - PIR Motion Sensor 8* - 4 x MAX7219 8x8 LED matrix 9* - Arduino Nano 10* 11* last update 20171024 by ericBcreator 12* 13* This code is free for personal use, not for commercial purposes. 14* Please leave this header intact. 15* 16* contact: ericBcreator@gmail.com 17*/ 18 19// 20// Include libraries 21// 22 23#include <stdio.h> 24#include <DS1302.h> // library for DS1302 RealTimeClock 25#include <LedControlMS.h> // library for 8x8 LED matrix 26 27#include <LowPower.h> // library to turn the Arduino into sleep mode when no motion is detected 28 29#include <Wire.h> 30#include <AM2320.h> // library for AM2320 temperature-humidity sensor 31AM2320 th; // pins connections: 1 to 5V, 2 (SDA) to A4, 3 to GND and 4 (SCL) A5 32 33// 34// Define pins 35// 36 37#define TEMPPIN A6 // temperature sensor pin 38 39#define PIRPIN 2 // PIR sensor interrupt pin (2 or 3 for Arduino Nano) 40 41#define CLOCKCEPIN 5 // DS1302 Chip Enable pin 42#define CLOCKIOPIN 6 // DS1302 Input/Output pin 43#define CLOCKCLKPIN 7 // DS1302 Serial Clock pin 44 45#define LCLOADPIN 10 // LC LOAD pin 46#define LCCLKPIN 11 // LC CLK pin 47#define LCDINPIN 12 // LC DataIn pin 48 49// 50// Setup objects 51// 52 53// DataIn, CLK, LOAD, numOfDevices (fixed at 4) 54LedControl lc = LedControl(LCDINPIN, LCCLKPIN, LCLOADPIN, 4); 55 56// Create a DS1302 clock object 57DS1302 rtc(CLOCKCEPIN, CLOCKIOPIN, CLOCKCLKPIN); 58 59// 60// Initialize variables 61// 62 63int ledBrightness = 0; // 0 -15 64int numOfTimeLoops = 5; // num of 2 second loops the time will display 65int delayTimeStatic = 4000; // display time for the static texts 66int animDelay = 55; // delay time during animations 67int clearLedDisplay = false; // not used 68int ledUpdateDelay = 20; // delay time between drawing LED columns 69int nextLineDelay = 1500; // delay time between multiple line displays 70int numOfLoopsUntilSleep = 5; // number of times the main loop will run before going into sleep mode 71 72int destMatrix, destCol; 73int animType = 0; 74int sleeping = true; 75 76volatile int sleepLoopCounter = 0; 77 78const char * DS1302ErrorMessage = "*RTC ERROR"; 79const char * AM2320ErrorMessage = "*TEMPERROR"; 80 81// 82// Setup 83// 84 85void setup() { 86 //setTime(); // run once to initialize the date and time of the rtc 87 88 int devices = lc.getDeviceCount(); 89 for(int address = 0; address < devices; address++) { 90 lc.shutdown(address, false); 91 // Set the brightness 92 lc.setIntensity(address, ledBrightness); 93 lc.clearDisplay(address); 94 } 95 96 pinMode (PIRPIN, INPUT); 97 digitalWrite (PIRPIN, LOW); 98 attachInterrupt(digitalPinToInterrupt(PIRPIN), PIRmotionDetected, RISING); 99 100 // for debugging 101 //Serial.begin(9600); 102 103 powerOnTest(); // check the sensors 104} 105 106// 107// Main loop 108// 109 110void loop() { 111 if (sleepLoopCounter == 0 && sleeping == true) { 112 displayAnim(); 113 sleeping = false; 114 } 115 116 if (sleepLoopCounter < numOfLoopsUntilSleep) { 117 sleepLoopCounter++; 118 displayDate(); 119 displayTime(); 120 displayTemp(); 121 displayAnim(); 122 } 123 else if (sleepLoopCounter == numOfLoopsUntilSleep) { 124 displayAnimClear(); 125 sleeping = true; 126 sleepLoopCounter++; 127 128 // Enter power down state with ADC and BOD module disabled. 129 // When the PIR detects motion, an interrupt calls the PIRmotionDetected() function and the script continue 130 LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 131 } 132} 133 134// 135// Functions 136// 137 138void setTime() { 139 // Initialize a new chip by turning off write protection and clearing the 140 // clock halt flag. These methods needn't always be called. See the DS1302 141 // datasheet for details. 142 rtc.writeProtect(false); 143 rtc.halt(false); 144 145 // Make a new time object to set the date and time. 146 // yy, mm, dd, hr, min, sec, day of week 147 Time t(2017, 10, 20, 16, 51, 00, Time::kFriday); 148 149 // Set the time and date on the chip. 150 rtc.time(t); 151} 152 153void powerOnTest() { 154 Time t = rtc.time(); 155 if (dayAsString(t.day) == DS1302ErrorMessage ) { 156 displayStringCondensed(0, DS1302ErrorMessage ); 157 } 158 159 switch(th.Read()) 160 case 1 or 2: 161 displayStringCondensed(0, AM2320ErrorMessage); 162} 163 164void PIRmotionDetected() { 165 if (digitalRead(PIRPIN) == HIGH) { 166 //Serial.println("Motion detected"); 167 168 sleepLoopCounter = 0; 169 170 lc.setLed(3,0,0,true); 171 lc.setLed(3,0,0,false); 172 } 173} 174 175void displayDate() { 176 Time t = rtc.time(); 177 178 String day = dayAsString(t.day); 179 char dayString[20]; 180 snprintf(dayString, sizeof(dayString), "%s ", day.c_str()); 181 displayStringCondensed(1, dayString); 182 delayAndClearLed(); 183 184 String month = monthAsString(t.mon); 185 char dateString[8]; 186 snprintf(dateString, sizeof(dateString), "%02d||%s", t.date, month.c_str()); 187 displayStringCondensed(1, dateString); 188 delayAndClearLed(); 189 190 char yearString[5]; 191 snprintf(yearString, sizeof(yearString), "%04d", t.yr); 192 displayStringCondensed(4, yearString); 193 delayAndClearLed(); 194} 195 196void displayTime() { 197 for (int i = 0; i <= numOfTimeLoops; i++) { 198 Time t = rtc.time(); 199 char timeString[9]; 200 snprintf(timeString, sizeof(timeString), "%02d||||%02d", t.hr, t.min); 201 displayStringCondensed(2, timeString); 202 203 lc.setLed(1,5,0,false); 204 lc.setLed(1,2,0,false); 205 delay(1000); 206 lc.setLed(1,5,0,true); 207 lc.setLed(1,2,0,true); 208 delay(1000); 209 } 210 211 if (clearLedDisplay) 212 lc.clearAll(); 213} 214 215void displayTemp () { 216 int intValue, fracValue; 217 218 if(th.Read() == 0) { 219 char tempString[10]; 220 intValue = th.t; 221 fracValue = th.t * 10 - intValue * 10; 222 223 snprintf(tempString, sizeof(tempString), "%02d.|%01d||C", intValue, fracValue); 224 displayStringCondensed(2, tempString); 225 delayAndClearLed(); 226 } 227 else 228 displayStringCondensed(0, AM2320ErrorMessage); 229 230 if(th.Read() == 0) { 231 char humString[10]; 232 intValue = th.h; 233 234 snprintf(humString, sizeof(humString), "%02d||/ ", intValue); 235 displayStringCondensed(7, humString); 236 delayAndClearLed(); 237 } 238 else 239 displayStringCondensed(0, AM2320ErrorMessage); 240} 241 242void displayAnim() { 243 switch (animType) { 244 case 0: 245 for (int row = 0; row <= 7; row++) { 246 for (int matrix = 0; matrix <= 3; matrix++) { 247 lc.setRow(matrix, 7 - row, B11111111); 248 } 249 delay(animDelay); 250 } 251 break; 252 253 case 1: 254 for (int row = 0; row <= 7; row++) { 255 for (int matrix = 0; matrix <= 3; matrix++) { 256 lc.setRow(matrix, row, B11111111); 257 } 258 delay(animDelay); 259 } 260 break; 261 } 262 263 animType++; 264 if (animType > 1) 265 animType = 0; 266 267 if (clearLedDisplay) 268 lc.clearAll(); 269} 270 271void displayAnimClear() { 272 for (int row = 0; row <= 7; row++) { 273 for (int matrix = 0; matrix <= 3; matrix++) { 274 lc.setRow(matrix, 7 - row, B00000000); 275 } 276 delay(animDelay); 277 } 278} 279 280void displayStringCondensed (int startCol, char * displayString) { 281 int i; 282 char c; 283 destMatrix = 0; 284 destCol = 7 - startCol; 285 286 for (i = 7; i > (7 - startCol); i--) // clear first columns if the startCol > 0 287 lc.setColumn(destMatrix, i, B00000000); 288 289 while (displayString[0] != 0) { 290 c = displayString[0]; 291 292 if (destMatrix == 4 || displayString[0] == '~') { // next line when we're out of matrices or a newline character is sent: ~ 293 clearLastColumns(); 294 destMatrix = 0; 295 destCol = 7 - startCol; 296 297 if (displayString[0] == '~') { 298 displayString++; 299 c = displayString[0]; 300 } 301 delay(nextLineDelay); 302 } 303 304 if (displayString[0] == '|') { // display one blank column 305 lc.setColumn(destMatrix, destCol, B00000000); 306 increaseColCounter(); 307 } 308 else if (displayString[0] == '.') { // display a point in a single column 309 lc.setColumn(destMatrix, destCol, B10000000); 310 increaseColCounter(); 311 } 312 else if (displayString[0] == '!') { // display a ! 313 lc.setColumn(destMatrix, destCol, B10111111); 314 increaseColCounter(); 315 } 316 else if (displayString[0] == '/') { // display a % sign, % sign won't work because of the snprintf function 317 lc.setColumn(destMatrix, destCol, B11000011); 318 increaseColCounter(); 319 lc.setColumn(destMatrix, destCol, B00110011); 320 increaseColCounter(); 321 lc.setColumn(destMatrix, destCol, B11001100); 322 increaseColCounter(); 323 lc.setColumn(destMatrix, destCol, B11000011); 324 increaseColCounter(); 325 } 326 else if (displayString[0] == '*') { // display a * 327 lc.setColumn(destMatrix, destCol, B00100010); 328 increaseColCounter(); 329 lc.setColumn(destMatrix, destCol, B00010100); 330 increaseColCounter(); 331 lc.setColumn(destMatrix, destCol, B01111111); 332 increaseColCounter(); 333 lc.setColumn(destMatrix, destCol, B00010100); 334 increaseColCounter(); 335 lc.setColumn(destMatrix, destCol, B00100010); 336 increaseColCounter(); 337 lc.setColumn(destMatrix, destCol, B00000000); 338 increaseColCounter(); 339 } 340 else { 341 if (destMatrix == 3 && destCol < 4) { // the character does not fit so enforce a new line 342 clearLastColumns(); 343 destMatrix = 0; 344 destCol = 7 - startCol; 345 displayString--; 346 delay(nextLineDelay); 347 } 348 else { 349 int pos = lc.getCharArrayPosition(c); 350 351 for (i = 0; i < 6; i++) { 352 lc.setColumn(destMatrix, destCol, alphabetBitmap[pos][i]); 353 increaseColCounter(); 354 } 355 } 356 } 357 358 displayString++; 359 } 360 361 clearLastColumns(); 362} 363 364void increaseColCounter() { 365 destCol--; 366 367 if (destCol < 0) { 368 destMatrix++; 369 destCol = 7; 370 } 371 372 delay(ledUpdateDelay); 373} 374 375void clearLastColumns() { 376 for (int i = destMatrix * 8 + destCol; i < 4 * 8; i++) { 377 lc.setColumn(destMatrix, destCol, B00000000); 378 increaseColCounter(); 379 } 380} 381 382void delayAndClearLed() { 383 delay(delayTimeStatic); 384 385 if (clearLedDisplay) 386 lc.clearAll(); 387} 388 389String dayAsString(const Time::Day day) { 390 switch (day) { 391 case Time::kSunday: return "|||Sun- day"; 392 case Time::kMonday: return "|||Mon- day"; 393 case Time::kTuesday: return "Tues- day"; 394 case Time::kWednesday: return "|||Wed-ness- day"; 395 case Time::kThursday: return "Thurs|||-day"; 396 case Time::kFriday: return "|||Fri- day"; 397 case Time::kSaturday: return "Satur|||-day"; 398 } 399 return DS1302ErrorMessage ; 400} 401 402String monthAsString(int month) { 403 switch (month) { 404 case 1: return "Jan"; 405 case 2: return "Feb"; 406 case 3: return "Mar"; 407 case 4: return "Apr"; 408 case 5: return "May"; 409 case 6: return "Jun"; 410 case 7: return "Jul"; 411 case 8: return "Aug"; 412 case 9: return "Sep"; 413 case 10: return "Oct"; 414 case 11: return "Nov"; 415 case 12: return "Dec"; 416 } 417 return DS1302ErrorMessage ; 418} 419
Link to library: arduino-ds1302-master
Downloadable files
32x8 LED matrix schematic
32x8 LED matrix schematic
32x8 LED matrix schematic
32x8 LED matrix schematic
Comments
Only logged in users can leave comments