//-----------------------------------------------------------------
// Author: RSP @KMUTNB
// Date: 2023-02-10
//-----------------------------------------------------------------

// TODO:
//  1) Add a Rotary Encoder module to change the light-level indicator
//     if the ADC value at A0 pin below 16.
//  2) Rewrite code to use FreeRTOS tasks and inter-task synchronization/communication services

// Don't forget to include libraries
#include <Adafruit_NeoPixel.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <Arduino_FreeRTOS.h>

#define BTN_PIN       (6)
#define NEOPIXEL_PIN  (5)
// I2C pins SDA/SCL = A4/A5 pins
#define LCD_I2C_ADDR  (0x27)

Adafruit_NeoPixel pixels( 8, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
LiquidCrystal_I2C lcd( LCD_I2C_ADDR, 16, 2 );
RTC_DS1307 rtc; // Adafruit RTClib uses 0x68 as the default address.

static uint8_t disp_mode = 0;

void setup() {
  Serial.begin(115200);
  Serial.println( F("Arduino Nano Demo...") );
  Serial.println( F("- Analog input reading (potentiometer)") );
  Serial.println( F("- PWM LED dimming") );
  Serial.println( F("- Push button") );
  Serial.println( F("- LCD16x2 I2C display module") );
  Serial.println( F("- 8-pixel NeoPixel RGB ring") );
  Serial.println( F("- DHT22 temperature & humidity sensor") );
  Serial.println( F("- RTC I2C DS1307") );
  pinMode( BTN_PIN, INPUT_PULLUP );

  create_tasks();

  pixels.begin();  // Initialize Neopixel ring
  pixels.clear();  // Clear Neopixel ring
  lcd.init();      // Initialize LCD display
  lcd.backlight(); // Turn on LCD backlight
  Wire.setClock(400000);
}

void create_tasks (void) {
  xTaskCreate(
    task1, "Task1", 128, NULL, 1, NULL
  );
  xTaskCreate(
    task2, "Task2", 128, NULL, 1, NULL
  );
}

void task1 (void *pvParameters) {
  while (1) {
    // 1) Detect a button press to toggle LCD display mode
    if (digitalRead(BTN_PIN) == LOW) {
      while (!digitalRead(BTN_PIN)) {
        delay(5);
      }
      disp_mode = (disp_mode + 1) % 4; // up to 4 modes
    }
  }
}

void task2 (void *pvParameters) {
  while (1) {
    // 7) Update the LCD display
    String str1="", str2="";
    switch (disp_mode) {
      case 0:
        break;
      case 1: // show pulse width and distance
        str1 = "   PW[us]: ";
        str2 = "Dist.[cm]: ";
        break;
      case 2: // show temperature and relative humidity
        str1 = " Temp.[C]: ";
        str2 = "Humid.[%]: ";
        break;
      case 3:
        str1 = String("Date: ");
        str2 = String("Time: ");
        break;  
      default:
        disp_mode = 0;
        break;
    }
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print( str1.c_str() );
    lcd.setCursor(0, 1);
    lcd.print( str2.c_str() );
    delay(250);
  }
}

void loop() {}
//-----------------------------------------------------------------
GND5VSDASCLSQWRTCDS1307+