Added battery icon printing
This commit is contained in:
parent
e71049146a
commit
f3b0fc2c28
17
TODO
17
TODO
@ -1,16 +1 @@
|
|||||||
--- main.c ---
|
Battery icon - how to calc percentage?
|
||||||
Battery icon
|
|
||||||
Check when to read battery
|
|
||||||
|
|
||||||
--- UI ---
|
|
||||||
123456mm >A
|
|
||||||
123456mm >B
|
|
||||||
_
|
|
||||||
XXXXXXXX | |
|
|
||||||
XXXXXXXX | |
|
|
||||||
XXXXXXXX |_|
|
|
||||||
|
|
||||||
Battery Image - 24x48 px
|
|
||||||
2px White Border
|
|
||||||
2px Black Border
|
|
||||||
2px horizontal segments per 5%
|
|
||||||
|
|||||||
189
code/main.c
189
code/main.c
@ -40,6 +40,13 @@
|
|||||||
#define OLED_X_SIZE 128
|
#define OLED_X_SIZE 128
|
||||||
#define OLED_Y_SIZE 64
|
#define OLED_Y_SIZE 64
|
||||||
|
|
||||||
|
#define OLED_BATTERY_ICON_X1 (OLED_X_SIZE - (CHAR_SIZE + 1) * 2 * 2)
|
||||||
|
#define OLED_BATTERY_ICON_X2 (OLED_X_SIZE - 1)
|
||||||
|
#define OLED_BATTERY_ICON_Y1 2
|
||||||
|
#define OLED_BATTERY_ICON_Y2 ((OLED_Y_SIZE / 8) - 1)
|
||||||
|
#define OLED_BATTERY_ICON_SIZE 2
|
||||||
|
#define OLED_BATTERY_ICON_PERCENT 5
|
||||||
|
|
||||||
// Time(ms) to keep the display on before sleep
|
// Time(ms) to keep the display on before sleep
|
||||||
#define DISPLAY_DELAY 3000
|
#define DISPLAY_DELAY 3000
|
||||||
|
|
||||||
@ -262,6 +269,9 @@ void display_send_cmd(uint8_t cmd);
|
|||||||
// OLED send data helper
|
// OLED send data helper
|
||||||
void display_send_data(const uint8_t *data, uint16_t buflen);
|
void display_send_data(const uint8_t *data, uint16_t buflen);
|
||||||
|
|
||||||
|
// OLED print area helper
|
||||||
|
void display_set_area(uint8_t start_x, uint8_t end_x, uint8_t start_y, uint8_t end_y);
|
||||||
|
|
||||||
// OLED init
|
// OLED init
|
||||||
void display_init();
|
void display_init();
|
||||||
|
|
||||||
@ -609,6 +619,60 @@ void display_send_data(const uint8_t *data, uint16_t buflen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void display_set_area(uint8_t start_x, uint8_t end_x, uint8_t start_y, uint8_t end_y)
|
||||||
|
{
|
||||||
|
uint8_t cmd_list[6] =
|
||||||
|
{
|
||||||
|
0x21, // Set Column Address
|
||||||
|
0x00, // Start Address
|
||||||
|
0x00, // End Address
|
||||||
|
0x22, // Set Page Address
|
||||||
|
0x00, // Start Page
|
||||||
|
0x00 // End Page
|
||||||
|
};
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
if (start_x >= OLED_X_SIZE)
|
||||||
|
{
|
||||||
|
start_x = OLED_X_SIZE - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_x >= OLED_X_SIZE)
|
||||||
|
{
|
||||||
|
end_x = OLED_X_SIZE - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_x < start_x)
|
||||||
|
{
|
||||||
|
end_x = start_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start_y >= (OLED_Y_SIZE / 8))
|
||||||
|
{
|
||||||
|
start_y = (OLED_Y_SIZE / 8) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_y >= (OLED_Y_SIZE / 8))
|
||||||
|
{
|
||||||
|
end_y = (OLED_Y_SIZE / 8) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_y < start_y)
|
||||||
|
{
|
||||||
|
end_y = start_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd[1] = start_x;
|
||||||
|
cmd[2] = end_x;
|
||||||
|
cmd[4] = start_y;
|
||||||
|
cmd[5] = end_y;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(cmd_list); ++i)
|
||||||
|
{
|
||||||
|
display_send_cmd(cmd_list[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void display_init()
|
void display_init()
|
||||||
{
|
{
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
@ -722,15 +786,6 @@ void get_symbol16(uint8_t index, uint8_t *out)
|
|||||||
void print_symbol(uint8_t symbol_idx, uint8_t x, uint8_t y, uint8_t invert)
|
void print_symbol(uint8_t symbol_idx, uint8_t x, uint8_t y, uint8_t invert)
|
||||||
{
|
{
|
||||||
uint8_t unfolded_symbol[CHAR_SIZE * 4];
|
uint8_t unfolded_symbol[CHAR_SIZE * 4];
|
||||||
uint8_t cmd_list[6] =
|
|
||||||
{
|
|
||||||
0x21, // Set Column Address
|
|
||||||
0x00, // Start Address
|
|
||||||
0x00, // End Address
|
|
||||||
0x22, // Set Page Address
|
|
||||||
0x00, // Start Page 0
|
|
||||||
0x00 // End Page
|
|
||||||
};
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
get_symbol16(symbol_idx, unfolded_symbol);
|
get_symbol16(symbol_idx, unfolded_symbol);
|
||||||
@ -750,16 +805,7 @@ void print_symbol(uint8_t symbol_idx, uint8_t x, uint8_t y, uint8_t invert)
|
|||||||
x = OLED_X_SIZE - CHAR_SIZE * 2;
|
x = OLED_X_SIZE - CHAR_SIZE * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_list[1] = x;
|
display_set_area(x, x + CHAR_SIZE * 2 - 1, y * 2, y * 2 + 1);
|
||||||
cmd_list[2] = x + CHAR_SIZE * 2 - 1;
|
|
||||||
cmd_list[4] = y * 2;
|
|
||||||
cmd_list[5] = y * 2 + 1;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(cmd_list); ++i)
|
|
||||||
{
|
|
||||||
display_send_cmd(cmd_list[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
display_send_data(unfolded_symbol, sizeof(unfolded_symbol));
|
display_send_data(unfolded_symbol, sizeof(unfolded_symbol));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,10 +940,7 @@ void print_clear_menu_area()
|
|||||||
// End Y - Depends On OLED Size
|
// End Y - Depends On OLED Size
|
||||||
cmd_list[5] = (OLED_Y_SIZE / 8) - 1;
|
cmd_list[5] = (OLED_Y_SIZE / 8) - 1;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(cmd_list); ++i)
|
display_set_area(0, OLED_BATTERY_ICON_X1 - 1, 2, (OLED_Y_SIZE / 8) - 1);
|
||||||
{
|
|
||||||
display_send_cmd(cmd_list[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(data); ++i)
|
for (i = 0; i < sizeof(data); ++i)
|
||||||
{
|
{
|
||||||
@ -962,6 +1005,106 @@ void print_option(uint8_t option)
|
|||||||
|
|
||||||
void print_battery_icon()
|
void print_battery_icon()
|
||||||
{
|
{
|
||||||
|
static uint8_t old_percent = 0xFF;
|
||||||
|
uint8_t buf[16];
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t y;
|
||||||
|
uint8_t percent;
|
||||||
|
uint8_t threshold;
|
||||||
|
uint8_t bits;
|
||||||
|
uint8_t mask;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(buf), ++i)
|
||||||
|
{
|
||||||
|
buf[i] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer safety
|
||||||
|
#if ((OLED_BATTERY_ICON_Y2 - OLED_BATTERY_ICON_Y1 + 1) * OLED_BATTERY_ICON_SIZE > sizeof(buf))
|
||||||
|
#error "THIS Y OVERFLOWS"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Draw left/right borders only once
|
||||||
|
if (0xFF == old_percent)
|
||||||
|
{
|
||||||
|
// Draw left border
|
||||||
|
display_set_area(OLED_BATTERY_ICON_X1, OLED_BATTERY_ICON_X1 + OLED_BATTERY_ICON_SIZE - 1,
|
||||||
|
OLED_BATTERY_ICON_Y1, OLED_BATTERY_ICON_Y2);
|
||||||
|
display_send_data(buf, (OLED_BATTERY_ICON_Y2 - OLED_BATTERY_ICON_Y1 + 1) * OLED_BATTERY_ICON_SIZE);
|
||||||
|
|
||||||
|
// Draw right border
|
||||||
|
display_set_area(OLED_BATTERY_ICON_X2 - 1, OLED_BATTERY_ICON_X2,
|
||||||
|
OLED_BATTERY_ICON_Y1, OLED_BATTERY_ICON_Y2);
|
||||||
|
display_send_data(buf, (OLED_BATTERY_ICON_Y2 - OLED_BATTERY_ICON_Y1 + 1) * OLED_BATTERY_ICON_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Calc battery percent
|
||||||
|
percent = 50;
|
||||||
|
|
||||||
|
// Do not draw if not needed
|
||||||
|
if ((old_percent / OLED_BATTERY_ICON_PERCENT) == (percent / OLED_BATTERY_ICON_PERCENT))
|
||||||
|
{
|
||||||
|
old_percent = percent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set bitmask
|
||||||
|
bits = 0x00;
|
||||||
|
for (i = 0; i < OLED_BATTERY_ICON_SIZE; ++i)
|
||||||
|
{
|
||||||
|
bits <<= 1;
|
||||||
|
bits += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Threshold is artificially bigger to not draw over border
|
||||||
|
// On lower border it underflows
|
||||||
|
threshold = 100 - ((OLED_BATTERY_ICON_PERCENT + 1) / 2) + OLED_BATTERY_ICON_PERCENT * 2;
|
||||||
|
|
||||||
|
for (y = OLED_BATTERY_ICON_Y1, y <= OLED_BATTERY_ICON_Y2; ++y)
|
||||||
|
{
|
||||||
|
mask = 0x00;
|
||||||
|
|
||||||
|
for (i = 0; i < 8 / OLED_BATTERY_ICON_SIZE; ++i)
|
||||||
|
{
|
||||||
|
mask <<= OLED_BATTERY_ICON_SIZE;
|
||||||
|
if (percent > threshold)
|
||||||
|
{
|
||||||
|
mask |= bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
threshold -= OLED_BATTERY_ICON_PERCENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add top border
|
||||||
|
if (0 == y)
|
||||||
|
{
|
||||||
|
mask |= (bits << (8 - OLED_BATTERY_ICON_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add bottom border
|
||||||
|
if (OLED_BATTERY_ICON_Y2 == y)
|
||||||
|
{
|
||||||
|
mask |= bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill buffer
|
||||||
|
for (i = 0; i < sizeof(buf); ++i)
|
||||||
|
{
|
||||||
|
buf[i] = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Diplay percent
|
||||||
|
display_set_area(OLED_BATTERY_ICON_X1 + OLED_BATTERY_ICON_SIZE * 2,
|
||||||
|
OLED_BATTERY_ICON_X2 - OLED_BATTERY_ICON_SIZE * 2,
|
||||||
|
y, y);
|
||||||
|
display_send_data(buf, OLED_BATTERY_ICON_X2 - OLED_BATTERY_ICON_X1 -
|
||||||
|
OLED_BATTERY_ICON_SIZE * 4 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer safety
|
||||||
|
#if ((OLED_BATTERY_ICON_X2 - OLED_BATTERY_ICON_X1 - OLED_BATTERY_ICON_SIZE * 4 + 1) > sizeof(buf))
|
||||||
|
#error "THIS X OVERFLOWS"
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user