/*
  Sensor LDR using Franzininho DIY, photoresistor and SSD1306
  by Anderson Costa with ❤ for the Wokwi community
  Visit https://wokwi.com to learn about the Wokwi Simulator
  Visit https://franzininho.com.br to learn about the Franzininho
*/
#include <TinyWireM.h>
#include <Tiny4kOLED.h>

#define LDR_PIN A3

// Essas constantes devem corresponder aos atributos "gama" e "rl10" do fotoresistor
const float GAMMA = 0.7;
const float RL10 = 50;

void setup() {
  // Configura como entrada o pino do fotoresistor
  pinMode(LDR_PIN, INPUT);

  // Inicializa o display oled
  oled.begin();

  // Duas fontes são fornecidas com esta biblioteca, FONT6X8 e FONT8X16
  oled.setFont(FONT6X8);

  // Limpa toda a memória do display
  oled.clear();

  splash();
  delay(3000);

  initDisplay();
}

void loop() {
  static unsigned long startTime = 0;
  unsigned long currentTime;

  // Retorna o número de milissegundos passados
  // desde que começou a executar o programa atual
  currentTime = millis();

  // Verifica se passou 1 segundo
  if ((currentTime - startTime) >= 1000) {
    // Reseta o temporizador
    startTime = currentTime;
    // Atualiza o display
    updateDisplay();
  }
}

void initDisplay() {
  oled.clear();
  oled.begin();
  oled.setCursor(18, 1);
  oled.print(F("Franzininho+LDR"));
}

void updateDisplay() {
  // Atualiza a iluminância
  float lux = getLux();

  // Posiciona o cursor
  oled.setCursor(40, 4);

  // Imprime a iluminância no display
  oled.print(lux, 1);
  oled.print(" lux     ");

  // Posiciona o cursor
  oled.setCursor(32, 5);
  oled.print("          ");
}

void splash() {
  oled.clear();
  oled.setCursor(18, 1);
  oled.print(F("Franzininho+LDR"));

  oled.setCursor(42, 3);
  oled.print(F("Exemplo"));

  oled.setCursor(32, 5);
  oled.print(F("LDR Sensor"));

  oled.setCursor(35, 7);
  oled.print(F("wokwi.com"));
}

float getLux() {
  // Converte o valor analógico em valor lux:
  int analogValue = analogRead(LDR_PIN);
  // Calcula a tensão com base no valor recebido do fotoresistor
  float voltage = analogValue / 1024. * 5;
  // Calcula a resistência com base na tensão
  float resistance = 2000 * voltage / (1 - voltage / 5);
  // O valor gama determina a inclinação do gráfico log(R) / log(lx)
  float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
  return lux;
}