Wakeup1.ino 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #define __PROG__ "Wakeup1"
  2. /*
  3. Wakeup1.ino demonstrate the possible interaction of interrupt with scheduled coroutine.
  4. Wakeup1.ino implements an 10s timeout to receive an interrupt.
  5. The interrupt is activated when the Arduino UNO pin 2 is shortcut to GND.
  6. The elapsed time between Arduino RESET and pin INT is printed.
  7. If no interrupt is provided during 10s, then the message "timeout" is printed.
  8. Copyright (c) 2016,2015 Jean-Marc Paratte
  9. Wakeup1.ino is free software: you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation, either version 3 of the License, or
  12. (at your option) any later version.
  13. Wakeup1.ino is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with Wakeup1.ino. If not, see <http://www.gnu.org/licenses/>.
  19. Last revised: 2016-07-08,2015-06-29
  20. */
  21. #include <jm_Scheduler.h>
  22. #include "led.h"
  23. //------------------------------------------------------------------------------
  24. /*
  25. https://www.arduino.cc/en/Reference/AttachInterrupt.html
  26. Board Digital Pins Usable For Interrupts
  27. ----------------------------------------------------------------------
  28. Uno, Nano, Mini, other 328-based 2, 3
  29. Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21
  30. Micro, Leonardo, other 32u4-based 0, 1, 2, 3, 7
  31. Zero all digital pins, except 4
  32. MKR1000 Rev.1 0, 1, 4, 5, 6, 7, 8, 9, A1, A2
  33. Due all digital pins
  34. */
  35. #define WAKEUP_PIN (2) // All models same digital pin usable for interrupts except MKR1000 Rev.1
  36. //------------------------------------------------------------------------------
  37. const timestamp_t WAKEUP_TIMEOUT = 5*TIMESTAMP_1SEC; // 5s
  38. jm_Scheduler wakeup_scheduler;
  39. void wakeup_coroutine_start()
  40. {
  41. Serial.print(F(" "));
  42. Serial.println( F("start... ") );
  43. led_on(); // LED ON
  44. wakeup_scheduler.rearm( wakeup_coroutine_stop, WAKEUP_TIMEOUT ); // set timeout
  45. // flush possible pending FALLING interrupt
  46. attachInterrupt(digitalPinToInterrupt(WAKEUP_PIN), dummy_interrupt, FALLING); // attach int.0 (Arduino UNO pin 2).
  47. // detachInterrupt(digitalPinToInterrupt(WAKEUP_PIN)); // detach int.0 (Arduino UNO pin 2).
  48. attachInterrupt(digitalPinToInterrupt(WAKEUP_PIN), wakeup_interrupt, FALLING); // attach int.0 (Arduino UNO pin 2).
  49. }
  50. void wakeup_coroutine_stop()
  51. {
  52. detachInterrupt(digitalPinToInterrupt(WAKEUP_PIN)); // detach int.0 (Arduino UNO pin 2).
  53. led_off(); // LED OFF
  54. timestamp_t wakeup_time = wakeup_scheduler.wakeup_time;
  55. timestamp_t wakeup_count = wakeup_scheduler.wakeup_read();
  56. if (wakeup_count == 0) // timeout ?
  57. {
  58. Serial.print(F(" "));
  59. Serial.println( F("timeout") );
  60. }
  61. else
  62. {
  63. Serial.print(F(" "));
  64. Serial.print( (wakeup_time - (wakeup_scheduler.time - WAKEUP_TIMEOUT))/1E6, 6 ); // print elapsed time in seconds.
  65. Serial.println( F("s") );
  66. Serial.print(F(" "));
  67. Serial.print( wakeup_count );
  68. Serial.println( F(" wakeup(s)") ); // print count of wakeups
  69. }
  70. wakeup_scheduler.stop(); // stop coroutine
  71. }
  72. void wakeup_interrupt()
  73. {
  74. wakeup_scheduler.wakeup();
  75. }
  76. void dummy_interrupt()
  77. {
  78. // does nothing!
  79. }
  80. //------------------------------------------------------------------------------
  81. uint8_t clock_sec = 0; // 0..59 seconds => 1 minute
  82. uint8_t clock_min = 0; // 0..59 minutes => 1 hour
  83. uint8_t clock_h24 = 0; // 0..23 hours => 1 day
  84. void clock_inc()
  85. {
  86. clock_sec++;
  87. if (clock_sec == 60)
  88. {
  89. clock_sec = 0;
  90. clock_min++;
  91. if (clock_min == 60)
  92. {
  93. clock_min = 0;
  94. clock_h24++;
  95. if (clock_h24 == 24) clock_h24 = 0;
  96. }
  97. }
  98. }
  99. void clock_display()
  100. {
  101. Serial.print( clock_h24/10 );
  102. Serial.print( clock_h24%10 );
  103. Serial.print( ':' );
  104. Serial.print( clock_min/10 );
  105. Serial.print( clock_min%10 );
  106. Serial.print( ':' );
  107. Serial.print( clock_sec/10 );
  108. Serial.print( clock_sec%10 );
  109. Serial.println();
  110. }
  111. //------------------------------------------------------------------------------
  112. jm_Scheduler clock_scheduler;
  113. void clock_coroutine()
  114. {
  115. static bool coroutine_first_start = true;
  116. if (!coroutine_first_start) clock_inc();
  117. clock_display();
  118. if (!wakeup_scheduler && digitalRead(WAKEUP_PIN)) wakeup_scheduler.start(wakeup_coroutine_start);
  119. coroutine_first_start = false;
  120. }
  121. //------------------------------------------------------------------------------
  122. void setup()
  123. {
  124. Serial.begin(115200);
  125. while (!Serial && millis()<3000); // timeout 3s for USB Serial ready
  126. Serial.print(F(__PROG__));
  127. Serial.print(F("..."));
  128. Serial.println();
  129. led_init();
  130. clock_scheduler.start(clock_coroutine, TIMESTAMP_1SEC); // Start coroutine immediately and repeat it every 1s.
  131. pinMode(WAKEUP_PIN, INPUT_PULLUP); // Arduino UNO pin 2 is int.0
  132. // while (!digitalRead(WAKEUP_PIN)); // wait for pullup
  133. }
  134. void loop()
  135. {
  136. yield();
  137. }