#include <Wire.h>
#include <LiquidCrystal_I2C.h> //从库管理器添加1602I2C库
#include <SPI.h>
#define LOG_PERIOD 2000
#define MAX_PERIOD 60000
unsigned long counts; // GM 变量
unsigned long long int counts_all;//longlong
unsigned long cpm; // CPM 变量
double total_doze;
unsigned int multiplier; //设置换算变量
unsigned long previousMillis; //测量时间
float usv;
char total_doze_display[8];
LiquidCrystal_I2C lcd(0x27, 16, 2); //设置LCD地址为 0x27 (1602显示器)
char convert(int a){return char(a+int('0'));}
void number_proc(double k){
if (k<1){
total_doze_display[0]='.'; total_doze_display[1]=convert(int(k*10)%10); total_doze_display[2]=convert(int(k*100)%10); total_doze_display[3]=convert(int(k*1000)%10); total_doze_display[4]=convert(int(k*10000)%10);
total_doze_display[5]='u'; total_doze_display[6]='S'; total_doze_display[7]='v';
}
else if(k<10){
dtostrf(k,5,3,total_doze_display);
total_doze_display[5]='u'; total_doze_display[6]='S'; total_doze_display[7]='v';
}
else if(k<100){
dtostrf(k,5,2,total_doze_display);
total_doze_display[5]='u'; total_doze_display[6]='S'; total_doze_display[7]='v';
}
else if(k<1000){
dtostrf(k,5,1,total_doze_display);
total_doze_display[5]='u'; total_doze_display[6]='S'; total_doze_display[7]='v';
}
else if(k<10000){
dtostrf(k/1000,5,3,total_doze_display);
total_doze_display[5]='m'; total_doze_display[6]='S'; total_doze_display[7]='v';
}
else if(k<100000){
dtostrf(k/1000,5,2,total_doze_display);
total_doze_display[5]='m'; total_doze_display[6]='S'; total_doze_display[7]='v';
}
return;
}
void tube_impulse() {
counts++;
counts_all++;
}
void setup()
{
counts = 0;
cpm = 0; //计数
multiplier = MAX_PERIOD / LOG_PERIOD; //计算乘数,取决于周期
//Serial.begin(9600);
attachInterrupt(0, tube_impulse, FALLING); //中断为下降沿触发
//////////////////
lcd.init();
// 输出数据到屏幕
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("GM tube starting"); //写一个开机boot加载的画面,提供一个盖革管启动的时间。
lcd.setCursor(0, 1);
for(int i=0;i<16;i++)
{
lcd.write(0xff);
delay(250);
}
lcd.clear();
}
void loop()
{
unsigned long currentMillis = millis();
lcd.setCursor(7, 0);
lcd.print("Ct.");
lcd.print(counts);
lcd.print(" ");
if (currentMillis - previousMillis > LOG_PERIOD) {
previousMillis = currentMillis;
cpm = counts * multiplier;//得出计数次数
usv = float(cpm) / 151;//带入公式计算出辐射强度
lcd.setCursor(0, 0);
lcd.print("CPM");
lcd.setCursor(3, 0);
lcd.print(" ");
lcd.setCursor(3, 0);
lcd.print(cpm);//输出cpm值
lcd.setCursor(0, 1);//第二行
lcd.print(usv);
lcd.print("/h");//输出强度值
//lcd.setCursor(8, 0);
//lcd.print(counts);
counts = 0;//复位
lcd.setCursor(7,1);
total_doze=double(counts_all)/9060;
number_proc(total_doze);
lcd.print(total_doze_display);
if (usv >= 10)
{
lcd.setCursor(15, 1);
lcd.print("*");//如果辐射大于10则显示危险
}
else if (usv < 10 && usv >= 0.52)
{
lcd.setCursor(15, 1);
lcd.print("!");//在0.52-10这个范围显示不安全
}
else if (usv < 0.52)
{
lcd.setCursor(15, 1);
lcd.print("-");//在这个值以下显示安全
}
delay(0.1);
}
}