// Используем код для активации дисплея и переключателя
#include <LiquidCrystal_I2C.h>
#define POSITIVE 1
const int i2c_addr = 0x27;
LiquidCrystal_I2C lcd(i2c_addr,40,4);
#define BUTTON_PIN 4
#define BUTTON_PIN_B 5
#define BUTTON_PIN_R 6
#define BUTTON_PIN_G 7
int led = 12;
int lastState = HIGH;
int value_R = 0;
int value_B = 0;
int value_G = 0;
// Зададим случайные вводные данные
// Последние 10 чисел в данных будут 0 для дальнейшего заполнения
int count;
float y_data[25] = {random(5, 20), random(5, 20), random(5, 20), random(5, 20),random(5, 20),random(5, 20), random(5, 20), random(5, 20), random(5, 20), random(5, 20), random(5, 20), random(5, 20), random(5, 20), random(5, 20), random(5, 20), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float x_data[25] = {random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), random(1, 5), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float x_pred_random = random(1, 5);
float y_pred;
float linRegrCoef[2] = {0,0};
float mse_res = 0;
int check_R = 0;
int check_B = 0;
int check_G = 0;
int check = 0;
int buttons = 0;
int all_check = 0;
void setup(){
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BUTTON_PIN_B, INPUT_PULLUP);
pinMode(BUTTON_PIN_R, INPUT_PULLUP);
pinMode(BUTTON_PIN_G, INPUT_PULLUP);
pinMode(led, OUTPUT);
count = 15;
lcd.begin(10, 4);
lcd.clear();
lcd.backlight();
}
void loop() {
if (check == 0){
code();
}
int value = digitalRead((BUTTON_PIN));
if ((lastState != value) && (check == 1)) {
lastState = value;
mse_res = 0;
float linRegrCoef[2] = {0,0};
Serial.print("i = ");
Serial.println(count);
simpLinReg(linRegrCoef, count);
mse(linRegrCoef[0], linRegrCoef[1], mse_res, count);
prediction(linRegrCoef[0], linRegrCoef[1]);
count++;
}
}
// Функция ввода кода
void code(){
value_R = digitalRead(BUTTON_PIN_R);
value_B = digitalRead(BUTTON_PIN_B);
value_G = digitalRead(BUTTON_PIN_G);
if (value_G == LOW){
check_G = 1;
if (buttons == 0 && check_R == 0 && check_B == 0 && check_G == 1){
buttons++;
check_G = 1;
}
}
if (value_B == LOW){
check_B = 1;
if (buttons == 1 && check_R == 0 && check_B == 1 && check_G == 1){
check_B = 1;
buttons++;
}
}
if (value_R == LOW){
check_R = 1;
if (buttons == 2 && check_R == 1 && check_B == 1 && check_G == 1){
check_R = 1;
buttons++;
}
}
if (buttons == 3 && check_R == 1 && check_B == 1 && check_G == 1){
check = 1;
digitalWrite(led, HIGH); // При правильном вводе кода загорается свет
}
else{
if (buttons != (check_R + check_B + check_G)){
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Access denied");
exit(0);
}
}
}
// Функция построения линейной регрессии
void simpLinReg(float* linRegrCoef, int n){
float x = 0;
float y = 0;
float xy = 0;
float xsq = 0;
// Расчеты для линейной регрессии
for (int i=0; i<n; i++){
x = x + x_data[i];
y = y + y_data[i];
xy = xy + x_data[i] * y_data[i];
xsq = xsq + x_data[i] * x_data[i];
}
x = x/n;
y = y/n;
xy = xy/n;
xsq = xsq/n;
// Алгоритм линейной регрессии
linRegrCoef[0] = (xy - x * y)/(xsq - x * x);
linRegrCoef[1] = y - linRegrCoef[0]*x;
// Вывод уравнения линейной регрессии на дисплей
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("y = ");
lcd.print(linRegrCoef[0], 2);
lcd.print(" * x + ");
lcd.print(linRegrCoef[1], 2);
// Вывод коэффициентов уравнения линейной регрессии в консоль (точные значения)
Serial.print("a = ");
Serial.println(linRegrCoef[0], 10);
Serial.print("b = ");
Serial.println(linRegrCoef[1], 10);
Serial.println("");
}
// Расчет mse
void mse(float a, float b, float mse_result, int n){
for (int i=0; i<n; i++){
mse_result = mse_result + ((y_data[i] - a * x_data[i] + b) * (y_data[i] - a * x_data[i] + b));
};
mse_result = mse_result/n;
lcd.setCursor(0, 1);
lcd.print("mse = ");
lcd.println(mse_result, 3);
}
// Предсказание следующего значения
void prediction(float a, float b){
float x_pred = random(1, 5);
float y_pred = a * x_pred + b;
lcd.setCursor(0, 2);
lcd.print("x_pred = ");
lcd.println(x_pred, 3);
lcd.setCursor(0, 3);
lcd.print("y_pred = ");
lcd.println(y_pred, 3);
x_data[count-1] = x_pred;
y_data[count-1] = y_pred;
}