Berkeley, CA
Offline
Newbie
Karma: 0
Posts: 4
|
 |
« on: May 31, 2011, 05:46:35 pm » |
I'm trying to develop a radiation data logger with an RTC for an upcoming trip to Chernobyl. I'm hoping to use it in conjunction with a GPS datalogger to map radiation hotspots. Equipment: UNO Adafruit Data Logger Shield http://www.ladyada.net/make/logshield/design.htmlGM-10 geiger counter http://www.blackcatsystems.com/GM/products/GM10GeigerCounter.htmlUsing this code from an earlier post by Radioactive: http://arduino.cc/forum/index.php/topic,54367.0.htmlI'm able to log CPM but I can't figure out how to get the csv to include a field of RTC time. I'm really new at this and any help would be greatly appreciated! Code: // Geiger Counter example
/* Adapted by Tracy Albert from programing for a frequecy counter by, Martin Nawrath KHM LAB3 Kunsthochschule f¸r Medien Kˆln Academy of Media Arts http://www.khm.de http://interface.khm.de/index.php/labor/experimente/ */ #include <FreqCounter.h> #include <SD.h> #include <Wire.h> #include "RTClib.h"
#define LOG_INTERVAL 1000 // mills between entries #define CS 10 #define MOSI 11 #define MISO 12 #define SCK 13 #define redLEDpin 2 #define greenLEDpin 3
RTC_DS1307 RTC; // define the Real Time Clock object
/////////////////////////////////////////////////// // // VARAIABLES // Sd2Card card; SdVolume volume; SdFile root; SdFile file;
char name[] = "GEIGER.CSV";
unsigned long frq = 0; unsigned long cnt = 0;
/////////////////////////////////////////////////// // // FUNCTIONS //
// store error strings in flash to save RAM #define error(s) error_P(PSTR(s))
void error_P(const char *str) { PgmPrint("error: "); SerialPrintln_P(str); if (card.errorCode()) { PgmPrint("SD error: "); Serial.print(card.errorCode(), HEX); Serial.print(','); Serial.println(card.errorData(), HEX); // red LED indicates error digitalWrite(redLEDpin, HIGH); } while(1); // effectively STOP the sketch }
void writeToFile(char *fileName, char *str) { if (file.open(root, fileName, O_CREAT | O_APPEND | O_WRITE)) { file.write((uint8_t *)str, strlen(str)); file.close(); } }
unsigned long getFrequency() { unsigned long freq = 0;
FreqCounter::f_comp=10; // Cal Value / Calibrate with professional Freq Counter FreqCounter::start(1000L); // 1 sec Gate Time L to force long. while (FreqCounter::f_ready == 0) { freq = FreqCounter::f_freq; } return freq; }
/////////////////////////////////////////////////// // // SETUP // void setup(void) { Serial.begin(9600); Serial.println("Geiger Counter 0.1");
// SD card error 1,ff fix. pinMode(CS, OUTPUT); pinMode(MOSI, OUTPUT); pinMode(MISO, INPUT); pinMode(SCK, OUTPUT); pinMode(10, OUTPUT); pinMode(redLEDpin, OUTPUT); pinMode(greenLEDpin, OUTPUT); // init all for SD access. if (!card.init(true)) error("card.init"); if (!volume.init(card)) error("volume.init"); if (!root.openRoot(volume)) error("openRoot");
Serial.println("Setup ready"); }
/////////////////////////////////////////////////// // // LOOP - FOREVER // void loop() { DateTime now;
// delay for the amount of time we want between readings delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); digitalWrite(greenLEDpin, HIGH);
// GET MEASUREMENT frq = getFrequency();
// DISPLAY IT ON SERIAL Serial.print(cnt++); Serial.print(" cpm: "); Serial.println(frq); // fetch the time now = RTC.now(); Serial.print(", "); Serial.print(now.year(), DEC); Serial.print("/"); Serial.print(now.month(), DEC); Serial.print("/"); Serial.print(now.day(), DEC); Serial.print(" "); Serial.print(now.hour(), DEC); Serial.print(":"); Serial.print(now.minute(), DEC); Serial.print(":"); Serial.print(now.second(), DEC); // WRITE TO FILE char buffer[32]; // all fields comma separated so Excel can make a graph sprintf(buffer, "%ld, cpm, %ld, Hz \r\n", cnt, frq, now);
writeToFile(name, buffer); }
|
|
|
|
|
Logged
|
|
|
|
|
Central MN, USA
Offline
Faraday Member
Karma: 38
Posts: 6050
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
|
 |
« Reply #1 on: May 31, 2011, 06:05:58 pm » |
Safety first friend! You will need a commercial counter with you. Regarding your question. I don't know either how to do a Geiger counter or SD card write but these three lines are very awfully close to what you want to do: char buffer[32]; // all fields comma separated so Excel can make a graph sprintf(buffer, "%ld, cpm, %ld, Hz \r\n", cnt, frq, now);
Currently the sprintf is just formatting cnt and frg. But there is no formatting for "now". Plus, now is not a basic data type, you should use now.minute for instance instead of now. So try the following to see if it works. char buffer[64]; // all fields comma separated so Excel can make a graph sprintf(buffer, "%ld, cpm, %ld, Hz %d minute \r\n", cnt, frq, now.minute);
If it works, just try expanding the code to include all date stuff you need.
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9551
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #2 on: June 03, 2011, 04:03:28 am » |
For your safety you should seriously consider to take a commercial radiationMeter. For the arduino sketch I would change the structure of your main loop (because of safety). main changes: - It continuesly displays the value on serial => see an accurate reading any time (display and SD card are now decoupled - it uses the LEDS to indicate the exceeding of a THRESHOLD value // to be defined. - it logs at fixed intervals AND if safety thresholds are exceeded - it creates a new logfile every day. This is more robust than using one file. Hopes this helps, unsigned long lastLogTime = 0; unsigned long lastDisplayTime = 0;
void loop() { // GET MEASUREMENTS unsigned long frq = getFrequency(); DateTime now = RTC.now();
if (frq < THRESHOLD_SAFE) // use the LEDS for warning !! { digitalWrite(greenLEDpin, HIGH); digitalWrite(redLEDpin, LOW); } else if (frq < THRESHOLD_WARNING) { digitalWrite(greenLEDpin, HIGH); digitalWrite(redLEDpin, HIGH); } else // SERIOUS RISK !! { digitalWrite(greenLEDpin, LOW); digitalWrite(redLEDpin, HIGH); // add a buzzer here for when you are sleeping??? }
// DISPLAY MEASUREMENTS ON SERIAL if (millis() - lastDisplayTime > DISPLAY_INTERVAL) // set this to e.g. 250 millis = 4x second { Serial.print(now.hour(), DEC); Serial.print(":"); Serial.print(now.minute(), DEC); Serial.print(":"); Serial.print(now.second(), DEC); Serial.print(" "); Serial.print(cnt++, DEC); Serial.print(" cpm."); Serial.print(frq); Serial.println(" hz. "); lastDisplayTime = millis(); }
// LOG EVERY INTERVAL OR IF FRQ IS TOO HIGH !! if ((millis() - lastLogTime > LOG_INTERVAL) || (frq > THRESHOLD_SAFE)) { // WRITE TO FILE // fields comma separated so Excel can make a graph - structure: DATE, TIME, CNT, FREQ char buffer[64]; sprintf(buffer, "%d-%d-%d, %d:%d:%d, %ld, %ld\r\n", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second(), cnt, frq );
char logFileName[24]; sprintf(logFileName, "%04d%02d%02d.csv", now.year(), now.month(), now.day());
writeToFile(logFileName, buffer); lastTime = millis(); } } Can you post the schematics of your device? Rob
|
|
|
|
|
Logged
|
|
|
|
|
Berkeley, CA
Offline
Newbie
Karma: 0
Posts: 4
|
 |
« Reply #3 on: July 07, 2011, 01:30:43 pm » |
Ah thanks for the help, I ended up pretty much completely redoing the code. I've got it working but the .txt files are coming out strange. I think using a string would work but I can't figure out how to get those to work. Pictures of the device here (with case I milled for it): http://www.flickr.com/photos/aceshigh450/5819196351/Schematic for the device: http://www.flickr.com/photos/aceshigh450/5912525613/And the new code: #include <FreqCounter.h> //FREQ #include <Wire.h> //For RTC #include "RTClib.h" //For RTC RTC_DS1307 RTC; //For RTC #include <SD.h> //For log const int chipSelect = 10; File myFile;
void setup() {
//Start Serial Serial.begin(57600); // connect to the serial port Serial.println("Frequency Counter"); //Start RTC Wire.begin(); RTC.begin(); if (! RTC.isrunning()) { Serial.println("RTC is NOT running!");} if (RTC.isrunning()){ Serial.println("RTC is running");} //Check SD Serial.print("Initializing SD card..."); pinMode(10, OUTPUT); // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); digitalWrite(2, HIGH); // set the LED on return; } Serial.println("card initialized.");
//Prep File //file open myFile = SD.open("test.txt", FILE_WRITE); //write to it: if (myFile) { Serial.print("Writing to test.txt..."); myFile.println("timestamp,date,time, cps,"); //note consistant data structure here //timestamp, date, time, cps<frq> // close the file: myFile.close(); Serial.println("ready."); } } long int cpm; long int frq;
void loop() { ///FREQ Counter components FreqCounter::f_comp= 10; // Set compensation to 12 //////////////////////IMPORTANT CHANGE INTERVAL FOR READINGS HERE/////////////// FreqCounter::start(1000); // Start counting with gatetime of 1000ms while (FreqCounter::f_ready == 0) // wait until counter ready
frq=FreqCounter::f_freq; // read result Serial.print("cps:"); Serial.println(frq); // print result ///RTC components DateTime now = RTC.now();
Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(' '); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.print(':'); Serial.print("gmt"); Serial.println(); Serial.println(); ///SAFETY // use the LEDS for warning !! //2CPS=117CPM=1.02µSv/hr=24.65µSv/dy=9000µSv/yr 9mSv/yr Airline safe dose if (frq <= 11) //11Cps=649cpm=5.70µSv/hr=136.98µSv/dy=50000µSv/yr 50mSv/yr Nuclear Worker Limit { digitalWrite(3, HIGH); digitalWrite(2, LOW); } else if (frq >11 && frq <= 22) //22Cps=1305cpm=11.415µSv/hr=273.96µSv/dy=100000µSv/yr 100000mSv/yr Threshold for detectable cancer risk { digitalWrite(3, HIGH); digitalWrite(2, HIGH); } else if (frq > 22) // { digitalWrite(3, LOW); digitalWrite(2, HIGH); } ///2=RED 3=GREEN /// Logging //file open myFile = SD.open("test.txt", FILE_WRITE); //write to it: if (myFile) { Serial.print("logging..."); //note consistant data structure here //timestamp, date, time, cps<frq> myFile.println(now.unixtime()); myFile.println(','); myFile.println(now.year(), DEC); myFile.println('/'); myFile.println(now.month(), DEC); myFile.println('/'); myFile.println(now.day(), DEC); myFile.println(','); myFile.println(now.hour(), DEC); myFile.println(':'); myFile.println(now.minute(), DEC); myFile.println(':'); myFile.println(now.second(), DEC); myFile.println(':'); myFile.println("gmt"); myFile.println(','); myFile.println(frq); // close the file: myFile.close(); Serial.println("done"); } }
I've included some safety features and the group I'm with will have a professional monitor. Also an example of the .txt data I'm getting out: timestamp,date,time, cps 1310058629 , 2011 / 7 / 7 , 17 : 10 : 29 : gmt , 0 1310058631 , 2011 / 7 / 7 , 17 : 10 : 31 : gmt , 0 1310058632 , 2011 / 7 / 7 , 17 : 10 : 32 : gmt , 0
Excel cant seem to wrap its head around the above (also I will hit the 65,000 row limit very quickly) What I'm hoping for is something formated timestamp,date, time, cps so 2011/xx/xx,xx:xx:xx:gmt, cps Any tips would be greatly appreciated!
|
|
|
|
« Last Edit: July 07, 2011, 01:33:03 pm by UrbexArch »
|
Logged
|
|
|
|
|
Denver
Offline
God Member
Karma: 19
Posts: 777
Inactive - PM
|
 |
« Reply #4 on: July 07, 2011, 03:14:41 pm » |
UberxArch I have Geiger logging sketch for the Adafruit data logging shield, that you might find useful . . . https://sites.google.com/site/diygeigercounter/logging-with-the-geiger-kitIt's not "Chernobyl certified", so take appropriate cautions with anything you will bring there. John
|
|
|
|
|
Logged
|
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom." ~ Clifford Stoll
|
|
|
|
Berkeley, CA
Offline
Newbie
Karma: 0
Posts: 4
|
 |
« Reply #5 on: July 08, 2011, 01:41:39 pm » |
John, Thats really impressive work! I was considering doing a more integrated solution like that using the board itself then opted for the more simple one that I can have the logger isolated from the sensor. Ya that sketch is intense, I guess what I'm trying to understand is how the string works, I can't get them to include the data I want in a usable format, I see you used the one from the logger example, I'm still lost...any tips? Thanks Bryan
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9551
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #6 on: July 08, 2011, 02:26:45 pm » |
change myFile.println() in myFile.print(): The ln stands for newline... if (myFile) { Serial.print("logging..."); //note consistant data structure here //timestamp, date, time, cps<frq> myFile.print(now.unixtime()); myFile.print(','); myFile.print(now.year(), DEC); myFile.print('/'); myFile.print(now.month(), DEC); myFile.print('/'); myFile.print(now.day(), DEC); myFile.print(','); myFile.print(now.hour(), DEC); myFile.print(':'); myFile.print(now.minute(), DEC); myFile.print(':'); myFile.print(now.second(), DEC); myFile.print(':'); myFile.print("gmt"); myFile.print(','); myFile.println(frq); // close the file: myFile.close(); Serial.println("done"); } Alternative you could use sprintf() to get better formatted lines. (leading zero's etc) char buffer[80]; // size can be adjusted of course sprintf(buffer, " %ld, %04d/%02d/%02d, %02d:%02dd:%02d:gmt, %ld", now.unixtime(), now.year(), now.month(), now.day(), now.hour(), mow.minute(), now.second(), frq); myFile.println(buffer);
|
|
|
|
|
Logged
|
|
|
|
|
Berkeley, CA
Offline
Newbie
Karma: 0
Posts: 4
|
 |
« Reply #7 on: July 10, 2011, 10:47:13 am » |
Wow this is great! Thanks so much for the help John and robtillaart. I did a test today using the logger and my GPS unit looks promising. I'll post some data when I get back. Thanks again!
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9551
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #8 on: July 10, 2011, 02:24:34 pm » |
I'll post some data when I get back Yes, do get back safely. Chernobyl is a very nice enviroment in the visible spectrum - saw a documentary last year, BBC??? amazing nature - but still radioactive!!
|
|
|
|
|
Logged
|
|
|
|
|
|