#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <FreeRTOS.h>
#include <task.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
#define WHITE_PIN 11
#define YELLOW_PIN 10
#define PHOTO_PIN A3
#define POT_PIN A1
#define MODE_PIN 8
#define SHUTDOWN_PIN 7
const float GAMMA = 0.7;
const float RL10 = 50;
int brightness = 0;
bool manual_mode = false;
String mode = "";
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
RTC_DS1307 rtc;
void setup() {
lcd.init();
lcd.backlight();
Serial.begin(9600);
pinMode(MODE_PIN, INPUT_PULLUP);
pinMode(SHUTDOWN_PIN, INPUT_PULLUP);
pinMode(PHOTO_PIN, INPUT);
pinMode(POT_PIN, INPUT);
pinMode(WHITE_PIN, OUTPUT);
pinMode(YELLOW_PIN, OUTPUT);
rtc.begin();
}
float readLux(){
int analogValue = analogRead(PHOTO_PIN);
float voltage = analogValue / 1024. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
return lux;
}
void printScr(DateTime now, String mode, int brightness, int luxValue){
// Вывод информации на экран
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(now.hour(), DEC);
lcd.print(":");
lcd.print(now.minute(), DEC);
lcd.print(":");
lcd.print(now.second(), DEC);
lcd.setCursor(10, 0);
lcd.print(mode);
lcd.setCursor(0, 1);
lcd.print("LED:");
lcd.print(brightness);
lcd.print(" Lux:");
lcd.print(luxValue);
}
int mainTask(DateTime now, int luxValue, int potentiometerValue){
if(!digitalRead(SHUTDOWN_PIN)){
digitalWrite(YELLOW_PIN, LOW);
analogWrite(WHITE_PIN, 0);
}
else{
manual_mode = digitalRead(MODE_PIN);
bool yellowOn = now.hour() >= 19 || now.hour() < 12;
if(manual_mode){
mode = "Manual";
}
else {
mode = "Auto";
}
if (!manual_mode) {
if (yellowOn) {
if (luxValue >= 0 && luxValue < 100) {
brightness = 255;
} else if (luxValue >= 100 && luxValue < 200) {
brightness = 127;
} else if (luxValue >= 200 && luxValue < 300) {
brightness = 63;
} else if (luxValue >= 300){
brightness = 0;
}
}
}
else {
brightness = map(potentiometerValue, 0, 1023, 0, 255);
}
analogWrite(WHITE_PIN, brightness);
digitalWrite(YELLOW_PIN, yellowOn ? HIGH : LOW);
}
return brightness;
}
void loopTask(void *pvParameters) {
while(1) {
DateTime now = rtc.now();
int luxValue = readLux();
int potentiometerValue = analogRead(POT_PIN);
int switchState = digitalRead(MODE_PIN);
printScr(now, mode, mainTask(now, luxValue, potentiometerValue), luxValue);
// Serial.println(luxValue);
// Serial.println(brightness);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void setupFreeRTOS() {
xTaskCreate(
loopTask, // Функция задачи
"Main Loop Task", // Имя задачи
256, // Размер стека
NULL, // Входной параметр
1, // Приоритет
NULL // Обработчик задачи
);
}
void loop() {
setupFreeRTOS();
vTaskStartScheduler();
}