Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- The GM 67-80 turn signal lever with single button cruise control
- has 2 switches inside it that switch at different depths of the
- button push. Because of this, it facilitates the ability to
- detect a fast or slow button release or press.
- This Arduino sketch is intended to interpret the fast or slow
- presses and releases, long duration press, double tap, and
- other gestures, and do separate actions in response.
- In this way the Arduino can do a variety of things based on
- input from one button, such as roll up and down power windows,
- or turn things on or off.
- The patterns tapped on the button remind me of morse code, so
- in this sketch I name many of the patterns using dits and dahs.
- Connection of the Arduino to serial monitor allows you to
- capture the patterns input with the button as array values,
- so you can easily alter the sketch for unique patterns.
- Electrical connections on the GM 67-80 turn signal lever:
- Pin 1 and pin 2 are separated by a notch
- Pin 1 normally open and switches closed at shallow depression
- Pin 2 common
- Pin 3 normally closed and switches open at deep depression
- Recognition of pass through of cruise control coast and set
- signals requires slow press and hold input to this sketch.
- What is passed to cruise control is fast press and hold,
- followed by the actual speed of button release. Any speed
- press followed by slow release is typically required for cruise
- control to set properly.
- In my experience with GM 67-80 single button cruise control in
- various vehicles, fast release may sometimes disengage cruise,
- but it is not reliable as a method of disengagement. In some
- models a fast press and release may accelerate and set a new
- faster speed by a couple miles per hour. Passing through
- settings that allow the cruise control to do these advanced
- features is not directly supported by this sketch, and all that
- I intend it to do is coast and set. However, it is possible
- to use non-pass-through gestures (all the gestures other than
- slow press and hold) to do things such as accelerate and
- disengage if you figure out how to wire those features into
- the cruise control.
- The sky is the limit regarding complexity of the button press
- gestures and resulting signals to external relays.
- Examples of things to control with this:
- roll power windows
- wiper mist
- hidden garage door remote
- push button start
- kill switch
- external or internal lights
- switch on or off assorted accessories
- cruise control
- Notes about matching arrays:
- clean collected array: this means remove the leading delay time,
- which means nothing, and if in the middle of the pattern there is
- a checkForMatchesTimer delay time and event, remove the
- checkForMatchesTimer expiration event
- and combine (add) the expiration time with the next delay time
- that happens before the next button activity event.
- map array: this means change the event timings to all be measured
- from 0 to 100, instead of 0 to 1500 or some other arbitrary number.
- The final array to match a pattern ends up showing you timings that
- are percentages of the longest event. The longest event used
- for pattern matching is typically less than a checkForMatchesTimer
- expiration, and is perhaps 1/2 second shown by approximately 80 in the
- array.
- match against some patterns special cases:
- for patterns that have 999 in a specific time slot, that indicates ignore
- that time slot in the collected array, do that by insert 999 in same slot
- of cleaned array, re-map, and compare.
- The purpose of ignoring certain times is to make it possible ot match
- patterns where the button is held down while waiting for a controlled
- device to do something such as coast on cruise control or roll up or roll
- down window until the button is released. I don't know that the
- finished application will actually use this feature of ignoring certain
- timing durations, but the feature is there should it be desired.
- In order to create a pattern for an arbitrary long press it is necessary
- to put 999 in a pattern, compile, upload, and capture the mapped pattern,
- then copy that mapped pattern into the pattern array settings to use as
- the model.
- This is version 15
- Demo of earlier version (13): https://youtu.be/xDpqLDz1xEk
- MIT license
- Copyright (c) 2021 David Lambert
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
- // Global settings
- // pin names
- #define SWITCHSHALLOW 3 // digital input from button shallow press
- #define SWITCHDEEP 4 // digital input from button deep press
- #define OUTPUT1 5
- #define OUTPUT2 6
- #define OUTPUT3 7
- #define OUTPUT4 8
- #define OUTPUT5 9
- #define OUTPUT6 10
- #define OUTPUT7 11
- #define OUTPUT8 12
- #define OUTPUT9 13
- #define OUTPUT10 A0
- #define OUTPUT11 A1
- #define OUTPUT12 A2
- #define OUTPUT13 A3
- // debounce settings
- unsigned long lastDebounceTime1 = 0; // the last time the output pin was toggled
- unsigned long lastDebounceTime2 = 0; // the last time the output pin was toggled
- const unsigned long debounceDelay = 10; // the debounce time; increase if the output flickers
- bool buttonState1 = LOW; // the current reading from the input pin
- bool lastButtonState1 = LOW; // the previous reading from the input pin
- bool buttonState2 = LOW; // the current reading from the input pin
- bool lastButtonState2 = LOW; // the previous reading from the input pin
- bool buttonChange1 = false;
- bool buttonChange2 = false;
- // timer settings
- unsigned long output9Timer = 0;
- unsigned long output9TimerDuration;
- bool output9TimerCounted = true;
- unsigned long output10Timer = 0;
- unsigned long output10TimerDuration;
- bool output10TimerCounted = true;
- unsigned long checkForMatchesTimer = 0;
- unsigned long resetArrayTimer = 0;
- bool checkForMatchesTimerCounted = true;
- bool resetArrayTimerCounted = true;
- const unsigned long checkForMatchesTimerDuration = 900;
- const unsigned long resetArrayTimerDuration = 925;
- // names of events and numbers assigned to them
- #define SwitchShallowPressed 1
- #define SwitchDeepPressed 2
- #define SwitchDeepReleased 3
- #define SwitchShallowReleased 4
- #define checkForMatchesTimerExpired 13
- #define resetArrayTimerExpired 14
- // array variables
- unsigned int index = 0;
- #define ARRAYLENGTH 30
- #define ERRORPERCENT 20
- unsigned int collectedPattern[ARRAYLENGTH];
- unsigned int collectedPatternCleaned[ARRAYLENGTH];
- unsigned int collectedPatternMapped[ARRAYLENGTH];
- // The patterns to be recognized when compared against button
- // presses and releases of different timings. There are
- // more than one pattern for most of these gestures, to make
- // the sketch more reliably pick up on slightly different ways
- // to do the gesture.
- // slow press and hold. This is pass through of cruise control coast and set command
- const PROGMEM unsigned int slowPressAndHold[ARRAYLENGTH] = {1, 29, 2, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int slowPressAndHold2[ARRAYLENGTH] = {1, 62, 2, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- // fastPressAndHold (fast press with long hold. Release immediately turns off device)
- const PROGMEM unsigned int fastPressAndHold[ARRAYLENGTH] = {1, 1, 2, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- // dit-dah-and-hold (fast press and release followed by press and hold. Release immediately turns off device)
- const PROGMEM unsigned int ditDahAndHold[ARRAYLENGTH] = {1, 4, 2, 15, 3, 2, 4, 21, 1, 1, 2, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int ditDahAndHold2[ARRAYLENGTH] = {1, 2, 2, 38, 3, 2, 4, 36, 1, 2, 2, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- // dit-dit-dah-and-hold (fast double tap followed by press and hold. Release immediately turns off device)
- const PROGMEM unsigned int ditDitDahAndHold[ARRAYLENGTH] = {1, 3, 2, 20, 3, 1, 4, 17, 1, 1, 2, 17, 3, 1, 4, 26, 1, 2, 2, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int ditDitDahAndHold2[ARRAYLENGTH] = {1, 2, 2, 41, 3, 1, 4, 39, 1, 2, 2, 38, 3, 1, 4, 46, 1, 2, 2, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- // dit (fast single tap)
- const PROGMEM unsigned int dit[ARRAYLENGTH] = {1, 2, 2, 25, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int dit2[ARRAYLENGTH] = {1, 3, 2, 49, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- // dit-dit (fast double tap)
- const PROGMEM unsigned int ditDit[ARRAYLENGTH] = {1, 2, 2, 25, 3, 1, 4, 14, 1, 4, 2, 20, 3, 2, 4, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int ditDit2[ARRAYLENGTH] = {1, 2, 2, 26, 3, 1, 4, 40, 1, 3, 2, 21, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- // dit-dit-dit (fast tripple tap)
- const PROGMEM unsigned int ditDitDit[ARRAYLENGTH] = {1, 2, 2, 25, 3, 1, 4, 14, 1, 4, 2, 20, 3, 2, 4, 14, 1, 4, 2, 20, 3, 2, 4, 100, 13, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int ditDitDit2[ARRAYLENGTH] = {1, 1, 2, 24, 3, 1, 4, 35, 1, 1, 2, 24, 3, 1, 4, 38, 1, 1, 2, 22, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0};
- // comment about dah (long press) this one may be too similar to press and hold.
- // Having a dit following dah seems to limit my tendency to make
- // a long press too long, so dah-dit and dah-dit-dit are better gestures.
- // dah-dit
- const PROGMEM unsigned int dahDit[ARRAYLENGTH] = {1, 2, 2, 85, 3, 2, 4, 15, 1, 3, 2, 17, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int dahDit2[ARRAYLENGTH] = {1, 1, 2, 59, 3, 1, 4, 24, 1, 1, 2, 24, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- // dah-dit-dit
- const PROGMEM unsigned int dahDitDit[ARRAYLENGTH] = {1, 3, 2, 69, 3, 1, 4, 23, 1, 1, 2, 24, 3, 1, 4, 16, 1, 1, 2, 28, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int dahDitDit2[ARRAYLENGTH] = {1, 2, 2, 90, 3, 1, 4, 21, 1, 1, 2, 27, 3, 1, 4, 25, 1, 1, 2, 32, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0};
- // comment about dit-dah, in testing I found this one is too
- // similar to dit-dah-and-hold and cause unintended results
- // dit-dah-dit
- const PROGMEM unsigned int ditDahDit[ARRAYLENGTH] = {1, 2, 2, 23, 3, 1, 4, 20, 1, 1, 2, 72, 3, 1, 4, 20, 1, 1, 2, 20, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int ditDahDit2[ARRAYLENGTH] = {1, 3, 2, 27, 3, 1, 4, 23, 1, 1, 2, 81, 3, 1, 4, 33, 1, 1, 2, 43, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0};
- const PROGMEM unsigned int ditDahDit3[ARRAYLENGTH] = {1, 3, 2, 28, 3, 1, 4, 25, 1, 2, 2, 84, 3, 1, 4, 31, 1, 2, 2, 42, 3, 1, 4, 100, 13, 0, 0, 0, 0, 0};
- // Array of names of all the patterns we want to detect:
- #define NUMPATTERNS 20
- unsigned int patternIndex = 0;
- const PROGMEM unsigned int patternTable[NUMPATTERNS] = {
- slowPressAndHold,
- slowPressAndHold2,
- fastPressAndHold,
- ditDahAndHold,
- ditDahAndHold2,
- ditDitDahAndHold,
- ditDitDahAndHold2,
- dit,
- dit2,
- ditDit,
- ditDit2,
- ditDitDit,
- ditDitDit2,
- dahDit,
- dahDit2,
- dahDitDit,
- dahDitDit2,
- ditDahDit,
- ditDahDit2,
- ditDahDit3
- };
- // decision handling variables
- bool onHold5 = false;
- bool onHold6 = false;
- bool onHold7 = false;
- bool onHoldShallow = false;
- bool onHoldDeep = false;
- void setup() {
- Serial.begin(115200);
- pinMode(SWITCHSHALLOW, INPUT_PULLUP);
- pinMode(SWITCHDEEP, INPUT_PULLUP);
- pinMode(OUTPUT1, OUTPUT);
- pinMode(OUTPUT2, OUTPUT);
- pinMode(OUTPUT3, OUTPUT);
- pinMode(OUTPUT4, OUTPUT);
- pinMode(OUTPUT5, OUTPUT);
- pinMode(OUTPUT6, OUTPUT);
- pinMode(OUTPUT7, OUTPUT);
- pinMode(OUTPUT8, OUTPUT);
- pinMode(OUTPUT9, OUTPUT);
- pinMode(OUTPUT10, OUTPUT);
- pinMode(OUTPUT11, OUTPUT);
- pinMode(OUTPUT12, OUTPUT);
- pinMode(OUTPUT13, OUTPUT);
- digitalWrite(OUTPUT1, LOW);
- digitalWrite(OUTPUT2, LOW);
- digitalWrite(OUTPUT3, LOW);
- digitalWrite(OUTPUT4, LOW);
- digitalWrite(OUTPUT5, LOW);
- digitalWrite(OUTPUT6, LOW);
- digitalWrite(OUTPUT7, LOW);
- digitalWrite(OUTPUT8, LOW);
- digitalWrite(OUTPUT9, LOW);
- digitalWrite(OUTPUT10, LOW);
- digitalWrite(OUTPUT11, LOW);
- digitalWrite(OUTPUT12, LOW);
- digitalWrite(OUTPUT13, LOW);
- clearArray(collectedPattern, ARRAYLENGTH);
- index = 0;
- Serial.println("Begin");
- }
- void cleanArray(unsigned int arrayIn[], unsigned int arrayOut[], unsigned int numItems) {
- // produce a version of the array that has the first element removed,
- // and checkForMatchesTimerExpired event time added to the subsequent time leading
- // up to another button event
- clearArray(arrayOut, ARRAYLENGTH);
- unsigned int iIn = 1;
- unsigned int iOut = 0;
- while (iIn < numItems) {
- if ( (iIn % 2) == 0) { // if iIn is even contains times
- arrayOut[iOut] = arrayIn[iIn];
- iIn++;
- iOut++;
- }
- else { // if iIn is odd contains events
- if ( arrayIn[iIn] == checkForMatchesTimerExpired && arrayIn[iIn + 1] != 0 && iIn > 1 && iIn < (numItems - 1)) {
- // if a timer expired event is in the middle of the array,
- // combine the time of expired event with time of next event
- // and remove the timer expired event
- arrayOut[iOut - 1] = arrayIn[iIn - 1] + arrayIn[iIn + 1];
- iIn = iIn + 2;
- }
- else {
- arrayOut[iOut] = arrayIn[iIn];
- iIn++;
- iOut++;
- }
- }
- }
- }
- bool mapAndCompareArray(unsigned int arrayIn[], unsigned int arrayMap[], const unsigned int arrayComp[], unsigned int numItems) {
- // produce a version of the cleaned array that has the timings mapped to a range
- // go through the cleaned array and re-range the times and get max time
- unsigned int i = 0;
- unsigned int maxTime = 0;
- while (i < numItems) { // copy array contents, get max time for mapping,
- // and insert 999 for times that should be ignored
- arrayMap[i] = arrayIn[i];
- if ( (i % 2) == 1) { // if i is odd contains times
- if (arrayMap[i] == 999) { // if collected pattern array has time 999 in any
- // position, tweak it so it is not skipped in the mapping
- arrayMap[i] == 998;
- }
- if (pgm_read_word_near(&arrayComp[i]) == 999) { // special position where we need to ignore timing
- arrayMap[i] = 999;
- }
- else if (arrayMap[i] > maxTime) {
- maxTime = arrayMap[i];
- }
- }
- i++;
- }
- // re-range all the times that are between 0 and max time
- // to be between 0 and 100
- i = 0;
- while (i < numItems) {
- if ( (i % 2) == 1) { // if i is odd contains times
- if (arrayMap[i] != 999) {
- arrayMap[i] = map(arrayMap[i], 0, maxTime, 0, 100);
- if (arrayIn[i] != 0 && arrayMap[i] == 0) {
- arrayMap[i] = 1;
- }
- }
- }
- i++;
- }
- // compare arrays up to the end or the first 0 of arrays
- // accept similarities of timing
- // instead of requiring the timing to be exactly the same
- bool same = true;
- unsigned int minVal;
- unsigned int maxVal;
- i = 0;
- while (i < numItems && same && ! (arrayMap[i] == 0 && pgm_read_word_near(&arrayComp[i]) == 0)) {
- if ( (i % 2) == 1) { // if i is odd contains times
- if (arrayMap[i] > ERRORPERCENT) {
- minVal = arrayMap[i] - ERRORPERCENT;
- }
- else {
- minVal = 1;
- }
- maxVal = arrayMap[i] + ERRORPERCENT;
- if (pgm_read_word_near(&arrayComp[i]) >= minVal && pgm_read_word_near(&arrayComp[i]) <= maxVal) {
- same = true;
- }
- else {
- same = false;
- }
- }
- else { // i is even and this element contains event
- same = arrayMap[i] == pgm_read_word_near(&arrayComp[i]);
- }
- i++;
- }
- return same;
- }
- void printFormattedArray(unsigned int arrayIn[], unsigned int numItems) {
- // print array elements up to the end or the first 0
- Serial.print("{");
- unsigned int i = 0;
- while (i < numItems) {
- Serial.print(arrayIn[i]);
- i++;
- if (i == numItems)
- Serial.println("}");
- else
- Serial.print(",");
- }
- }
- void clearArray(unsigned int arrayA[], unsigned int numItems) {
- unsigned int i = 0;
- while (i < numItems) {
- arrayA[i] = 0;
- i++;
- }
- // comment: = we only want to clear the index when
- // clearing the collectedPattern array,
- // not the other arrays
- }
- void appendToArray(unsigned int arrayA[], unsigned int numItems, unsigned int value) {
- if (index < numItems) {
- arrayA[index] = value;
- index++;
- }
- }
- void loop() {
- //Read and debounce switches.
- bool reading1 = ! digitalRead(SWITCHSHALLOW);
- bool reading2 = digitalRead(SWITCHDEEP);
- // check to see if you just pressed the button and reset timer
- if (reading1 != lastButtonState1) {
- lastDebounceTime1 = millis();
- }
- if ((millis() - lastDebounceTime1) > debounceDelay) {
- // whatever the reading is at, it's been there for longer than the debounce
- if (reading1 != buttonState1) {
- buttonState1 = reading1;
- buttonChange1 = true;
- digitalWrite(OUTPUT1, buttonState1);
- }
- }
- // check to see if you just pressed the button and reset timer
- if (reading2 != lastButtonState2) {
- lastDebounceTime2 = millis();
- }
- if ((millis() - lastDebounceTime2) > debounceDelay) {
- // whatever the reading is at, it's been there for longer than the debounce
- if (reading2 != buttonState2) {
- buttonState2 = reading2;
- buttonChange2 = true;
- digitalWrite(OUTPUT2, buttonState2);
- }
- }
- // check for changes of switch states and reset timers
- if ( buttonChange1 ) {
- buttonChange1 = false;
- unsigned long diffmilli = millis() - resetArrayTimer;
- if (diffmilli > 65000) {
- diffmilli = 65000;
- }
- unsigned int diffmillint = (unsigned int) diffmilli;
- appendToArray(collectedPattern, ARRAYLENGTH, diffmillint);
- if ( buttonState1 ) {
- appendToArray(collectedPattern, ARRAYLENGTH, SwitchShallowPressed);
- }
- else {
- appendToArray(collectedPattern, ARRAYLENGTH, SwitchShallowReleased);
- }
- checkForMatchesTimerCounted = false;
- resetArrayTimerCounted = false;
- checkForMatchesTimer = millis();
- resetArrayTimer = millis();
- }
- else if ( buttonChange2 ) {
- buttonChange2 = false;
- unsigned long diffmilli = millis() - resetArrayTimer;
- if (diffmilli > 65000) {
- diffmilli = 65000;
- }
- unsigned int diffmillint = (unsigned int) diffmilli;
- appendToArray(collectedPattern, ARRAYLENGTH, diffmillint);
- if ( buttonState2 ) {
- appendToArray(collectedPattern, ARRAYLENGTH, SwitchDeepPressed);
- }
- else {
- appendToArray(collectedPattern, ARRAYLENGTH, SwitchDeepReleased);
- }
- checkForMatchesTimerCounted = false;
- resetArrayTimerCounted = false;
- checkForMatchesTimer = millis();
- resetArrayTimer = millis();
- }
- // look for timers expired
- // checkForMatchesTimer checks the collectedPattern array for matches
- // against stored patterns 900 ms after the latest button activity
- if ((millis() - checkForMatchesTimer) > checkForMatchesTimerDuration && checkForMatchesTimerCounted == false) {
- checkForMatchesTimerCounted = true;
- unsigned long diffmilli = millis() - checkForMatchesTimer;
- if (diffmilli > 65000) {
- diffmilli = 65000;
- }
- unsigned int diffmillint = (unsigned int) diffmilli;
- appendToArray(collectedPattern, ARRAYLENGTH, diffmillint);
- appendToArray(collectedPattern, ARRAYLENGTH, checkForMatchesTimerExpired);
- // if the checkForMatchesTimer expired we
- // want to execute the following code
- cleanArray(collectedPattern, collectedPatternCleaned, ARRAYLENGTH);
- // step through patternTable and look for a match of
- // cleaned collected pattern against patterns in progmem
- // and exit on first match with index number set to the
- // matched pattern
- for (patternIndex = 0; patternIndex < NUMPATTERNS; patternIndex++) {
- if (mapAndCompareArray(collectedPatternCleaned, collectedPatternMapped, pgm_read_word_near(&(patternTable[patternIndex])), ARRAYLENGTH)) {
- break;
- }
- }
- // use the index number of the matched pattern to do an
- // action
- switch (patternIndex) {
- case 0:
- case 1:
- onHoldShallow = true;
- onHoldDeep = true;
- digitalWrite(OUTPUT3, HIGH);
- digitalWrite(OUTPUT4, HIGH);
- Serial.print("slow-press-and-hold ");
- Serial.println("onHoldShallow and onHoldDeep turned on");
- break;
- case 2:
- onHold5 = true;
- Serial.print("fastPressAndHold ");
- Serial.println("onHold5 turned on");
- digitalWrite(OUTPUT5, HIGH);
- break;
- case 3:
- case 4:
- onHold6 = true;
- Serial.print("dit-dah-and-hold ");
- Serial.println("onHold6 turned on");
- digitalWrite(OUTPUT6, HIGH);
- break;
- case 5:
- case 6:
- onHold7 = true;
- Serial.print("dit-dit-dah-and-hold ");
- Serial.println("onHold7 turned on");
- digitalWrite(OUTPUT7, HIGH);
- break;
- case 7:
- case 8:
- // flip OUTPUT8
- digitalWrite(OUTPUT8, !digitalRead(OUTPUT8));
- Serial.println("dit");
- break;
- case 9:
- case 10:
- // turn on OUTPUT9 and set a timer to turn it off in 1 second
- digitalWrite(OUTPUT9, HIGH);
- output9Timer = millis();
- output9TimerDuration = 1000;
- output9TimerCounted = false;
- Serial.println("dit-dit");
- break;
- case 11:
- case 12:
- // turn on OUTPUT10 and set a timer to turn it off in 2 second
- digitalWrite(OUTPUT10, HIGH);
- output10Timer = millis();
- output10TimerDuration = 2000;
- output10TimerCounted = false;
- Serial.println("dit-dit-dit");
- break;
- case 13:
- case 14:
- // flip OUTPUT11
- digitalWrite(OUTPUT11, !digitalRead(OUTPUT11));
- Serial.println("dah-dit");
- break;
- case 15:
- case 16:
- // flip OUTPUT12
- digitalWrite(OUTPUT12, !digitalRead(OUTPUT12));
- Serial.println("dah-dit-dit");
- break;
- case 17:
- case 18:
- case 19:
- // flip OUTPUT13
- digitalWrite(OUTPUT13, !digitalRead(OUTPUT13));
- Serial.println("dit-dah-dit");
- break;
- case NUMPATTERNS:
- Serial.println("no match found");
- printFormattedArray(collectedPatternMapped, ARRAYLENGTH);
- break;
- }
- }
- if ((millis() - resetArrayTimer) > resetArrayTimerDuration && resetArrayTimerCounted == false) {
- // If a button is depressed, the longest timer expired event is
- // not used. This is because this is where we clear the collected
- // pattern array, and we don't want to do that if extended events
- // may occur with button depressed. Those events may go on until
- // the button is released.
- if ( buttonState1 || buttonState2 ) {
- resetArrayTimerCounted = true;
- }
- else {
- resetArrayTimerCounted = true;
- // clear out the collected pattern array and start the index
- // back to 0, waiting for the first event to be added to it.
- clearArray(collectedPattern, ARRAYLENGTH);
- index = 0;
- }
- }
- // turn off OUTPUT9 if it has been on for a while
- if ((millis() - output9Timer) > output9TimerDuration && output9TimerCounted == false) {
- output9TimerCounted = true;
- digitalWrite(OUTPUT9, LOW);
- }
- // turn off OUTPUT10 if it has been on for a while
- if ((millis() - output10Timer) > output10TimerDuration && output10TimerCounted == false) {
- output10TimerCounted = true;
- digitalWrite(OUTPUT10, LOW);
- }
- // look for actions that need to be taken as soon as button is released
- if ( ! buttonState1 && ! buttonState2 && onHold5) {
- onHold5 = false;
- Serial.println("onHold5 turned off");
- digitalWrite(OUTPUT5, LOW);
- // clear out the collected pattern array and start the index
- // back to 0, waiting for the first event to be added to it.
- // and stop looking for timer expirations
- checkForMatchesTimerCounted = true;
- resetArrayTimerCounted = true;
- clearArray(collectedPattern, ARRAYLENGTH);
- index = 0;
- }
- if ( ! buttonState1 && ! buttonState2 && onHold6) {
- onHold6 = false;
- Serial.println("onHold6 turned off");
- digitalWrite(OUTPUT6, LOW);
- // clear out the collected pattern array and start the index
- // back to 0, waiting for the first event to be added to it.
- // and stop looking for timer expirations
- checkForMatchesTimerCounted = true;
- resetArrayTimerCounted = true;
- clearArray(collectedPattern, ARRAYLENGTH);
- index = 0;
- }
- if ( ! buttonState1 && ! buttonState2 && onHold7) {
- onHold7 = false;
- Serial.println("onHold7 turned off");
- digitalWrite(OUTPUT7, LOW);
- // clear out the collected pattern array and start the index
- // back to 0, waiting for the first event to be added to it.
- // and stop looking for timer expirations
- checkForMatchesTimerCounted = true;
- resetArrayTimerCounted = true;
- clearArray(collectedPattern, ARRAYLENGTH);
- index = 0;
- }
- // onHoldShallow and onHoldDeep is regulating the releasing
- // of button for pass through of cruise control setting
- if ( ! buttonState1 && ! buttonState2 && onHoldShallow) {
- onHoldShallow = false;
- digitalWrite(OUTPUT3, LOW);
- Serial.println("onHoldShallow turned off");
- // clear out the collected pattern array and start the index
- // back to 0, waiting for the first event to be added to it.
- // and stop looking for timer expirations
- checkForMatchesTimerCounted = true;
- resetArrayTimerCounted = true;
- clearArray(collectedPattern, ARRAYLENGTH);
- index = 0;
- }
- if ( buttonState1 && ! buttonState2 && onHoldDeep) {
- onHoldDeep = false;
- digitalWrite(OUTPUT4, LOW);
- Serial.println("onHoldDeep turned off");
- // clear out the collected pattern array and start the index
- // back to 0, waiting for the first event to be added to it.
- // and stop looking for timer expirations
- checkForMatchesTimerCounted = true;
- resetArrayTimerCounted = true;
- clearArray(collectedPattern, ARRAYLENGTH);
- index = 0;
- }
- // more debounce code
- lastButtonState1 = reading1;
- lastButtonState2 = reading2;
- } // end of loop
Add Comment
Please, Sign In to add comment