diff --git a/dosimeter.cpp b/dosimeter.cpp new file mode 100644 index 0000000..4c0b7d1 --- /dev/null +++ b/dosimeter.cpp @@ -0,0 +1,71 @@ +#include "dosimeter.h" + +#include "Arduino.h" + +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; + +static inline void clearISR() { + unsigned long gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status); +} + +static void ICACHE_RAM_ATTR isr() { + 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(); +} + +void DosimeterType::begin(int pin, int _type) { + type = _type; + + pinMode(pin, INPUT); + attachInterrupt(digitalPinToInterrupt(pin), isr, RISING); +} + +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); +} + +bool DosimeterType::isValid() { + if (valid) { + return true; + } else { + valid = millis() > (60l * 1000); + return valid; + } +} diff --git a/dosimeter.h b/dosimeter.h new file mode 100644 index 0000000..3fa982a --- /dev/null +++ b/dosimeter.h @@ -0,0 +1,23 @@ +#ifndef _DOSIMETER_H_ +#define _DOSIMETER_H_ + +#define M4011 (1) +#define J305 (2) + +#define BUCKETS_PER_MINUTE (60) +#define BUCKET_WIDTH_IN_MS ((60l * 1000) / BUCKETS_PER_MINUTE) + +class DosimeterType { +public: + void begin(int pin, int type); + + bool isValid(); + + float getEquivalentDoseRate(); + int getCPM(); +private: +}; + +extern DosimeterType Dosimeter; + +#endif diff --git a/examples/example.ino b/examples/example.ino new file mode 100644 index 0000000..5c43fb7 --- /dev/null +++ b/examples/example.ino @@ -0,0 +1,30 @@ +#include + +#define TUBE_PIN (4) + +void setup() { + Serial.begin(9600); + + Dosimeter.begin(TUBE_PIN, J305); +} + +void loop() { + Serial.print("CPM: "); + Serial.print(Dosimeter.getCPM()); + if (Dosimeter.isValid()) { + Serial.println(); + } else { + Serial.println(" (invalid)"); + } + + Serial.print("dose rate: "); + Serial.print(Dosimeter.getEquivalentDoseRate()); + Serial.print(" µSv/h"); + if (Dosimeter.isValid()) { + Serial.println(); + } else { + Serial.println(" (invalid)"); + } + + delay(1000); +}