E70BS линеарно напајање 30A 13,8V за радио

DIY линеарно напајање 30A 13,8V за аматерски радио — трансформатор, стабилизација, заштита од пренапона, Arduino мјерење и галерија израде аутора E70BS.

На овој страници

Како је све почело…

Љубав према техници и електроници временом ме довела до хобија аматерске радио-комуникације, и ту почиње ова прича. Да скратим причу, положио сам испит и добио позивни знак E70BS, купио свој први уређај (Yaesu FT991A) и требало ми је напајање. Тако је настало пројектовање и израда мог линеарног напајања за радио.

Компјутерско напајање за HAM радио

У почетку сам користио Chieftec компјутерско напајање декларисано на 40 ампера на 12V грани. Скинуо сам све непотребне жице и искористио оне за GPU са 2×8 pin конекторима да напајам радио. Ради одлично, али радио није у стању да произведе пуну RF излазну снагу на 12V. Нисам хтио да форсирам напајање на 13,8V, јер сам имао лоша искуства с таквим модификацијама. Пола волта или тако нешто би било у реду, али овдје говоримо о порасту напона већем од 10 %. Не кажем да се то не може урадити, само сам одлучио да кренем другим путем.

E70BS линеарно напајање за радио

Направио сам доста класичних напајања у прошлости. Знам да смо одавно у ери прекидачких напајања, али волим да имам класичан извор напајања с великим добрим старим трансформатором за неке намјене.
И волим да правим ствари, велика је радост кад направиш нешто лијепо. Одлучио сам да направим напајање које ће бити што стабилније, заштитити радио од пренапона и свести на минимум свако потенцијално сметње које би могле доћи од напајања. Још једно ограничење пројекта било је да искористим што више дијелова које већ имам. То је укључивало кутију од старог ЕКГ апарата, трансформатор, кондензаторе, хладњак с излазним транзисторима и још неке дијелове. Знате, уобичајене ствари које вам леже по кући 🙂

Фазе пројекта

Подијелио сам овај пројекат у двије фазе. Прва је само напајање, трансформатор, исправљач и кондензатори, са стабилизацијом и заштитом од пренапона. Друга је контрола и мјерење да буде мало модерније и лијепо изгледа.

Прва фаза

Шема E70BS линеарног напајања — прва фаза

Стабилизација напона

Имао сам трансформатор са излазом од 16V и исправио га Грецовим спојем од 35A и кондензаторима од 50000 микрофарада. Послије тога иде добри стари LM317 регулатор напона који покреће 6 комада 2SD797 паралелно. Нисам ставио емитерске отпорнике на крају, јер сам хтио да избјегнем пад напона, а моји транзистори су били упарени. Ту је десетокретни 5K тример RV1 за подешавање излазног напона. D2 је Зенер диода од 14V и спречава да се RV1 окрене преко 14 волти.

Заштита од пренапона

Први покушај…

Овај дио ми је одузео највише времена за пројектовање. Прво сам покушао да то направим са FQP47P06 P-каналним FET-ом, али имао сам пад напона D-S од 2V са два таква паралелно и оптерећењем од 20A. Касније сам експериментисао са повећањем G-S напона, али пад је био исти иако су гејтови требали бити потпуно отворени. То је био show-stopper. Мислим да сам добио неке лажне FQP47P06 FET-ове.

Други покушај…

Онда ми је мој пријатељ Зоран E76C причао о BTS555 и одлучио сам да пробам. Користи се у аутомобилској индустрији и има струју оптерећења од 165A и отпор у укљученом стању од 2,5 mOhm. Након што сам прочитао његов datasheet, прилагодио сам коло које сам користио за контролу тих проклетих P-каналних FET-ова, и то је урадило посао. Да скратим причу, транзистори Q1 до Q3 са D1 Зенер диодом од 14V раде тако да затворе U1 BTS555 у случају пренапона. У овој постави ће искључити излаз ако улаз пређе 14,5V. То је за заштиту радија у случају да стабилизацијски дио прегори и спријечи да 22V DC са исправљачког моста иде директно у радио. Тестирао сам ово колико сам могао и ради као сат. Лијепо је имати то, за сваки случај.

Друга фаза

Шема E70BS линеарног напајања — управљање друге фазе

Arduino Nano и контрола брзине вентилатора

Нисам имао пристојан Arduino Nano и елементе за приказ у Proteus-у, па шема може изгледати чудно, али схватићете поенту. Користио сам 3 Dallas DS18B20 сензора за мјерење температуре. Два за различите зоне на тунелу хладњака за излазне транзисторе, а трећи за температуру исправљачког моста. Користим очитања са U3 и U4 за контролу брзине вентилатора. У зависности од температуре, Arduino излази D7, D8 и D9 иду у високо стање и отварају транзистор Q1 више или мање, тако да имамо три различите брзине вентилатора. Можда ћете питати зашто тако компликован начин, зашто не PWM? Па, имао сам случајеве гдје је PWM правио неки непријатан шум, или да то назовем сметњама, или QRM-ом, па сам одлучио да избјегнем његову употребу овдје.

Сензори струје и напона

Користио сам INA219 сензор напона и струје за мјерење напона. Лак је за употребу, има своју Arduino библиотеку и врло је прецизан у мјерењу напона. У стању је да мјери и струју до 3A, али нисам успио да прилагодим shunt отпорник и код тако да добијем чак и задовољавајуће прецизно мјерење при струји од 30 ампера. Да не говорим о шунту довољно великом да издржи ту струју. Зато сам се за ту намјену пребацио на ACS712ELCTR-30A-T Hall ефект сензор. Морам рећи да сам врло задовољан њиме, иако сам био скептичан у вези величине његових пинова у поређењу са струјом од 30A коју би требало да поднесе.

Arduino код

Нисам почистио код, и нисам неки гуру за кодирање па не очекујте чуда овдје 🙂 Користио сам неке дијелове које сам нашао на интернету, и ако сам пропустио да некоме дам заслуге, извињавам се. Мислим да је довољно коментарисан да вам не створи проблеме ако одлучите да направите своју верзију напајања.

// code for  E70BS Linear PSU for Radio
// Firmware version 1.6.3
#include <Wire.h>
#include <Adafruit_INA219.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>  
#include <DallasTemperature.h>  

// Set the LCD address to 0x27 (or 0x3F) for a 16 chars and 2 line display
//LiquidCrystal_I2C lcd(0x27, 16, 2);
LiquidCrystal_I2C lcd(0x27, 20, 4);       //If using a 20 x 4 display, uncomment this line and comment out the line above

// Data wire is plugged into pin 4 on the Arduino
#define ONE_WIRE_BUS 4
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
// const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);
byte nextSensor = 0;  
byte const numSensors = 3; 
byte Address[numSensors][8]; 
byte sensorCount;  
DeviceAddress Probe01 = { 0x28, 0xCD, 0x02, 0x3B, 0x05, 0x00, 0x00, 0xA1 };
DeviceAddress Probe02 = { 0x28, 0xFF, 0xDD, 0x5B, 0x85, 0x16, 0x05, 0x98 };
DeviceAddress Probe03 = { 0x28, 0x44, 0x06, 0x3B, 0x05, 0x00, 0x00, 0xC2 };

float shuntMultiplier = 0.022;
Adafruit_INA219 ina219;
unsigned int x = 0; //for acs712 hall current sensor
float AbsI = 0;
//temp settings for fan speeds
  float tempon1 = 45.00;
  float tempon2 = 53.00;
  float tempon3 = 60.00;
  bool logA = false; 
//end of temp settings for fan speeds
  float Temp1;
  float Temp2;
  float Temp3;
  //test
  int varSpeed;
 //end test
float a;

//These 5 arrays paint the bars that go across the screen.  
byte zero[] = {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
};
byte one[] = {
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000
};

byte two[] = {
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
  B11000
};

byte three[] = {
  B11100,
  B11100,
  B11100,
  B11100,
  B11100,
  B11100,
  B11100,
  B11100
};

byte four[] = {
  B11110,
  B11110,
  B11110,
  B11110,
  B11110,
  B11110,
  B11110,
  B11110
};

byte five[] = {
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};

long randNumber;
  int speed1 = 7;
  int speed2 = 8;
  int speed3 = 9;
void setup(void)
{
  pinMode(speed1, OUTPUT);
  pinMode(speed2, OUTPUT);
  pinMode(speed3, OUTPUT);
  
  Serial.begin(9600);
  lcd.init();
  lcd.clear();
  lcd.backlight();      // Make sure backlight is on
  sensors.setResolution(Probe01, 10);  
  sensors.setResolution(Probe02, 10);
  sensors.setResolution(Probe03, 10);

  sensors.begin();
  //bool setMaxCurrentShunt(float ampere = 20.0, float ohm = 0.002);
  uint32_t currentFrequency;

  // Initialize the INA219.
  // By default the initialization will use the largest range (32V, 2A).  However
  // you can call a setCalibration function to change this range (see comments).
  if (! ina219.begin())
  {
    lcd.display();
    lcd.setCursor(0, 0); // top left
    lcd.print("Failed to find INA219 chip");

    while (1) {
      delay(10);
    }
  }
  // To use a slightly lower 32V, 1A range (higher precision on amps):
  //ina219.setCalibration_32V_1A();
  // Or to use a lower 16V, 400mA range (higher precision on volts and amps):
  //ina219.setCalibration_16V_400mA();
  sensorCount = sensors.getDeviceCount();
  oneWire.reset_search();
  for (byte i = 0; i < sensorCount; i++)
  {
    // assigns the next address found to Address[i][0..7]
    if (!oneWire.search(Address[i]))
    {
      Serial.print("Unable to find address");
      Serial.print("\n");
    }
  }
  
  // initialize the LCD and allocate the 5 arrays to a number.
  lcd.init();
  lcd.backlight();
  lcd.createChar(0, zero);
  lcd.createChar(1, one);
  lcd.createChar(2, two);
  lcd.createChar(3, three);
  lcd.createChar(4, four);
  lcd.createChar(5, five);
introFunction();
lcd.clear();
}

void loop(void)
{

 Temp1 = sensors.getTempC(Probe01);
 Temp2 = sensors.getTempC(Probe02);
 Temp3 = sensors.getTempC(Probe03);

  sensors.requestTemperatures();
  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  float power_mW = 0;
  float shuntCurrent_A = 0;
  float absloadvoltage = 0;
  float absshuntCurrent_A = 0;
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();

  loadvoltage = busvoltage + (shuntvoltage / 1000);
  absloadvoltage = abs(loadvoltage);
  current_mA = ina219.getCurrent_mA();
  shuntCurrent_A = current_mA * shuntMultiplier;
  absshuntCurrent_A = abs(shuntCurrent_A);

  float AcsValue = 0.0, Samples = 0.0, AvgAcs = 0.0, AcsValueF = 0.0;

  for (int x = 0; x < 150; x++) { //Get 150 samples
    AcsValue = analogRead(A0);     //Read current sensor values
    Samples = Samples + AcsValue;  //Add samples together
    delay (3); // let ADC settle before next sample 3ms
  }
  AvgAcs = Samples / 150.0; //Taking Average of Samples

  AcsValueF = (2.5 - (AvgAcs * (5.0 / 1024.0)) ) / 0.066; 
 float AcsValueG;
  if (AcsValueF < 0.2)
  {
    AcsValueG = 0;
  }
  else
  {
    AcsValueG = AcsValueF;
    }
  
  AbsI = abs(AcsValueG);

  // code credits to https://www.engineersgarage.com/acs712-current-sensor-with-arduino/

  lcd.display();
  lcd.setCursor(0, 0); // top left
  lcd.setCursor(0, 0);
  lcd.print("T1=");
  lcd.print(Temp1, 0);
  lcd.print("C");
  lcd.print(" ");
  lcd.setCursor(7, 0);
  lcd.print("T2=");
  lcd.print(Temp2, 0);
  lcd.print("C");
  lcd.print(" ");
  lcd.setCursor(14, 0);
  lcd.print("T3=");
  lcd.print(Temp3, 0);
  lcd.print("C");
  if(Temp2 <10){
  lcd.print(" ");
    }

    lcd.setCursor(0,2);
    lcd.print("I=");
    lcd.print(AbsI);
    lcd.print("A");
    lcd.print(" ");
    lcd.setCursor(10, 2);
    lcd.print("U=");
    lcd.print(absloadvoltage, 2);
    lcd.print("V");
    if(absloadvoltage <10){
    lcd.print(" ");
    }
    updateProgressBar(AbsI, 30, 3);

setSpeed();

}

 void setSpeed()

 {

 if (Temp1 > tempon3 || Temp2 > tempon3)
{
//  varSpeed = 3;
  digitalWrite(speed1, HIGH);
  digitalWrite(speed2, HIGH);
  digitalWrite(speed3, HIGH);  
  }
else  if (Temp1 > tempon2 || Temp2 > tempon2)
{
//  varSpeed = 2;
  digitalWrite(speed1, LOW);
  digitalWrite(speed2, HIGH);
  digitalWrite(speed3, LOW);  
  }
 else  if (Temp1 > tempon1 || Temp2 > tempon1)
{
//  varSpeed = 1;
  digitalWrite(speed1, HIGH);
  digitalWrite(speed2, LOW);
  digitalWrite(speed3, LOW); 
    logA = true; 
  }

else  if ((Temp1 < tempon1 || Temp2 < tempon1) && logA == false)
{
//  varSpeed = 0;
  digitalWrite(speed1, LOW);
  digitalWrite(speed2, LOW);
  digitalWrite(speed3, LOW);

  }  

     else if (Temp1 < tempon1 -6  || Temp2 < tempon1 - 4)
  {
  digitalWrite(speed1, LOW);
  digitalWrite(speed2, LOW);
  digitalWrite(speed3, LOW);
  logA = false;
    } 
  }
 
 void introFunction()
 {
  digitalWrite(speed1, HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Linear Power Supply");
  delay(5000);
  lcd.setCursor(1, 1);
  lcd.print("Designed by E70BS");
  digitalWrite(speed1, LOW);
  digitalWrite(speed2, HIGH);
  delay(3000);
  lcd.setCursor(1, 2);
  lcd.print("  Firmware 1.6.3");
  delay(3000);
  digitalWrite(speed2, LOW);
  digitalWrite(speed3, HIGH);
  lcd.setCursor(8, 3);
  lcd.print("\"73\"");
  delay(3000);
  digitalWrite(speed1, LOW);
  digitalWrite(speed2, LOW);
  digitalWrite(speed3, LOW);
  
 
  }
 void updateProgressBar(unsigned long count, unsigned long totalCount, int lineToPrintOn)
 {
    
    double factor = totalCount/100.0;         
    int percent = (count+1)/factor;
    int number = percent/5;
    int remainder = percent%5;
    if(number > 0)
    {
      for(int j = 0; j < number; j++)
      {
        lcd.setCursor(j,lineToPrintOn);
       lcd.write(5);
      }
    }
       lcd.setCursor(number,lineToPrintOn);
       lcd.write(remainder); 
     if(number < 20)
    {
      for(int j = number+1; j <= 19; j++)
      {
        lcd.setCursor(j,lineToPrintOn);
       lcd.write(0);
      }
    }  
 }

Нећу много коментарисати код. Само да напоменем, требаће вам да промијените адресе Probe01 – Probe03 да одговарају адресама ваших Dallas DS18B20 сензора. Остатак кода би требао бити генерички. Моји излазни транзистори су на хладњаку са ваздушним тунелом, и поставио сам:

float tempon1 = 45.00;
float tempon2 = 53.00;
float tempon3 = 60.00;

да одговара мом подешавању. Ако имате друго рјешење хладњака, можда ћете хтјети ово другачије подесити, или вам можда чак неће требати вентилатори. Кад је мој радио у RX, вентилатори се не укључују, а у мјешовитом RX/TX режиму иду на брзину један, понекад на брзину два, зависно од собне температуре и подешавања снаге радија.

Дисплеј

Морам рећи да је FT-991A прилично жедан струје, троши до 20A зависно од режима, опсега и подешавања снаге. Згодно је видјети потрошњу на напајању. Навикао сам се на ту особину и свиђа ми се.

Дисплеј напајања

Тестирање

Прије него што сам уопште прикључио радио на напајање, морало је проћи неке тестове док нисам био задовољан. Главни је био да га држим под пристојним оптерећењем неко вријеме да видим како се понаша. Након што сам спалио неколико прилично великих отпорника, нашао сам дио електричног гријача који је одрадио посао као вјештачко оптерећење. Жица гријача је постала црвена, али је издржала 22 ампера сат времена. То ми је било довољно јер радио никад није у TX цијело вријеме, и то је доказало да су хлађење и конструкција довољно добри.

Напајање под тестом оптерећења

Израда E70BS линеарног напајања за радио

Фотографисао сам цијели процес и ево галерије која приказује израду напајања од почетка до краја. Требало ми је скоро годину дана од идеје до готовог уређаја, али задовољан сам резултатом.

Закључак

Користим ово напајање већ годину дана. Ради као сат. Заиста волим да видим потрошњу на дисплеју, а трака снаге на четвртој линији дисплеја је врло згодна. Додао сам два XT60 конектора напријед, и они су одличан додатак кад треба да напајате нешто друго осим радија. У сваком случају, XT60 могу поднијети чак и потрошњу радија, па мислим да су добар избор. Такође сам направио USB везу са Arduino доступном позади, тако да могу да ажурирам firmware по потреби без отварања напајања. Све у свему, мислим да овај пројекат није био ништа друго до потпуни успјех. Лијепо је, није превелико за своју снагу и особине, и најважније од свега, поуздано је и домаће израде. Ако наставим овако, почећу да звучим као Gollum… Моје, моје драго 🙂

Ево неколико фотографија готовог уређаја и моје скромне радио-собе.

E73CV двојно напајање

Мој пријатељ Стево E73CV направио је другу варијанту овог напајања. Имао је мало другачије потребе па је комбиновао овај дизајн у мало мањој верзији са прекидачким напајањем. Овим му се захваљујем за слике. Ово је још једно лијепо ручно рађено инжењерско дјело.

Ево резултата:

Ажурирање новембар 2024. Уградио сам TVS диоду 5KP14CA паралелно са DC излазом. Требала би да дјелује као још један слој заштите за уређаје прикључене на напајање.

Ако вам се свиђа овај чланак, можда би вам се свидио и онај о изради вјештачког оптерећења од 250W.

Хвала на читању, и ако имате питања или желите да направите E70BS линеарно напајање за радио и треба вам помоћ, оставите коментар и потрудићу се да одговорим што прије.

73,

E70BS

Извори