76

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Выходной ток транзистора единственное ограничение.

77

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Добавлена кнопка I/U на D3

Тестируйте:

#include <Wire.h>
#include <EEPROM.h>
#include <Encoder.h>  // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 Encoder myEnc(8, 9);//CLK, DT
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 
 unsigned long times,oldPosition  = -999,newPosition,times_lcd,times_u=millis()+50000,times_i=millis()+50000;
 int u_out,u_dig,menu,i_out;
 const float u_k = 7.10; // калибровка регулятора напряжения
 const float i_k = 0.975;// калибровка измерителя тока 
 const float r = 0.01;   // сопротивление шунта
 byte power = 1; // при подачи питания выходное напряжение 0 В - OFF
 float i;
 byte w,set_u,set_i;
 
void setup(){
  Serial.begin(9600);
  Wire.begin();lcd.init();lcd.backlight();
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  pinMode(10,INPUT);//  SW энкодер MENU
  pinMode(2,INPUT_PULLUP); // кнопка ON/OFF
  pinMode(3,INPUT_PULLUP); // кнопка U/I
  pinMode(A0,INPUT); // input I
  u_out=EEPROM.read(0)*256+EEPROM.read(1);
  i_out=EEPROM.read(2)*256+EEPROM.read(3);
  }
 
void loop(){i_kz();
  if(digitalRead(3)==LOW){menu++;if(menu>1){menu=0;}delay(200);}
  if(digitalRead(2)==LOW&&power==0){power = 1;delay(200);}
  if(digitalRead(2)==LOW&&power==1){power = 0;delay(200);}

  if(digitalRead(10)==LOW && menu==0){set_u++;if(set_u>1){set_u=0;}set_i=100;times_u=millis();times_i=millis()+50000;delay(200);}
  if(digitalRead(10)==LOW && menu==1){set_i++;if(set_i>1){set_i=0;}set_u=100;times_i=millis();times_u=millis()+50000;delay(200);}
  
  //////// set out 0-28 V
  if(menu==0 && set_u==0 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition*10;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==0 && set_u==1 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}

  if(u_out<0){u_out=0;}if(u_out>280){u_out=280;}u_dig = float(u_out)/10/u_k*4096/5.00;   

  Serial.println(u_dig);
     
  //////// set i 0-2.5 A
 
  if(menu==1 && set_i==0 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition*100;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==1 && set_i==1 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}
     
  if(i_out<0){i_out=0;}if(i_out>999){i_out=999;}
 
  //////// lcd
  i_kz();
  
  if(millis()-times_lcd>400){times_lcd=millis();}
  
  lcd.setCursor(0, 0);if(menu==0){lcd.print("U*= ");}else{lcd.print("U = ");}
  
  if(millis()-times_u<5000&&menu==0){
  if(set_u==0){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print("  ");lcd.print(".");lcd.print(u_out%10);}}
  if(set_u==1){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(" ");}}
  }
  else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);set_u=1;}
  lcd.print(" V "); 
  lcd.setCursor(11, 0);lcd.print(abs(i),2);lcd.print("A");



  lcd.setCursor(0, 1);if(menu==1){lcd.print("I*= ");}else{lcd.print("I = ");}
  
  if(millis()-times_i<5000&&menu==1){
  if(set_i==0){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(" ");lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}}
  if(set_i==1){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(i_out/100);lcd.print(".");lcd.print("  ");}}
  }
  else{lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);set_i=1;}
  lcd.print(" A ");

  i_kz();

  //////////////// EEPROM
  if(millis()-times>5000&&w==1){EEPROM.update(0,highByte(u_out));EEPROM.update(1,lowByte(u_out));
  EEPROM.update(2,highByte(i_out));EEPROM.update(3,lowByte(i_out));
  times=millis();w=0;}
  }//loop
 
void MCP4725(int data){  
  byte buffer[3];
  buffer[0] = 0b01000000;
  // data=0;
  // buffer[0] = 0b01100000; // запись в память ЦАП 0 В 
  buffer[1] = data >> 4;              
  buffer[2] = data << 4;
  Wire.beginTransmission(0x60);
  Wire.write(buffer[0]);
  Wire.write(buffer[1]);
  Wire.write(buffer[2]);
  Wire.endTransmission();
  }  
void i_kz(){  
  i = analogRead(A0)/250.00*i_k;
 
  if(i > float(i_out/100.0)){MCP4725(0);lcd.setCursor(12, 1);lcd.print("ERR");delay(3000);power=1;}
  else{lcd.setCursor(12, 1);
  if(power==0){MCP4725(u_dig+i*4.00);lcd.print("ON ");}
  if(power==1){MCP4725(0);lcd.print("OFF");}
  }
  
  }
  
 
void to_Timer(){newPosition = myEnc.read()/4;}

78

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Уточните какую схему Вы используете в измерители тока  с ОУ или АЦП?

Скетч который я переделал для ОУ.

Если с ОУ, то Вам надо будет подобрать номиналы R6 R7, то есть уменьшить коэффициент усиления, так как я расширил регулировку тока до 9,99 А.

79

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

liman324 пишет:

Уточните какую схему Вы используете в измерители тока  с ОУ или АЦП?

Скетч который я переделал для ОУ.

Если с ОУ, то Вам надо будет подобрать номиналы R6 R7, то есть уменьшить коэффициент усиления, так как я расширил регулировку тока до 9,99 А.

Премного благодарен! Собрал вариант с ОУ, про резисторы R6, R7 уже понял (использую заводской шунт на 5А). За максимальный ток отвечает строка:   if(i_out<0){i_out=0;}if(i_out>999){i_out=999;} ?

80

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

За максимальный ток отвечает строка:   if(i_out<0){i_out=0;}if(i_out>999){i_out=999;} ?

да


Так же понадобится подобрать коэффициент:
const float i_k = 0.975;// калибровка измерителя тока

81

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

liman324 пишет:

Добавлена кнопка I/U на D3

Тестируйте:

Работает как часы!  Помощь ресурсу по реквизитам: 4276 4500 1139 3002 ?

82

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Помощь ресурсу по реквизитам: 4276 4500 1139 3002

Да, все верно. Заранее спасибо!

83

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Есть еще предложение:
Сделать выбор режима работы токовой защиты: "отсечка/стабилизация" дополнительной кнопкой, это возможно?

84

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Стабилизация по току возможна, но измерение тока производится на 10 битном входе ардуино, что не очень точно, стабилизация по току будет иметь большую нестабильность и инертность, так как она будет программной. В этом режиме при КЗ выхода потребуется несколько десятков мсек чтобы контроллер дал команду снизить выходное напряжение  до нуля.

Суть метода программной стабилизации тока такая - при повышении тока нагрузки от заданного, контроллер даст команду снизить на какое то значение выходное напряжение, далее измерение тока, если ток все равно большой, процесс повторяется по новой, пока ток нагрузки не станет равным установленному значению. На это может уйти несколько десятков или даже сотен циклов измерения тока и отправки команды в ЦАП. Из-за этого и проявляется большая инертность программной стабилизации тока.

85 (2023-01-19 22:12:31 отредактировано Sergey-77)

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

liman324 пишет:

Стабилизация по току возможна, но измерение тока производится на 10 битном входе ардуино, что не очень точно, стабилизация по току будет иметь большую нестабильность и инертность, так как она будет программной. В этом режиме при КЗ выхода потребуется несколько десятков мсек чтобы контроллер дал команду снизить выходное напряжение  до нуля.

Суть метода программной стабилизации тока такая - при повышении тока нагрузки от заданного, контроллер даст команду снизить на какое то значение выходное напряжение, далее измерение тока, если ток все равно большой, процесс повторяется по новой, пока ток нагрузки не станет равным установленному значению. На это может уйти несколько десятков или даже сотен циклов измерения тока и отправки команды в ЦАП. Из-за этого и проявляется большая инертность программной стабилизации тока.

В общим чертах понятно о чем речь. Но все же, прошу критически оценить следующий алгоритм:

- в режиме "отсечки" выставляем требуемое значение тока и напряжения;
- нажимаем кнопку "отсечка/стабилизация", при этом фиксируется значение тока и соответствующая данному напряжению мощность (схема переходит в режим стабилизации);
- при каждой итерации замера тока, меняем значение напряжения через зафиксированное значение мощности (с точностью до 0,1В);
- выход из режима стабилизации: нажатие кнопки "отсечка/стабилизация";

Индикация:
- режим "отсечка": маленькая буква "О" после символа тока (I) вверху (наподобие отображения градусов);
- режим "стабилизация": маленькая буква "С" после символа тока (I) вверху, если в режиме "стабилизация" происходит увеличение тока от заданного, надпись "ON" меняется на "SТВ";

Переключение режимов осуществляется кнопкой "отсечка/стабилизация".
Установка тока или напряжения в режиме "стабилизация" не доступна.

86

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Я подумаю как это реализовать. У меня возможности собрать полностью схему, поэтому понадобится с Вашей стороны провести несколько тестов скетча.

87

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

liman324 пишет:

Я подумаю как это реализовать. У меня возможности собрать полностью схему, поэтому понадобится с Вашей стороны провести несколько тестов скетча.

Конечно, не вопрос.

88

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Скетч изменил, на D4 кнопка STAB

- режим "отсечка": маленькая буква "О" после символа тока (I) вверху (наподобие отображения градусов);
- режим "стабилизация": маленькая буква "С" после символа тока (I) вверху,

Индикацию пока не реализовал, есть сложности с размещением символов. Пока просто сделал букву S после буквы A если активен режим стабилизации.

Не уверен что сразу заработает.

#include <Wire.h>
#include <EEPROM.h>
#include <Encoder.h>  // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 Encoder myEnc(8, 9);//CLK, DT
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 
 unsigned long times,oldPosition  = -999,newPosition,times_lcd,times_u=millis()+50000,times_i=millis()+50000;
 int u_out,u_dig,menu,i_out;
 const float u_k = 7.10; // калибровка регулятора напряжения
 const float i_k = 0.975;// калибровка измерителя тока 
 const float r = 0.01;   // сопротивление шунта
 byte power = 1; // при подачи питания выходное напряжение 0 В - OFF
 float i;
 byte w,set_u,set_i;
 bool stab;
 int u_stab;
 
 
void setup(){
  Wire.begin();lcd.init();lcd.backlight();
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  pinMode(10,INPUT);//  SW энкодер MENU
  pinMode(2,INPUT_PULLUP); // кнопка ON/OFF
  pinMode(3,INPUT_PULLUP); // кнопка U/I
  pinMode(4,INPUT_PULLUP); // кнопка STAB_I
  pinMode(A0,INPUT); // input I
  u_out=EEPROM.read(0)*256+EEPROM.read(1);
  i_out=EEPROM.read(2)*256+EEPROM.read(3);
  }
 
void loop(){
  if(stab==0){i_kz();}
  if(digitalRead(3)==LOW){menu++;if(menu>1){menu=0;}delay(200);}
  if(digitalRead(2)==LOW&&power==0){power = 1;delay(200);}
  if(digitalRead(2)==LOW&&power==1){power = 0;delay(200);}

  if(digitalRead(4)==LOW&&stab==0){stab = 1;lcd.setCursor(10, 1);lcd.print("S");delay(300);}
  if(digitalRead(4)==LOW&&stab==1){stab = 0;lcd.setCursor(10, 1);lcd.print(" ");delay(300);}
  
  if(digitalRead(10)==LOW && menu==0){set_u++;if(set_u>1){set_u=0;}set_i=100;times_u=millis();times_i=millis()+50000;delay(200);}
  if(digitalRead(10)==LOW && menu==1){set_i++;if(set_i>1){set_i=0;}set_u=100;times_i=millis();times_u=millis()+50000;delay(200);}
  
  //////// set out 0-28 V
  if(menu==0 && set_u==0 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition*10;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==0 && set_u==1 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}

  if(u_out<0){u_out=0;}if(u_out>280){u_out=280;}u_dig = float(u_out/10)/u_k*4096/5.00;   

  if(stab==1){
    i = analogRead(A0)/250.00*i_k;
    if(i > float(i_out/100.0)){u_dig--;if(u_dig<0){u_dig=0;}lcd.setCursor(12, 1);lcd.print("STB");}
     else{
      u_dig = float(u_out/10)/u_k*4096/5.00;lcd.setCursor(12, 1);lcd.print("ON ");
      }
      if(power==1){MCP4725(0);lcd.setCursor(12, 1);lcd.print("OFF");}else{MCP4725(u_dig+i*4.00);}
    }

     
  //////// set i 0-2.5 A
 
  if(menu==1 && set_i==0 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition*100;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==1 && set_i==1 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}
     
  if(i_out<0){i_out=0;}if(i_out>999){i_out=999;}
 
  //////// lcd
  if(stab==0){i_kz();}
  
  if(millis()-times_lcd>400){times_lcd=millis();}
  
  lcd.setCursor(0, 0);if(menu==0){lcd.print("U*= ");}else{lcd.print("U = ");}
  
  if(millis()-times_u<5000&&menu==0){
  if(set_u==0){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print("  ");lcd.print(".");lcd.print(u_out%10);}}
  if(set_u==1){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(" ");}}
  }
  else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);set_u=1;}
  lcd.print(" V "); 
  lcd.setCursor(11, 0);lcd.print(abs(i),2);lcd.print("A");



  lcd.setCursor(0, 1);if(menu==1){lcd.print("I*= ");}else{lcd.print("I = ");}
  
  if(millis()-times_i<5000&&menu==1){
  if(set_i==0){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(" ");lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}}
  if(set_i==1){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(i_out/100);lcd.print(".");lcd.print("  ");}}
  }
  else{lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);set_i=1;}
  lcd.setCursor(9, 1);lcd.print("A");

  if(stab==0){i_kz();}

  //////////////// EEPROM
  if(millis()-times>5000&&w==1){EEPROM.update(0,highByte(u_out));EEPROM.update(1,lowByte(u_out));
  EEPROM.update(2,highByte(i_out));EEPROM.update(3,lowByte(i_out));
  times=millis();w=0;}
  }//loop
 
void MCP4725(int data){  
  byte buffer[3];
  buffer[0] = 0b01000000;
  // data=0;
  // buffer[0] = 0b01100000; // запись в память ЦАП 0 В 
  buffer[1] = data >> 4;              
  buffer[2] = data << 4;
  Wire.beginTransmission(0x60);
  Wire.write(buffer[0]);
  Wire.write(buffer[1]);
  Wire.write(buffer[2]);
  Wire.endTransmission();
  }  
void i_kz(){  
  i = analogRead(A0)/250.00*i_k;
 
  if(i > float(i_out/100.0)){MCP4725(0);lcd.setCursor(12, 1);lcd.print("ERR");delay(3000);power=1;}
  else{lcd.setCursor(12, 1);
  if(power==0){MCP4725(u_dig+i*4.00);lcd.print("ON ");}
  if(power==1){MCP4725(0);lcd.print("OFF");}
  }
  
  }
  
 
void to_Timer(){newPosition = myEnc.read()/4;}

89

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Я плохо протестировал предыдущий скетч с кнопкой I/U:

- При выборе регулировки значения напряжения после запятой, на экране цифры меняются, а по факту напряжение на выходе нет. До запятой напряжение регулируется.

- Защита по току не работает (на экране ток меняется).


По второму скетчу:

-  При выборе регулировки значения напряжения после запятой, на экране цифры меняются, а по факту напряжение на выходе нет. До запятой напряжение регулируется.

- токовая отсечка работает, но показания тока на экране стали отличатся от фактических процентов на 30;

- Режим стабилизации: индикация стабилизации работает, ток показывает, но напряжение остается неизменным.

90

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Давайте сначала решим вопрос по первому скетчу. Изменения я в него внес (http://forum.rcl-radio.ru/viewtopic.php?pid=7203#p7203), сейчас все должно работать.

91

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Вообще ничего не изменилось. Дополнение про ток: величина тока энкодером выставляется, но показаний фактического тока нет, одни нули. Защита не работает.

92

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Должно работать

Я ошибки увидел, вывел значение регулировки ЦАПа в монитор порта, 10 доли не регулировались, теперь регулируются.  На вход А0 измеритель тока подаю 3,3 В показания тока 2,66 А, токовый вход работает, показания меняются.

#include <Wire.h>
#include <EEPROM.h>
#include <Encoder.h>  // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 Encoder myEnc(8, 9);//CLK, DT
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 
 unsigned long times,oldPosition  = -999,newPosition,times_lcd,times_u=millis()+50000,times_i=millis()+50000;
 int u_out,u_dig,menu,i_out;
 const float u_k = 7.10; // калибровка регулятора напряжения
 const float i_k = 0.975;// калибровка измерителя тока 
 const float r = 0.01;   // сопротивление шунта
 byte power = 1; // при подачи питания выходное напряжение 0 В - OFF
 float i;
 byte w,set_u,set_i;
 
void setup(){
  Serial.begin(9600);
  Wire.begin();lcd.init();lcd.backlight();
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  pinMode(10,INPUT);//  SW энкодер MENU
  pinMode(2,INPUT_PULLUP); // кнопка ON/OFF
  pinMode(3,INPUT_PULLUP); // кнопка U/I
  pinMode(A0,INPUT); // input I
  u_out=EEPROM.read(0)*256+EEPROM.read(1);
  i_out=EEPROM.read(2)*256+EEPROM.read(3);
  }
 
void loop(){i_kz();
  if(digitalRead(3)==LOW){menu++;if(menu>1){menu=0;}delay(200);}
  if(digitalRead(2)==LOW&&power==0){power = 1;delay(200);}
  if(digitalRead(2)==LOW&&power==1){power = 0;delay(200);}

  if(digitalRead(10)==LOW && menu==0){set_u++;if(set_u>1){set_u=0;}set_i=100;times_u=millis();times_i=millis()+50000;delay(200);}
  if(digitalRead(10)==LOW && menu==1){set_i++;if(set_i>1){set_i=0;}set_u=100;times_i=millis();times_u=millis()+50000;delay(200);}
  
  //////// set out 0-28 V
  if(menu==0 && set_u==0 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition*10;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==0 && set_u==1 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}

  if(u_out<0){u_out=0;}if(u_out>280){u_out=280;}u_dig = float(u_out)/10/u_k*4096/5.00;   

  Serial.println(u_dig);
     
  //////// set i 0-2.5 A
 
  if(menu==1 && set_i==0 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition*100;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==1 && set_i==1 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}
     
  if(i_out<0){i_out=0;}if(i_out>999){i_out=999;}
 
  //////// lcd
  i_kz();
  
  if(millis()-times_lcd>400){times_lcd=millis();}
  
  lcd.setCursor(0, 0);if(menu==0){lcd.print("U*= ");}else{lcd.print("U = ");}
  
  if(millis()-times_u<5000&&menu==0){
  if(set_u==0){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print("  ");lcd.print(".");lcd.print(u_out%10);}}
  if(set_u==1){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(" ");}}
  }
  else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);set_u=1;}
  lcd.print(" V "); 
  lcd.setCursor(11, 0);lcd.print(abs(i),2);lcd.print("A");



  lcd.setCursor(0, 1);if(menu==1){lcd.print("I*= ");}else{lcd.print("I = ");}
  
  if(millis()-times_i<5000&&menu==1){
  if(set_i==0){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(" ");lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}}
  if(set_i==1){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(i_out/100);lcd.print(".");lcd.print("  ");}}
  }
  else{lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);set_i=1;}
  lcd.print(" A ");

  i_kz();

  //////////////// EEPROM
  if(millis()-times>5000&&w==1){EEPROM.update(0,highByte(u_out));EEPROM.update(1,lowByte(u_out));
  EEPROM.update(2,highByte(i_out));EEPROM.update(3,lowByte(i_out));
  times=millis();w=0;}
  }//loop
 
void MCP4725(int data){  
  byte buffer[3];
  buffer[0] = 0b01000000;
  // data=0;
  // buffer[0] = 0b01100000; // запись в память ЦАП 0 В 
  buffer[1] = data >> 4;              
  buffer[2] = data << 4;
  Wire.beginTransmission(0x60);
  Wire.write(buffer[0]);
  Wire.write(buffer[1]);
  Wire.write(buffer[2]);
  Wire.endTransmission();
  }  
void i_kz(){  
  i = analogRead(A0)/250.00*i_k;
 
  if(i > float(i_out/100.0)){MCP4725(0);lcd.setCursor(12, 1);lcd.print("ERR");delay(3000);power=1;}
  else{lcd.setCursor(12, 1);
  if(power==0){MCP4725(u_dig+i*4.00);lcd.print("ON ");}
  if(power==1){MCP4725(0);lcd.print("OFF");}
  }
  
  }
  
 
void to_Timer(){newPosition = myEnc.read()/4;}

93

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Так же учтите что схема рассчитана на ток нагрузки 2,5 А, если вы будете использовать ток до 5 А, то Ван нужно коэффициент усиления ОУ понизить в два раза.
Так же подобрать значение
const float i_k = 0.975;// калибровка измерителя тока
оно должно быть примерно равно:
const float i_k = 0.975*2;// калибровка измерителя тока

94

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Все работает!

95

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

liman324 пишет:

Так же учтите что схема рассчитана на ток нагрузки 2,5 А, если вы будете использовать ток до 5 А, то Ван нужно коэффициент усиления ОУ понизить в два раза.
Так же подобрать значение
const float i_k = 0.975;// калибровка измерителя тока
оно должно быть примерно равно:
const float i_k = 0.975*2;// калибровка измерителя тока

Для начального скетча с первой страницы я подобрал кэф ОУ и значение калибровки.
Мне другое непонятно: 
i = analogRead(A0)/250.00*i_k;  этой строкой мы определяем величину напряжения подаваемого на А0? Я не могу найти в коде где участвует сопротивление шунта.

96

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

По второму скетчу, есть ряд моментов

токовая отсечка работает, но показания тока на экране стали отличатся от фактических процентов на 30;

Тут надо отстаивать коэффициент усиления ОУ если ток выше 2,5 А, и менять параметр:
const float i_k = 0.975;// калибровка измерителя тока
что бы ток точно показывал.

Режим стабилизации: индикация стабилизации работает, ток показывает, но напряжение остается неизменным.

Напряжение на индикаторе не должно меняться, так это напряжение не измеренное а выставленное энкодером, можно сделать чтобы оно менялось на фактическое, но тогда Вы не сможете регулировать напряжение которое устанавливается энкодером.

Места на экране мало, вывести установленное напряжение и фактическое напряжение при токовой стабилизации проблематично.

По факту, реальное значение напряжения должно меняться (быть меньше установленного) при токовой стабилизации, так как токовая стабилизация осуществляется только за счет уменьшения напряжения на выходе.

Я внесу сейчас исправления во второй скетч, устраню проблему с регулятором напряжения.

По вопросу отображения фактического напряжения в режиме стабилизации тока, подумайте как поступить. Есть вариант отображать его и заблокировать энкодер или оставить как есть.

97

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Второй скетч:

#include <Wire.h>
#include <EEPROM.h>
#include <Encoder.h>  // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 Encoder myEnc(8, 9);//CLK, DT
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 
 unsigned long times,oldPosition  = -999,newPosition,times_lcd,times_u=millis()+50000,times_i=millis()+50000;
 int u_out,u_dig,menu,i_out;
 const float u_k = 7.10; // калибровка регулятора напряжения
 const float i_k = 0.975;// калибровка измерителя тока 
 const float r = 0.01;   // сопротивление шунта
 byte power = 1; // при подачи питания выходное напряжение 0 В - OFF
 float i;
 byte w,set_u,set_i;
 bool stab;
 int u_stab;
 
 
void setup(){
  Wire.begin();lcd.init();lcd.backlight();
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  pinMode(10,INPUT);//  SW энкодер MENU
  pinMode(2,INPUT_PULLUP); // кнопка ON/OFF
  pinMode(3,INPUT_PULLUP); // кнопка U/I
  pinMode(4,INPUT_PULLUP); // кнопка STAB_I
  pinMode(A0,INPUT); // input I
  u_out=EEPROM.read(0)*256+EEPROM.read(1);
  i_out=EEPROM.read(2)*256+EEPROM.read(3);
  }
 
void loop(){
  if(stab==0){i_kz();}
  if(digitalRead(3)==LOW){menu++;if(menu>1){menu=0;}delay(200);}
  if(digitalRead(2)==LOW&&power==0){power = 1;delay(200);}
  if(digitalRead(2)==LOW&&power==1){power = 0;delay(200);}

  if(digitalRead(4)==LOW&&stab==0){stab = 1;lcd.setCursor(10, 1);lcd.print("S");delay(300);}
  if(digitalRead(4)==LOW&&stab==1){stab = 0;lcd.setCursor(10, 1);lcd.print(" ");delay(300);}
  
  if(digitalRead(10)==LOW && menu==0){set_u++;if(set_u>1){set_u=0;}set_i=100;times_u=millis();times_i=millis()+50000;delay(200);}
  if(digitalRead(10)==LOW && menu==1){set_i++;if(set_i>1){set_i=0;}set_u=100;times_i=millis();times_u=millis()+50000;delay(200);}
  
  //////// set out 0-28 V
  if(menu==0 && set_u==0 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition*10;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==0 && set_u==1 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}

  if(u_out<0){u_out=0;}if(u_out>280){u_out=280;}u_dig = float(u_out)/10/u_k*4096/5.00;   

  if(stab==1){
    i = analogRead(A0)/250.00*i_k;
    if(i > float(i_out/100.0)){u_dig--;if(u_dig<0){u_dig=0;}lcd.setCursor(12, 1);lcd.print("STB");}
     else{
      u_dig = float(u_out)/10/u_k*4096/5.00;lcd.setCursor(12, 1);lcd.print("ON ");
      }
      if(power==1){MCP4725(0);lcd.setCursor(12, 1);lcd.print("OFF");}else{MCP4725(u_dig+i*4.00);}
    }

     
  //////// set i 0-2.5 A
 
  if(menu==1 && set_i==0 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition*100;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==1 && set_i==1 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}
     
  if(i_out<0){i_out=0;}if(i_out>999){i_out=999;}
 
  //////// lcd
  if(stab==0){i_kz();}
  
  if(millis()-times_lcd>400){times_lcd=millis();}
  
  lcd.setCursor(0, 0);if(menu==0){lcd.print("U*= ");}else{lcd.print("U = ");}
  
  if(millis()-times_u<5000&&menu==0){
  if(set_u==0){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print("  ");lcd.print(".");lcd.print(u_out%10);}}
  if(set_u==1){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(" ");}}
  }
  else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);set_u=1;}
  lcd.print(" V "); 
  lcd.setCursor(11, 0);lcd.print(abs(i),2);lcd.print("A");



  lcd.setCursor(0, 1);if(menu==1){lcd.print("I*= ");}else{lcd.print("I = ");}
  
  if(millis()-times_i<5000&&menu==1){
  if(set_i==0){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(" ");lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}}
  if(set_i==1){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(i_out/100);lcd.print(".");lcd.print("  ");}}
  }
  else{lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);set_i=1;}
  lcd.setCursor(9, 1);lcd.print("A");

  if(stab==0){i_kz();}

  //////////////// EEPROM
  if(millis()-times>5000&&w==1){EEPROM.update(0,highByte(u_out));EEPROM.update(1,lowByte(u_out));
  EEPROM.update(2,highByte(i_out));EEPROM.update(3,lowByte(i_out));
  times=millis();w=0;}
  }//loop
 
void MCP4725(int data){  
  byte buffer[3];
  buffer[0] = 0b01000000;
  // data=0;
  // buffer[0] = 0b01100000; // запись в память ЦАП 0 В 
  buffer[1] = data >> 4;              
  buffer[2] = data << 4;
  Wire.beginTransmission(0x60);
  Wire.write(buffer[0]);
  Wire.write(buffer[1]);
  Wire.write(buffer[2]);
  Wire.endTransmission();
  }  
void i_kz(){  
  i = analogRead(A0)/250.00*i_k;
 
  if(i > float(i_out/100.0)){MCP4725(0);lcd.setCursor(12, 1);lcd.print("ERR");delay(3000);power=1;}
  else{lcd.setCursor(12, 1);
  if(power==0){MCP4725(u_dig+i*4.00);lcd.print("ON ");}
  if(power==1){MCP4725(0);lcd.print("OFF");}
  }
  
  }
  
 
void to_Timer(){newPosition = myEnc.read()/4;}

98

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Считаю более правильным на экран выводить фактическое напряжение. А в режиме "Стабилизация" изменение тока или напряжения сделать недоступным.

99

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

По работе ОУ.

При питании 5 В, напряжение на выходе ОУ не может быть больше 3,5 В(примерно), при изменении коэффициента усиления ОУ проследите чтобы при токе от 0 до 5 А напряжение на выходе ОУ меняться, а не упираться в потолок отсечки выхода ОУ в 3,5 В.

100

Re: LM723 + ARDUINO = ИСТОЧНИК ПИТАНИЯ 0-28В 0-2.5А С ЗАЩИТОЙ ПО ТОКУ

Второй скетч поправил, сделал немного по другому. Когда активна стабилизация по току, на дисплей выводится текущее значение напряжения, но регулировка напряжения тоже доступна, если нажать кнопку энкодера то начинаю мигать выставленные значения напряжение. Через 5 секунд мигание прекращается и на дисплей снова выводится текущее напряжение.

#include <Wire.h>
#include <EEPROM.h>
#include <Encoder.h>  // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 Encoder myEnc(8, 9);//CLK, DT
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 
 unsigned long times,oldPosition  = -999,newPosition,times_lcd,times_u=millis()+50000,times_i=millis()+50000;
 int u_out,u_dig,menu,i_out;
 const float u_k = 7.10; // калибровка регулятора напряжения
 const float i_k = 0.975;// калибровка измерителя тока 
 const float r = 0.01;   // сопротивление шунта
 byte power = 1; // при подачи питания выходное напряжение 0 В - OFF
 float i;
 byte w,set_u,set_i;
 bool stab;
 int u_stab;
 
 
void setup(){
  Serial.begin(9600);
  Wire.begin();lcd.init();lcd.backlight();
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  pinMode(10,INPUT);//  SW энкодер MENU
  pinMode(2,INPUT_PULLUP); // кнопка ON/OFF
  pinMode(3,INPUT_PULLUP); // кнопка U/I
  pinMode(4,INPUT_PULLUP); // кнопка STAB_I
  pinMode(A0,INPUT); // input I
  u_out=EEPROM.read(0)*256+EEPROM.read(1);
  i_out=EEPROM.read(2)*256+EEPROM.read(3);
  }
 
void loop(){
  if(stab==0){i_kz();}
  if(digitalRead(3)==LOW){menu++;if(menu>1){menu=0;}delay(200);}
  if(digitalRead(2)==LOW&&power==0){power = 1;delay(200);}
  if(digitalRead(2)==LOW&&power==1){power = 0;delay(200);}

  if(digitalRead(4)==LOW&&stab==0){stab = 1;lcd.setCursor(10, 1);lcd.print("S");delay(300);}
  if(digitalRead(4)==LOW&&stab==1){stab = 0;lcd.setCursor(10, 1);lcd.print(" ");delay(300);}
  
  if(digitalRead(10)==LOW && menu==0){set_u++;if(set_u>1){set_u=0;}set_i=100;times_u=millis();times_i=millis()+50000;delay(200);}
  if(digitalRead(10)==LOW && menu==1){set_i++;if(set_i>1){set_i=0;}set_u=100;times_i=millis();times_u=millis()+50000;delay(200);}
  
  //////// set out 0-28 V
  
  if(menu==0 && set_u==0 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition*10;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==0 && set_u==1 && millis()-times_u<5000){
    if (newPosition != oldPosition){times_u=millis();oldPosition = newPosition;u_out=u_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(stab==0){
  if(u_out<0){u_out=0;}if(u_out>280){u_out=280;}u_dig = float(u_out)/10/u_k*4096/5.00; 
  }
  Serial.println(u_dig);  

  if(stab==1){
    i = analogRead(A0)/250.00*i_k;
    if(i > float(i_out/100.0)){u_dig--;if(u_dig<0){u_dig=0;}lcd.setCursor(12, 1);lcd.print("STB");}
     else{
      u_dig = float(u_out)/10/u_k*4096/5.00;lcd.setCursor(12, 1);lcd.print("ON ");
      }
      if(power==1){MCP4725(0);lcd.setCursor(12, 1);lcd.print("OFF");}else{MCP4725(u_dig+i*4.00);}
    }

     
  //////// set i 0-2.5 A
 
  if(menu==1 && set_i==0 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition*100;myEnc.write(0);newPosition=0;times=millis();w=1;}}
  if(menu==1 && set_i==1 && millis()-times_i<5000){
    if (newPosition != oldPosition){times_i=millis();oldPosition = newPosition;i_out=i_out+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;}}
     
  if(i_out<0){i_out=0;}if(i_out>999){i_out=999;}
 
  //////// lcd
  if(stab==0){i_kz();}
  
  if(millis()-times_lcd>400){times_lcd=millis();}
  
  lcd.setCursor(0, 0);if(menu==0){lcd.print("U*= ");}else{lcd.print("U = ");}

  
  if(millis()-times_u<5000&&menu==0){
  if(set_u==0){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print("  ");lcd.print(".");lcd.print(u_out%10);}}
  if(set_u==1){ if(millis()-times_lcd>200){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);}else{lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(" ");}}
  }
  else{
    if(stab==0){lcd.print(u_out/100);lcd.print(u_out/10%10);lcd.print(".");lcd.print(u_out%10);set_u=1;}
    if(stab==1){lcd.print((u_dig *10 *u_k *5.00/4096.00)/10,1);set_u=1;}
    }
  lcd.print(" V "); 
  lcd.setCursor(11, 0);lcd.print(abs(i),2);lcd.print("A");



  lcd.setCursor(0, 1);if(menu==1){lcd.print("I*= ");}else{lcd.print("I = ");}
  
  if(millis()-times_i<5000&&menu==1){
  if(set_i==0){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(" ");lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}}
  if(set_i==1){ if(millis()-times_lcd>200){lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);}
    else{lcd.print(i_out/100);lcd.print(".");lcd.print("  ");}}
  }
  else{lcd.print(i_out/100);lcd.print(".");lcd.print(i_out/10%10);lcd.print(i_out%10);set_i=1;}
  lcd.setCursor(9, 1);lcd.print("A");

  if(stab==0){i_kz();}

  //////////////// EEPROM
  if(millis()-times>5000&&w==1){EEPROM.update(0,highByte(u_out));EEPROM.update(1,lowByte(u_out));
  EEPROM.update(2,highByte(i_out));EEPROM.update(3,lowByte(i_out));
  times=millis();w=0;}
  }//loop
 
void MCP4725(int data){  
  byte buffer[3];
  buffer[0] = 0b01000000;
  // data=0;
  // buffer[0] = 0b01100000; // запись в память ЦАП 0 В 
  buffer[1] = data >> 4;              
  buffer[2] = data << 4;
  Wire.beginTransmission(0x60);
  Wire.write(buffer[0]);
  Wire.write(buffer[1]);
  Wire.write(buffer[2]);
  Wire.endTransmission();
  }  
void i_kz(){  
  i = analogRead(A0)/250.00*i_k;
 
  if(i > float(i_out/100.0)){MCP4725(0);lcd.setCursor(12, 1);lcd.print("ERR");delay(3000);power=1;}
  else{lcd.setCursor(12, 1);
  if(power==0){MCP4725(u_dig+i*4.00);lcd.print("ON ");}
  if(power==1){MCP4725(0);lcd.print("OFF");}
  }
  
  }
  
 
void to_Timer(){newPosition = myEnc.read()/4;}