Browse Source

Implement button handling

- Add power button handling
- Add led switch logic
- Code cleanup
Alexey Edelev 4 years ago
parent
commit
e81d1369c0

+ 86 - 0
Arduino/eScooterControl/buttoncontrol.cpp

@@ -0,0 +1,86 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of eScooterControl project https://github.com/semlanik/eScooterControl
+ *
+ * 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.
+ */
+
+#include "buttoncontrol.h"
+#include "pinconfig.h"
+
+const unsigned long ReactionTime = 700;
+
+/*
+ * Do not use interruption here because film buttons have false positives in case of bad contact. 
+ * It's better to dispatch them frequently and count positives manually by digitalRead
+ */
+ButtonControl::ButtonControl() : m_triggers(0)
+   ,m_triggerTime(0)
+   ,m_previousState(HIGH)
+   ,m_ledState(LOW)
+{
+  pinMode(LedPin, OUTPUT);
+  pinMode(PowerPin, OUTPUT);
+  pinMode(ButtonPin, INPUT_PULLUP);
+}
+
+void ButtonControl::dispatch() {
+  int state = digitalRead(ButtonPin);
+  if (m_previousState == HIGH && state == LOW) {
+    if (m_triggers == 0) {
+      m_triggerTime = millis();
+    }
+    ++m_triggers;
+  }
+
+  m_previousState = state;
+
+  unsigned long currentTime = millis();
+
+  if ((currentTime - m_triggerTime) >= ReactionTime) {
+    if (m_triggers == 1 && state == LOW) {
+//      Serial.println("Power off");
+      digitalWrite(PowerPin, HIGH);
+    } else if (m_triggers == 1 && state == HIGH) {
+//      Serial.println("Toggle led");
+      toggleLedState();
+    } else if (m_triggers == 2 && state == HIGH) {
+//      Serial.println("Toggle eco");
+      //TODO: Enable eco mode
+    }
+    
+    if (state == HIGH) {
+      //Action finished reset number of triggers
+      m_triggers = 0;
+    }
+  }
+}
+
+void ButtonControl::toggleLedState()
+{
+  if (m_ledState == HIGH) {
+    m_ledState = LOW;
+  } else {
+    m_ledState = HIGH;
+  }
+
+  digitalWrite(LedPin, m_ledState);
+}

+ 44 - 0
Arduino/eScooterControl/buttoncontrol.h

@@ -0,0 +1,44 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of eScooterControl project https://github.com/semlanik/eScooterControl
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include "singleton.h"
+
+class ButtonControl : public Singleton<ButtonControl>
+{
+public:
+  void dispatch();
+  void toggleLedState();
+
+private:
+  friend class Singleton;
+  ButtonControl();
+
+  unsigned int m_triggers;
+  unsigned long m_triggerTime;
+  int m_previousState;
+  int m_ledState;
+};

+ 8 - 0
Arduino/eScooterControl/eScooterControl.ino

@@ -26,15 +26,18 @@
 #include "display.h"
 #include "speedometer.h"
 #include "accelerationcontrol.h"
+#include "buttoncontrol.h"
 
 /* we always wait a bit between updates of the display */
 const unsigned long AcceleratorPedalUpdateTime = 200;
 const unsigned long DisplayUpdateTime = 250;
 const unsigned long BatteryUpdateTime = 1000;
+const unsigned long ButtonHandlingTime = 50;
 
 Thread gDisplayThread = Thread(DisplayUpdateTime);
 Thread gBatteryThread = Thread(BatteryUpdateTime);
 Thread gAcceleratorPedalThread = Thread(AcceleratorPedalUpdateTime);
+Thread gButtonThread = Thread(ButtonHandlingTime);
 
 unsigned char fakeBatteryLevel = 0;
 
@@ -64,6 +67,11 @@ void setup() {
       fakeBatteryLevel = 0;
     }
   });
+
+  ButtonControl::instance();
+  gButtonThread.assignCallback([](unsigned long){
+    ButtonControl::instance()->dispatch();
+  });
 //  Serial.println("Init complete");
 }
 

+ 7 - 1
Arduino/eScooterControl/pinconfig.h

@@ -30,6 +30,12 @@
   #include <WProgram.h>
 #endif
 
+
+const int ButtonPin = 4;
+const int PowerPin = 5;
+
+const int LedPin = 6;
+
 const int HallSensorPin = 2;
 const int PulsePerCircle = 45;
 
@@ -45,6 +51,6 @@ const int AcceleratorSensorPin = A0;
 const int AcceleratorSensorDiff = 548;
 const int AcceleratorSensorStep = 10;
 
-const int CruiseTime = 3000; //milliseconds
+const int CruiseTime = 3000; //ms
 
 const uint8_t AcceleratorAddress = 0x60;

+ 2 - 0
Arduino/eScooterControl/speedometer.cpp

@@ -36,9 +36,11 @@
 const float TireLength = 0.6783;
 const float TireLengthCoef = 2441.88;
 
+namespace {
 void callback() {
   Speedometer::instance()->incrementHallCounter();
 }
+}
 
 Speedometer::Speedometer() : mMomentSpeed(0)
  ,mLastHallTime(0)