Components and supplies
Arduino Nano 33 IoT
Clock Stepper Motor
SparkFun Micro OLED Breakout
SparkFun Motor Driver - Dual TB6612FNG (1A)
SparkFun Logic Level Converter - Bi-Directional
Apps and platforms
Arduino IoT Cloud
Arduino Web Editor
Project description
Code
Code for IoT Alarm Clock
arduino
1/* 2 Sketch generated by the Arduino IoT Cloud Thing "Alarm_Clock" 3 https://create.arduino.cc/cloud/things/... 4 5 Arduino IoT Cloud Properties description 6 7 The following variables are automatically generated and updated when changes are made to the Thing properties 8 9 int alarmHour; 10 int gmt; 11 String wifi_time; 12 int alarmMinute; 13 int readClockMaxValue; 14 15 Properties which are marked as READ/WRITE in the Cloud Thing will also have functions 16 which are called when their values are changed from the Dashboard. 17 These functions are generated with the Thing and added at the end of this sketch. 18*/ 19 20#include "thingProperties.h" 21 22//OLED example 23/****************************************************************************** 24 MicroOLED_Demo.ino 25 SFE_MicroOLED Library Demo 26 Jim Lindblom @ SparkFun Electronics 27 Original Creation Date: October 27, 2014 28 29 This sketch uses the MicroOLED library to draw a 3-D projected 30 cube, and rotate it along all three axes. 31 32 Development environment specifics: 33 Arduino 1.0.5 34 Arduino Pro 3.3V 35 Micro OLED Breakout v1.0 36 37 This code is beerware; if you see me (or any other SparkFun employee) at the 38 local, and you've found our code helpful, please buy us a round! 39 40 Distributed as-is; no warranty is given. 41 ******************************************************************************/ 42 43// wifi rtc 44/********************************************************** 45 MKR1000 - MKR WiFi 1010 - MKR VIDOR 4000 WiFi RTC 46 47 This sketch asks NTP for the Linux epoch and sets the internal Arduino MKR1000's RTC accordingly. 48 49 created 08 Jan 2016 50 by Arturo Guadalupi <a.guadalupi@arduino.cc> 51 52 modified 26 Sept 2018 53 54 http://arduino.cc/en/Tutorial/WiFiRTC 55 This code is in the public domain. 56*/ 57 58 59 60//pins 61 62/*5-pin jst 63 black "RET" -> HV side (Logic Level Converter) -> D10 OUTPUT to arm alarm PIN RET_SET 64 brown "SET" -> HV side (Logic Level Converter) -> D10 OUTPUT to arm alarm PIN RET_SET 65 red -> "GND" -> (source) 66 orange -> "6V" -> (source) 67 yellow -> "ALARM" -> x 68*/ 69#define RET_SET 10 //black and brown wire on jst 5 connector 70 71/* 7-pin-jst 72 black -> x 73 brown -> x 74 red -> GND 75 orange -> x 76 yellow -> D9 -> INPUT from button on backside PIN jst_7_yellow 77 green -> D8 -> OUTPUT to arm and engage alarm PIN jst_7_green 78 blue -> x - used to be battery voltage. if provided 3.3v terrible things happen 79*/ 80 81#define jst_7_green 8 // green OUTPUT to arm and engage alarm 82#define jst_7_yellow 9 //yellow INPUT from button on backside 83 84/* clock / motor driver 85 BI1 -> D11 86 BI2 -> D12 87 Em (Emitter) on clock for predefined position -> A0 PIN EM 88*/ 89#define BI1 11 90#define BI2 12 91#define read_clock A0 92 93/* 2-pin-jst 94 blue -> 3.3V Input 95 red -> D7 INPUT reads snooze button PIN snooze 96*/ 97#define snooze 7 //snooze button on top 98 99/* o-led 100 GND 101 3.3V 102 SDI -> SDA i2c A4 103 SCK -> SCL i2c A5 104 RST -> D6 OLED reset PIN PIN_RESET 105*/ 106#define PIN_RESET 6 //OLED reset 107 108/* front panel 109 red -> 3.3V Input 110 black -> GND Input 111 yellow -> D5 INPUT Button sleep PIN sleep | PLUG IN ORANGE CABLE FROM FRONT PANEL 112 orange -> D4 INPUT Button Alarm armed pressed PIN arm_alarm | PLUG IN YELLOW CABLE FROM BUTTON BOARD 113*/ 114#define arm_alarm 4 //button from small front panel 115#define sleep 5 //button sleep on front panel 116 117 118//alarm in tivoli 119boolean alarm_armed = false; 120boolean alarm_engaged = false; 121 122boolean last_button_state; 123unsigned long millis_when_button_was_not_pressed; 124unsigned long millis_when_display_was_lit = 0; 125boolean display_on = false; 126 127unsigned long button_press_duration = 800; // milliseconds button is held down when pressing it 128 129 130//clock 131 132unsigned long epoch; 133unsigned long millis_of_last_epoch; 134int millis_until_next_epoch = 300000; //five minutes 135 136int displayedMinute = 0; 137int displayedHour = 0; 138 139 140unsigned long millis_pin_status_clocks_hands = millis(); 141 142int pin_status_clocks_hands = 1; 143bool clock_in_predefined_position = false; //true if clock is displaying 12:00 at 12:00 144 145int read_clock_value_for_predefined_position = 370; //test with ac/dc power supply was 312, 302, 305, 270, 387, 400 .. 146 147bool clock_looking_for_reference_position = true; 148 149bool stay_in_reference_position = true; 150unsigned long millis_staying_in_reference_position = millis(); 151 152bool set_time_button_was_pressed = false; 153 154//int times to do the math 155int minuteNow = 0; 156int hourNow = 0; 157 158//int alarmMinute = 0; now as cloud property 159//int alarmHour = 6; now as cloud property 160 161 162//OLED 163 164#include <Wire.h> // Include Wire if you're using I2C 165#include <SFE_MicroOLED.h> // Include the SFE_MicroOLED library 166 167#define DC_JUMPER 1 //like in hardware setup on board, position of solder jumper 168//reset defined above 169/* 170 A5 - SCL 171 A4 - SDA 172*/ 173MicroOLED oled(PIN_RESET, DC_JUMPER); // I2C declaration 174 175 176//wifi real time clock 177 178#include <RTCZero.h> 179 180RTCZero real_time_clock; 181 182 183void setup() 184{ 185 // Initialize serial and wait for port to open: 186 Serial.begin(9600); 187 // This delay gives the chance to wait for a Serial Monitor without blocking if none is found 188 delay(1500); 189 190 // Defined in thingProperties.h 191 initProperties(); 192 193 // Connect to Arduino IoT Cloud 194 ArduinoCloud.begin(ArduinoIoTPreferredConnection); 195 196 /* 197 The following function allows you to obtain more information 198 related to the state of network and IoT Cloud connection and errors 199 the higher number the more granular information you’ll get. 200 The default is 0 (only errors). 201 Maximum is 4 202 */ 203 setDebugMessageLevel(2); 204 ArduinoCloud.printDebugInfo(); 205 206 delay(10000); //necessary for serial routine to run see https://forum.arduino.cc/index.php?topic=605436.0 207 208 pinMode(LED_BUILTIN, OUTPUT); 209 210 //tivoli and arduino pins 211 212 /*5-pin jst 213 black "RET" -> HV side (Logic Level Converter) -> D10 OUTPUT to arm alarm PIN RET_SET 214 brown "SET" -> HV side (Logic Level Converter) -> D10 OUTPUT to arm alarm PIN RET_SET 215 red -> "GND" -> (source) 216 orange -> "6V" -> (source) 217 yellow -> "ALARM" -> x 218 */ 219 pinMode(RET_SET, OUTPUT); 220 221 /* 7-pin-jst 222 black -> x 223 brown -> x 224 red -> GND 225 orange -> x 226 yellow -> D9 -> INPUT from button on backside PIN jst_7_yellow 227 green -> D8 -> OUTPUT to arm and engage alarm PIN jst_7_green 228 blue -> x - used to be battery voltage. if provided 3.3v terrible things happen 229 */ 230 pinMode(jst_7_yellow, INPUT); //INPUT Set Alarm from Button on backside, analog 0 if button is pressed 231 pinMode(jst_7_green, OUTPUT); 232 233 /* 2-pin-jst 234 blue -> 3.3V Input 235 red -> D7 INPUT reads snooze button PIN snooze 236 */ 237 pinMode(snooze, INPUT); //reads snooze button 238 239 /* clock / motor driver 240 BI1 -> D11 241 BI2 -> D12 242 Em (Emitter) on clock for predefined position -> A0 PIN read_clock 243 */ 244 pinMode(BI1, OUTPUT); 245 pinMode(BI2, OUTPUT); 246 pinMode(read_clock, INPUT); 247 248 digitalWrite(BI1, LOW); 249 digitalWrite(BI2, LOW); 250 251 /* o-led 252 GND 253 3.3V 254 SDI -> SDA i2c A4 255 SCK -> SCL i2c A5 256 RST -> D6 OLED reset PIN PIN_RESET 257 */ 258 //PIN_RESET used in oled library 259 260 /* front panel 261 red -> 3.3V Input 262 black -> GND Input 263 yellow -> D3 INPUT Button Alarm armed pressed PIN arm_alarm | PLUG IN YELLOW CABLE FROM BUTTON BOARD 264 orange -> D2 INPUT Button sleep PIN sleep | PLUG IN ORANGE CABLE FROM FRONT PANEL 265 */ 266 267 pinMode(arm_alarm, INPUT); //INPUT Button Alarm armed pressed | PLUG IN GREAY CABLE FROM BUTTON BOARD 268 pinMode(sleep, INPUT); //reads sleep button 269 270 271 //oled 272 273 oled.begin(); // Initialize the OLED 274 oled.clear(ALL); // Clear the display's internal memory 275 oled.clear(PAGE); // Clear the buffer. 276 277 //oled.setFontType(1); 278 //oled.flipHorizontal(1); 279 //oled.flipVertical(1); 280 281 282 //wifi rtc 283 284 real_time_clock.begin(); 285 286 readClockMaxValue=0; 287 288 setRTC(); // get time/epoch from ntp server 289 290 291 //setup complete 292 print_text("Hallo"); 293 294 295} 296 297void loop() 298{ 299 ArduinoCloud.update(); 300 // Your code here 301 302 303 //get time 304 305 minuteNow = real_time_clock.getMinutes(); 306 hourNow = real_time_clock.getHours() + gmt; 307 308 if (hourNow > 23) 309 { 310 hourNow = hourNow - 24; 311 } 312 313 wifi_time = String(hourNow) + ":" + String(minuteNow); 314 315 if ((millis_of_last_epoch + millis_until_next_epoch) <= millis()) //get new time/epoch 316 { 317 setRTC(); 318 } 319 320 321 //for debugging 322 //Serial.println(wifi_time); 323 324 if(analogRead(read_clock) > readClockMaxValue) 325 { 326 readClockMaxValue = analogRead(read_clock); 327 } 328 329 330 //set off alarm 331 //if alarm time == time now AND alarm is armed 332 if (((minuteNow >= alarmMinute) && ((minuteNow <= alarmMinute + 4 )) && (alarmHour == hourNow)) && (alarm_armed == true)) 333 { 334 335 //show alarm time 336 if (alarm_engaged == false && display_on == false) 337 { 338 millis_when_display_was_lit = millis(); //display will light up 339 } 340 341 alarm_engaged = true; 342 } 343 else 344 { 345 alarm_engaged = false; 346 } 347 348 349 //check if displayed time in clock is equal to time 350 if (analogRead(read_clock) >= read_clock_value_for_predefined_position) 351 { 352 clock_in_predefined_position = true; 353 digitalWrite(LED_BUILTIN, HIGH); 354 355 if (clock_looking_for_reference_position == true) 356 { 357 clock_looking_for_reference_position = false; 358 displayedMinute = 0; 359 360 if (hourNow < 12) 361 { 362 displayedHour = 0; 363 } 364 else 365 { 366 displayedHour = 12; 367 } 368 369 //stay in reference position for two seconds 370 stay_in_reference_position = true; 371 millis_staying_in_reference_position = millis(); 372 373 } 374 375 } 376 else 377 { 378 clock_in_predefined_position = false; 379 digitalWrite(LED_BUILTIN, LOW); 380 } 381 382 383 //check if clock is on time 384 if (hourNow == 12 && minuteNow == 0) 385 { 386 if (clock_in_predefined_position == false) 387 { 388 readClockMaxValue = 0; 389 clock_looking_for_reference_position = true; 390 } 391 } 392 393 //stay in reference position for two seconds 394 if(stay_in_reference_position == true and millis() - millis_staying_in_reference_position >= 2000) 395 { 396 stay_in_reference_position = false; 397 } 398 399 //move clock's hands if necessary 400 if (clock_looking_for_reference_position == true) 401 { 402 move_clocks_hand(); 403 } 404 else 405 { 406 if (stay_in_reference_position == false) 407 { 408 //if displayed time is five minutes (or less) early, wait for it, else, move hands 409 if(((displayedHour*60+displayedMinute) < (hourNow*60+minuteNow)) || ((displayedHour*60+displayedMinute) > (hourNow*60+minuteNow+5))) 410 { 411 move_clocks_hand(); 412 } 413 } 414 } 415 416 /* 417 //set clock manually 418 if (digitalRead(jst_7_yellow) == HIGH) 419 { 420 421 } 422 */ 423 424 425 //set alarm time 426 //if button is pressed to change wake up time at least for press duration 427 if (digitalRead(snooze) == HIGH) 428 { 429 //turn on display or keep it on respectively (display is already on when alarm is engaged) 430 millis_when_display_was_lit = millis(); //turns on display 431 432 //if wake up time is displayed and button is pressed again 433 if ((display_on == true) && (last_button_state == 0)) 434 { 435 //change wake up time 436 alarmMinute = alarmMinute + 5; 437 } 438 439 //if wake up time is displayed and button still pressed 440 else if ((display_on == true) && (millis() >= millis_when_button_was_not_pressed + button_press_duration) && (millis() < millis_when_button_was_not_pressed + 3 * button_press_duration)) 441 { 442 //change wake up time 443 alarmMinute = alarmMinute + 5; 444 } 445 446 //if wake up time is displayed and button is pressed for over three turns, speed up wake up time count 447 else if ((display_on == true) && (millis() >= millis_when_button_was_not_pressed + 3 * button_press_duration) && (millis() < millis_when_button_was_not_pressed + 6 * button_press_duration)) 448 { 449 //change wake up time 450 alarmMinute = alarmMinute + 15; 451 } 452 453 //if wake up time is displayed and button is pressed for over six turns, speed up wake up time count even more 454 else if ((display_on == true) && (millis() >= millis_when_button_was_not_pressed + 6 * button_press_duration)) 455 { 456 //change wake up time 457 alarmMinute = alarmMinute + 30; 458 } 459 460 //weck_Minute = alarmMinute; weck_minute renamed to alarmMinute 461 462 463 } // if button is pressed (sleep button also changes wake up time) 464 else 465 { 466 millis_when_button_was_not_pressed = millis(); //to determine how long button is held down from when it wasn't pressed yet 467 } 468 469 //track last button state (snooze) 470 last_button_state = digitalRead(snooze); 471 472 if (alarmMinute >= 60) 473 { 474 alarmMinute = 0; 475 alarmHour = alarmHour + 1; 476 477 if (alarmHour == 24) 478 { 479 alarmHour = 0; 480 } 481 482 //weck_Stunde = alarmHour; weck_Stunde renamed to alarmHour 483 484 } 485 486 487 //display alarm time 488 if ((millis() - millis_when_display_was_lit) <= 4000) 489 { 490 display_alarm_time(); 491 } 492 else 493 { 494 stop_displaying_alarm_time(); 495 } 496 497 498 //arm alarm 499 //if alarm is armed (button is pressed) 500 if (digitalRead(arm_alarm) == HIGH) //button pressed to arm alarm 501 { 502 503 //show alarm time 504 if (alarm_armed == false && display_on == false) 505 { 506 millis_when_display_was_lit = millis(); //display will light up 507 } 508 509 alarm_armed = true; 510 } 511 else if (digitalRead(arm_alarm) == LOW) 512 { 513 alarm_armed = false; 514 } 515 516 517 //play radio or not according to alarm settings 518 519 digitalWrite(jst_7_green, HIGH); 520 digitalWrite(RET_SET, HIGH); 521 522 if (alarm_armed == true && alarm_engaged == false) // don't play radio, waiting for alarm to engage 523 { 524 digitalWrite(jst_7_green, LOW); 525 digitalWrite(RET_SET, LOW); 526 } 527 528} 529 530 531void display_alarm_time() 532{ 533 //display wake up time 534 535 oled.setFontType(3); // max font 5 columns 1 row 536 oled.flipHorizontal(1); 537 oled.flipVertical(1); 538 539 oled.setCursor(0, 0); // Set the text cursor to the upper-left of the screen. 540 if (alarmHour < 10) 541 { 542 oled.print("0"); 543 oled.print(alarmHour); 544 } 545 else 546 { 547 oled.print(alarmHour); 548 } 549 550 oled.print(":"); // Print ":" 551 552 if (alarmMinute < 10) 553 { 554 oled.print("0"); 555 oled.print(alarmMinute); 556 } 557 else 558 { 559 oled.print(alarmMinute); 560 } 561 562 oled.display(); 563 564 display_on = true; 565 566} 567 568void stop_displaying_alarm_time() 569{ 570 oled.clear(ALL); // Clear the display's internal memory 571 oled.clear(PAGE); // Clear the buffer. 572 display_on = false; 573} 574 575void print_text(String text) 576{ 577 578 oled.setFontType(1); // max font 5 columns 1 row 579 oled.flipHorizontal(1); 580 oled.flipVertical(1); 581 582 oled.setCursor(0, 0); // Set the text cursor to the upper-left of the screen. 583 584 oled.print(text); 585 586 oled.display(); 587 588 delay(5000); //display for 5 seconds 589 590 oled.clear(ALL); // Clear the display's internal memory 591 oled.clear(PAGE); // Clear the buffer. 592 593} 594 595void move_clocks_hand() 596{ 597 //millis_pin_status_clocks_hands defaults millis in setup 598 //BI1, BI2 default LOW in setup 599 600 if (millis() >= millis_pin_status_clocks_hands + 100) 601 { 602 //pin_status_clocks_hands defaults to 1 603 switch (pin_status_clocks_hands) 604 { 605 case 1: 606 { 607 pin_status_clocks_hands = 2; 608 digitalWrite(BI1, HIGH); 609 digitalWrite(BI2, LOW); 610 } 611 break; 612 case 2: 613 { 614 pin_status_clocks_hands = 3; 615 digitalWrite(BI1, LOW); 616 digitalWrite(BI2, LOW); 617 } 618 break; 619 case 3: 620 { 621 pin_status_clocks_hands = 4; 622 digitalWrite(BI1, LOW); 623 digitalWrite(BI2, HIGH); 624 } 625 break; 626 case 4: 627 { 628 pin_status_clocks_hands = 1; 629 digitalWrite(BI1, LOW); 630 digitalWrite(BI2, LOW); 631 632 displayedMinute++; 633 634 if (displayedMinute == 60) 635 { 636 displayedHour = displayedHour + 1; 637 displayedMinute = 0; 638 } 639 if (displayedHour == 24) 640 { 641 displayedHour = 0; 642 } 643 } 644 break; 645 } 646 millis_pin_status_clocks_hands = millis(); 647 } 648} 649 650 651 652 653void onGmtChange() { 654 // Do something 655} 656 657 658void onAlarmMinuteChange() { 659 // Do something 660} 661 662 663void onAlarmHourChange() { 664 // Do something 665} 666 667 668 669void setRTC() { 670 671 epoch = WiFi.getTime(); 672 673 real_time_clock.setEpoch(epoch); 674 675 millis_of_last_epoch = millis(); 676 677 678} 679
Comments
Only logged in users can leave comments
MoritzDornseifer
0 Followers
•0 Projects
Table of contents
Intro
7
0