dosimeter-arduino/dosimeter.cpp

104 lines
2.1 KiB
C++
Raw Permalink Normal View History

2021-12-04 21:22:46 +00:00
#include "dosimeter.h"
2021-12-06 19:02:14 +00:00
#include <Arduino.h>
#include <ESP8266TimerInterrupt.h>
2021-12-04 21:22:46 +00:00
DosimeterType Dosimeter;
static float getCalibrationFactor(int type) {
switch(type) {
case J305:
case M4011:
return 0.0065;
break;
default:
return NAN;
}
}
int type;
volatile int buckets[BUCKETS_PER_MINUTE] = {0};
int last = 0;
bool valid = false;
2021-12-06 19:02:14 +00:00
bool measureDose = false;
volatile float dose = 0;
ESP8266Timer timer;
2021-12-04 21:22:46 +00:00
static inline void clearISR() {
unsigned long gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
}
2021-12-06 19:02:14 +00:00
static void ICACHE_RAM_ATTR geigerISR() {
2021-12-04 21:22:46 +00:00
int next = (millis() / BUCKET_WIDTH_IN_MS) % BUCKETS_PER_MINUTE;
if (last != next) {
for (int i = (last + 1) % BUCKETS_PER_MINUTE; i != next; i = (i + 1) % BUCKETS_PER_MINUTE) {
buckets[i] = 0;
}
buckets[next] = 1;
last = next;
} else {
buckets[next]++;
}
clearISR();
}
2021-12-06 19:02:14 +00:00
// timerISR gets called every minute
static void ICACHE_RAM_ATTR timerISR() {
if (measureDose && valid) {
dose += Dosimeter.getEquivalentDoseRate() / 60;
}
}
2021-12-04 21:22:46 +00:00
void DosimeterType::begin(int pin, int _type) {
type = _type;
pinMode(pin, INPUT);
2021-12-06 19:02:14 +00:00
attachInterrupt(digitalPinToInterrupt(pin), geigerISR, RISING);
timer.attachInterruptInterval(60l * 1000 * 1000, timerISR);
2021-12-04 21:22:46 +00:00
}
int DosimeterType::getCPM() {
int result = 0;
for (int i = 0; i < BUCKETS_PER_MINUTE; i++) {
result += buckets[i];
}
return result;
}
float DosimeterType::getEquivalentDoseRate() {
return getCPM() * getCalibrationFactor(type);
}
2021-12-06 19:02:14 +00:00
float DosimeterType::getEquivalentDose() {
if (measureDose) {
return dose;
} else {
return NAN;
}
}
2021-12-04 21:22:46 +00:00
bool DosimeterType::isValid() {
if (valid) {
return true;
} else {
valid = millis() > (60l * 1000);
return valid;
}
}
2021-12-06 19:02:14 +00:00
void DosimeterType::startRecording() {
dose = 0;
measureDose = true;
}
void DosimeterType::stopRecording() {
measureDose = false;
}