ups 12v attiny

minamonra
Offline
Зарегистрирован: 18.06.2014

Тема на коте тыц.

Плата тут.

Все просто, зарядка - генератор тока, переключение на акк - реле, усложнять не хотел, будет время прикручу какую нибуть 34063 на заряд и ШИМ стаб на выход.

Накорябал примерно так:

//                           || пин attiny13:         || чего:
#define  RELAY_PIN      1 // || PCINT1 (6-PB1) ...... || реле
#define  BAT_PIN        1 // || ADC1   (7-PB2) ...... || напряжение на аккумуляторе
#define  PWR_PIN        3 // || ADC3   (2-PB3) ...... || напряжение на входе
#define  CHARGE_PIN     4 // || PCINT4 (3-PB4) ...... || заряжатель
#define  INDICATOR_PIN  0 // || PCINT0 (5-PB0) ...... || светодио
#define  INTERVAL  300UL          // время задержки перехода на внешнее питание
static unsigned long PMillis = 0; // счетчик задержки
static int  BAT;                  // напряжение на аккумуляторе
static int  PWR;                  // напряжение на входе
static byte BATSTATE = 0;         // состояние аккумулятора 0 - при разрядке достиг минимума 10.80, 1 - можно разряжать
static byte CHARGEST = 1;         // 0 - нужно зарядить, 1 - full (по-умолчанию думаем что заряжен, и ждем 13.22) 
const  int  FULL_BATT    = 675;   // 14.22
const  int  LOW_BATT     = 512;   // 10.80
const  int  SUP_BATT     = 629;   // 13.22 напряжение включения добивки акк
const  int  DONT_BATT    = 530;   // 11.20 не включаемся до этого напряжения на акк после разряда (ждем чтобы подзаридили)
const  int  LOW_PWR      = 690;   // 14.20 на входе (зарядку включать бесполезно)
const  int  OUT_PWR      = 640;   // 14.00 уровень напряжения на входе при котором переходим на аккумулятор

void setup () {
 pinMode(INDICATOR_PIN, OUTPUT);  // 
 pinMode(RELAY_PIN,     OUTPUT);  // 
 pinMode(BAT_PIN,        INPUT);  //
 pinMode(PWR_PIN,        INPUT);  //
 pinMode(CHARGE_PIN,    OUTPUT);  //
}

void loop () {
 BAT = analogRead (BAT_PIN);
 PWR = analogRead (PWR_PIN);
 if (BAT > DONT_BATT) BATSTATE = 1;     // если на акк больше 11.00 - можем перейти на акк
 if (BAT < LOW_BATT ) BATSTATE = 0;     // если на акк меньше 10.80 - акк разряжен
 if (BAT > FULL_BATT) CHARGEST = 1;     // выкл зарядки
 if (BAT < SUP_BATT ) CHARGEST = 0;     // вкл зарядки
 if (PWR < LOW_PWR) PMillis = millis(); // обнуление задержки
 if (PWR > LOW_PWR) {                   // переход на внешнее питание с задержкой INTERVAL
    if (millis() - PMillis > INTERVAL) {   
      PMillis = millis();
      digitalWrite (RELAY_PIN,  LOW );
    }
 }
 if (PWR < OUT_PWR and BATSTATE == 1) { // если на входе меньше 14 и аккумулятор не разряжен - работаем
    digitalWrite (RELAY_PIN, HIGH);
    digitalWrite (CHARGE_PIN, LOW);
    digitalWrite (INDICATOR_PIN,LOW);
 }
 if (PWR < OUT_PWR and BATSTATE == 0) { // на входе пусто и аккумулятор сдох !!!
    digitalWrite (RELAY_PIN,  LOW );
 }
 if (PWR > LOW_PWR and CHARGEST == 1) { // если можем заряжать но акк заряжен
    digitalWrite (CHARGE_PIN, LOW   );
    digitalWrite (INDICATOR_PIN,HIGH);
 }
 if (PWR > LOW_PWR and CHARGEST == 0) { // заряжаем
    digitalWrite (CHARGE_PIN, HIGH );
    digitalWrite (INDICATOR_PIN,LOW);
 }
}

Работает.
Может кто код посмотрит, с целью улучшения? (не кодер я).
Или просто мыли какие?

minamonra
Offline
Зарегистрирован: 18.06.2014

Попробую другую схему для зарядки аккумулятора. Кусок её выдернул отсюда.

VD2 и VD3 - смотря какой ток.

minamonra
Offline
Зарегистрирован: 18.06.2014

Попробовал, измерения - отлично. Step-down корявый, - перепробовал несколько индуктивностей, разную частоту, греется слишком сильно, хотя сам по себе step-down не такой уж и холодный, даже на нормальных контроллерах (по крайней мере из тех что пробовал). Ну ещё может что не учёл. Тот же пушпулл на 3525 на двух мосфетах при токах 3-5 ампер холодным у меня получается... а тут 600-800 мА и уже горячо.

Для теста накорябал такое:

#include <PWM.h>
#include "arduino.h"
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
// set the LCD address to 0x27 for a 16 chars and 2 line display
int VBAT = 0;
int IBAT = 0;
int CURRENT = 65;
int DUTY = 0;
int32_t frequency = 40000; // desired frequency in Hertz
#define PWM_PIN 3           // the output pin for the pwm 
#define  INTERVAL  200UL          // 
static unsigned long PMillis = 0; // 
void setup () {
 pinMode(0, INPUT);
 pinMode(1, INPUT);
 lcd.init();
 lcd.backlight();
 InitTimersSafe(); 
 bool success = SetPinFrequencySafe(PWM_PIN, frequency);
 //if the pin frequency was set successfully, turn pin 13 on
 if(success) {
    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);
 } 
}
void loop () {
 VBAT = analogRead(0);
 IBAT = analogRead(1);
 if (IBAT>CURRENT) DUTY--;
 if (IBAT<CURRENT) DUTY++;
 pwmWrite(PWM_PIN, DUTY);
 if (millis() - PMillis > INTERVAL) {   
  PMillis = millis();
  lcd.setCursor(0, 0);
  lcd.print("V:");
  if (VBAT<1000) lcd.print(0); if (VBAT<100) lcd.print(0); if (VBAT<10) lcd.print(0);
  lcd.print(VBAT);
  lcd.setCursor(0, 1);
  lcd.print("I:");
  if (IBAT<1000) lcd.print(0); if (IBAT<100) lcd.print(0); if (IBAT<10) lcd.print(0);
  lcd.print(IBAT);
  lcd.setCursor(0, 2);
 }
}

 

s_1405695822_1459995_d12333f3c3.jpg

Файлы тут.

 

minamonra
Offline
Зарегистрирован: 18.06.2014

Заменил зарядку на 34063, на столе собрал почти вот такую схему:

s_1405757666_7727135_8bfa982766.gif

Управление с мк шим в напряжение, R9/C1 - фильтр. При включении на 7-ую ногу подается напряжение выключающее 34063. Ток регулируется подачей 0..5 на базу VT1 (0 - макс ток). Максимум для схемы 750-800 мА.

 

barbus
Offline
Зарегистрирован: 06.04.2013

minamonra можете добавить польную схему с даработками на тини13