/*
Based on TLS237 sensor (same as used in Unihedron Sky Meter)
Arduino Nano compact design.
*/

#include <FreqMeasure.h> // https://www.pjrc.com/teensy/td_libs_FreqMeasure.html
#include <Math.h>

// Режим отладки
// В этом режиме отладочная информация выводится в последовательный порт.
#define DEBUG

unsigned long time;
double gainCorrection = 1.0;
double ZP = 22.0; //ZP is the zero point, defined as the light input that produces an output of 1 Hz.
float M;//magnitudes/arcSecond2

int pinSensor = 8;// 12pin ATMEGA168/328
int pinButtonStart = 2;
int wait =0;

#define readSensor  digitalRead(pinSensor)
#define buttonRead  digitalRead(pinButtonStart)

void setup() 
{                
  pinMode(pinSensor, INPUT_PULLUP);
  pinMode(pinButtonStart, INPUT_PULLUP); 
  Serial.begin(9600);
}

void loop() 
{
  String cmd;
  if(Serial.available() > 0)
  {
    cmd = Serial.readStringUntil('#');
    if(cmd == "START")
    {
      Serial.print("OK"); Serial.println("#");
      measurement();
    }
  }
  if(buttonRead == LOW) buttonPressing();
  digitalWrite(13, LOW);
}

void buttonPressing()
{
  delay(20);
  if(buttonRead == HIGH) return;
  #ifdef  DEBUG
    Serial.println("Pressing button");
  #endif
  measurement();
}

void measurement()
{
  #ifdef  DEBUG
    Serial.println("Start of measurement");
  #endif
  double sum = 0;
  int count = 0;
  delay(1000);
  wait = 1;
  time = millis();
  FreqMeasure.begin();
  while(wait)
  {
    unsigned long currentTime = millis(); 
    if(currentTime >= (time + 30000)) // Time out 30sec.
    {
      Serial.println("Time out error measurement");
      wait = 0;
      FreqMeasure.end();
      return;
    }
    if (FreqMeasure.available()) 
    {
      // average several reading together
      sum = sum + FreqMeasure.read();
      count = count + 1;
      if (count > 30) 
      {
        double frequency = F_CPU/(sum / count);
        sum = 0;
        count = 0;
        #ifdef  DEBUG
          Serial.print("frequency: ");Serial.println(frequency);
        #endif
        //M = (-2.5*log10((frequency) * gainCorrection)) + ZP; //Frequency to magnitudes/arcSecond2 formula
        M = ZP - 2.5*log10((frequency) * gainCorrection); //Frequency to magnitudes/arcSecond2 formula
        wait = 0;
        FreqMeasure.end();
      }
    }
  }
  Serial.print(M); Serial.println(" mag/arcsec2 #");
  #ifdef  DEBUG
    Serial.println("End of measurement");
  #endif
}

/* http://nsbm.darksky.org/tech.php
M = (-2.5 * log10((F-dark frequency)*gain correction))+ZP,
where M is the sky brightness (mag/arcsec2), 
F is the measured frequency (raw, in Hz), 
T is the sensor temperature (C) and ZP is the zero point, 
defined as the light input that produces an output of 1 Hz.
*/



