Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geiger first test version #134

Merged
merged 7 commits into from
Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions examples/Radiation_CAJOE/Radiation_CAJOE.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/**
* @file main.cpp
* @date June 2018 - 2021
* @brief Radiation sensor example
* @license GPL3
*
* @license GPL3
*
* Full documentation:
* https://github.com/kike-canaries/canairio_sensorlib#canairio-air-quality-sensors-library
*
* Full implementation for WiFi and Bluetooth Air Quality fixed and mobile station:
* https://github.com/kike-canaries/canairio_firmware#canairio-firmware
*
* CanAirIO project:
* https://canair.io
*/

#include <Arduino.h>

#include <Sensors.hpp>

void onSensorDataOk() {
Serial.print(" CO2: " + sensors.getStringCO2());
Serial.print(" CO2humi: " + String(sensors.getCO2humi()));
Serial.print(" CO2temp: " + String(sensors.getCO2temp()));

Serial.print(" H: " + String(sensors.getHumidity()));
Serial.println(" T: " + String(sensors.getTemperature()));
}

void onSensorDataError(const char* msg) {
Serial.println(msg);
}

/******************************************************************************
* M A I N
******************************************************************************/

void setup() {
Serial.begin(115200);
delay(200);
Serial.println("\n== Sensor test setup ==\n");

Serial.println("-->[SETUP] Detecting sensors..");

sensors.setSampleTime(5); // config sensors sample time interval
sensors.setOnDataCallBack(&onSensorDataOk); // all data read callback
sensors.setOnErrorCallBack(&onSensorDataError); // [optional] error callback
sensors.setDebugMode(true); // [optional] debug mode

sensors.init(); // forced UAQ sensor. Empty for auto detection

delay(500);
}

void loop() {
sensors.loop(); // read sensor data and showed it
}
// *************** GEIGER ****************
// ***************************************



// variables shared between main code and interrupt code
hw_timer_t * timer = NULL;
volatile uint32_t updateTime = 0; // time for next update
volatile uint16_t tic_cnt = 0;

// To calculate a running average over 10 sec, we keep tic counts in 250ms intervals and add all 40 tic_buf values
#define TICBUFSIZE 40 // running average buffer size
volatile uint16_t tic_buf[TICBUFSIZE]; // buffer for 40 times 250ms tick values (to have a running average for 10 seconds)
volatile uint16_t tic_buf_cnt = 0;

// In order to display a history of the last 7 minutes, we keep the last 50 values of 10sec tics
#define SEC10BUFSIZE 50 // history array for displaymode==true
volatile uint16_t sec10 = 0; // every 10 seconds counter
volatile uint16_t sec10_buf[SEC10BUFSIZE]; // buffer to hold 10 sec history (40*10 = 400 seconds)
volatile bool sec10updated = false; // set to true when sec10_buf is updated


// #########################################################################
// Interrupt routine called on each click from the geiger tube
//
void IRAM_ATTR TicISR() {
tic_cnt++;
}

// #########################################################################
// Interrupt timer routine called every 250 ms
//
void IRAM_ATTR onTimer() {
tic_buf[tic_buf_cnt++] = tic_cnt;
tic_cnt = 0;
if (tic_buf_cnt>=TICBUFSIZE) {
uint16_t tot = 0;
for (int i=0; i<TICBUFSIZE; i++) tot += tic_buf[i];
sec10_buf[sec10++] = tot;
tic_buf_cnt = 0;
if (sec10>=SEC10BUFSIZE) sec10 = 0;
sec10updated = true;
}
}

// Convert tics to mR/hr
float tics2mrem(uint16_t tics) {
return float(tics) * TICFACTOR;
}

void geigerInit() {

Serial.begin(115200); // For debug
Serial.println("Geiger counter startup");
updateTime = millis(); // Next update time
// attach interrupt routine to TIC interface from the geiger counter module
pinMode(PINTIC, INPUT);
attachInterrupt(PINTIC, TicISR, FALLING);

// attach interrupt routine to internal timer, to fire every 250 ms
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 250000, true); // 250 ms
timerAlarmEnable(timer);
Serial.println("Geiger counter ready");
}

void geigerLoop() {

// curent mR/hr value to display - add all tics from walking average 10 seconds
uint16_t v=0;
for (int i=0; i<TICBUFSIZE; i++) {
v+=tic_buf[i];
}

// convert tics to mR/hr and put in display buffer for TFT
float mrem = tics2mrem(v);
char buf[12];
dtostrf(mrem, 7, (mrem<1 ? 2: (mrem<10 ? 1 : 0)), buf);

Serial.print("mRem: "); Serial.println (mrem);
Serial.print("tics: "); Serial.println(v);

}

/*// Convert tics to mR/hr
//
float tics2mrem(uint16_t tics) {
return float(tics) * TICFACTOR;
}
*/

/* // convert millirem value to a log percentage on analog and bar graph
//
int mrem2perc(float mrem, int maxperc) {
if (mrem<=0) {
return 0;
} */

147 changes: 146 additions & 1 deletion src/Sensors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ bool Sensors::readAllSensors() {
bme680Read();
dhtRead();
disableWire1();

geigerLoop();;
printValues();
printSensorsRegistered(devmode);
printUnitsRegistered(devmode);
Expand Down Expand Up @@ -117,6 +117,7 @@ void Sensors::init(int pms_type, int pms_rx, int pms_tx) {
sht31Init();
aht10Init();
dhtInit();
geigerInit();
printSensorsRegistered(true);
}

Expand Down Expand Up @@ -1717,3 +1718,147 @@ bool Sensors::serialInit(int pms_type, unsigned long speed_baud, int pms_rx, int
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SENSORSHANDLER)
Sensors sensors;
#endif

// *************** GEIGER ****************
// ***************************************
#ifdef ESP8266
static volatile unsigned long counts = 0;
static int secondcounts[60];
static unsigned long int secidx_prev = 0;
static unsigned long int count_prev = 0;
static unsigned long int second_prev = 0;
#else

// variables shared between main code and interrupt code
hw_timer_t * timer = NULL;
#endif
volatile uint32_t updateTime = 0; // time for next update
volatile uint16_t tic_cnt = 0;

// To calculate a running average over 10 sec, we keep tic counts in 250ms intervals and add all 40 tic_buf values
#define TICBUFSIZE 40 // running average buffer size
volatile uint16_t tic_buf[TICBUFSIZE]; // buffer for 40 times 250ms tick values (to have a running average for 10 seconds)
volatile uint16_t tic_buf_cnt = 0;

// In order to display a history of the last 7 minutes, we keep the last 50 values of 10sec tics
#define SEC10BUFSIZE 50 // history array for displaymode==true
volatile uint16_t sec10 = 0; // every 10 seconds counter
volatile uint16_t sec10_buf[SEC10BUFSIZE]; // buffer to hold 10 sec history (40*10 = 400 seconds)
volatile bool sec10updated = false; // set to true when sec10_buf is updated

#ifdef ESP8266
// interrupt routine
ICACHE_RAM_ATTR static void TicISR()
{
counts++;
}
#else
// #########################################################################
// Interrupt routine called on each click from the geiger tube
//
void IRAM_ATTR TicISR() {
tic_cnt++;
}
#endif

// #########################################################################
// Interrupt timer routine called every 250 ms
//
void IRAM_ATTR onTimer() {
tic_buf[tic_buf_cnt++] = tic_cnt;
tic_cnt = 0;
if (tic_buf_cnt>=TICBUFSIZE) {
uint16_t tot = 0;
for (int i=0; i<TICBUFSIZE; i++) tot += tic_buf[i];
sec10_buf[sec10++] = tot;
tic_buf_cnt = 0;
if (sec10>=SEC10BUFSIZE) sec10 = 0;
sec10updated = true;
}
}

// Convert tics to mR/hr
float tics2mrem(uint16_t tics) {
return float(tics) * TICFACTOR;
}

void geigerInit() {
Serial.begin(115200); // For debug
Serial.println("Geiger counter startup");
#ifndef ESP8266
updateTime = millis(); // Next update time
// attach interrupt routine to TIC interface from the geiger counter module
pinMode(PINTIC, INPUT);
attachInterrupt(PINTIC, TicISR, FALLING);

// attach interrupt routine to internal timer, to fire every 250 ms
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 250000, true); // 250 ms
timerAlarmEnable(timer);
Serial.println("Geiger counter ready");
#else
// start counting
memset(secondcounts, 0, sizeof(secondcounts));
Serial.println("Starting count ...");

pinMode(PINTIC, INPUT);
attachInterrupt(digitalPinToInterrupt(PINTIC), TicISR, FALLING);
#endif
}

void geigerLoop() {
#ifdef ESP32
// curent mR/hr value to display - add all tics from walking average 10 seconds
uint16_t v=0;
for (int i=0; i<TICBUFSIZE; i++) {
v+=tic_buf[i];
}

// convert tics to mR/hr and put in display buffer for TFT
float mrem = tics2mrem(v);
char buf[12];
dtostrf(mrem, 7, (mrem<1 ? 2: (mrem<10 ? 1 : 0)), buf);

Serial.print("mRem: "); Serial.println (mrem);
Serial.print("tics: "); Serial.println(v);
#else
// update the circular buffer every second
unsigned long int second = millis() / 1000;
unsigned long int secidx = second % 60;
if (secidx != secidx_prev) {
// new second, store the counts from the last second
unsigned long int count = counts;
secondcounts[secidx_prev] = count - count_prev;
count_prev = count;
secidx_prev = secidx;
}
// report every LOG_PERIOD
if ((second - second_prev) >= LOG_PERIOD) {
second_prev = second;

// calculate sum
int cpm = 0;
for (int i = 0; i < 60; i++) {
cpm += secondcounts[i];
}
Serial.print("Counts: "); Serial.println(counts);
Serial.print("cpm: "); Serial.println(cpm);
}
#endif
}

/*// Convert tics to mR/hr
//
float tics2mrem(uint16_t tics) {
return float(tics) * TICFACTOR;
}
*/

/* // convert millirem value to a log percentage on analog and bar graph
//
int mrem2perc(float mrem, int maxperc) {
if (mrem<=0) {
return 0;
} */

23 changes: 21 additions & 2 deletions src/Sensors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@
#define CSL_VERSION "0.5.4"
#define CSL_REVISION 357

/**************************************************************
* GEIGER
* ************************************************************/
// Define pin for tics from geiger counter
#ifdef ESP8266
#define PINTIC D5
#else
#define PINTIC 27
#endif
#define TICFACTOR 0.05 // factor between number of tics/second --> mR/hr
#define LOG_PERIOD 10 // for esp8266 variant

/***************************************************************
* S E T U P E S P 3 2 B O A R D S A N D F I E L D S
***************************************************************/
Expand Down Expand Up @@ -98,7 +110,8 @@
X(PRESS, "hPa", "P") \
X(ALT, "m", "Alt") \
X(GAS, "Ohm", "Gas") \
X(UCOUNT, "COUNT", "UCOUNT")
X(UCOUNT, "COUNT", "UCOUNT")\
X(RADIATION, "mR", "mRem")

#define X(unit, symbol, name) unit,
typedef enum UNIT : size_t { SENSOR_UNITS } UNIT;
Expand All @@ -121,7 +134,8 @@ typedef enum UNIT : size_t { SENSOR_UNITS } UNIT;
X(SAHT10, "AHT10", 3) \
X(SAM232X, "AM232X", 3) \
X(SDHTX, "DHTX", 3) \
X(SCOUNT, "SCOUNT", 3)
X(SCOUNT, "SCOUNT", 3) /*\
X(SRADIATION, "CAJOE", 2) */

#define X(utype, uname, umaintype) utype,
typedef enum SENSORS : size_t { SENSORS_TYPES } SENSORS; // backward compatibility
Expand Down Expand Up @@ -441,6 +455,9 @@ class Sensors {
void unitRegister(UNIT unit);

uint8_t *getUnitsRegistered();

// void geigerInit();
// void geigerLoop();

// @todo use DEBUG_ESP_PORT ?
#ifdef WM_DEBUG_PORT
Expand All @@ -455,3 +472,5 @@ extern Sensors sensors;
#endif

#endif
void geigerInit();
void geigerLoop();