// Micro SD card interface
#include <SPI.h>
#include <SD.h>
#define SD_CS 53 // Chip select for micro SD card
String FileName = "";
File myFile;
//------------------------------------------------------------------------------------------------------------------
// Display interface
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27
//------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------
//Dac interface to set the two reference voltages of the two discriminators
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 Discriminator_1;
Adafruit_MCP4725 Discriminator_2;
int Dac_Value;
float Dac_Voltage;
float Discri_1_Max = 4.938; //The maximum voltage of both DAC outputs have been measured with a voltmeter
float Discri_2_Max = 4.896; // These parameters are used to convert the DAC digital input to real voltage
//------------------------------------------------------------------------------------------------------------------
// Gamma Sensor's Interface
#include <Wire.h>
/*
We will be using the I2C hardware interface on the Arduino in
combination with the built-in Wire library to interface.
Arduino analog input 5 - I2C SCL
Arduino analog input 4 - I2C SDA
Command List
0xA0 :: Reset
0xB0 :: Read Status
0xB1 :: Read Measuring Time
0xB2 :: Read Measuring Value (10min avg / 1min update) ( not used in this program )
0xB3 :: Read Measuring Value (1min avg / 1min update)
0xB4 :: Read Firmware Version
Address Assignment
Default Address :: 0x18
A0 Open, A1 Short :: 0x19
A0 Short, A1 Open :: 0x1A
A0 Open, A1 Open :: 0x1B
*/
int addr = 0x18; // address of FTLAB module
unsigned long Delta_t;
byte buffer[2] = {0, 0}; //Buffer is the output data structure for the FTLAB output
int status = 0; // Status of FTLAB internal processor
int Minutes = 0; // Running time in minutes
uint8_t Read_Status = 0xB0; // Definitions of FTLAB commands
uint8_t Read_Firmware = 0xB4;
uint8_t Read_Time = 0xB1;
uint8_t Read_10_Min = 0xB2;
uint8_t Read_Gamma = 0xB3;
float value = 0.0f; // readout of the digital FTLAB output
float Compteur = 0.0f; //Accumulation of the FTLAB digital output up to a time defined by the Scaler variable
float Total_Count; // Total count of the FTLAB digital output
boolean Read_Gamma_Detector = false; // to start and stop the FTLAB
boolean Printer_Status = true; // Set ON or OFF the printout on serial monitor or Excel program
String Ligne = ""; // The result line to be printed
String Voltage1; // Discriminator 1 level
String Voltage2; // Discriminator 2 level
String Fichier; // Filename to write the data on SD card
String Scale;
int Scaler ; // delay between successive printout
int Scaler_Count = 0; // used to start a printout
String Titre = "Gamma FtLab counter file."; // Sample name
boolean Time_Flag = false; // Flag if stop time parameter is set
boolean FtLab_Time = false; // used to start second timer for FTLAB reading
int Stop_Time; // counter to test if Stop Time is reached
volatile long interrupt_Counter; // variable incremented by the first interrupt, used by the analog pulses output
long Pulse_Rate; // interrupt_Counter is loaded into this variable after 60 seconds
long Scaler_Counter; // Accumulation of the counted values up to a time defined by the Scaler variable
volatile long interrupt_Counter_2; // variable incremented by the second interrupt
long Pulse_Rate_2; // interrupt_Counter_2 is loaded into this variable after 60 seconds
long Scaler_Counter_2; // same as Scaler_Counter for discriminator 2
const byte interrupt_Pin = 2; // define the 2 interrupts pins
const byte interrupt_Pin_2 = 3;
unsigned long milli_Begin; // Start and stop timer variables
unsigned long milli_End;
unsigned long G_Time_Begin; // Start and stop timer variables for FTLAB readings
unsigned long G_Time_End;
boolean SD_Card = false;
// Send command to FTLAB internal processor and read output data
void Gamma_Mod_Read(int cmd)
{
/* Begin Write Sequence */
Wire.beginTransmission(addr);
Wire.write(cmd);
Wire.endTransmission();
/* End Write Sequence */
delay(10);
/* Begin Read Sequence */
Wire.requestFrom(addr, 2);
byte i = 0;
while (Wire.available())
{
buffer[i] = Wire.read();
i++;
}
/* End Read Sequence */
/* View Results */
//Print_Result(cmd);
}
void software_Reset()
{
asm volatile (" jmp 0");
}
void setup()
{
//Arduino Initialize
Serial.begin(9600);
Wire.begin();
//Read Firmware version
Gamma_Mod_Read(0xB4);
//Reset before operating the sensor
Gamma_Mod_Read(0xA0);
Gamma_Mod_Read(Read_Status);
Serial.print("SD card ");
if (!SD.begin(SD_CS))
{
Serial.println("initialization failed!");
}
else
{
Serial.println("initialization OK.");
}
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Scaler = 5;
Delta_t = 2 * 1000 - 200;
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.noAutoscroll();
lcd.setCursor(0, 0);
lcd.print("Gamma counter");
pinMode(interrupt_Pin, INPUT); // Set interrupts pins
pinMode(interrupt_Pin_2, INPUT);
Discriminator_1.begin(0x60); // Set reference voltage to the discriminators
Discriminator_1.setVoltage(0, false);
Discriminator_2.begin(0x61);
Discriminator_2.setVoltage(0, false);
}
// Two interrupt routines for the analog output counters
void Pulse_Detected()
{
interrupt_Counter ++;
}
void Pulse_Detected_2()
{
interrupt_Counter_2 ++;
}
void loop()
{
String Command = "";
boolean wait_read;
String parameter; // reading the parameter from Excel program after a command is accepted
Serial.flush();
// Management of the commands
if (Serial.available() > 0)
{
Command = Serial.readStringUntil(':'); // Use of colon (:) as a separator to indicate an end of string
if (Command == "Start") // Start all counters
{
if (SD_Card)
{
if (FileName == "")
{
Serial.println("No file Name!");
}
else
{
if ( SD.exists(FileName))
{
Serial.println("File exist!");
}
else
{
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open(FileName, FILE_WRITE);
}
}
}
Scaler_Count = 0;
Compteur = 0;
Minutes = 0;
interrupt_Counter = 0;
interrupt_Counter_2 = 0;
Scaler_Counter = 0;
Scaler_Counter_2 = 0;
Total_Count = 0;
FtLab_Time = false;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" Time: ");
lcd.setCursor(0, 2);
lcd.print("Counts: ");
lcd.setCursor(0, 3);
lcd.print(" Total: ");
if (myFile)
{
myFile.println(Titre + " " + Fichier + " " + Voltage1 + " " + Voltage2);
myFile.println("Time (minutes) ; Ftlab counts ;Discriminator 1;Discriminator 2");
}
Gamma_Mod_Read(0xA0);
Gamma_Mod_Read(Read_Status);
attachInterrupt(digitalPinToInterrupt(interrupt_Pin), Pulse_Detected, RISING);
attachInterrupt(digitalPinToInterrupt(interrupt_Pin_2), Pulse_Detected_2, FALLING);
interrupt_Counter_2 = 0;
interrupt_Counter = 0;
milli_Begin = millis();
G_Time_Begin = millis();
Read_Gamma_Detector = true;
Serial.println("Counter Started");
if ( Printer_Status )
{
//Serial.print(Titre);
//Serial.println(";");
delay(500);
Serial.print("Minutes");
Serial.print(";");
Serial.print("FTLAB counter");
Serial.print(";");
Serial.print("Discriminator 1");
Serial.print(";");
Serial.print("Discriminator 2");
Serial.println(";");
}
}
if (Command == "Stop") // Manual stop of all counters
{
Read_Gamma_Detector = false;
// close the file:
myFile.println("Manual stop");
myFile.close();
detachInterrupt(digitalPinToInterrupt(interrupt_Pin));
detachInterrupt(digitalPinToInterrupt(interrupt_Pin_2));
Serial.println("File closed. Gamma Counter Stopped.");
}
if (Command == "Reset") // reset microcontroller
{
software_Reset();
}
if (Command == "Scaler") // set delay time between each printout
{
wait_read = true;
while (wait_read)
{
if (Serial.available() > 0)
{
wait_read = false;
parameter = Serial.readStringUntil(':');
//Serial.println(parameter);
if (parameter.toInt() > 0)
{
Scale = parameter;
Scaler = parameter.toInt();
Serial.print("Scaler = ");
Serial.println(Scaler);
}
else
{
Serial.println("Parameter Error!");
}
}
}
}
if (Command == "Stop_Time") // Total counting time
{
wait_read = true;
while (wait_read)
{
if (Serial.available() > 0)
{
parameter = Serial.readStringUntil(':');
wait_read = false;
if (parameter.toInt() > 0)
{
Stop_Time = parameter.toInt();
Time_Flag = true;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Max Time: ");
lcd.setCursor(11, 0);
lcd.print(Stop_Time);
Serial.print("Stop Time = ");
Serial.println(Stop_Time);
}
else
{
Serial.println("Parameter Error!");
}
}
}
}
if (Command == "Discri_1") // Set discriminator 1 Voltage
{
wait_read = true;
while (wait_read)
{
if (Serial.available() > 0)
{
parameter = Serial.readStringUntil(':');
wait_read = false;
Voltage1 = " Discriminator 1 = " + parameter + "V";
Dac_Voltage = parameter.toFloat();
if ((Dac_Voltage >= 0) && (Dac_Voltage < Discri_1_Max))
{
Serial.print("Discri 1 voltage = ");
Serial.println(Dac_Voltage, 3);
Dac_Voltage = Dac_Voltage / Discri_1_Max * 4095 ;
Dac_Value = (int) Dac_Voltage;
Discriminator_1.setVoltage(Dac_Value, false);
}
else
{
Serial.println("Parameter Error!");
}
}
}
}
if (Command == "Discri_2") // Set discriminator 2 Voltage
{
wait_read = true;
while (wait_read)
{
if (Serial.available() > 0)
{
parameter = Serial.readStringUntil(':');
wait_read = false;
Voltage2 = " Discriminator 2 = " + parameter + "V";
Dac_Voltage = parameter.toFloat();
if ((Dac_Voltage >= 0) && (Dac_Voltage < Discri_2_Max))
{
Serial.print("Discri 2 voltage = ");
Serial.println(Dac_Voltage, 3);
Dac_Voltage = Dac_Voltage / Discri_2_Max * 4095 ;
Dac_Value = (int) Dac_Voltage;
Discriminator_2.setVoltage(Dac_Value, false);
}
else
{
Serial.println("Parameter Error!");
}
}
}
}
if (Command == "File_Name") // Set filename for SD card
{
wait_read = true;
while (wait_read)
{
if (Serial.available() > 0)
{
FileName = Serial.readStringUntil(':');
Fichier = FileName;
FileName = FileName + ".csv";
wait_read = false;
if ( SD.exists(FileName) )
{
Serial.println("File exist!");
}
else
{
Serial.println("File Name " + FileName + " OK");
}
}
}
}
if (Command == "Titre") // General purpose info, most of the time used for the rock or mineral name.
{
wait_read = true;
//Serial.println(Command);
while (wait_read)
{
if (Serial.available() > 0)
{
Titre = Serial.readStringUntil(':');
wait_read = false;
myFile.println(Titre);
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(Titre.substring(0, 19));
Serial.print("Titre = ");
Serial.println(Titre);
}
}
}
if (Command == "SD_Card") // Set SD card ON or OFF
{
wait_read = true;
while (wait_read)
{
if (Serial.available() > 0)
{
parameter = Serial.readStringUntil(':');
wait_read = false;
if ( parameter == "ON" )
{
Serial.println("SD_Card ON");
SD_Card = true;
}
else
{
Serial.println("SD_Card Off");
SD_Card = false;
//Serial.println("OK");
}
}
}
}
if (Command == "Printer") // Set printout ON or OFF
{
wait_read = true;
while (wait_read)
{
if (Serial.available() > 0)
{
parameter = Serial.readStringUntil(':');
wait_read = false;
if ( parameter == "ON" )
{
Serial.println("Printer ON");
Printer_Status = true;
}
else
{
Serial.println("Printer Off");
Printer_Status = false;
}
}
}
}
}
// Executed after command Start, read the data from all counters and send results to Excel or SD card.
if (Read_Gamma_Detector)
{
milli_End = millis();
if ((milli_End - milli_Begin) >= 60000) // 60 sec timer forced by FTLAB internal software
{
// Gestion pulse counter
milli_Begin = milli_End;
Pulse_Rate = interrupt_Counter;
Pulse_Rate_2 = interrupt_Counter_2;
interrupt_Counter =0;
interrupt_Counter_2 =0;
FtLab_Time = true;
G_Time_Begin = millis();
Minutes ++;
}
if (FtLab_Time) // Start 5 seconds timer after each 60 sec period before accressing the FTLAB internal processor for measurement reading.
{
G_Time_End = millis();
if ((G_Time_End - G_Time_Begin) >= 5000)
{
FtLab_Time = false;
//G_Time_Begin = G_Time_End;
Scaler_Count ++ ;
Gamma_Mod_Read(Read_Gamma);
value = (buffer[0] + (float)buffer[1] / 100) * 12 / 1.44; //Calculates the number of counts read from FTLAB internal processor.
Compteur = Compteur + value;
Total_Count = Total_Count + value;
Scaler_Counter = Scaler_Counter + Pulse_Rate;
Scaler_Counter_2 = Scaler_Counter_2 + Pulse_Rate_2;
if (Scaler_Count >= Scaler) // Print results after "Scaler" time.
{
// Creates results string for printout.
Ligne = String(Minutes) + " ; " + String(Compteur) + " ; " + String(Scaler_Counter) + " ; " + String(Scaler_Counter_2);
if (SD_Card)
{
myFile.println(Ligne); // Data sent to SD card.
myFile.flush();
}
if ( Printer_Status )
{
Ligne = Ligne + ";";
Serial.println(Ligne); // Data sent to Excel or Arduino serial monitor.
}
// Data sent to small LCD display
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(Scaler_Counter);
lcd.setCursor(10, 0);
lcd.print(" ");
lcd.setCursor(10, 0);
lcd.print(Scaler_Counter_2);
lcd.setCursor(8, 1);
lcd.print(Minutes);
lcd.setCursor(8, 2);
lcd.print(" ");
lcd.setCursor(8, 2);
lcd.print(Compteur, 0);
lcd.setCursor(8, 3);
lcd.print(Total_Count, 0);
//Reset the counters after printout
Compteur = 0;
Scaler_Count = 0;
Scaler_Counter = 0;
Scaler_Counter_2 = 0;
}
if (Time_Flag)
{
if (Stop_Time <= Minutes) // Stops all counters
{
detachInterrupt(digitalPinToInterrupt(interrupt_Pin));
detachInterrupt(digitalPinToInterrupt(interrupt_Pin_2));
Read_Gamma_Detector = false;
// close the file:
if (SD_Card)
{
myFile.close();
}
delay(1000);
Serial.println("Counter_Stopped");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print("Counter Stopped");
}
}
}
}
}
}