E70BS linearno napajanje 30A 13,8V za radio

DIY linearno napajanje 30A 13,8V za amaterski radio — transformator, stabilizacija, zaštita od prenapona, Arduino mjerenje i galerija izrade autora E70BS.

Na ovoj stranici

Kako je sve počelo…

Ljubav prema tehnici i elektronici vremenom me dovela do hobija amaterske radio-komunikacije, i tu počinje ova priča. Da skratim priču, položio sam ispit i dobio pozivni znak E70BS, kupio svoj prvi uređaj (Yaesu FT991A) i trebalo mi je napajanje. Tako je nastalo projektovanje i izrada mog linearnog napajanja za radio.

Kompjutersko napajanje za HAM radio

U početku sam koristio Chieftec kompjutersko napajanje deklarisano na 40 ampera na 12V grani. Skinio sam sve nepotrebne žice i iskoristio one za GPU sa 2×8 pin konektorima da napajam radio. Radi odlično, ali radio nije u stanju da proizvede punu RF izlaznu snagu na 12V. Nisam htio da forsiram napajanje na 13,8V, jer sam imao loša iskustva s takvim modifikacijama. Pola volta ili tako nešto bi bilo u redu, ali ovdje govorimo o porastu napona većem od 10 %. Ne kažem da se to ne može uraditi, samo sam odlučio da krenem drugim putem.

E70BS linearno napajanje za radio

Napravio sam dosta klasičnih napajanja u prošlosti. Znam da smo odavno u eri prekidačkih napajanja, ali volim da imam klasičan izvor napajanja s velikim dobrim starim transformatorom za neke namjene.
I volim da pravim stvari, velika je radost kad napraviš nešto lijepo. Odlučio sam da napravim napajanje koje će biti što stabilnije, zaštititi radio od prenapona i svesti na minimum svako potencijalno smetnje koje bi mogle doći od napajanja. Još jedno ograničenje projekta bilo je da iskoristim što više dijelova koje već imam. To je uključivalo kutiju od starog EKG aparata, transformator, kondenzatore, hladnjak s izlaznim tranzistorima i još neke dijelove. Znate, uobičajene stvari koje vam leže po kući 🙂

Faze projekta

Podijelio sam ovaj projekat u dvije faze. Prva je samo napajanje, transformator, ispravljač i kondenzatori, sa stabilizacijom i zaštitom od prenapona. Druga je kontrola i mjerenje da bude malo modernije i lijepo izgleda.

Prva faza

Šema E70BS linearnog napajanja — prva faza

Stabilizacija napona

Imao sam transformator sa izlazom od 16V i ispravio ga Grecovim spojem od 35A i kondenzatorima od 50000 mikrofarada. Poslije toga ide dobri stari LM317 regulator napona koji pokreće 6 komada 2SD797 paralelno. Nisam stavio emiterske otpornike na kraju, jer sam htio da izbjegnem pad napona, a moji tranzistori su bili upareni. Tu je desetokretni 5K trimer RV1 za podešavanje izlaznog napona. D2 je Zener dioda od 14V i sprečava da se RV1 okrene preko 14 volti.

Zaštita od prenapona

Prvi pokušaj…

Ovaj dio mi je oduzeo najviše vremena za projektovanje. Prvo sam pokušao da to napravim sa FQP47P06 P-kanalnim FET-om, ali imao sam pad napona D-S od 2V sa dva takva paralelno i opterećenjem od 20A. Kasnije sam eksperimentisao sa povećanjem G-S napona, ali pad je bio isti iako su gejtovi trebali biti potpuno otvoreni. To je bio show-stopper. Mislim da sam dobio neke lažne FQP47P06 FET-ove.

Drugi pokušaj…

Onda mi je moj prijatelj Zoran E76C pričao o BTS555 i odlučio sam da probam. Koristi se u automobilskoj industriji i ima struju opterećenja od 165A i otpor u uključenom stanju od 2,5 mOhm. Nakon što sam pročitao njegov datasheet, prilagodio sam kolo koje sam koristio za kontrolu tih prokletih P-kanalnih FET-ova, i to je uradilo posao. Da skratim priču, tranzistori Q1 do Q3 sa D1 Zener diodom od 14V rade tako da zatvore U1 BTS555 u slučaju prenapona. U ovoj postavci će isključiti izlaz ako ulaz pređe 14,5V. To je za zaštitu radija u slučaju da stabilizacijski dio pregori i spriječi da 22V DC sa ispravljačkog mosta ide direktno u radio. Testirao sam ovo koliko sam mogao i radi kao sat. Lijepo je imati to, za svaki slučaj.

Druga faza

Šema E70BS linearnog napajanja — upravljanje druge faze

Arduino Nano i kontrola brzine ventilatora

Nisam imao pristojan Arduino Nano i elemente za prikaz u Proteusu, pa šema može izgledati čudno, ali shvatićete poentu. Koristio sam 3 Dallas DS18B20 senzora za mjerenje temperature. Dva za različite zone na tunelu hladnjaka za izlazne tranzistore, a treći za temperaturu ispravljačkog mosta. Koristim očitanja sa U3 i U4 za kontrolu brzine ventilatora. U zavisnosti od temperature, Arduino izlazi D7, D8 i D9 idu u visoko stanje i otvaraju tranzistor Q1 više ili manje, tako da imamo tri različite brzine ventilatora. Možda ćete pitati zašto tako komplikovan način, zašto ne PWM? Pa, imao sam slučajeve gdje je PWM pravio neki neprijatan šum, ili da to nazovem smetnjama, ili QRM-om, pa sam odlučio da izbjegnem njegovu upotrebu ovdje.

Senzori struje i napona

Koristio sam INA219 senzor napona i struje za mjerenje napona. Lak je za upotrebu, ima svoju Arduino biblioteku i vrlo je precizan u mjerenju napona. U stanju je da mjeri i struju do 3A, ali nisam uspio da prilagodim shunt otpornik i kod tako da dobijem čak i zadovoljavajuće precizno mjerenje pri struji od 30 ampera. Da ne govorim o shuntu dovoljno velikom da izdrži tu struju. Zato sam se za tu namjenu prebacio na ACS712ELCTR-30A-T Hall efekt senzor. Moram reći da sam vrlo zadovoljan njime, iako sam bio skeptičan u vezi veličine njegovih pinova u poređenju sa strujom od 30A koju bi trebao da podnese.

Arduino kod

Nisam počistio kod, i nisam neki guru za kodiranje pa ne očekujte čuda ovdje 🙂 Koristio sam neke dijelove koje sam našao na internetu, i ako sam propustio da nekome dam zasluge, izvinjavam se. Mislim da je dovoljno komentarisan da vam ne stvori probleme ako odlučite da napravite svoju verziju napajanja.

// 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);
      }
    }  
 }

Neću mnogo komentarisati kod. Samo da napomenem, trebaće vam da promijenite adrese Probe01 – Probe03 da odgovaraju adresama vaših Dallas DS18B20 senzora. Ostatak koda bi trebao biti generički. Moji izlazni tranzistori su na hladnjaku sa vazdušnim tunelom, i postavio sam:

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

da odgovara mom podešavanju. Ako imate drugo rješenje hladnjaka, možda ćete htjeti ovo drugačije podesiti, ili vam možda čak neće trebati ventilatori. Kad je moj radio u RX, ventilatori se ne uključuju, a u mješovitom RX/TX režimu idu na brzinu jedan, ponekad na brzinu dva, zavisno od sobne temperature i podešavanja snage radija.

Displej

Moram reći da je FT-991A prilično žedan struje, troši do 20A zavisno od režima, opsega i podešavanja snage. Zgodno je vidjeti potrošnju na napajanju. Navikao sam se na tu osobinu i sviđa mi se.

Displej napajanja

Testiranje

Prije nego što sam uopšte priključio radio na napajanje, moralo je proći neke testove dok nisam bio zadovoljan. Glavni je bio da ga držim pod pristojnim opterećenjem neko vrijeme da vidim kako se ponaša. Nakon što sam spalio nekoliko prilično velikih otpornika, našao sam dio električnog grijača koji je odradio posao kao vještačko opterećenje. Žica grijača je postala crvena, ali je izdržala 22 ampera sat vremena. To mi je bilo dovoljno jer radio nikad nije u TX cijelo vrijeme, i to je dokazalo da su hlađenje i konstrukcija dovoljno dobri.

Napajanje pod testom opterećenja

Izrada E70BS linearnog napajanja za radio

Fotografisao sam cijeli proces i evo galerije koja prikazuje izradu napajanja od početka do kraja. Trebalo mi je skoro godinu dana od ideje do gotovog uređaja, ali zadovoljan sam rezultatom.

Zaključak

Koristim ovo napajanje već godinu dana. Radi kao sat. Zaista volim da vidim potrošnju na displeju, a traka snage na četvrtoj liniji displeja je vrlo zgodna. Dodao sam dva XT60 konektora naprijed, i oni su odličan dodatak kad treba da napajate nešto drugo osim radija. U svakom slučaju, XT60 mogu podnijeti čak i potrošnju radija, pa mislim da su dobar izbor. Takođe sam napravio USB vezu sa Arduino dostupnom pozadi, tako da mogu da ažuriram firmware po potrebi bez otvaranja napajanja. Sve u svemu, mislim da ovaj projekat nije bio ništa drugo do potpuni uspjeh. Lijepo je, nije preveliko za svoju snagu i osobine, i najvažnije od svega, pouzdano je i domaće izrade. Ako nastavim ovako, počeću da zvučim kao Gollum… Moje, moje drago 🙂

Evo nekoliko fotografija gotovog uređaja i moje skromne radio-sobe.

E73CV dvojno napajanje

Moj prijatelj Stevo E73CV napravio je drugu varijantu ovog napajanja. Imao je malo drugačije potrebe pa je kombinovao ovaj dizajn u malo manjoj verziji sa prekidačkim napajanjem. Ovim mu se zahvaljujem za slike. Ovo je još jedno lijepo ručno rađeno inženjersko djelo.

Evo rezultata:

Ažuriranje novembar 2024. Ugradio sam TVS diodu 5KP14CA paralelno sa DC izlazom. Trebala bi da djeluje kao još jedan sloj zaštite za uređaje priključene na napajanje.

Ako vam se sviđa ovaj članak, možda bi vam se svidio i onaj o izradi vještačkog opterećenja od 250W.

Hvala na čitanju, i ako imate pitanja ili želite da napravite E70BS linearno napajanje za radio i treba vam pomoć, ostavite komentar i potrudiću se da odgovorim što prije.

73,

E70BS

Izvori