#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);
  }

 

}