#include "Arduino.h"
#include "Ticker.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define version  "1.0.0"

Ticker tickerRedLED;
Ticker tickerBlueLED;
Ticker tickerBuilinLED;

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);


/**************************************/
/*           GPIO define              */
/**************************************/
#define RXD2    16
#define TXD2    17
#define RXD3    27
#define TXD3    26 
#define SW1     32
#define SW2     33
#define RELAY   25
#define LED_IO4  4
#define LED_IO12  12
#define SLID_SW  36
#define BUZZER  13



/**************************************/
/*          Pre-define function       */
/**************************************/
void Relay(bool state);
void RedLED(bool state);
void BlueLED(bool state);
void BuildinLED(bool state);
void buzzer_beep(int times);
bool Sw1(void);
bool Sw2(void);
bool Slid_sw(void);
void library_version(void);
void TickBlueLED_blink(void);
void TickRedLED_blink(void);
void TickBuildinLED_blink(void);

/***********************************************************************
 * FUNCTION:    Relay
 * DESCRIPTION: Control ON-OFF Relay[pin25]
 * PARAMETERS:  0 or 1
 * RETURNED:    nothing
 ***********************************************************************/
void Relay(bool state)
{
  digitalWrite(RELAY, state);
}

/***********************************************************************
 * FUNCTION:    BlueLED
 * DESCRIPTION: ON-OFF Blue LED[pin12]
 * PARAMETERS:  0 or 11
 * RETURNED:    nothing
 ***********************************************************************/
void RedLED(bool state)
{
  digitalWrite(LED_IO12, state);
}

/***********************************************************************
 * FUNCTION:    RedLED
 * DESCRIPTION: ON-OFF Red LED[pin4]
 * PARAMETERS:  0 or 1
 * RETURNED:    nothing
 ***********************************************************************/
void BlueLED(bool state)
{
  digitalWrite(LED_IO4, state);
}


/***********************************************************************
 * FUNCTION:    BlueinLED
 * DESCRIPTION: ON-OFF Bulidin LED[pin2]
 * PARAMETERS:  0 or 1
 * RETURNED:    nothing
 ***********************************************************************/
void BuildinLED(bool state)
{
  digitalWrite(LED_BUILTIN, state);
}

/***********************************************************************
 * FUNCTION:    buzzer_beep
 * DESCRIPTION: buzzer sound beep[pin13]
 * PARAMETERS:  times
 * RETURNED:    nothing
 ***********************************************************************/
void buzzer_beep(int times)
{
#define PLUSE_BUZZER
  // #define DC_BUZZER

  for (int _i = 0; _i < times; _i++)
  {
#ifdef PLUSE_BUZZER
#define dt 50 // 0.1sec

    int _j;
    for (_j = dt; _j > 0; _j--)
    {
      digitalWrite(BUZZER, HIGH);
      vTaskDelay(1);
      digitalWrite(BUZZER, LOW);
      vTaskDelay(1);
    }
    vTaskDelay(100);
#endif

#ifdef DC_BUZZER
    digitalWrite(BUZZER, HIGH);
    vTaskDelay(70);
    digitalWrite(BUZZER, LOW);
    vTaskDelay(70);
#endif
  }
}

/***********************************************************************
 * FUNCTION:    Sw1
 * DESCRIPTION: Read SW1[pin33]
 * PARAMETERS:  nothing
 * RETURNED:    0 or 1
 ***********************************************************************/
bool Sw1(void)
{
  bool _status = !digitalRead(SW1);
  return _status;
}

/***********************************************************************
 * FUNCTION:    Sw2
 * DESCRIPTION: Read SW2[pin14]
 * PARAMETERS:  nothing
 * RETURNED:    0 or 1
 ***********************************************************************/
bool Sw2(void)
{
  bool _status = !digitalRead(SW2);
  return _status;
}

/***********************************************************************
 * FUNCTION:    Slid_sw
 * DESCRIPTION: Read Slid Switch[15]
 * PARAMETERS:  nothing
 * RETURNED:    0 or 1
 ***********************************************************************/
bool Slid_sw(void)
{
  bool _status = !digitalRead(SLID_SW);
  return _status;
}

/***********************************************************************
 * FUNCTION:    TickBlueLED
 * DESCRIPTION: Blink BlueLED[pin4]
 * PARAMETERS:  nothing
 * RETURNED:    0 = Off, 1 < blink
 ***********************************************************************/
void TickBlueLED(float second)
{
  if (second <= 0)
  {
    tickerBlueLED.detach();
    BlueLED(0);
  }
  else
  {
    tickerBlueLED.attach(second, TickBlueLED_blink);
  }
}

/***********************************************************************
 * FUNCTION:    TickRedLED
 * DESCRIPTION: Blink RedLED[pin12]
 * PARAMETERS:  nothing
 * RETURNED:    0 = Off, 1 < blink
 ***********************************************************************/
void TickRedLED(float second)
{
  if (second <= 0)
  {
    tickerRedLED.detach();
    RedLED(0);
  }
  else
  {
    tickerRedLED.attach(second, TickRedLED_blink);
  }
}

/***********************************************************************
 * FUNCTION:    BuildinLED
 * DESCRIPTION: Blink BuildinLED[pin2]
 * PARAMETERS:  nothing
 * RETURNED:    0 = Off, 1 < blink
 ***********************************************************************/
void TickBuildinLED(float second)
{
  if (second <= 0)
  {
    tickerBuilinLED.detach();
    BuildinLED(0);
  }
  else
  {
    tickerBuilinLED.attach(second, TickBuildinLED_blink);
  }
}

 /***********************************************************************
 * FUNCTION:    TickBlueLED_blink
 * DESCRIPTION: ON-OFF Red LED
 * PARAMETERS:  bool state
 * RETURNED:    nothing
 ***********************************************************************/
void TickBlueLED_blink(void){
    bool _state = digitalRead(LED_IO4);
    digitalWrite(LED_IO4, !_state);
}

 /***********************************************************************
 * FUNCTION:    TickRedLED_blink
 * DESCRIPTION: ON-OFF Red LED
 * PARAMETERS:  bool state
 * RETURNED:    nothing
 ***********************************************************************/
void TickRedLED_blink(void){
    bool _state = digitalRead(LED_IO12);
    digitalWrite(LED_IO12, !_state);
}



 /***********************************************************************
 * FUNCTION:    void TickBuildinLED_blink(void){
 * DESCRIPTION: ON-OFF Buildin LED
 * PARAMETERS:  bool state
 * RETURNED:    nothing
 ***********************************************************************/
void TickBuildinLED_blink(void){
        bool _state = digitalRead(BUILTIN_LED);
        digitalWrite(BUILTIN_LED, !_state);
}
/**************************************/
/*          Header project            */
/**************************************/
void header_print(void)
{
    Serial.printf("\r\n***********************************************************************\r\n");
    Serial.printf("* Project      :     tiny32_v3_wokwi_vscode\r\n");
    Serial.printf("* Description  :     this code is template source code useful for tiny32_v3 and tiny32_v4 \r\n");
    Serial.printf("*                    hardware simulate run with wokwi simulate, it works with vscode \r\n");
    Serial.printf("* Hardware     :     tiny32_v4 and tiny32_v4\r\n");
    Serial.printf("* Author       :     Tenergy Innovation Co., Ltd.\r\n");
    Serial.printf("* Date         :     19/06/2023\r\n");
    Serial.printf("* Revision     :     %s\r\n", version);
    Serial.printf("* Rev1.0       :     Origital\r\n");
    Serial.printf("* website      :     http://www.tenergyinnovation.co.th\r\n");
    Serial.printf("* Email        :     [email protected]\r\n");
    Serial.printf("* TEL          :     +66 82-308-3299\r\n");
    Serial.printf("***********************************************************************/\r\n");
}

/***********************************************************************
 * FUNCTION:    setup
 * DESCRIPTION: setup process
 * PARAMETERS:  nothing
 * RETURNED:    nothing
 ***********************************************************************/
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(SW1, INPUT);
  pinMode(SW2, INPUT);
  pinMode(SLID_SW, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LED_IO12, OUTPUT);
  pinMode(LED_IO4, OUTPUT);
  pinMode(RELAY, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  digitalWrite(LED_IO12, LOW);
  digitalWrite(LED_IO4, LOW);
  digitalWrite(BUZZER, LOW);

  lcd.init(); // initialize the lcd
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("*    TENERGY   *");
  lcd.setCursor(0,1);
  lcd.print("*   INNOVATION *");

  header_print();
  buzzer_beep(2);
  TickBuildinLED(0.5);
  TickRedLED(1.0);
  TickBlueLED(1.5);

}

/***********************************************************************
 * FUNCTION:    loop
 * DESCRIPTION: loop process
 * PARAMETERS:  nothing
 * RETURNED:    nothing
 ***********************************************************************/
void loop() {
  // put your main code here, to run repeatedly:

  if(Sw1())
  {
    buzzer_beep(1);
    while(Sw1());
    Serial.printf("SW1 is pressed\r\n");
    
  }


  if(Sw2())
  {
    buzzer_beep(1);
    while(Sw2());
    Serial.printf("SW2 is pressed\r\n");
    
  }


  delay(10); // this speeds up the simulation
}
NOCOMNCVCCGNDINLED1PWRRelay Module