Тема: XL4016
Основная статья - http://rcl-radio.ru/?p=131518
#define KALL_U 115
#define KALL_I 1.52
#define KALL_I_0 0.02
#include <Wire.h>
#include <U8glib.h> // https://github.com/olikraus/u8glib/
#include <Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <EEPROM.h>
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
Encoder myEnc(6, 5);// DT, CLK
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST);
float u=0, i_alarm=0;
long i_dig,i_sum,i;
int n,m;
bool w,w1,alarm,iu,off;
long times,oldPosition = -999,newPosition,times0;
void setup() {
delay(200);
Wire.begin();
Serial.begin(9600);
pinMode(7,INPUT); // SW ENCODER
pinMode(12,INPUT_PULLUP);// OVERLOAD OFF
MsTimer2::set(3, to_Timer);MsTimer2::start();
if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении
u = float(EEPROM.read(0));i_alarm=float(EEPROM.read(1));
ADMUX = 0b000;
ADCSRD |= 1 << REFS2;
ADCSRA |= 1 << ADEN | 1 << ADSC | 1 << ADATE | 0b111;
cli();
// TIMER_1 D9 OUTPUT
DDRB = 1 << PB1;
TCCR1A = 0;TCCR1B = 0;
TCCR1A = 1 << COM1A1 | 1 << WGM11;
TCCR1B = 1 << WGM13 | 1 << WGM12 | 1 << CS10;
ICR1 = 5000;
OCR1A = KALL_U*u/10;
sei();
}
void loop(){
while((ADCSRA & (1 << ADIF)) == 0);
i_dig = (ADCL|ADCH << 8);
i_sum = i_sum+i_dig;
n++;if(n>999){n=0;i=i_sum/1000;i_sum=0;w=1;}
if(digitalRead(7)==LOW &&iu==0){iu=1;times=millis();w=1;w1=1;delay(200);}
if(digitalRead(7)==LOW &&iu==1){iu=0;times=millis();w=1;w1=1;delay(200);}
if(float(i)*KALL_I/1000.0-KALL_I_0>i_alarm/10.0){alarm=1;OCR1A = 0;}
if(digitalRead(12)==LOW&&alarm==1){alarm=0;OCR1A = KALL_U*u/10;delay(200);}
if(digitalRead(12)==LOW&&alarm==0 && off==0){off=1;alarm=0;OCR1A = 0;delay(200);}
if(digitalRead(12)==LOW&&alarm==0 && off==1){off=0;alarm=0;OCR1A = KALL_U*u/10;delay(200);}
if(iu==0){
if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
u=u+newPosition;myEnc.write(0);newPosition=0;
if(u<0){u=0;}if(u>250){u=250;}times=millis();if(alarm==0&&off==0){OCR1A = KALL_U*u/10;}w=1;w1=1;}
}
if(iu==1){
if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
i_alarm=i_alarm+newPosition;myEnc.write(0);newPosition=0;
if(i_alarm<0){i_alarm=0;}if(i_alarm>30){i_alarm=30;}times=millis();w=1;w1=1;}
}
if(w==1){w=0;
u8g.firstPage();
do {
u8g.drawLine(0, 26, 128, 26);u8g.drawLine(0, 53, 128, 53);
u8g.setFont(u8g_font_profont29r);
u8g.drawStr(0,22,"U");u8g.setPrintPos(35, 22);u8g.print(u/10.0,1);u8g.drawStr(110,22,"V");
u8g.drawStr(0,50,"I");u8g.setPrintPos(35, 50);u8g.print(float(i)*KALL_I/1000.0-KALL_I_0,2);u8g.drawStr(110,50,"A");
u8g.setFont(u8g_font_profont12r);u8g.setPrintPos(0, 64);u8g.print(i_alarm/10.0,1);
if(iu==0){u8g.drawStr(25,64,"A ");}else{u8g.drawStr(25,64,"A*");}
u8g.setPrintPos(60, 64);
if(alarm==1){u8g.print("OVERLOAD");}
if(alarm==0&&off==0){u8g.print("enabled ");}
if(alarm==0&&off==1){u8g.print("disabled");}
} while( u8g.nextPage() );}
if(millis()-times>3000 && w1==1){EEPROM.update(0,u);EEPROM.update(1,i_alarm);w1=0;w=1;iu=0;myEnc.write(0);}
}
void to_Timer(){newPosition = myEnc.read()/4;}