You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
atmega-geiger/src/user_interface.c

146 lines
3.4 KiB

/**
* Dispay
*/
#include "user_interface.h"
#include "twi.h"
#include "ssd1306.h"
#include "sevenseg.h"
#include "global_state.h"
#include "radiation.h"
static bool ended_loading = false;
static struct SevenSeg sseg = {
.x0 = 0,
.y0 = 0,
.charwidth = 17,
.thick = 3,
.spacing = 4,
};
void clear_screen()
{
ssd1306_clearScreen();
}
void init_user_interface()
{
TWI_Init();
ssd1306_128x32_i2c_init();
ssd1306_clearScreen();
}
void turn_off_display()
{
ssd1306_displayOff();
}
void show_current_radiation()
{
static struct rad_results last_results = {};
static struct rad_results results;
static uint8_t pending_dark_frames = 0;
static bool is_invert = false;
static bool was_dark = false;
// 12 step counter is better suited for display flashing effect
static uint8_t tick_counter_12 = 0;
tick_counter_12 += 1;
if (tick_counter_12 == 12) {
tick_counter_12 = 0;
}
// this is called from main, so we can sleep
if (!ended_loading) {
int progress = rad_get_progress();
if (progress == 100) {
show_loading_screen(100, false);
ended_loading = true;
// so user sees it
_delay_ms(250);
clear_screen();
// start showing values
} else {
if (progress < 10) { progress = 10; }
show_loading_screen(progress, false);
return;
}
}
if (pending_dark_frames > 0) {
pending_dark_frames -= 1;
return;
}
rad_get_reading(&results);
// Severe inverts display to make it super obvious that shit's bad
if (results.danger_level >= RAD_LEVEL_4_SEVERE) {
if (!is_invert) {
ssd1306_invertMode();
is_invert = true;
}
} else {
if (is_invert) {
is_invert = false;
ssd1306_normalMode();
}
}
// blinking, higher radiation = faster
if (results.danger_level == RAD_LEVEL_1_ELEVATED) {
if (tick_counter_12 == 0) {
pending_dark_frames = 1;
}
}
if (results.danger_level == RAD_LEVEL_2_DANGER) {
if (tick_counter_12 == 0 || tick_counter_12 == 6) {
pending_dark_frames = 1;
}
}
if (results.danger_level >= RAD_LEVEL_3_HIGH_DANGER) {
if (tick_counter_12 == 0 || tick_counter_12 == 4 || tick_counter_12 == 8) {
pending_dark_frames = 1;
}
}
if (pending_dark_frames) {
clear_screen();
was_dark = true;
return;
}
if (was_dark
|| results.cpm_x10 != last_results.cpm_x10
|| results.usvh_decimals != last_results.usvh_decimals
|| results.danger_level != last_results.danger_level)
{
was_dark = false;
if (results.usvh_decimals != last_results.usvh_decimals || results.danger_level != last_results.danger_level) {
clear_screen();
}
memcpy(&last_results, &results, sizeof(struct rad_results));
// This is an optimized function that draws black as well as white lines as rectangles,
// so we don't need to redraw the whole screen
sseg_number(&sseg, results.usvh_num, 5, results.usvh_decimals);
ssd1306_setColor(0xFFFF);
for (uint8_t lv = 1; lv <= results.danger_level; lv++) {
uint8_t xx = 129 - lv * 3;
ssd1306_fillRect(
xx, 20, xx, 30
);
}
}
}