// These constants should match the photoresistor's "gamma" and "rl10" attributes
const float    GAMMA      = 0.7;
const float    RL10       = 50;
const int      SENSOR_PIN = A0;
const int      LED_PIN    = 12;
const uint32_t MAX_LUX    = 2000;
const uint8_t  MAX_PWM    = 255;
const String LUX_MESS = "Current lux read: ";
const String PWM_MESS = "Current PWM calc: ";

float prevLux;
uint8_t prevPWM;

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  float lux = readAnalogLux(SENSOR_PIN);
  luxToSM(lux);
  uint8_t pwm = getPWMVal(lux);
  analogWrite(LED_PIN, pwm);
}

float readAnalogLux(const int pin) {
  // Convert the analog value into lux value:
  int analogValue = analogRead(pin);
  float voltage = analogValue / 1024. * 5;
  float resistance = 2000 * voltage / (1 - voltage / 5);
  float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
  return lux;
}

uint8_t getPWMVal(const float currLux) {
  if (currLux > MAX_LUX) {
    return 0;
  }
  // The value of the LED should be inversely proportional to the birghtness read
  uint8_t currPWM = MAX_PWM - (currLux * MAX_PWM / MAX_LUX);
  pwmToSM(currPWM);
  return currPWM;
}

void pwmToSM(const uint8_t pwmVal) {
  if (prevPWM != pwmVal) {
    prevPWM = pwmVal;
    Serial.print(PWM_MESS);
    Serial.println(pwmVal);
  }
}

void luxToSM(const float luxVal) {
  if (prevLux != luxVal) {
    prevLux = luxVal;
    Serial.print(LUX_MESS);
    Serial.println(luxVal);
  }
}