
//Arduino pro micro 5V
//Bench PSU power monitor using INA226

#define printdebug

const byte My_Address = 10;
const byte LCD_Address = 0x3F;
//encoder pins
const int8_t pinA = 7;
const int8_t pinB = 8;
#define Enc_K 9



enum output_mode{
  V24_KEY, //any input key prints results on usb port
  V24_CONT,//prints results on usb port continuously
  CSV,//Continuous output for graphs
  LCD_A,//result display continuous on the LCD
  LCD_mA,//result display continuous on the LCD
};
int mode = LCD_mA; //default used for output control
int Last_mode = -1; //start value
enum reading_type{
  V,
  A,
  W 
};
//LCD outputs
boolean print_results = true;
int LCD_Mode = 0; //index to start value for menu TOP
int CSV_source = 0; //index to start value for CSV output: sensor to monitor
int CSV_period = 5; //index to start value for CSV output:
int LCD_source = 3; //index to start value for LCD output:
int Last_LCD_source = -1; //last used index for real time display

//rail sensor INA226 Settings and I2C
int const sensors = 5;
byte addresses[] = {0x40,0x44,0x48,0x41,0x45};
float Correction[] = {0.84,0.84,0.84,0.84,0.84};
float Amps[] = {11,11,11,11,11};
float Res[] = {0.006,0.006,0.006,0.006,0.006};

//LCD menu options
enum menu_level{
  TOP,
  SUB, 
  OFF,
};
boolean SET = false; //menu is use flag
boolean key_pressed;
//csv source
static const char* NAME[] = {"5v ","12v","USB","Var","3v "};
static const uint8_t NAME_COUNT = sizeof(NAME) / sizeof(NAME[0]);
//mode
static const char* MODE[] = {"V24_KEY ",  "V24_CONT",  "CSV     ",  "LCD Amps",  "LCD mA  "}; //sames as output_mode
static const uint8_t MODE_COUNT = sizeof(MODE) / sizeof(MODE[0]);
//csv print period
static const char* PERIOD[] = {"0  ","100","200","300","400","500"};
static const uint8_t PERIOD_COUNT = sizeof(PERIOD) / sizeof(PERIOD[0]);
//lcd output
static const char* LCD_DIS[] = {"V  ","A  ","W  ","5v ","12v","3v ","Var","USB"};
static const uint8_t LCD_COUNT = sizeof(LCD_DIS) / sizeof(LCD_DIS[0]);

//results output loop timer
long int  interval ;
long int last_time;

boolean flash;

//Power supply monitor
#include <Wire.h>
#include "INA226_WE_mod.h"
#include <LiquidCrystal_I2C.h>
#include <BasicEncoder.h>
#include <EEPROM.h>

BasicEncoder encoder(pinA, pinB);
LiquidCrystal_I2C lcd(LCD_Address,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

INA226_WE INA_array[sensors];
int incomingByte = 0;



void setup(){ 
  //Serial
  Serial.begin(115200);
  //while (!Serial);             // Do not enable as it stops the micro pro booting up with no USB
  
   Wire.begin(My_Address); 
   pinMode(Enc_K, INPUT);
   //pinMode(LED_BUILTIN, OUTPUT);  
   
  //LCD Startup
  lcd.init();  // initialize the lcd 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(2,0);//pixel,row
  lcd.print(F("Arduino ATX"));
  lcd.setCursor(4,1);
  lcd.print(F("Powered"));
  delay(1000);
  lcd.clear();
  
  //Check i2c
  if (mode == CSV){
    print_results = false;
  }
  if (!Scan_loop(print_results)){ //check for I2C error
    lcd.clear();
    lcd.print("I2C Fail");
    delay(1000);
  }

  INA_setup(print_results);

  LCD_Mode = EEPROM.read(0);
  CSV_source = EEPROM.read(1);
  CSV_period = EEPROM.read(2);
  LCD_source = EEPROM.read(3);
  interval = CSV_period * 100;
  mode = LCD_Mode;

  lcd.setCursor(4, 0);
  lcd.print(MODE[mode]);
  
  if (mode == V24_KEY){Serial.println(F("Arduino_Power Micro V1 Ready"));}

    
}


void loop(){
  enc_check_key();
  if (SET){
    encoder_loop();
    return;
  }
  
  if ((mode == V24_KEY) & (Serial.available() > 0)) {
    // read the incoming byte:
    incomingByte = Serial.read();
    measure_V24();
    Serial.flush();
  }
  
  if (millis() > (last_time + interval) ) {
    flash = !flash;
    if (mode == V24_CONT){
        measure_V24();
      }
    else if(mode == CSV){
        measure_CSV(CSV_source);
    }
    last_time = millis();
  }
  
  if (mode == LCD_A | mode == LCD_mA){
    //source changed
    if ((Last_mode != mode) | (Last_LCD_source != LCD_source)){
      lcd.clear();
      //delay(500);    
    }   
    Write_LCD();
    Last_LCD_source = LCD_source;
  }
  
  Last_mode = mode;
  //blink();
}

void blink() {
  //monitor for arduino crash
  if (flash){digitalWrite(LED_BUILTIN, HIGH);}else{digitalWrite(LED_BUILTIN, LOW);}   // turn the LED on (HIGH is the voltage level)
}





//
