|
|
|
@ -14,15 +14,15 @@ |
|
|
|
|
#include <math.h> |
|
|
|
|
|
|
|
|
|
#define MEAS_BIN_COUNT 120 |
|
|
|
|
typedef uint8_t ticks_t; |
|
|
|
|
typedef uint16_t ticks_t; |
|
|
|
|
typedef uint8_t binnum_t; |
|
|
|
|
#define TICKS_MAX 255 |
|
|
|
|
#define TICKS_MAX 0xFFFF |
|
|
|
|
|
|
|
|
|
#define NEEDED_TICKS_FOR_VALUE_DISPLAY 5 |
|
|
|
|
|
|
|
|
|
#define TICKS_NEEDED_FOR_AUTORANGE 15 |
|
|
|
|
#define TICKS_NEEDED_FOR_AUTORANGE 10 |
|
|
|
|
|
|
|
|
|
uint16_t get_tick_count_in_bins(binnum_t bincount); |
|
|
|
|
uint32_t get_tick_count_in_bins(binnum_t bincount); |
|
|
|
|
|
|
|
|
|
/// measurements in the last X seconds
|
|
|
|
|
static volatile ticks_t measurements[MEAS_BIN_COUNT]; |
|
|
|
@ -40,6 +40,7 @@ ISR(INT0_vect) |
|
|
|
|
measurements[meas_bin]++; |
|
|
|
|
} |
|
|
|
|
req_update_display = true; |
|
|
|
|
disp_show_tick_mark = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void second_callback_irq() |
|
|
|
@ -82,9 +83,10 @@ void second_callback_irq() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void init_radiation() { |
|
|
|
|
void init_radiation() |
|
|
|
|
{ |
|
|
|
|
// clear the measurement buffer
|
|
|
|
|
memset((void*) measurements, 0, sizeof(measurements)); |
|
|
|
|
memset((void *) measurements, 0, sizeof(measurements)); |
|
|
|
|
|
|
|
|
|
as_input(D2); |
|
|
|
|
|
|
|
|
@ -93,34 +95,30 @@ void init_radiation() { |
|
|
|
|
EIMSK = _BV(INT0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t rad_get_progress() { |
|
|
|
|
ticks_t ticks = get_tick_count_in_bins(num_live_bins); |
|
|
|
|
uint8_t rad_get_progress() |
|
|
|
|
{ |
|
|
|
|
uint16_t ticks = get_tick_count_in_bins(num_live_bins); |
|
|
|
|
|
|
|
|
|
if (ticks >= NEEDED_TICKS_FOR_VALUE_DISPLAY) { |
|
|
|
|
return 100; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return (((uint16_t)ticks * 100) / (uint16_t)NEEDED_TICKS_FOR_VALUE_DISPLAY); |
|
|
|
|
return (((uint16_t) ticks * 100) / (uint16_t) NEEDED_TICKS_FOR_VALUE_DISPLAY); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint16_t get_tick_count_in_bins(binnum_t bincount) { |
|
|
|
|
uint32_t get_tick_count_in_bins(binnum_t bincount) |
|
|
|
|
{ |
|
|
|
|
if (bincount == 0) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint16_t all_ticks = 0; |
|
|
|
|
uint32_t all_ticks = 0; |
|
|
|
|
|
|
|
|
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { |
|
|
|
|
|
|
|
|
|
// going backwards
|
|
|
|
|
binnum_t bin = meas_bin; |
|
|
|
|
for (;;) { |
|
|
|
|
ticks_t in_bin = measurements[bin]; |
|
|
|
|
if ((0xFFFF - all_ticks) < in_bin) { |
|
|
|
|
all_ticks = 0xFFFF; |
|
|
|
|
} else { |
|
|
|
|
all_ticks += in_bin; |
|
|
|
|
} |
|
|
|
|
all_ticks += (uint32_t) measurements[bin]; |
|
|
|
|
|
|
|
|
|
if (bin == meas_oldest_bin) { |
|
|
|
|
break; |
|
|
|
@ -144,37 +142,56 @@ uint16_t get_tick_count_in_bins(binnum_t bincount) { |
|
|
|
|
return all_ticks; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint16_t rad_get_cpm() { |
|
|
|
|
// bins take 1 second
|
|
|
|
|
void rad_get_reading(struct rad_results *out) |
|
|
|
|
{ |
|
|
|
|
if (!out) { return; } |
|
|
|
|
|
|
|
|
|
float count = get_tick_count_in_bins(num_observed_bins); |
|
|
|
|
float cpm = (count / (float)num_observed_bins) * 60.0f; |
|
|
|
|
return (uint16_t) roundf(cpm * 10.0f); |
|
|
|
|
} |
|
|
|
|
// bins take 1 second
|
|
|
|
|
const float count = (float) get_tick_count_in_bins(num_observed_bins); |
|
|
|
|
const float cpm = (count / (float) num_observed_bins) * 60.0f; |
|
|
|
|
|
|
|
|
|
uint16_t rad_get_usvh(uint8_t *out_decimals) { |
|
|
|
|
float count = get_tick_count_in_bins(num_observed_bins); |
|
|
|
|
float cpm = (count / (float)num_observed_bins) * 60.0f; |
|
|
|
|
out->cpm_x10 = (uint32_t) roundf(cpm * 10.0f); |
|
|
|
|
|
|
|
|
|
// https://sites.google.com/site/diygeigercounter/technical/gm-tubes-supported
|
|
|
|
|
|
|
|
|
|
float usvh = (cpm / 153.8f); |
|
|
|
|
|
|
|
|
|
if (usvh < 99.0f) { |
|
|
|
|
*out_decimals = 3; |
|
|
|
|
return (uint16_t) roundf(usvh * 1000.0f); |
|
|
|
|
const float usvh = (cpm / 153.8f); |
|
|
|
|
|
|
|
|
|
if (usvh < 2.0f) { |
|
|
|
|
out->danger_level = RAD_LEVEL_0_SAFE; |
|
|
|
|
} else if (usvh < 10.0f) { |
|
|
|
|
out->danger_level = RAD_LEVEL_1_ELEVATED; |
|
|
|
|
} else if (usvh < 20.0f) { |
|
|
|
|
out->danger_level = RAD_LEVEL_2_DANGER; |
|
|
|
|
} else if (usvh < 1000.0f) { |
|
|
|
|
out->danger_level = RAD_LEVEL_3_HIGH_DANGER; |
|
|
|
|
} else { |
|
|
|
|
out->danger_level = RAD_LEVEL_4_SEVERE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (usvh < 999.0f) { |
|
|
|
|
*out_decimals = 2; |
|
|
|
|
return (uint16_t) roundf(usvh * 100.0f); |
|
|
|
|
} |
|
|
|
|
// // for testing only
|
|
|
|
|
// if (usvh < 1.0f) {
|
|
|
|
|
// out->danger_level = RAD_LEVEL_0_SAFE;
|
|
|
|
|
// } else if (usvh < 3.0f) {
|
|
|
|
|
// out->danger_level = RAD_LEVEL_1_ELEVATED;
|
|
|
|
|
// } else if (usvh < 6.0f) {
|
|
|
|
|
// out->danger_level = RAD_LEVEL_2_DANGER;
|
|
|
|
|
// } else if (usvh < 9.0f) {
|
|
|
|
|
// out->danger_level = RAD_LEVEL_3_HIGH_DANGER;
|
|
|
|
|
// } else {
|
|
|
|
|
// out->danger_level = RAD_LEVEL_4_SEVERE;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (usvh < 9999.0f) { |
|
|
|
|
*out_decimals = 1; |
|
|
|
|
return (uint16_t) roundf(usvh * 10.0f); |
|
|
|
|
if (usvh < 99.0f) { |
|
|
|
|
out->usvh_decimals = 3; |
|
|
|
|
out->usvh_num = (uint32_t) roundf(usvh * 1000.0f); |
|
|
|
|
} else if (usvh < 999.0f) { |
|
|
|
|
out->usvh_decimals = 2; |
|
|
|
|
out->usvh_num = (uint32_t) roundf(usvh * 100.0f); |
|
|
|
|
} else if (usvh < 9999.0f) { |
|
|
|
|
out->usvh_decimals = 1; |
|
|
|
|
out->usvh_num = (uint32_t) roundf(usvh * 10.0f); |
|
|
|
|
} else { |
|
|
|
|
out->usvh_decimals = 0; |
|
|
|
|
out->usvh_num = (uint32_t) roundf(usvh); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*out_decimals = 0; |
|
|
|
|
return (uint16_t) roundf(usvh); |
|
|
|
|
} |
|
|
|
|