SOS Flasher Using Millis Function with Enable Switch

Introduction

In this tutorial, you will learn to use the millis() function in creating an S.O.S Morse Code flasher. The advantage in using millis() function over the delay() function is the non-blocking code which means you can manage other inputs and outputs at the same time.

Circuit Diagram

Hardware Instruction

  1. Connect the LED to Arduino Uno A1 with a limiting resistor of about 560 Ohms.
  2. Connect the tactile switch to Arduino Uno A0. The other pin of the switch to the ground. The switch is configured as active LOW and internal pull-up resistor is use.
  3. Copy and paste the provided source code. Please feel free to modify it according to your liking. Enjoy.

Video Demonstration

Call To Action

If you have any question regarding this tutorial, please drop me a message in the comment box.

Please do LIKE and SHARE this to your friends and please do SUBSCRIBE. Click this to Subscribe.

Source Code

  1/*
  2 *  S.O.S. signal implementation using
  3 *  millis() function
  4 *  
  5 *  Author: George Bantique, TechToTinker
  6 *  Date: August 23, 2020
  7 *  
  8 *  Please feel free to modify it and 
  9 *  adapt it according to your application.
 10 *  
 11 */
 12#define LED_PIN A1
 13#define SW1_PIN A0
 14
 15const unsigned long DOTS_INTERVAL = 250;
 16const unsigned long DASH_INTERVAL = 750;
 17const unsigned long LOWS_INTERVAL = 500;
 18const unsigned long BETW_INTERVAL = 700;
 19unsigned long startMillis;
 20
 21// true: sos signal is ON
 22// false: sos signal is OFF
 23bool isSOS = false;
 24
 25// Tracks the current steps
 26uint8_t steps = 0;
 27
 28// Holds the current state of the LED
 29bool ledState = false;
 30
 31// This is for button debouncing
 32bool currState = HIGH;
 33bool prevState = HIGH;
 34bool buttonState = HIGH;
 35unsigned long debounceStart = 0;
 36unsigned long debounceDuration = 50;
 37
 38
 39void setup() {
 40  pinMode(LED_PIN, OUTPUT);
 41  pinMode(SW1_PIN, INPUT_PULLUP);
 42  Serial.begin(9600);
 43}
 44
 45void loop() {
 46  /*
 47   *  dots signals:
 48   *    is the short duration lights ON
 49   *  dash signals:
 50   *    is the longer duration lights ON
 51   *    compared to dots
 52   *  lows signals:
 53   *    is the duration of lights OFF
 54   *  betw signals:
 55   *    is essentially a low signals but 
 56   *    with different duration
 57   *  
 58   *  Here is the breakdown of the steps:
 59   *  0:  in-between signals
 60   *  1:  dot signal
 61   *  2:  low signal
 62   *  3:  dot signal
 63   *  4:  low signal
 64   *  5:  dot signal
 65   *  6:  in-between signals
 66   *  7:  dash signal
 67   *  8:  low signal
 68   *  9:  dash signal
 69   *  10: low signal
 70   *  11: dash signal
 71   *  12: in-between signals
 72   */
 73
 74  // Logic for the SOS
 75  //  Pseudo code:
 76  //    if SOS is ON, check the current steps
 77  //      if steps is 1, 3, and 5
 78  //        send a dots signals
 79  //      if steps is 7, 9, and 11
 80  //        send a dash signals
 81  //      if steps is 0, 6, and 12
 82  //        send a between signals
 83  //      else, it means 2, 4, 8, 10
 84  //        send a low signals
 85  //  The duration of each signal is achieve using
 86  //    the millis() function
 87  //    For example:
 88  //      if ( ( millis() - startMillis ) >= DOTS_INTERVAL ) {
 89  //        steps++;  
 90  //        startMillis = millis(); // save the start time
 91  //      }
 92  //    The ( millis() - startMillis ) is basically the elapse time
 93  //      since the startMillis is recorded
 94  //      so that ( ( millis() - startMillis ) >= DOTS_INTERVAL ) is 
 95  //      basically for checking if the required interval is achieve.
 96  //      If it becomes true, increment the counter and record the time
 97  //      and so on
 98  if (isSOS) {
 99    if        ( ( steps == 1  ) ||
100                ( steps == 3  ) ||
101                ( steps == 5 ) ) {
102      ledState = true;
103      if ( ( millis() - startMillis ) >= DOTS_INTERVAL ) {
104        steps++;  
105        startMillis = millis(); // save the start time
106      }
107    } else if ( ( steps == 7 ) ||
108                ( steps == 9 ) ||
109                ( steps == 11 ) ) {
110      ledState = true;
111      if ( ( millis() - startMillis ) >= DASH_INTERVAL ) {
112        // signal interval is complete
113        // move to the next step
114        steps++;  
115        startMillis = millis(); // save the start time
116      }
117    } else if ( ( steps == 0  ) ||
118                ( steps == 6 ) ||
119                ( steps == 12 ) ) {
120      ledState = false;
121      if ( ( millis() - startMillis ) >= BETW_INTERVAL ) {
122        steps++;  
123        startMillis = millis(); // save the start time
124      }                  
125    } else {
126      ledState = false;
127      
128      if ( ( millis() - startMillis ) >= LOWS_INTERVAL ) {
129        steps++;  
130        startMillis = millis(); // save the start time
131      } 
132    }
133    // if the steps reach steps 13, go back to steps 0
134    if (steps > 12) steps = 0;
135  }
136
137  // Update the output signal
138  digitalWrite(LED_PIN, ledState);
139
140  /*
141   *  This is for debouncing the tactile switch
142   */
143  currState = digitalRead(SW1_PIN);
144  if (currState != prevState) {
145    debounceStart = millis();
146  }
147  
148  if ((millis() - debounceStart) > debounceDuration) {
149    if (currState != buttonState) {
150      buttonState = currState;
151      if (currState == LOW) {
152        if ( isSOS ) {
153          // currently sending SOS, now turn it off
154          isSOS = false;
155          Serial.println("off");
156          ledState = false;
157        } else {
158          // currently SOS is off, now turn it on
159          isSOS = true;
160          startMillis = millis();
161          Serial.println("on");
162          steps = 0;
163        }
164      }
165    }
166  }
167  prevState = currState;
168
169  // Do other stuffs here, without blocking
170}


Posts in this series



No comments yet!

GitHub-flavored Markdown & a sane subset of HTML is supported.