Browse Source

Inital version

- Display speed based on hall sensor
- Display fake battery level
Alexey Edelev 5 years ago
parent
commit
de7e4f4d73

+ 150 - 0
Arduino/eScooterControl/display.cpp

@@ -0,0 +1,150 @@
+/*
+ * 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 "display.h"
+
+#include "pinconfig.h"
+
+#include <avr/pgmspace.h>
+
+const PROGMEM byte BatteryLevel = B00000010;
+
+const PROGMEM byte Digit[10][5] = {
+  {
+    B00000111,
+    B00000101,
+    B00000101,
+    B00000101,
+    B00000111
+  },{
+    B00000110,
+    B00000101,
+    B00000100,
+    B00000100,
+    B00000100
+  },{
+    B00000111,
+    B00000100,
+    B00000111,
+    B00000001,
+    B00000111
+  },{
+    B00000111,
+    B00000100,
+    B00000111,
+    B00000100,
+    B00000111
+  },{
+    B00000101,
+    B00000101,
+    B00000111,
+    B00000100,
+    B00000100
+  },{
+    B00000111,
+    B00000001,
+    B00000111,
+    B00000100,
+    B00000111
+  },{
+    B00000111,
+    B00000001,
+    B00000111,
+    B00000101,
+    B00000111
+  },{
+    B00000111,
+    B00000100,
+    B00000110,
+    B00000001,
+    B00000001
+  },{
+    B00000111,
+    B00000101,
+    B00000111,
+    B00000101,
+    B00000111
+  },{
+    B00000111,
+    B00000101,
+    B00000111,
+    B00000100,
+    B00000111
+  }
+};
+
+Display::Display() : mLedControl(DisplayDataPin, DisplayClkPin, DisplayCsPin,1)
+ ,mDisplayBuffer({
+  B00000000,
+  B00000000,
+  B00000000,
+  B00000000,
+  B00000000,
+  B00000000,
+  B00000000,
+  B00000000})
+{
+  mLedControl.shutdown(0, false);
+  mLedControl.setIntensity(0, 0);
+  mLedControl.clearDisplay(0);  
+}
+
+void Display::drawSpeed(unsigned char number)
+{
+  if (number > 99) {
+    number = 99;
+  }
+  unsigned char tens = number / 10;
+  unsigned char ones = number % 10;
+
+  for (int i = 0; i < 5; i++) {
+    mDisplayBuffer[i] = 0;
+    byte tensDigit = pgm_read_byte(&(Digit[tens][i]));
+    byte onesDigit = pgm_read_byte(&(Digit[ones][i]));
+    mDisplayBuffer[i] |= (tensDigit | onesDigit << 4);
+  }
+}
+
+void Display::drawBatteryLevel(unsigned char level)
+{ 
+  if (level > 5) {
+    level = 5;
+  }
+
+  mDisplayBuffer[6] = 0;
+  mDisplayBuffer[7] = 0;
+
+  byte batteryLevelChar = pgm_read_byte(&(BatteryLevel));
+  for (unsigned char i = 0; i < level; ++i) {
+    mDisplayBuffer[6] |= batteryLevelChar << i;
+    mDisplayBuffer[7] |= batteryLevelChar << (i + 1);
+  }
+}
+
+void Display::updateDisplayBuffer()
+{
+  for(int i = 0; i < 8; i++) {
+    mLedControl.setColumn(0, i, mDisplayBuffer[i]);    
+  }
+}

+ 44 - 0
Arduino/eScooterControl/display.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"
+
+#include <LedControl.h>
+
+class Display : public Singleton<Display>
+{
+public:
+  void drawSpeed(unsigned char number);
+  void drawBatteryLevel(unsigned char level);
+  void updateDisplayBuffer();
+
+private:
+  Display();
+  friend class Singleton;
+
+  byte mDisplayBuffer[8];
+  LedControl mLedControl;
+};

+ 59 - 0
Arduino/eScooterControl/eScooterControl.ino

@@ -0,0 +1,59 @@
+/*
+ * 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 "thread.h"
+#include "display.h"
+#include "speedometer.h"
+
+/* we always wait a bit between updates of the display */
+const unsigned long DisplayUpdateTime = 500;
+const unsigned long BatteryUpdateTime = 1000;
+
+Thread gDisplayThread = Thread(DisplayUpdateTime);
+Thread gBatteryThread = Thread(BatteryUpdateTime);
+
+unsigned char fakeBatteryLevel = 0;
+
+void setup() {
+  Speedometer::instance()->attachToDisplay(Display::instance());
+  
+  gDisplayThread.assignCallback([](){
+    Display::instance()->updateDisplayBuffer();
+  });
+
+  gBatteryThread.assignCallback([](){
+    Display::instance()->drawBatteryLevel(fakeBatteryLevel);
+    fakeBatteryLevel++;
+    if (fakeBatteryLevel > 5) {
+      fakeBatteryLevel = 0;
+    }
+  });
+  
+  pinMode(3, OUTPUT);
+  digitalWrite(3, LOW);
+}
+
+void loop() {
+  Thread::dispatch();
+}

+ 31 - 0
Arduino/eScooterControl/pinconfig.h

@@ -0,0 +1,31 @@
+/*
+ * 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
+
+const int HallSensorPin = 2;
+
+const int DisplayDataPin = 10;
+const int DisplayClkPin = 11;
+const int DisplayCsPin = 12;

+ 44 - 0
Arduino/eScooterControl/singleton.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
+
+template<typename T>
+class Singleton
+{
+public:
+  static T *instance() {
+    static T _instance;
+    return &_instance;
+  }
+  
+protected:
+  Singleton() = default;
+
+private:
+  Singleton(const Singleton&) = delete;
+  Singleton(const Singleton&&) = delete;
+  Singleton& operator=(const Singleton&) = delete;
+  Singleton& operator=(const Singleton&&) = delete;
+};

+ 66 - 0
Arduino/eScooterControl/speedometer.cpp

@@ -0,0 +1,66 @@
+/*
+ * 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 "speedometer.h"
+
+#include "pinconfig.h"
+#include "display.h"
+
+/*
+ * Tire diameter = 0.2159 meters
+ * Tile length = pi*d = 0.6783 meters
+ * Tire length in hour = 3600.0 * Tile length = 2441.88
+ */
+
+const float TireLength = 0.6783;
+const float TireLengthCoef = 2441.88;
+
+void callback() {
+  Speedometer::instance()->incrementHallCounter();
+}
+
+Speedometer::Speedometer() : mMomentSpeed(0)
+ ,mLastHallTime(0)
+ ,mHallCounter(0)
+ ,mDisplay(nullptr)
+{
+  pinMode(HallSensorPin, INPUT_PULLUP);
+  attachInterrupt(digitalPinToInterrupt(HallSensorPin), callback, RISING);
+}
+
+void Speedometer::attachToDisplay(Display *display) {
+  mDisplay = display;
+}
+
+void Speedometer::incrementHallCounter()
+{
+  mHallCounter++;
+  unsigned long currentTime = millis();
+  mMomentSpeed = TireLengthCoef/(currentTime - mLastHallTime);
+  mLastHallTime = currentTime;
+
+  if (mDisplay != nullptr) {
+    mDisplay->drawSpeed(mMomentSpeed);
+  }
+}

+ 45 - 0
Arduino/eScooterControl/speedometer.h

@@ -0,0 +1,45 @@
+/*
+ * 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 Display;
+
+class Speedometer : public Singleton<Speedometer> {
+public:
+  void attachToDisplay(Display *display);
+  void incrementHallCounter();
+
+private:
+  Speedometer();
+  friend class Singleton;
+  
+  unsigned int mMomentSpeed;
+  unsigned long mLastHallTime;
+  unsigned int mHallCounter;//TODO: Not used for now, need for moment speed correction
+  
+  Display *mDisplay;
+};

+ 54 - 0
Arduino/eScooterControl/thread.cpp

@@ -0,0 +1,54 @@
+/*
+ * 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 "thread.h"
+
+unsigned char Thread::sThreadSlots = 0;
+Thread* Thread::sThreadPool[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
+
+Thread::Thread(unsigned long delay) : mDelay(delay)
+ ,mCallback(nullptr)
+{
+  if (sThreadSlots < 8) {
+    sThreadPool[sThreadSlots++] = this;
+  }
+}
+
+void Thread::dispatchThread()
+{
+  unsigned long time = millis();
+  unsigned long delay = time - mLastCallTime;
+  if (delay >= mDelay) {
+    mCallback(delay);
+    mLastCallTime = time;
+  }
+}
+
+void Thread::dispatch() {
+  for (unsigned char i = 0; i < sThreadSlots; i++) {
+    if (sThreadPool[i] != nullptr) {
+      sThreadPool[i]->dispatchThread();
+    }
+  }
+}

+ 54 - 0
Arduino/eScooterControl/thread.h

@@ -0,0 +1,54 @@
+/*
+ * 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
+
+#if defined(ARDUINO) && ARDUINO >= 100
+  #include <Arduino.h>
+#else
+  #include <WProgram.h>
+#endif
+
+typedef void (*threadCallback)(unsigned long);
+
+class Thread {
+public:
+  Thread(unsigned long delay = 0); 
+
+  void assignCallback(threadCallback callback) {
+    mCallback = callback;
+  }
+  
+  static void dispatch();
+
+private:
+  void dispatchThread();
+
+  unsigned long mDelay;
+  threadCallback mCallback;
+  unsigned long mLastCallTime;
+  
+  static unsigned char sThreadSlots;
+  static Thread* sThreadPool[8];
+};