diff --git a/p8-firmware/headers/Screens.h b/p8-firmware/headers/Screens.h index bf2acc2..4c052de 100644 --- a/p8-firmware/headers/Screens.h +++ b/p8-firmware/headers/Screens.h @@ -7,7 +7,7 @@ #include "pinoutP8.h" #include "powerControl.h" -#define KM_PER_STEP 0.00065f //65cm per step +#define KM_PER_STEP 0.00065f //65cm per step /* A screen with a public method bool doesImplementSwipe____ returning true says to the screen controller @@ -62,44 +62,45 @@ class TimeScreen : public WatchScreenBase { void screenSetup() { clearDisplay(true); currentDay = -1; - writeString(80, 125, 3, "%"); - writeChar(20, 152, 3, distanceShowing ? GLYPH_KM : GLYPH_WALKING, COLOUR_WHITE, COLOUR_BLACK); + writeString(80, 145, 3, "%"); + writeChar(20, 172, 3, distanceShowing ? GLYPH_KM : GLYPH_WALKING, COLOUR_WHITE, COLOUR_BLACK); + // drawRectOutline(14, 14, getWidthOfString("00:00:00", 4) + 12, 40, 1, COLOUR_WHITE); } void screenDestroy() {} void screenLoop() { writeString(20, 20, 4, getTimeWithSecs()); - writeString(20, 65, 3, getDate()); + writeString(20, 70, 3, getDate()); //Only update the day string on a new day if (getDayOfWeek(day(), month(), year()) != currentDay) { - writeString(20, 95, 3, getDay()); + writeString(20, 100, 3, getDay()); } if (!getChargeState()) { if (getBatteryPercent() < 99) - writeChar(20, 122, 3, GLYPH_BATTERY, COLOUR_RED, COLOUR_BLACK); + writeChar(20, 142, 3, GLYPH_BATTERY, COLOUR_RED, COLOUR_BLACK); else - writeChar(20, 122, 3, GLYPH_BATTERY, COLOUR_GREEN, COLOUR_BLACK); + writeChar(20, 142, 3, GLYPH_BATTERY, COLOUR_GREEN, COLOUR_BLACK); } else { - writeChar(20, 122, 3, GLYPH_BATTERY, COLOUR_WHITE, COLOUR_BLACK); + writeChar(20, 142, 3, GLYPH_BATTERY, COLOUR_WHITE, COLOUR_BLACK); } - writeIntWithoutPrecedingZeroes(40, 125, 3, getBatteryPercent()); + writeIntWithoutPrecedingZeroes(40, 145, 3, getBatteryPercent()); steps = getStepCount(); if (distanceShowing) { sprintf(distanceChar, "%.3f", steps * KM_PER_STEP); - writeString(40, 155, 3, distanceChar); + writeString(40, 175, 3, distanceChar); } else { - writeIntWithoutPrecedingZeroes(40, 155, 3, steps); + writeIntWithoutPrecedingZeroes(40, 175, 3, steps); } } void screenTap(uint8_t x, uint8_t y) { if (distanceShowing) { - writeString(40,155,3," "); - writeChar(20, 152, 3, GLYPH_WALKING, COLOUR_WHITE, COLOUR_BLACK); + writeString(40, 175, 3, " "); + writeChar(20, 172, 3, GLYPH_WALKING, COLOUR_WHITE, COLOUR_BLACK); distanceShowing = !distanceShowing; - } else{ + } else { distanceShowing = !distanceShowing; - writeChar(20, 152, 3, GLYPH_KM, COLOUR_WHITE, COLOUR_BLACK); + writeChar(20, 172, 3, GLYPH_KM, COLOUR_WHITE, COLOUR_BLACK); } } bool doesImplementSwipeRight() { return false; } @@ -109,6 +110,67 @@ class TimeScreen : public WatchScreenBase { uint8_t getScreenUpdateTimeMS() { return 20; } //20ms update time }; +/* + This screen is a rudimentary exercise screen + */ +class ExerciseScreen : public WatchScreenBase { + private: + bool hasStartedWorkout = false; + int startStepCount; //Starting step count, to calculate difference + int currentSteps; //Current step count + char distanceChar[10]; //Buffer for distance sprintf + int startTime; //Millis when workout was started + + public: + void screenSetup() { + clearDisplay(true); + if (hasStartedWorkout == false) { + drawRectOutlineWithChar(80, 60, 80, 80, 5, COLOUR_GREEN, GLYPH_WALKING_NO_EARTH, 8); //Button to start workout + writeString(120 - (getWidthOfString("Start Logging", 2) / 2), 150, 2, "Start Logging"); //Button label + } else { + writeString(0, 0, 3, "Exercise:"); //Exercise label + writeChar(0, 78, 3, GLYPH_WALKING, COLOUR_WHITE, COLOUR_BLACK); //Walking glyph + writeChar(0, 108, 3, GLYPH_KM, COLOUR_WHITE, COLOUR_BLACK); //KM glyph + writeString(120 - (getWidthOfString("Long tap to stop logging.", 1) / 2), 204, 1, "Long tap to stop logging."); //Info at bottom of screen + } + } + void screenDestroy() {} + void screenLoop() { + if (hasStartedWorkout) { + //Print current workout info if we have started a workout + currentSteps = getStepCount(); + writeString(0, 30, 3, getStopWatchTime(startTime, millis())); //Workout time + writeIntWithoutPrecedingZeroes(20, 80, 3, currentSteps - startStepCount); //Step count + sprintf(distanceChar, "%.3f", (currentSteps - startStepCount) * KM_PER_STEP); //KM walked calc + writeString(20, 110, 3, distanceChar); + } + } + void screenTap(uint8_t x, uint8_t y) { + if (x > 80 && x < 160 && y > 60 && y < 140 && hasStartedWorkout == false) { //If we click the button and we haven't started a workout + startWorkout(); + } + } + void screenLongTap(uint8_t x, uint8_t y) { + if (hasStartedWorkout == true) { //Only stop workout if we have started one + stopWorkout(); + } + } + void startWorkout() { + hasStartedWorkout = true; + screenSetup(); + startStepCount = getStepCount(); + startTime = millis(); + } + void stopWorkout() { + hasStartedWorkout = false; + screenSetup(); + } + bool doesImplementSwipeRight() { return false; } + bool doesImplementSwipeLeft() { return false; } + bool doesImplementLongTap() { return true; } //We do use long tap to stop the workout + uint8_t getScreenUpdateTimeMS() { return 100; } //Slower update time +}; + /* This screen is a basic stopwatch */ diff --git a/p8-firmware/headers/WatchScreenBase.h b/p8-firmware/headers/WatchScreenBase.h index f777051..e5c999d 100644 --- a/p8-firmware/headers/WatchScreenBase.h +++ b/p8-firmware/headers/WatchScreenBase.h @@ -21,6 +21,7 @@ class WatchScreenBase { virtual void screenDestroy() {} virtual void screenLoop() {} virtual void screenTap(uint8_t x, uint8_t y) {} + virtual void screenLongTap(uint8_t x, uint8_t y) {} virtual void swipeLeft() {} virtual void swipeRight() {} virtual void swipeUp() {} @@ -29,5 +30,6 @@ class WatchScreenBase { virtual bool doesImplementSwipeRight() { return true; } virtual bool doesImplementSwipeUp() { return true; } virtual bool doesImplementSwipeDown() { return true; } + virtual bool doesImplementLongTap() { return false; } virtual uint8_t getScreenUpdateTimeMS() { return 20; } }; \ No newline at end of file diff --git a/p8-firmware/headers/font.h b/p8-firmware/headers/font.h index 2109e59..feb1dd3 100644 --- a/p8-firmware/headers/font.h +++ b/p8-firmware/headers/font.h @@ -34,6 +34,7 @@ #define GLYPH_BATTERY 18 #define GLYPH_SMILEY 19 #define GLYPH_KM 20 +#define GLYPH_WALKING_NO_EARTH 21 const unsigned char font[][5] = //Unprintable characters (used for images) @@ -59,7 +60,7 @@ const unsigned char font[][5] = {0x00, 0xFC, 0xFE, 0xFC, 0x00}, //Battery glyph {0x24, 0x00, 0x00, 0x42, 0x3C}, //Smiley {0xEF, 0x24, 0x6A, 0x20, 0xE0}, //KM glyph - {0x00, 0x66, 0x89, 0x95, 0x6A}, + {0x28, 0x24, 0x1E, 0x64, 0x08}, //Guy walking no earth {0x60, 0x60, 0x60, 0x60, 0x60}, {0x94, 0xA2, 0xFF, 0xA2, 0x94}, {0x08, 0x04, 0x7E, 0x04, 0x08}, diff --git a/p8-firmware/headers/pinoutP8.h b/p8-firmware/headers/pinoutP8.h index 1efa846..1ce4b87 100644 --- a/p8-firmware/headers/pinoutP8.h +++ b/p8-firmware/headers/pinoutP8.h @@ -1,57 +1,57 @@ #ifndef _PINOUT_ #define _PINOUT_ -#define COMMENT_FOR_PINETIME //Comment this for pinetime +#define COMMENT_FOR_PINETIME //Comment this for pinetime #ifdef COMMENT_FOR_PINETIME #define P8 //LCD Stuff -#define LCD_SCK 2 //SPI Clock -#define LCD_SDI 3 //SPI MOSI -#define LCD_CS 25 //Chip select -#define LCD_RESET 26 //Display reset -#define LCD_RS 18 //Command/data selector -#define LCD_DET 9 //LCD detect? - -//Flash chip -#define SPI_SCK 2 -#define SPI_MOSI 3 -#define SPI_MISO 4 -#define SPI_CE 5 +#define LCD_SCK 2 //SPI Clock +#define LCD_SDI 3 //SPI MOSI +#define LCD_CS 25 //Chip select +#define LCD_RESET 26 //Display reset +#define LCD_RS 18 //Command/data selector +#define LCD_DET 9 //LCD detect? + +//Flash chip +#define SPI_SCK 2 +#define SPI_MOSI 3 +#define SPI_MISO 4 +#define SPI_CE 5 //Touchscreen -#define TP_SDA 6 -#define TP_SCL 7 -#define TP_RESET 13 -#define TP_INT 28 //Touchscreen interrupt (by default the controller is in sleep mode, and will wake up (and send an interrupt) when a touch event is detected) +#define TP_SDA 6 +#define TP_SCL 7 +#define TP_RESET 13 +#define TP_INT 28 //Touchscreen interrupt (by default the controller is in sleep mode, and will wake up (and send an interrupt) when a touch event is detected) //Accelerometer -#define BMA421_SDA 6 -#define BMA421_SCL 7 -#define BMA421_INT 8 +#define BMA421_SDA 6 +#define BMA421_SCL 7 +#define BMA421_INT 8 //Heartrate sensor -#define HR_SDA 6 -#define HR_SCL 7 -#define HR_TEST 30 +#define HR_SDA 6 +#define HR_SCL 7 +#define HR_TEST 30 //Battery #define CHARGE_INDICATION -1 -#define POWER_INDICATION 19 -#define BATTERY_VOLTAGE 31 -#define POWER_CONTROL 24 +#define POWER_INDICATION 19 +#define BATTERY_VOLTAGE 31 +#define POWER_CONTROL 24 //Various IO -#define GREEN_LEDS 27 -#define VIBRATOR_OUT 16 -#define PUSH_BUTTON_IN 17 -#define PUSH_BUTTON_OUT -1 +#define GREEN_LEDS 27 +#define VIBRATOR_OUT 16 +#define PUSH_BUTTON_IN 17 +#define PUSH_BUTTON_OUT -1 //Backlight control -#define LCD_BACKLIGHT_LOW 14 -#define LCD_BACKLIGHT_MID 22 +#define LCD_BACKLIGHT_LOW 14 +#define LCD_BACKLIGHT_MID 22 #define LCD_BACKLIGHT_HIGH 23 #else @@ -59,50 +59,50 @@ //PINETIME: //LCD Stuff -#define LCD_SCK 2 //SPI Clock -#define LCD_SDI 3 //SPI MOSI -#define LCD_CS 25 //Chip select -#define LCD_RESET 26 //Display reset -#define LCD_RS 18 //Command/data selector -#define LCD_DET 9 //LCD detect? - -//Flash chip -#define SPI_SCK 2 -#define SPI_MOSI 3 -#define SPI_MISO 4 -#define SPI_CE 5 +#define LCD_SCK 2 //SPI Clock +#define LCD_SDI 3 //SPI MOSI +#define LCD_CS 25 //Chip select +#define LCD_RESET 26 //Display reset +#define LCD_RS 18 //Command/data selector +#define LCD_DET 9 //LCD detect? + +//Flash chip +#define SPI_SCK 2 +#define SPI_MOSI 3 +#define SPI_MISO 4 +#define SPI_CE 5 //Touchscreen -#define TP_SDA 6 -#define TP_SCL 7 -#define TP_RESET 10 -#define TP_INT 28 //Touchscreen interrupt (by default the controller is in sleep mode, and will wake up (and send an interrupt) when a touch event is detected) +#define TP_SDA 6 +#define TP_SCL 7 +#define TP_RESET 10 +#define TP_INT 28 //Touchscreen interrupt (by default the controller is in sleep mode, and will wake up (and send an interrupt) when a touch event is detected) //Accelerometer -#define BMA421_SDA 6 -#define BMA421_SCL 7 -#define BMA421_INT 8 +#define BMA421_SDA 6 +#define BMA421_SCL 7 +#define BMA421_INT 8 //Heartrate sensor -#define HR_SDA 6 -#define HR_SCL 7 -#define HR_TEST 30 +#define HR_SDA 6 +#define HR_SCL 7 +#define HR_TEST 30 //Battery #define CHARGE_INDICATION 12 -#define POWER_INDICATION 19 -#define BATTERY_VOLTAGE 31 -#define POWER_CONTROL 24 +#define POWER_INDICATION 19 +#define BATTERY_VOLTAGE 31 +#define POWER_CONTROL 24 //Various IO -#define GREEN_LEDS 27 -#define VIBRATOR_OUT 16 -#define PUSH_BUTTON_IN 13 -#define PUSH_BUTTON_OUT 15 +#define GREEN_LEDS 27 +#define VIBRATOR_OUT 16 +#define PUSH_BUTTON_IN 13 +#define PUSH_BUTTON_OUT 15 //Backlight control -#define LCD_BACKLIGHT_LOW 14 -#define LCD_BACKLIGHT_MID 22 +#define LCD_BACKLIGHT_LOW 14 +#define LCD_BACKLIGHT_MID 22 #define LCD_BACKLIGHT_HIGH 23 -#endif //COMMENT_FOR_PINETIME -#endif //_PINOUT_ \ No newline at end of file +#endif //COMMENT_FOR_PINETIME +#endif //_PINOUT_ \ No newline at end of file diff --git a/p8-firmware/p8-firmware.ino b/p8-firmware/p8-firmware.ino index d3ecb22..859ae92 100644 --- a/p8-firmware/p8-firmware.ino +++ b/p8-firmware/p8-firmware.ino @@ -25,7 +25,7 @@ void setup() { initWatchdog(); //Start the watchdog initFastSPI(); //Initialize EasyDMA SPI initDisplay(); //Initialize display - writeChar(100, 120-32, 8, GLYPH_SMILEY, COLOUR_WHITE, COLOUR_BLACK); + writeChar(100, 120 - 32, 8, GLYPH_SMILEY, COLOUR_WHITE, COLOUR_BLACK); initI2C(); //Initialize the I2C interface initTouch(); //Initialize touch panel initAccel(); //Initialize the accelerometer @@ -36,7 +36,9 @@ void setup() { } void randomTests() { - //NRF_RTC1->TASKS_TRIGOVRFLW = 1; + /* NRF_NVMC->CONFIG = 2; + NRF_NVMC->ERASEUICR = 1; + NVIC_SystemReset(); */ } void loop() { diff --git a/p8-firmware/screenController.cpp b/p8-firmware/screenController.cpp index 3ed03c7..365984d 100644 --- a/p8-firmware/screenController.cpp +++ b/p8-firmware/screenController.cpp @@ -10,16 +10,17 @@ long lastScreenUpdate = 0; There will be a pointer to the current screen which will have the methods called on it Finally a screen will be switched by moving the pointer to a different instance of a different screen */ -//DemoScreen demoScreen; TimeScreen timeScreen; StopWatchScreen stopWatchScreen; TimeDateSetScreen timeDateSetScreen; -DemoScreen demoScreen; +/* DemoScreen demoScreen; */ InfoScreen infoScreen; PowerScreen powerScreen; +ExerciseScreen exerciseScreen; int currentHomeScreenIndex = 0; -WatchScreenBase* homeScreens[NUM_SCREENS] = {&timeScreen, &stopWatchScreen, &timeDateSetScreen, &infoScreen, &powerScreen, &demoScreen}; +WatchScreenBase* homeScreens[NUM_SCREENS] = {&timeScreen, &exerciseScreen, &stopWatchScreen, &timeDateSetScreen, &infoScreen, &powerScreen /* , &demoScreen */}; + WatchScreenBase* currentScreen = homeScreens[currentHomeScreenIndex]; /* @@ -122,7 +123,11 @@ void handleTap(uint8_t x, uint8_t y) { /* Sleep when we receive a long tap */ void handleLongTap(uint8_t x, uint8_t y) { - enterSleep(); + if (currentScreen->doesImplementLongTap() == true) { + currentScreen->screenLongTap(x, y); + } else { + enterSleep(); + } } /* @@ -148,11 +153,12 @@ void drawAppIndicator() { uint8_t startOfString = 120 - (widthOfIndicator / 2); //Draw the current screen indicators writeChar(startOfString + (0 * indicatorFontSize * FONT_WIDTH) + (0 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 0) ? GLYPH_CLOCK_SEL : GLYPH_CLOCK_UNSEL, COLOUR_WHITE, COLOUR_BLACK); - writeChar(startOfString + (1 * indicatorFontSize * FONT_WIDTH) + (1 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 1) ? GLYPH_STOPWATCH_SEL : GLYPH_STOPWATCH_UNSEL, COLOUR_WHITE, COLOUR_BLACK); - writeChar(startOfString + (2 * indicatorFontSize * FONT_WIDTH) + (2 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 2) ? GLYPH_SETTINGS_SEL : GLYPH_SETTINGS_UNSEL, COLOUR_WHITE, COLOUR_BLACK); - writeChar(startOfString + (3 * indicatorFontSize * FONT_WIDTH) + (3 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 3) ? GLYPH_INFO_SEL : GLYPH_INFO_UNSEL, COLOUR_WHITE, COLOUR_BLACK); - writeChar(startOfString + (4 * indicatorFontSize * FONT_WIDTH) + (4 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 4) ? GLYPH_POWER_SEL : GLYPH_POWER_UNSEL, COLOUR_WHITE, COLOUR_BLACK); - writeChar(startOfString + (5 * indicatorFontSize * FONT_WIDTH) + (5 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 5) ? GLYPH_DATA_SEL : GLYPH_DATA_UNSEL, COLOUR_WHITE, COLOUR_BLACK); + writeChar(startOfString + (1 * indicatorFontSize * FONT_WIDTH) + (1 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 1) ? GLYPH_DATA_SEL : GLYPH_DATA_UNSEL, COLOUR_WHITE, COLOUR_BLACK); + writeChar(startOfString + (2 * indicatorFontSize * FONT_WIDTH) + (2 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 2) ? GLYPH_STOPWATCH_SEL : GLYPH_STOPWATCH_UNSEL, COLOUR_WHITE, COLOUR_BLACK); + writeChar(startOfString + (3 * indicatorFontSize * FONT_WIDTH) + (3 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 3) ? GLYPH_SETTINGS_SEL : GLYPH_SETTINGS_UNSEL, COLOUR_WHITE, COLOUR_BLACK); + writeChar(startOfString + (4 * indicatorFontSize * FONT_WIDTH) + (4 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 4) ? GLYPH_INFO_SEL : GLYPH_INFO_UNSEL, COLOUR_WHITE, COLOUR_BLACK); + writeChar(startOfString + (5 * indicatorFontSize * FONT_WIDTH) + (5 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 5) ? GLYPH_POWER_SEL : GLYPH_POWER_UNSEL, COLOUR_WHITE, COLOUR_BLACK); + /* writeChar(startOfString + (6 * indicatorFontSize * FONT_WIDTH) + (6 * indicatorFontSize), 216, indicatorFontSize, (currentHomeScreenIndex == 6) ? GLYPH_DATA_SEL : GLYPH_DATA_UNSEL, COLOUR_WHITE, COLOUR_BLACK); */ //Draw the "can scroll left/right" indicators in the corners of the screen switch (currentHomeScreenIndex) { case 0: @@ -160,17 +166,8 @@ void drawAppIndicator() { writeChar(225, 216, indicatorFontSize, GLYPH_ARROW_RIGHT, COLOUR_WHITE, COLOUR_BLACK); break; case 1: - writeChar(0, 216, indicatorFontSize, GLYPH_ARROW_LEFT, COLOUR_WHITE, COLOUR_BLACK); - writeChar(225, 216, indicatorFontSize, GLYPH_ARROW_RIGHT, COLOUR_WHITE, COLOUR_BLACK); - break; case 2: - writeChar(0, 216, indicatorFontSize, GLYPH_ARROW_LEFT, COLOUR_WHITE, COLOUR_BLACK); - writeChar(225, 216, indicatorFontSize, GLYPH_ARROW_RIGHT, COLOUR_WHITE, COLOUR_BLACK); - break; case 3: - writeChar(0, 216, indicatorFontSize, GLYPH_ARROW_LEFT, COLOUR_WHITE, COLOUR_BLACK); - writeChar(225, 216, indicatorFontSize, GLYPH_ARROW_RIGHT, COLOUR_WHITE, COLOUR_BLACK); - break; case 4: writeChar(0, 216, indicatorFontSize, GLYPH_ARROW_LEFT, COLOUR_WHITE, COLOUR_BLACK); writeChar(225, 216, indicatorFontSize, GLYPH_ARROW_RIGHT, COLOUR_WHITE, COLOUR_BLACK);