//  #include <LowPower.h>
#include <BME280I2C.h>
#include <Wire.h>
#include <SimpleModbusSlave.h>
#define SERIAL_BAUD 9600

#define  ledPin  13 // onboard led  
#define  buttonPin  7 // push button 

//////////////// registers of your slave ///////////////////
enum
{
  // just add or remove registers and your good to go...
  // The first register starts at address 0
  ADC0,
  ADC1,
  ADC2,
  ADC3,
  ADC4,
  ADC5,
  LED_STATE,
  BUTTON_STATE,
  TOTAL_ERRORS,
  // leave this one
  TOTAL_REGS_SIZE
  // total number of registers for function 3 and 16 share the same register array
};


unsigned int holdingRegs[TOTAL_REGS_SIZE]; // function 3 and 16 register array



BME280I2C bme;    // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure Ã—1, temperature Ã—1, humidity Ã—1, filter off,

//////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(SERIAL_BAUD);


  while (!Serial) {} // Wait

  Wire.begin();

  while (!bme.begin())
  {
    Serial.println("Snímaè BME280 nalezen");
    delay(500);
  }

  switch (bme.chipModel())
  {
    case BME280::ChipModel_BME280:
      Serial.println("Snímaè BME280 nalezen");
      break;
    case BME280::ChipModel_BMP280:
      Serial.println("Snímaè BMP280 nalezen");
      break;
    default:
      Serial.println("Nalezen neznámý snímaè");
  }

  /* parameters(long baudrate,
                  unsigned char ID,
                  unsigned char transmit enable pin,
                  unsigned int holding registers size,
                  unsigned char low latency)

       The transmit enable pin is used in half duplex communication to activate a MAX485 or similar
       to deactivate this mode use any value < 2 because 0 & 1 is reserved for Rx & Tx.
       Low latency delays makes the implementation non-standard
       but practically it works with all major modbus master implementations.
  */
  modbus_configure(19200, 1, 2, TOTAL_REGS_SIZE, 0);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);

}


//////////////////////////////////////////////////////////////////
void loop()
{

//  printBME280Data(&Serial);
float temp(NAN), hum(NAN), pres(NAN);
  BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
  BME280::PresUnit presUnit(BME280::PresUnit_Pa);
  bme.read(pres, temp, hum, tempUnit, presUnit);


  //***nepouzivat na modbusu*** LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

  // modbus_update() is the only method used in loop(). It returns the total error
  // count since the slave started. You don't have to use it but it's useful
  // for fault finding by the modbus master.
  holdingRegs[TOTAL_ERRORS] = modbus_update(holdingRegs);
  for (byte i = 0; i < 6; i++)
  {
    holdingRegs[i] = analogRead(i);
    delayMicroseconds(50);
  }
  
  byte buttonState = digitalRead(buttonPin); // read button states

  // assign the buttonState value to the holding register
  holdingRegs[BUTTON_STATE] = buttonState;
  holdingRegs[ADC0] = temp;
  holdingRegs[ADC1] = hum;
  holdingRegs[ADC2] = pres;

  // read the LED_STATE register value and set the onboard LED high or low with function 16
  byte ledState = holdingRegs[LED_STATE];

  if (ledState) // set led
    digitalWrite(ledPin, HIGH);
  if (ledState == 0 || buttonState) // reset led
  {
    digitalWrite(ledPin, LOW);
    holdingRegs[LED_STATE] = 0;
  }

}


//////////////////////////////////////////////////////////////////
void printBME280Data
(
  Stream * client
)
{
  //  float temp(NAN), hum(NAN), pres(NAN);
  //  BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
  //  BME280::PresUnit presUnit(BME280::PresUnit_Pa);

  //  bme.read(pres, temp, hum, tempUnit, presUnit);



  //  client->print("Teplota: ");
  //  client->print(temp);
  //  client->print("°" + String(tempUnit == BME280::TempUnit_Celsius ? 'C' : 'F'));
  //  client->print("\t\tRelativní Vlhkost: ");
  //  client->print(hum);
  //  client->print("%");
  //  client->print("\t\tTlak: ");
  //  client->print(pres);
  //  client->println("Pa");
  //  delay(50);
}

