/*    Project: MassControl
 *     Author: João Carvalho
 *       Date: Jul 28, 2022
 * 
*/


// LIBRARIES
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16,2);


// GLOBAL VARIABLES 

const int tare_button = 2,
    warning_led = 13,
    readings_quant = 100;

const int sensors[] = {A0, A1, A2};

const int quant_sensors = sizeof(sensors) / sizeof(A0);

int readings[quant_sensors][readings_quant];
int references[quant_sensors], modes[quant_sensors];
float thicknesses[quant_sensors];

// -------------------------> SETTINGS <------------------------------- //

void setup() {
    // Init serial comunication
    Serial.begin(9600);

    pinMode(tare_button, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(tare_button), tare_f, FALLING);



        // inicialização do display lcd
    lcd.init();
    lcd.setBacklight(HIGH);

    // inicialização do processo
    apresentacao();

    // Set analog reference to 1V1
    analogReference(INTERNAL);

    for(int i=0; i<500; i++) {
        Serial.println(analogRead(A0));
    }

    tare_f();
}

// -------------------------> MAIN <----------------------------- //

void loop() {

    // main functions
    reader();
    calc_mode();
    measure();




    // prints
    Serial.print("Medidas: ");
    Serial.println(" S_1: " + String(thicknesses[0]) +
                   " S_2: " + String(thicknesses[1]) +
                   " S_3: " + String(thicknesses[2]));
    delay(1000);    
}

// -------------------------> AUXILIAR FUNCTIONS <------------------------- //

void apresentacao(){
  // tela de apresentação
  
  lcd.setCursor(0,0);
           //0123456789ABCDEF
  lcd.print("      Tag       ");
  
  lcd.setCursor(0,1);
           //0123456789ABCDEF
  lcd.print("MassControl v1.0");

  // tempo de exibição da tela de apresentação
  delay(3000);
}


void reader() {
    // Perform readings and calculate the mode
    for (int id = 0; id < quant_sensors; id++) {
        // Performs number of readings defined in readings_quant
        for (int i = 0; i < readings_quant; i++) {
            readings[id][i] = analogRead(sensors[id]);
        }
        //modes[id] = calc_mode(readings);
    }
}

void calc_mode() {
    // Calculates the mode of the readings performed
    for (int id = 0; id < quant_sensors; id++) {
        int mode = 0;
        
        // reference element
        for (int i = 0; i < readings_quant; i++) {
            int counter = 0, counter_max = 0;

            // other values to compare with reference
            for (int j = 0; j < readings_quant; j++) {
                if (readings[id][i] == readings[id][j]) {
                    counter++;
                }
            }

            // verify if the element is the mode
            if (counter > counter_max) {
                mode = readings[id][i];
                counter_max = counter;
            }
        }
        modes[id] = mode;
    }
}

void measure() {
    for (int id = 0; id < quant_sensors; id++) {
        int height = modes[id] - references[id];
        //Serial.println(height);
        //Serial.println(height/15);
        thicknesses[id] = height / 15.0;
    }
}

void tare_f() {
    reader();
    calc_mode();
    for (int id = 0; id < quant_sensors; id++) {
        references[id] = modes[id];
    }
}