From 2abf99fab8da94b5a1c92760cceab1c090e712be Mon Sep 17 00:00:00 2001 From: Nitek Date: Sun, 7 Jun 2020 19:25:50 +0200 Subject: [PATCH] Split code --- Cache.ino | 239 +++------------------------------------------- Colors.h | 13 +++ LedNavigation.cpp | 96 +++++++++++++++++++ LedNavigation.h | 27 ++++++ Logbook.cpp | 5 + Logbook.h | 11 +++ Rfid.cpp | 16 ++++ Rfid.h | 16 ++++ Stage.h | 10 ++ Tilt.cpp | 91 ++++++++++++++++++ Tilt.h | 30 ++++++ 11 files changed, 329 insertions(+), 225 deletions(-) create mode 100644 Colors.h create mode 100644 LedNavigation.cpp create mode 100644 LedNavigation.h create mode 100644 Logbook.cpp create mode 100644 Logbook.h create mode 100644 Rfid.cpp create mode 100644 Rfid.h create mode 100644 Stage.h create mode 100644 Tilt.cpp create mode 100644 Tilt.h diff --git a/Cache.ino b/Cache.ino index fead6d7..4d0d75c 100644 --- a/Cache.ino +++ b/Cache.ino @@ -6,6 +6,12 @@ #include #include #include +#include "Stage.h" +#include "Colors.h" +#include "Tilt.h" +#include "LedNavigation.h" +#include "Rfid.h" +#include "Logbook.h" /** @@ -31,32 +37,13 @@ NeoPixelBus ring(LED_COUNT, LED_PIN); TinyGPSPlus gps; QMC5883LCompass compass; LSM6DS3 gyro; -MFRC522 mfrc522(RC522_CS_PIN, RC522_RST_PIN); // Create MFRC522 instance +MFRC522 mfrc522(RC522_CS_PIN, RC522_RST_PIN); -#define O_X_DOWN 0x01 -#define O_X_UP 0x02 -#define O_Y_DOWN 0x04 -#define O_Y_UP 0x08 -#define O_Z_DOWN 0x10 -#define O_Z_UP 0x20 -uint8_t currentOrientation; +uint8_t currentStage = 0; +std::vector stages{new Tilt(gyro, ring), new LedNavigation(compass, gps, ring), new Rfid(mfrc522), new Logbook()}; +Stage* stage = stages[0]; -#define colorSaturation 4 -RgbColor red(colorSaturation, 0, 0); -RgbColor green(0, colorSaturation, 0); -RgbColor blue(0, 0, colorSaturation); -RgbColor white(colorSaturation); -RgbColor black(0); - -bool blinker = false; - -uint8_t stage = 0; - -uint8_t tiltSequence[] = {O_Z_DOWN, O_Y_DOWN, O_Z_DOWN, O_X_UP, O_Y_DOWN, O_Z_DOWN, 0x00}; -uint8_t tiltPointer = 0; - -const double TARGET_LAT = 48.4168602, TARGET_LON = 9.9433157; void setup() { @@ -69,25 +56,6 @@ void setup() ring.Begin(); ring.Show(); - //Over-ride default settings if desired - gyro.settings.gyroEnabled = 1; //Can be 0 or 1 - gyro.settings.gyroRange = 2000; //Max deg/s. Can be: 125, 245, 500, 1000, 2000 - gyro.settings.gyroSampleRate = 104; //Hz. Can be: 13, 26, 52, 104, 208, 416, 833, 1666 - gyro.settings.gyroBandWidth = 200; //Hz. Can be: 50, 100, 200, 400; - - gyro.settings.accelEnabled = 1; - gyro.settings.accelRange = 16; //Max G force readable. Can be: 2, 4, 8, 16 - gyro.settings.accelSampleRate = 833; //Hz. Can be: 13, 26, 52, 104, 208, 416, 833, 1666, 3332, 6664, 13330 - gyro.settings.accelBandWidth = 200; //Hz. Can be: 50, 100, 200, 400; - - // Set orientation threshold - gyro.writeRegister(LSM6DS3_ACC_GYRO_TAP_THS_6D, LSM6DS3_ACC_GYRO_SIXD_THS_60_degree); - // Enable low pass filter 2 - gyro.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x10); - gyro.writeRegister(LSM6DS3_ACC_GYRO_CTRL8_XL, 0x01); - // Enable interrupt - gyro.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, LSM6DS3_ACC_GYRO_INT1_6D_ENABLED); - gyro.begin(); compass.init(); @@ -112,189 +80,10 @@ void setup() void loop() { - switch(stage) { - case 0: - stageTilt(); - break; - case 1: - stageGotoPlayground(); - break; - default: - Serial.println("Not implemented!"); - } - - smartDelay(1000); - - if (millis() > 5000 && gps.charsProcessed() < 10) - Serial.println(F("No GPS data received: check wiring")); -} - -void smartDelay(unsigned long ms) -{ - unsigned long start = millis(); - do - { - while (Serial2.available()) - gps.encode(Serial2.read()); - stageRfid(); - } while (millis() - start < ms); + stage->handle(); } -void printDateTime(TinyGPSDate &d, TinyGPSTime &t) -{ - if (d.isValid()) - { - char sz[32]; - sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year()); - Serial.print(sz); - } - - if (t.isValid()) - { - char sz[32]; - sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second()); - Serial.print(sz); - } +void nextStage() { + stage = stages[currentStage++]; + stage->init(); } - -void stageTilt() { - uint8_t orientation; - gyro.readRegister(&orientation, LSM6DS3_ACC_GYRO_D6D_SRC); - - if(currentOrientation == orientation) { - return; - } - - currentOrientation = orientation; - - if(orientation == tiltSequence[tiltPointer]) { - tiltPointer++; - if(tiltSequence[tiltPointer] == 0) { - for(uint8_t i = 0; i < 10; i++) { - ring.ClearTo(white); - ring.Show(); - smartDelay(200); - ring.ClearTo(green); - ring.Show(); - smartDelay(200); - } - return; - } - ring.ClearTo(black); - ring.Show(); - smartDelay(500); - ring.ClearTo(green); - ring.Show(); - return; - } - - tiltPointer = 0; - ring.ClearTo(red); - ring.Show(); - - /*switch(orientation){ - case O_X_DOWN: - Serial.println("X down"); - break; - case O_X_UP: - Serial.println("X up"); - break; - case O_Y_DOWN: - Serial.println("Y down"); - break; - case O_Y_UP: - Serial.println("Y up"); - break; - case O_Z_DOWN: - Serial.println("Z down"); - break; - case O_Z_UP: - Serial.println("Z up"); - break; - default: - Serial.println("Unknown orientation"); - } - - - char orientationString[9]; - itoa(orientation, orientationString, 2); - Serial.print("\nOrientation:\n"); - Serial.printf("%s", orientationString);*/ -} - -void stageGotoPlayground() { - compass.read(); - - printDateTime(gps.date, gps.time); - - if(gps.satellites.isValid()) - { - Serial.printf("%d ", gps.satellites.value()); - } - - ring.ClearTo(black); - - if(gps.location.isValid()) { - Serial.printf("%f, %f, a: %d", gps.location.lat(), gps.location.lng(), gps.location.age()); - Serial.println(); - - unsigned long distanceMeters = - (unsigned long)TinyGPSPlus::distanceBetween( - gps.location.lat(), - gps.location.lng(), - TARGET_LAT, - TARGET_LON); - - int16_t course = - TinyGPSPlus::courseTo( - gps.location.lat(), - gps.location.lng(), - TARGET_LAT, - TARGET_LON); - - - int16_t azimuth = compass.getAzimuth(); - - char myArray[3]; - compass.getDirection(myArray, azimuth); - - Serial.print(" Azimuth: "); - Serial.print(azimuth); - Serial.print(" Direction: "); - Serial.print(myArray[0]); - Serial.print(myArray[1]); - Serial.print(myArray[2]); - - // Offset between LED #0 and azimuth == 0 - int16_t ledOffset = 90; - - Serial.printf(" d: %lu c: %d ang: %d", distanceMeters, course, (uint16_t)round(azimuth + ledOffset + course + 11.25f)); - - uint16_t ledIndex = (uint16_t)round((azimuth + ledOffset + course + 11.25f)/22.5) % 16; - ring.SetPixelColor(ledIndex, green); - } else { - if(blinker) { - ring.ClearTo(red); - } - blinker = !blinker; - } - Serial.println(); - Serial.println(); - - ring.Show(); -} - -void stageRfid() { - // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. - if ( ! mfrc522.PICC_IsNewCardPresent()) { - return; - } - - // Select one of the cards - if ( ! mfrc522.PICC_ReadCardSerial()) { - return; - } - - // Dump debug info about the card; PICC_HaltA() is automatically called - mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); -} \ No newline at end of file diff --git a/Colors.h b/Colors.h new file mode 100644 index 0000000..35a4901 --- /dev/null +++ b/Colors.h @@ -0,0 +1,13 @@ +#ifndef Colors_h +#define Colors_h + +#include + +#define colorSaturation 4 +const RgbColor red(colorSaturation, 0, 0); +const RgbColor green(0, colorSaturation, 0); +const RgbColor blue(0, 0, colorSaturation); +const RgbColor white(colorSaturation); +const RgbColor black(0); + +#endif \ No newline at end of file diff --git a/LedNavigation.cpp b/LedNavigation.cpp new file mode 100644 index 0000000..5b43b59 --- /dev/null +++ b/LedNavigation.cpp @@ -0,0 +1,96 @@ +#include "LedNavigation.h" + +void LedNavigation::handle() { + _compass.read(); + + _printDateTime(_gps.date, _gps.time); + + if(_gps.satellites.isValid()) + { + Serial.printf("%d ", _gps.satellites.value()); + } + + _ring.ClearTo(black); + + if(_gps.location.isValid()) { + Serial.printf("%f, %f, a: %d", _gps.location.lat(), _gps.location.lng(), _gps.location.age()); + Serial.println(); + + unsigned long distanceMeters = + (unsigned long)TinyGPSPlus::distanceBetween( + _gps.location.lat(), + _gps.location.lng(), + TARGET_LAT, + TARGET_LON); + + int16_t course = + TinyGPSPlus::courseTo( + _gps.location.lat(), + _gps.location.lng(), + TARGET_LAT, + TARGET_LON); + + + int16_t azimuth = _compass.getAzimuth(); + + char myArray[3]; + _compass.getDirection(myArray, azimuth); + + Serial.print(" Azimuth: "); + Serial.print(azimuth); + Serial.print(" Direction: "); + Serial.print(myArray[0]); + Serial.print(myArray[1]); + Serial.print(myArray[2]); + + // Offset between LED #0 and azimuth == 0 + int16_t ledOffset = 90; + + Serial.printf(" d: %lu c: %d ang: %d", distanceMeters, course, (uint16_t)round(azimuth + ledOffset + course + 11.25f)); + + uint16_t ledIndex = (uint16_t)round((azimuth + ledOffset + course + 11.25f)/22.5) % 16; + _ring.SetPixelColor(ledIndex, green); + } else { + if(_blinker) { + _ring.ClearTo(red); + } + _blinker = !_blinker; + } + Serial.println(); + Serial.println(); + + _ring.Show(); + + _smartDelay(500); + + if (millis() > 5000 && _gps.charsProcessed() < 10) { + Serial.println(F("No GPS data received: check wiring")); + } +}; + + +void LedNavigation::_smartDelay(unsigned long ms) { + unsigned long start = millis(); + do + { + while (Serial2.available()) { + _gps.encode(Serial2.read()); + } + } while (millis() - start < ms); +}; + +void LedNavigation::_printDateTime(TinyGPSDate &d, TinyGPSTime &t) { + if (d.isValid()) + { + char sz[32]; + sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year()); + Serial.print(sz); + } + + if (t.isValid()) + { + char sz[32]; + sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second()); + Serial.print(sz); + } +}; diff --git a/LedNavigation.h b/LedNavigation.h new file mode 100644 index 0000000..e59d7a3 --- /dev/null +++ b/LedNavigation.h @@ -0,0 +1,27 @@ +#ifndef LedNavigation_h +#define LedNavigation_h + +#include +#include +#include +#include +#include "Stage.h" +#include "Colors.h" + +class LedNavigation: public Stage { + public: + LedNavigation(QMC5883LCompass &compass, TinyGPSPlus &gps, NeoPixelBus &ring): _compass(compass), _gps(gps), _ring(ring) + {}; + void handle(); + private: + const double TARGET_LAT = 48.4168602; + const double TARGET_LON = 9.9433157; + bool _blinker = false; + QMC5883LCompass _compass; + TinyGPSPlus _gps; + NeoPixelBus _ring; + void _smartDelay(unsigned long ms); + void _printDateTime(TinyGPSDate &d, TinyGPSTime &t); +}; + +#endif \ No newline at end of file diff --git a/Logbook.cpp b/Logbook.cpp new file mode 100644 index 0000000..6d814c1 --- /dev/null +++ b/Logbook.cpp @@ -0,0 +1,5 @@ +#include "Logbook.h" + +void Logbook::handle() { + // TODO start Hotspot and Webserver +}; \ No newline at end of file diff --git a/Logbook.h b/Logbook.h new file mode 100644 index 0000000..3a1d0b1 --- /dev/null +++ b/Logbook.h @@ -0,0 +1,11 @@ +#ifndef Logbook_h +#define Logbook_h + +#include "Stage.h" + +class Logbook: public Stage { + public: + void handle(); +}; + +#endif \ No newline at end of file diff --git a/Rfid.cpp b/Rfid.cpp new file mode 100644 index 0000000..23dd358 --- /dev/null +++ b/Rfid.cpp @@ -0,0 +1,16 @@ +#include "Rfid.h" + +void Rfid::handle() { + // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. + if ( ! _mfrc522.PICC_IsNewCardPresent()) { + return; + } + + // Select one of the cards + if ( ! _mfrc522.PICC_ReadCardSerial()) { + return; + } + + // Dump debug info about the card; PICC_HaltA() is automatically called + _mfrc522.PICC_DumpToSerial(&(_mfrc522.uid)); +}; \ No newline at end of file diff --git a/Rfid.h b/Rfid.h new file mode 100644 index 0000000..5f04046 --- /dev/null +++ b/Rfid.h @@ -0,0 +1,16 @@ +#ifndef Rfid_h +#define Rfid_h + +#include "Stage.h" +#include + +class Rfid: public Stage { + public: + Rfid(MFRC522 &mfrc522): _mfrc522(mfrc522) + {}; + void handle(); + private: + MFRC522 _mfrc522; +}; + +#endif \ No newline at end of file diff --git a/Stage.h b/Stage.h new file mode 100644 index 0000000..992598a --- /dev/null +++ b/Stage.h @@ -0,0 +1,10 @@ +#ifndef Stage_h +#define Stage_h + +class Stage { + public: + virtual void init() {}; + virtual void handle(); +}; + +#endif \ No newline at end of file diff --git a/Tilt.cpp b/Tilt.cpp new file mode 100644 index 0000000..bb7d4f0 --- /dev/null +++ b/Tilt.cpp @@ -0,0 +1,91 @@ +#include + +void Tilt::init() { + + _gyro.writeRegister(LSM6DS3_ACC_GYRO_CTRL3_C, LSM6DS3_ACC_GYRO_SW_RESET_RESET_DEVICE); + + //Over-ride default settings if desired + _gyro.settings.gyroEnabled = 1; //Can be 0 or 1 + _gyro.settings.gyroRange = 2000; //Max deg/s. Can be: 125, 245, 500, 1000, 2000 + _gyro.settings.gyroSampleRate = 104; //Hz. Can be: 13, 26, 52, 104, 208, 416, 833, 1666 + _gyro.settings.gyroBandWidth = 200; //Hz. Can be: 50, 100, 200, 400; + + _gyro.settings.accelEnabled = 1; + _gyro.settings.accelRange = 16; //Max G force readable. Can be: 2, 4, 8, 16 + _gyro.settings.accelSampleRate = 833; //Hz. Can be: 13, 26, 52, 104, 208, 416, 833, 1666, 3332, 6664, 13330 + _gyro.settings.accelBandWidth = 200; //Hz. Can be: 50, 100, 200, 400; + + _gyro.begin(); + + // Set orientation threshold + _gyro.writeRegister(LSM6DS3_ACC_GYRO_TAP_THS_6D, LSM6DS3_ACC_GYRO_SIXD_THS_60_degree); + // Enable low pass filter 2 + _gyro.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x10); + _gyro.writeRegister(LSM6DS3_ACC_GYRO_CTRL8_XL, 0x01); + // Enable interrupt + _gyro.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, LSM6DS3_ACC_GYRO_INT1_6D_ENABLED); +}; + +void Tilt::handle() { + uint8_t orientation; + _gyro.readRegister(&orientation, LSM6DS3_ACC_GYRO_D6D_SRC); + + if(_currentOrientation == orientation) { + return; + } + + _currentOrientation = orientation; + + if(orientation == _tiltSequence[_tiltPointer++]) { + if(_tiltSequence.size() == _tiltPointer) { + for(uint8_t i = 0; i < 10; i++) { + _ring.ClearTo(white); + _ring.Show(); + sleep(200); + _ring.ClearTo(green); + _ring.Show(); + sleep(200); + } + return; + } + _ring.ClearTo(black); + _ring.Show(); + sleep(500); + _ring.ClearTo(green); + _ring.Show(); + return; + } + + _tiltPointer = 0; + _ring.ClearTo(red); + _ring.Show(); + + /*switch(orientation){ + case O_X_DOWN: + Serial.println("X down"); + break; + case O_X_UP: + Serial.println("X up"); + break; + case O_Y_DOWN: + Serial.println("Y down"); + break; + case O_Y_UP: + Serial.println("Y up"); + break; + case O_Z_DOWN: + Serial.println("Z down"); + break; + case O_Z_UP: + Serial.println("Z up"); + break; + default: + Serial.println("Unknown orientation"); + } + + + char orientationString[9]; + itoa(orientation, orientationString, 2); + Serial.print("\nOrientation:\n"); + Serial.printf("%s", orientationString);*/ +}; \ No newline at end of file diff --git a/Tilt.h b/Tilt.h new file mode 100644 index 0000000..334129f --- /dev/null +++ b/Tilt.h @@ -0,0 +1,30 @@ +#ifndef Tilt_h +#define Tilt_h + +#include +#include +#include "Stage.h" +#include "Colors.h" + +#define O_X_DOWN 0x01 +#define O_X_UP 0x02 +#define O_Y_DOWN 0x04 +#define O_Y_UP 0x08 +#define O_Z_DOWN 0x10 +#define O_Z_UP 0x20 + +class Tilt: public Stage { + public: + Tilt(LSM6DS3 &gyro, NeoPixelBus &ring): _gyro(gyro), _ring(ring) { + }; + void init(); + void handle(); + private: + std::vector _tiltSequence{O_Z_DOWN, O_Y_DOWN, O_Z_DOWN, O_X_UP, O_Y_DOWN, O_Z_DOWN}; + uint8_t _tiltPointer = 0; + uint8_t _currentOrientation; + LSM6DS3 _gyro; + NeoPixelBus _ring; +}; + +#endif \ No newline at end of file