Added menu for resetting the counter and showing battery voltage

This commit is contained in:
Mark van Renswoude 2017-08-05 21:59:07 +02:00
parent 703d1ccc2b
commit b6974d9e80
12 changed files with 346 additions and 126 deletions

View File

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 198 KiB

View File

@ -0,0 +1,3 @@
Customizations to the original library for this project:
- Split font6x8 into .c and .h file so that I could reference it in another file.

View File

@ -0,0 +1,96 @@
#include "font6x8.h"
const uint8_t ssd1306xled_font6x8 [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, // 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // horiz lines
};

View File

@ -1,3 +1,6 @@
#ifndef __SSD1306Font6x8
#define __SSD1306Font6x8
/**
* SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays
*
@ -21,99 +24,8 @@
// ----------------------------------------------------------------------------
/* Standard ASCII 6x8 font */
const uint8_t ssd1306xled_font6x8 [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, // 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // horiz lines
};
extern const uint8_t ssd1306xled_font6x8 [] PROGMEM;
// ============================================================================
#endif

View File

@ -153,14 +153,15 @@ ISR(TIMER0_COMPA_vect)
inline uint8_t readAndClearFlag(ButtonState* state, uint8_t flag)
inline uint8_t readAndClearFlag(ButtonState* state, uint8_t flag, uint8_t clearAdditionalFlag)
{
uint8_t result;
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
result = hasFlag((*state).flags, flag);
(*state).flags &= ~(flag);
if (result)
(*state).flags &= ~(flag | clearAdditionalFlag);
}
return result;
@ -169,23 +170,23 @@ inline uint8_t readAndClearFlag(ButtonState* state, uint8_t flag)
uint8_t button_is_pressed(ButtonState* state)
{
return readAndClearFlag(state, BSFPressed);
return readAndClearFlag(state, BSFPressed, 0);
}
uint8_t button_is_released(ButtonState* state)
{
return readAndClearFlag(state, BSFReleased);
return readAndClearFlag(state, BSFReleased, BSFPressed);
}
uint8_t button_is_repeated(ButtonState* state)
{
return readAndClearFlag(state, BSFRepeated);
return readAndClearFlag(state, BSFRepeated, 0);
}
uint8_t button_is_pressed_or_repeated(ButtonState* state)
{
return readAndClearFlag(state, BSFPressed | BSFRepeated);
return readAndClearFlag(state, BSFPressed | BSFRepeated, 0);
}

View File

@ -4,11 +4,12 @@
#include <ssd1306xled.h>
#include "power.h"
#include "buttons.h"
#include "screen/state.h"
#include "screen/counter.h"
#include "screen/menu.h"
// Forward declarations
uint8_t handleGlobalInput();
void handleCurrentScreen();
@ -22,34 +23,18 @@ int main()
buttons_init();
setCurrentScreen(Counter);
while (1)
{
checkPower();
if (!handleGlobalInput())
{
if (powerState == On)
{
handleCurrentScreen();
if (!buttons_active())
sleepUntilButton(_BV(BUTTON_UP) | _BV(BUTTON_DOWN) | _BV(BUTTON_OPTION));
}
}
}
return 0;
}
uint8_t handleGlobalInput()
{
if (button_is_pressed_short(&buttonOption))
{
// Turn off power to the screen
if (powerState == On)
setPowerState(ManualOff);
{
handleCurrentScreen();
return 1;
if (!buttons_active() && !peekScreenInvalidated())
sleepUntilButton(_BV(BUTTON_UP) | _BV(BUTTON_DOWN) | _BV(BUTTON_OPTION));
}
}
return 0;
@ -58,5 +43,9 @@ uint8_t handleGlobalInput()
void handleCurrentScreen()
{
handleCounterScreen();
switch (currentScreen)
{
case Counter: handleCounterScreen(); break;
case Menu: handleMenuScreen(); break;
}
}

View File

@ -3,6 +3,7 @@
#include <ssd1306xled.h>
#include "state.h"
#include "../buttons.h"
#include "../power.h"
#define CounterMinValue -99
@ -21,6 +22,22 @@ void blankDigitColumn(uint8_t* column, uint8_t width);
void handleCounterScreen()
{
if (button_is_pressed_short(&buttonOption))
{
// Turn off power to the screen
if (powerState == On)
setPowerState(ManualOff);
return;
}
if (button_is_pressed_long(&buttonOption))
{
setCurrentScreen(Menu);
return;
}
if (button_is_pressed_or_repeated(&buttonUp))
{
if (counter < CounterMaxValue)
@ -32,14 +49,24 @@ void handleCounterScreen()
counter--;
}
if (counter != lastDrawnCounter || getScreenInvalidated())
uint8_t invalidated = getScreenInvalidated();
if (counter != lastDrawnCounter || invalidated)
{
if (invalidated)
ssd1306_clear();
drawCounter();
lastDrawnCounter = counter;
}
}
void resetCounter()
{
counter = 0;
}
void drawCounter()
{
uint8_t column = DigitFullOffset;

View File

@ -40,6 +40,7 @@
extern void handleCounterScreen();
extern void resetCounter();
#endif

155
Source/src/screen/menu.c Normal file
View File

@ -0,0 +1,155 @@
#include "menu.h"
#include <stdint.h>
#include <stdlib.h>
#include <ssd1306xled.h>
#include "../../lib/ssd1306xled/font6x8.h"
#include "state.h"
#include "../buttons.h"
#include "../power.h"
#include "counter.h"
#define MenuItemReset 0
#define MenuItemCancel 1
#define MenuCount MenuItemCancel + 1
uint8_t currentIndex = 0;
uint8_t lastDrawnIndex = MenuCount;
// Forward declarations
void drawMenu();
void drawMenuItem(uint8_t itemIndex, char* caption);
void selectMenuItem();
void closeMenu();
void ssd1306_string_inverted(char *s);
void ssd1306_char_inverted(char ch);
void handleMenuScreen()
{
if (button_is_pressed_or_repeated(&buttonUp))
{
if (currentIndex >= MenuCount - 1)
currentIndex = 0;
else
currentIndex++;
}
else if (button_is_pressed_or_repeated(&buttonDown))
{
if (currentIndex <= 0)
currentIndex = MenuCount - 1;
else
currentIndex--;
}
else if (button_is_released(&buttonOption))
{
selectMenuItem();
return;
}
uint8_t invalidated = getScreenInvalidated();
if (currentIndex != lastDrawnIndex || invalidated)
{
if (invalidated)
ssd1306_clear();
drawMenu();
lastDrawnIndex = currentIndex;
}
}
void drawMenu()
{
// Since there are only two items at the moment, they're always going to be
// involved in the change, so simply repaint them.
drawMenuItem(MenuItemReset, "Reset ");
drawMenuItem(MenuItemCancel, "Cancel ");
// Can't use sprintf because that'll use up more than the
// space we have left on the ATTiny.
uint8_t intPart = vcc / 1000;
if (intPart > 9) intPart = 9;
uint8_t floatPart = (vcc % 1000) / 10;
char statusText[22] = "Battery: 0-00- \0";
itoa(intPart, &statusText[9], 10);
if (floatPart <= 9)
itoa(floatPart, &statusText[12], 10);
else
itoa(floatPart, &statusText[11], 10);
// itoa adds a \0 character
statusText[10] = '.';
statusText[13] = 'v';
ssd1306_setpos(0, 7);
ssd1306_string(statusText);
}
void drawMenuItem(uint8_t itemIndex, char* caption)
{
ssd1306_setpos(0, itemIndex);
if (itemIndex == currentIndex)
ssd1306_string_inverted(caption);
else
ssd1306_string(caption);
}
void selectMenuItem()
{
switch (currentIndex)
{
case MenuItemReset:
resetCounter();
closeMenu();
break;
case MenuItemCancel:
closeMenu();
break;
}
}
void closeMenu()
{
// Reset everything for the next time
currentIndex = 0;
lastDrawnIndex = MenuCount;
setCurrentScreen(Counter);
}
void ssd1306_string_inverted(char *s)
{
while (*s)
{
ssd1306_char_inverted(*s++);
}
}
void ssd1306_char_inverted(char ch)
{
uint8_t c = ch - 32;
ssd1306_send_data_start();
for (uint8_t i = 0; i < 6; i++)
{
ssd1306_send_byte(~pgm_read_byte(&ssd1306xled_font6x8[c * 6 + i]));
}
ssd1306_send_data_stop();
}

10
Source/src/screen/menu.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __ScreenMenu
#define __ScreenMenu
#include <stdint.h>
extern void handleMenuScreen();
#endif

View File

@ -1,9 +1,20 @@
#include "state.h"
Screen currentScreen = Counter;
uint8_t screenInvalidated = 0;
void setCurrentScreen(Screen value)
{
if (value != currentScreen)
{
currentScreen = value;
setScreenInvalidated();
}
}
uint8_t getScreenInvalidated()
{
if (screenInvalidated)
@ -16,6 +27,12 @@ uint8_t getScreenInvalidated()
}
uint8_t peekScreenInvalidated()
{
return screenInvalidated;
}
void setScreenInvalidated()
{
screenInvalidated = 1;

View File

@ -3,7 +3,16 @@
#include <stdint.h>
typedef enum { Counter, Menu } Screen;
extern Screen currentScreen;
extern void setCurrentScreen(Screen value);
extern uint8_t getScreenInvalidated();
extern uint8_t peekScreenInvalidated();
extern void setScreenInvalidated();
#endif