1

Тема: NEW_DIGITAL_POWER (разработка)

Линейный регулятор напряжения и тока с микроконтроллерным управлением.

http://forum.rcl-radio.ru/uploads/images/2023/09/61086d10405e90a65d8faf10de349ab4.png

ШИМ регулятор

http://forum.rcl-radio.ru/uploads/images/2023/09/7eeb51dcbd074e703f0ed7b39483c5c1.png

2

Re: NEW_DIGITAL_POWER (разработка)

LGT8F328

#define K_PWM1 7.65

float u_pwm1;
float u_out_pwm1=12;
int pwm1;


void setup() {
  pinMode(11,OUTPUT);
  cli();
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = 0;
  TCCR2A |= (1<<COM2A1);
  TCCR1B |= (1<<WGM22);
  TCCR2A |= (1<<WGM21) | (1<<WGM20);
  TCCR2B |= (1 << CS21)|(1<<CS20); 
  OCR2A = 127; 
  sei();
  analogReadResolution(12);
  pinMode(A0,INPUT);
}

void loop(){
  
  u_pwm1=5.00/4095*analogRead(A0)*K_PWM1;
  if(u_pwm1<u_out_pwm1){pwm1--;if(pwm1<1){pwm1=1;}}
  if(u_pwm1>u_out_pwm1){pwm1++;if(pwm1>255){pwm1=255;}}
  OCR2A = pwm1;
  
  }

3

Re: NEW_DIGITAL_POWER (разработка)

#define ANALOG_I A3
#define ANALOG_U A6
#define SW       10

#define U_OUT_K 3359
#define I_OUT_K 1730
#define I_STAB_K 4410
#define U_OUT_IND 1382
#define I_0 0

#include <Wire.h>
#include <Encoder.h>           // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip 
#include <U8glib.h>            // https://github.com/olikraus/u8glib/
#include <EEPROM.h>
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST);  // Dev 0, Fast I2C / TWI
Encoder myEnc(7, 8);// DT, CLK

float u_pwm1;
float u_out_pwm1=5;
int pwm1;
unsigned long i_sum,u_sum,times,times1;
int ads_i,i,menu;
int u,u_out,i_stab;
long oldPosition  = -999,newPosition,times3;
bool w,w1;


void setup(){
  analogReadResolution(12);
  analogReference(DEFAULT);//INTERNAL4V096 DEFAULT(Uп)
  pinMode(11,OUTPUT);
  pinMode(A0,INPUT);
  pinMode(ANALOG_I,INPUT);
  pinMode(ANALOG_U,INPUT);
  pinMode(SW,INPUT);        // encoder SW
  Serial.begin(9600);
  Wire.begin();delay(300);
  u_out=EEPROM.read(0)*10.0+EEPROM.read(1);
  i_stab=EEPROM.read(2);
// TIMER_1 D9 OUTPUT
  DDRB = 1 << PB1;
  noInterrupts();
  TCCR1A=0;TCCR1B=0;
  TCCR1A = 1 << COM1A1 | 1 << WGM11;
  TCCR1B = 1 << WGM13 | 1 << WGM12 | 1 << CS10;
  OCR1A = float(u_out)/100.0*U_OUT_K;
  ICR1 = 10000;
// TIMER_3 D2 OUTPUT
  TCCR3A=0;TCCR3B=0;
  DDRF |= (1<<PF2);
  HDR = 1 << HDR3;
  TCCR3A = 1 << COM3B1 | 1 << WGM31;
  TCCR3B = 1 << WGM33 | 1 << WGM32 | 1 << CS30;
  OCR3B = I_STAB_K*float(i_stab)/100.0;// 4700 1A
  ICR3 = 10000;
// TIMER_2 D11 OUTPUT  
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = 0;
  TCCR2A |= (1<<COM2A1);
  TCCR1B |= (1<<WGM22);
  TCCR2A |= (1<<WGM21) | (1<<WGM20);
  TCCR2B |= (1 << CS21) | (1 << CS20); 
   TIMSK2 = 1 << OCIE2A;
  OCR2A = 255; 
// F=32000000/256/32/1=3906.25 Hz
  interrupts();
  u8g.firstPage();do {u8g.setFont(u8g_font_profont12r);
  u8g.drawStr(30,20,"POWER SUPPLY");
  u8g.drawStr(35,50,"0-30V 0-2A");
  } 
  while( u8g.nextPage() );
  delay(1000);
}

void loop() {
 if(digitalRead(10)==LOW){menu++;if(menu>2){menu=0;}times3=millis();w=1;delay(200);}

 if(menu==1){
 if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
    u_out=u_out+newPosition;myEnc.write(0);newPosition=0;times3=millis();w=1;w1=1;if(u_out>300){u_out=300;}if(u_out<0){u_out=0;}
    OCR1A = float(u_out)/100.0*U_OUT_K;
    }}
 if(menu==2){
 if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
    i_stab=i_stab+newPosition;myEnc.write(0);newPosition=0;times3=millis();w=1;w1=1;if(i_stab>200){i_stab=200;}if(i_stab<0){i_stab=0;}
    OCR3B = I_STAB_K*float(i_stab)/100.0;
    }}
    
///////////////////////////////////////////////////////////  
  if(millis()-times>100){times=millis();ads_i++;
   i_sum = i_sum + analogRead(ANALOG_I);
   u_sum = u_sum + analogRead(ANALOG_U);
   }
  if(ads_i>9){ads_i=0;i = i_sum/10.0;i_sum=0; u = u_sum/10.0;u_sum=0;
  Serial.print("I_out: ");Serial.println(abs(float(i-I_0)/I_OUT_K));
  Serial.print("U_out = ");Serial.println(float(u)/U_OUT_IND,1);
  }
//// PWM1 ////////////////////////////////////////////////
  u_pwm1=5.00/4095*analogRead(A0)*(u_out+3.00);
  if(u_pwm1<u_out_pwm1){pwm1--;if(pwm1<1){pwm1=1;}}
  if(u_pwm1>u_out_pwm1){pwm1++;if(pwm1>255){pwm1=255;}}
  OCR2A = pwm1;  
//////////////////////////////////////////////////////////
 
/// OLED PRINT ///////////////////////////////////////////
  u8g.firstPage();do {
    u8g.setFont(u8g_font_profont17r);
    u8g.setPrintPos(0, 15);u8g.print(float(u_out)/10.0,1);
    if(menu==0||menu==2){u8g.drawStr(55,15,">");}
    if(menu==1){u8g.drawStr(55,15,"*");}
    u8g.setPrintPos(67, 15);u8g.print(float(u)*10.0/U_OUT_IND,1);
    u8g.drawStr(120,15,"V"); 
    u8g.drawLine(0, 22, 128, 22);  
    u8g.setPrintPos(0, 40);u8g.print(float(i_stab)/100.0,2);
    if(menu==0||menu==1){u8g.drawStr(55,40,">");}
    if(menu==2){u8g.drawStr(55,40,"*");}
    u8g.setPrintPos(67, 40);u8g.print(float(i-I_0)/I_OUT_K,2);
    u8g.drawStr(120,40,"A");
    u8g.drawLine(0, 47, 128, 47);
    }
  while( u8g.nextPage() );

 if(millis()-times3>5000 && w==1){
  EEPROM.update(0,u_out/10%10);EEPROM.update(1,u_out%10);EEPROM.update(2,i_stab);
 menu=0;w=0;}
  
}

ISR(TIMER2_COMPA_vect) {
  newPosition = myEnc.read()/4;
  }

  

4

Re: NEW_DIGITAL_POWER (разработка)

Доброго времени суток. Тема хоть и не новая, но интересная и своевременна. Схемотехника понятна, немного шлифануть
в мелочах, но это потом. Из предварительного скетча понятен только диапазон напряжения и тока. Всё остальное что он
должен делать нет. Скетч я сам написать не смогу. По этому не сочтите за наглость но есть такое пожелание:
1. Контролер-ATMEGA8-328 или Arduino.
2. Дисплей LCD1602.
3.V-  0-30V   I-  0-5A.
4. Регулировка и переключение между V и I кнопкой энкодера.
5. Кнопка управления реле которое отключает только нагрузку  ON/OFF.
6. Чтобы запоминало последнее установленное значение, а лучше что-бы  было 2,3,4 значения ,которые можно установить и они запомнились, естественно потом их можно и менять.
Спасибо за Ваши разработки.