#include <LiquidCrystal_I2C.h>
const int lcdAddress = 0x27;
const int cols = 16;
const int rows = 2;
LiquidCrystal_I2C lcd(lcdAddress, cols, rows);
uint16_t power; // power - текущая мощность от PZEM (Потенциометр)
uint16_t npower = 100; // npower - значения необходимой мощности
uint8_t StepMajor = 255; // StepMajor - Значение грубой регулировки (меньше - выше мощность)
uint8_t StepMinor = 128; // StepMinor - Значение плавной регулировки 0..255
bool PowerAdjust = true;
uint16_t PowerCalc;
uint8_t Step, Temp;
bool up, down;
uint16_t oldValue;
void setup() {
Serial.begin(9600);
Serial.println("Start");
lcd.init();
lcd.backlight();
}
void loop() {
if (Serial.available())
{
npower = Serial.parseInt();
Serial.read();
StepMinor = 128;
StepMajor = 255;
PowerAdjust = true;
}
power = analogRead(A0);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("P:");
lcd.setCursor(3, 0);
lcd.print(power);
lcd.setCursor(0, 1);
lcd.print("N:");
lcd.setCursor(3, 1);
lcd.print(npower);
Regulator();
delay(1000);
}
void Regulator() {
if (PowerAdjust){ // Режим грубой настройки
(power == 0 ? Temp = 1 : Temp = 3); // Пока мощность на 0 читаем по 1 разу, потом суммируем из трёх замеров
PowerCalc += power;
if (Step++ >= Temp){
PowerCalc /= Temp;
int16_t calcPower = PowerCalc - npower;
int16_t newCount = StepMajor;
if (calcPower <= -30) { // в зависимости от различия нужной и текущей мощности изменяем количество ступеней
newCount-=10;
} else if (calcPower <= -10){
newCount-=2;
} else if (calcPower <= -5){
newCount-=1;
} else if (calcPower <= -1){
newCount-=1;
down = true;
} else if (calcPower == 0){
PowerAdjust = false; // мощность совпала - выходим
} else if (calcPower >= 30){
newCount+=10;
} else if (calcPower >= 10){
newCount+=2;
} else if (calcPower >= 5){
newCount+=1;
} else if (calcPower >= 1){
newCount+=1;
up = true;
}
if (newCount < 0){
newCount = 0;
} else if (newCount > 255) {
newCount = 255;
}
StepMajor = newCount;
Serial.print("major:");
Serial.println(StepMajor);
if (up && down) { PowerAdjust = false; } // если и вверх и вниз двигали, то переходим к плавной подгонке
Step = 1;
PowerCalc = 0;
}
if (!PowerAdjust){
Serial.println("Major complete!");
up = false;
down = false;
PowerCalc = 0;
Step = 1;
}
} else { // Режим плавной регулировки, поддержания
PowerCalc += power;
oldValue = StepMinor;
if (Step++ == 3){
PowerCalc /= 3;
int16_t calcPower = PowerCalc - npower;
int16_t newCount = StepMinor;
if (calcPower <= -10) {
newCount-=10;
} else if (calcPower <= -5){
newCount-=3;
} else if (calcPower <= -2){
newCount-=1;
} else if (calcPower >= 10){
newCount+=10;
} else if (calcPower >= 5){
newCount+=3;
} else if (calcPower >= 2){
newCount+=1;
}
if (newCount < 0){
newCount = 128;
StepMajor--;
} else if (newCount > 255) {
newCount = 128;
StepMajor++;
}
Step = 1;
PowerCalc = 0;
StepMinor = newCount;
if (StepMinor != oldValue) {
Serial.print("minor:");
Serial.println(StepMinor);
}
}
}
}