Auto Start Auto Stop Battery Charger Devresi

Başlatan ghistmanzero, 14 Şubat 2018, 22:39:26

ghistmanzero

Alıntı yapılan: mg1980 - 15 Şubat 2018, 14:32:24
Eğer anlattığım sistemi komple yapmak isterseniz de kodların tamamını paylaşabilirim.

Analog olarak işin içinden çıkmak pek mümkün olmayacak gibi. Paylaşırsanız incelemek isterim. Yardımınız için teşekkürler

mg1980

Kodun tamamını sunuyorum. C diline daha hakim olanlar daha pratik hale getirebilirler.Ben bu kadar yapabildim.Kolay gelsin..
#include <LiquidCrystal.h>  //CD4051 ANALOG SWİÇ İLE  VOLTAJ KADEMESİ OTOMATİK SEÇİMİ
#include <TimerOne.h>       // 07.11.2017
#include <EEPROM.h>
#include <MsTimer2.h>

LiquidCrystal lcd(7,6,5,4,3,2);// 7=RS,6=E,5=D4,4=D5,3=D6,2=D7

const byte VOLC=A0;
const byte AMPOLC=A1;
const byte ROLE=8;

const byte YUK=9;
const byte BUTON=A4;
const byte BUTON1=12;
boolean durum; //BUTON için
boolean durum1; //BUTON1 için
byte saat=0;
int sayac=0;

double pwmv=0;
double girisVoltaji=0.0;
double toplam=0.0;
double ort=0.0;
byte i=0;
int t=0;
int mVperAmp=66;// 30A ACS712 için 5A için 185 olacak.
int okunanmV=0;
int ACSoffset=2500; // ölçüm olmadığında mevcut sabit voltaj
double Voltage=0;
double Amps=0;
double ortlm=0;
double toplamamp=0;
byte sarjsuresi;
double srjsuredk;
int c=1200; // Normal süre peryodu=24 dk.(Kontrol+akimolc peryodu=0,5 sn)
int d=1200; //Hızlı süre peryodu=24 dk.
byte hizli=0;
int seviye;
int y=0;

byte x=0;
byte m=0;
double okunan[20];  // volt için
double temp;
double okunanA[20]; // amper için
double tempA;



void setup() //*************************************************************
{ 
  delay(500);
  lcd.begin(16,2);
  pinMode(VOLC,INPUT);
  pinMode(AMPOLC,INPUT);
  
  pinMode(ROLE,OUTPUT); // ŞARJ AKIMINI AÇMA -KAPAMA
  pinMode(YUK,OUTPUT); // AMPUL DEVREYE ALARAK VOLTAJ ÖLÇME
  pinMode(BUTON,INPUT_PULLUP); //A4 pin
  pinMode(BUTON1,INPUT_PULLUP);//12.pin
  pinMode(11,OUTPUT);  // 
  pinMode(13,OUTPUT);  // 
  pinMode(A2,OUTPUT);  //
  pinMode(A3,OUTPUT);  //Buzer
  pinMode(A5,OUTPUT);  // Flash için.şarj olduğu ikazı
  digitalWrite(A2,LOW); //
  //Timer1.initialize(1000000); //Timer1 kesmesinde PWM çalışmıyor.PWM bu timeri kullanıyor.
  //Timer1.attachInterrupt(zaman);
  MsTimer2::set(1000, zaman);  //Timer2 için .Zaman takipine lazım.
  MsTimer2::start();
  
  digitalWrite(A3,HIGH);
  delay(100);
  digitalWrite(A3,LOW);
  delay(100);
  digitalWrite(A3,HIGH);
  delay(100);
  digitalWrite(A3,LOW);
  
  lcd.setCursor(0,0);
  lcd.print("AKU SARJI");
  lcd.setCursor(0,1);
  lcd.print("BEKLEYIN........");
  delay(1500);

  hizli=EEPROM.read(2);
  sarjsuresi=EEPROM.read(0);
  srjsuredk=EEPROM.read(1);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("SRJ Z=");
  lcd.print(sarjsuresi);
  lcd.print("s.");
  
  lcd.setCursor(0,1);
  lcd.print("SRJ Z=");
  lcd.print(srjsuredk,1);
  lcd.print("dk.");
  delay(5000);
  
}

void loop() //**********************************************************
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("NORMAL..> 7Ah");
  lcd.setCursor(0,1);
  lcd.print("HIZLI..> * BAS!");
  delay(2000);
  
  for(t=0;t<70;t++)
  {
    durum=digitalRead(BUTON);
    if (durum==0)
    {
      while(1)
      {
        EEPROM.write(0,0);
        delay(10);
        EEPROM.write(1,0);
        delay(10);
        hizli=0;
        EEPROM.write(2,0);
        delay(10);
        sarj();
        
      }
    }
    
    durum1=digitalRead(BUTON1);
    if (durum1==0)
    {
      while(1)
      {
        EEPROM.write(0,0);
        delay(10);
        EEPROM.write(1,0);
        delay(10);
        hizli=1;
        EEPROM.write(2,1);
        delay(10);
        hizlisarj();
        
      }
    }
    digitalWrite(A3,HIGH);
    delay(20);
    digitalWrite(A3,LOW);
    delay(80);
  }
  while(1)
    {
     EEPROM.write(0,0);
     delay(10);
     EEPROM.write(1,0);
     delay(10);
     if(hizli==1) hizlisarj(); //DİKKAT.hizlisarj konumunda elk.kesilirse oradan devam için.
     hizli=0;
     EEPROM.write(2,0);
     delay(10);
     sarj();
    }
}

void sarj()  //**********************************************************************************************
{
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("NORMAL SARJ");
      lcd.setCursor(0,1);
      lcd.print("OLCUYOR...");
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      delay(100);
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      
      digitalWrite(YUK,HIGH); // AMPUL DEVREDE VOLTAJ ÖLÇ
      delay(2000);                                  //3500
      

     for(i=0;i<20;i++) {                           // 20 kez voltaj ölçüm numunesi alınıyor.Ortalaması alınacak
        girisVoltaji=analogRead(VOLC)*0.0049*3;   // 3 katsayısı gerilim bölücü ile 14,1v 4.7v  ölçüldüğü için
        okunan[i]=girisVoltaji;                  // ...DİZİ İÇİNE ÖLÇÜM SIRASINA GÖRE YERLEŞTİRME..
        delay(5);                               // 5 idi.
     }
      
      
      for(x=0;x<20;x++) {                    //Dizi elemanlarının KÜÇÜKTEN BÜYÜĞE sıralanması
        for(m=x+1;m<20;m++) {
          if(okunan[x]>okunan[m]) {
            temp=okunan[x];
            okunan[x]=okunan[m];
            okunan[m]=temp;
          }
        }
        
      }
      
       toplam=0;
        for(x=2;x<18;x++){  //En küçük iki değer ile en büyük iki değeri eliyoruz
         toplam=toplam+okunan[x]; // Kalan 16 değeri topluyoruz.
        }
        ort=toplam/16;
         
    
     digitalWrite(YUK,LOW); //Ampul ve ölçme devre dışı
     delay(1000);
     if(ort>13.4){          // Akü voltajı 14V ise şarjı kes.
      while(1){
        bitti();
      }
     }
     else if(ort<12)
     {
      pwmv=12.7;
      seviye=0;
      duzenle(seviye);
     }
     else if(ort>=12 && ort<12.5)
     {
      pwmv=13;
      seviye=1;
      duzenle(seviye);
     }
     
     else if(ort>=12.5 && ort<13)
     {
      pwmv=13.5;
      seviye=2;
      duzenle(seviye);
     }
     else if(ort>=13 && ort<13.5)
     {
      pwmv=14;
      seviye=3;
      duzenle(seviye);
     }
     else if(ort>=13.2 && ort<14)
     {
      pwmv=14.5;
      seviye=4;
      duzenle(seviye);
     }
     else if(ort>=13.3 && ort<14)
     {
      pwmv=15;
      seviye=5;
      duzenle(seviye);
     }
     else if(ort>=13.4 && ort<14)
     {
      pwmv=15.5;
      seviye=6;
      duzenle(seviye);
     }
     else if(ort>=12.5 && ort<13)
     {
      pwmv=16.5;
      seviye=7;
      duzenle(seviye);
     }
    else
    {
     while(1){
      bitti();
     } 
    }
}

void hizlisarj()     //***************************************************************************************
{
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("HIZLI SARJ");
      lcd.setCursor(0,1);
      lcd.print("OLCUYOR...");
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      delay(100);
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      
      digitalWrite(YUK,HIGH); // AMPUL DEVREDE VOLTAJ ÖLÇ
      delay(2000);
      

     for(i=0;i<20;i++) {                           // 20 kez voltaj ölçüm numunesi alınıyor.Ortalaması alınacak
        girisVoltaji=analogRead(VOLC)*0.0049*3;   // 3 katsayısı gerilim bölücü ile 14,1v 4.7v  ölçüldüğü için
        okunan[i]=girisVoltaji;                  // ...DİZİ İÇİNE ÖLÇÜM SIRASINA GÖRE YERLEŞTİRME..
        delay(5);                               // 5 idi.
     }
      
      
      for(x=0;x<20;x++) {                    //Dizi elemanlarının KÜÇÜKTEN BÜYÜĞE sıralanması
        for(m=x+1;m<20;m++) {
          if(okunan[x]>okunan[m]) {
            temp=okunan[x];
            okunan[x]=okunan[m];
            okunan[m]=temp;
          }
        }
        
      }
      
       toplam=0;
        for(x=2;x<18;x++){  //En küçük iki değer ile en büyük iki değeri eliyoruz
         toplam=toplam+okunan[x]; // Kalan 16 değeri topluyoruz.
        }
        ort=toplam/16;
         
     
     digitalWrite(YUK,LOW); //Ampul ve ölçme devre dışı
     delay(1000);
     if(ort>13.4){          // Akü voltajı 14V ise şarjı kes.
      while(1){
       bitti();
      }
     }
     else if(ort<12)
     {
      pwmv=12.7;
      seviye=0;
      duzenlehizli(seviye);
     }
     else if(ort>=12 && ort<13)
     {
      pwmv=14;
      seviye=1;
      duzenlehizli(seviye); 
     }
     else if(ort>=12.5 && ort<13)
     {
      pwmv=15;
      seviye=2;
      duzenlehizli(seviye);
     }
     else if(ort>=12.7 && ort<13.5)
     {
      pwmv=16.5;
      seviye=3;
      duzenlehizli(seviye);
     }
     else
      {
       while(1){
        bitti();
       }
      }
}

void duzenle(int seviye)
{
  switch(seviye)
  {
    case 0:                       //12.7v..0.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=12.7;
           break;
    case 1:                      //13v.....1.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=13;
           break;
    case 2:                     //13.5v.....4.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=13.5;
           break;         
    case 3:                     //14v.......3.KANAL
           
           digitalWrite(11,LOW);  //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=14;
           break;
    case 4:                     //14.5v......2.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=14.5;
           break;   
    case 5:                    //15v..........5.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=15;
           break;
    case 6:                    //15.5v.........7.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=15.5;
           break;   
    case 7:                    // 16.5v.........6.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=16.5;
           break;
  }
  
  kontrol(c);
}

void duzenlehizli(int seviye)   
{
  switch(seviye)
  {
    case 0:                       //12.7v..0.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=12.7;
           break;
    /*case 1:                      //13v.....1.KANAL
           digitalWrite(A2,LOW); //A  CD4051 pini
           digitalWrite(11,HIGH); //B  CD4051 pini
           digitalWrite(13,HIGH); //C  CD4051 pini
           pwmv=13;
           kontrol(d);
           break;
    case 2:                     //13.5v.....4.KANAL
           digitalWrite(A2,HIGH); //A  CD4051 pini
           digitalWrite(11,HIGH); //B  CD4051 pini
           digitalWrite(13,LOW); //C  CD4051 pini
           pwmv=13.5;
           kontrol(d);
           break;  */
    case 1:                     //14v.......3.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=14;
           break;
    /*case 4:                     //14.5v......2.KANAL
           digitalWrite(A2,HIGH); //A  CD4051 pini
           digitalWrite(11,LOW); //B  CD4051 pini
           digitalWrite(13,HIGH); //C  CD4051 pini
           pwmv=14.5;
           kontrol(d);
           break; */
    case 2:                    //15v..........5.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=15;
           break;
    /*case 6:                    //15.5v.........7.KANAL
           digitalWrite(A2,LOW); //A  CD4051 pini
           digitalWrite(11,LOW); //B  CD4051 pini
           digitalWrite(13,LOW); //C  CD4051 pini
           pwmv=15.5;
           kontrol(d);
           break;  */
    case 3:                    // 16.5v.........6.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=16.5;
           break;
  }
  
  kontrol(d);
}

void lcd_Yaz()      //****************************************************************************
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("AKU=");              
  lcd.print(ort,1);     //(ort,1) buradaki 1 ifadesi virgülden sonra 1 hane yazmak için               
  lcd.print("v");
  
  if(hizli==1) {
    lcd.setCursor(11,0);
    lcd.print("*");   
  }
  lcd.setCursor(12,0);
  lcd.print("Z=");              
  lcd.print(saat);  
  lcd.setCursor(0,1);
  lcd.print("SRJ=");              
  lcd.print(pwmv,1);
  lcd.print("v");
  lcd.setCursor(10,1);
  lcd.print("I=");              
  lcd.print(ortlm,1);
  return;  
}
void zaman()  //Timer2 kesmesiyle zamanın takibi için.//*********************************************
{
 sayac++;
 if(sayac==3600)  //3600
 {
  saat++;
  sayac=0;
  if(saat==24) saat=0;
  lcd_Yaz();
 }
}



void kontrol(int s) //Bütün voltaj kademeleri için tek fonksiyon yazıldı.//*******************
{
      
      for(y=0;y<s;y++)          
      {
       digitalWrite(ROLE,HIGH); // ŞARJ akımını aç. Role mosfet Drain akımını akü (-) kutubuna verecek
       digitalWrite(A5,HIGH);  //DENEME
       delay(650);
       akimolc();
       lcd_Yaz();
       
       if(hizli==1)   // 72A için şarj akımı 2A'e düşerse
       {
        if(ortlm<3 && ortlm>1)
        {
        seviye=seviye+1;
        delay(50);
        digitalWrite(A3,HIGH);
        delay(100);
        digitalWrite(A3,LOW);
        if(seviye==4) bitti();
        duzenlehizli(seviye);
        }
       }
       else                    
       {
        if(ortlm<0.7 && ortlm>0.3)//şarj akımı 1A'den küçükse voltajı bir kademe yükselt.7A için
        {
         seviye=seviye+1;
         delay(50);
         digitalWrite(A3,HIGH);
         delay(100);
         digitalWrite(A3,LOW);
         if(seviye==5) bitti();
         duzenle(seviye); 
        }
       }
       
       if(ortlm>10) {   //AŞIRI AKIM KORUMA-Cihaz için
        
        digitalWrite(ROLE,LOW);
        digitalWrite(A5,LOW);
        digitalWrite(YUK,LOW);
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("**HATA**");
        lcd.setCursor(0,1);
        lcd.print("*ASIRI AKIM!!* ");
        
        while(1){
          digitalWrite(A3,HIGH);
          delay(100);
          digitalWrite(A3,LOW);
          delay(100);
        }
       }
       
       digitalWrite(A5,LOW);  //DENEME
       delay(450);
       if(ortlm>0.2 && ortlm<0.5) {
        bitti();
       }
       if(ortlm<0) {         
        
        digitalWrite(ROLE,LOW);
        digitalWrite(A5,LOW);
        digitalWrite(YUK,LOW);
        
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("**HATA**");
        lcd.setCursor(0,1);
        lcd.print("*AKU YOK!!* ");
        
        while(1){
          digitalWrite(A3,HIGH);
          delay(100);
          digitalWrite(A3,LOW);
          delay(100);
        }
      }   
                                 
      if(y==600) 
      {
       voltolc();
       lcd_Yaz();
      }
      
   }
   digitalWrite(ROLE,LOW);
                                 
   if(hizli==1) // sarj-hizlisarj fonksiyonundan duzenle-duzenlehizli'ye dallandığı için
   {
    hizlisarj();
   }
   else   //Bu bölüm 7Ah akü için
   {
    if(ortlm>3) {   //AŞIRI AKIM KORUMA.72Ah için yukarda yazılı.
        
        digitalWrite(ROLE,LOW);
        digitalWrite(A5,LOW);
        digitalWrite(YUK,LOW);
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("**HATA**");
        lcd.setCursor(0,1);
        lcd.print("*ASIRI AKIM!!* ");
        
        while(1){
          digitalWrite(A3,HIGH);
          delay(100);
          digitalWrite(A3,LOW);
          delay(100);
        }
       }
    sarj(); 
   }
   
}

void akimolc()   //***************************************************************************
{
  byte b;
  for(b=0;b<20;b++) {                           // 20 kez voltaj ölçüm numunesi alınıyor.Ortalaması alınacak
  okunanmV=analogRead(AMPOLC);
  Voltage=(okunanmV/1024.0)*5000;
  Amps=((Voltage-ACSoffset)/mVperAmp);
  okunanA[b]=Amps;
  delay(5);
  
}

  for(x=0;x<20;x++) {                    //Dizi elemanlarının KÜÇÜKTEN BÜYÜĞE sıralanması
        for(m=x+1;m<20;m++) {
          if(okunanA[x]>okunanA[m]) {
            tempA=okunanA[x];
            okunanA[x]=okunanA[m];
            okunanA[m]=tempA;
          }
        }
        
      }
      toplamamp=0;
      for(x=2;x<18;x++){  //En küçük iki değer ile en büyük iki değeri eliyoruz
         toplamamp=toplamamp+okunanA[x]; // Kalan 16 değeri topluyoruz.
        }
 ortlm=toplamamp/16;    
 
 return; 
}

void voltolc()
{
      digitalWrite(ROLE,LOW);
      delay(50);
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      delay(100);
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      
      digitalWrite(YUK,HIGH); // AMPUL DEVREDE VOLTAJ ÖLÇ
      delay(2000);                                  //3500
            
     for(i=0;i<20;i++) {                           // 20 kez voltaj ölçüm numunesi alınıyor.Ortalaması alınacak
        girisVoltaji=analogRead(VOLC)*0.0049*3;   // 3 katsayısı gerilim bölücü ile 14,1v 4.7v  ölçüldüğü için
        okunan[i]=girisVoltaji;                  // ...DİZİ İÇİNE ÖLÇÜM SIRASINA GÖRE YERLEŞTİRME..
        delay(5);                               // 5 idi.
     }
      
      
      for(x=0;x<20;x++) {                    //Dizi elemanlarının KÜÇÜKTEN BÜYÜĞE sıralanması
        for(m=x+1;m<20;m++) {
          if(okunan[x]>okunan[m]) {
            temp=okunan[x];
            okunan[x]=okunan[m];
            okunan[m]=temp;
          }
        }
        
      }
      
       toplam=0;
        for(x=2;x<18;x++){  //En küçük iki değer ile en büyük iki değeri eliyoruz
         toplam=toplam+okunan[x]; // Kalan 16 değeri topluyoruz.
        }
        ort=toplam/16;
         
    
     digitalWrite(YUK,LOW); //Ampul ve ölçme devre dışı
     delay(200);
     digitalWrite(ROLE,HIGH);
     if(ort>13.4){          // Akü voltajı 14V ise şarjı kes.
      while(1){
        bitti();
      }
     }
     return;
}

void bitti()   //**********************************************************************
{
  digitalWrite(ROLE,LOW);
  digitalWrite(YUK,LOW);
  digitalWrite(11,LOW);
  digitalWrite(13,LOW);
  digitalWrite(A2,LOW);
  digitalWrite(A5,LOW);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("AKU=");               
  lcd.print(ort);                      
  lcd.print("v");
  lcd.setCursor(0,1);
  lcd.print("**SARJ TAMAM**");
  lcd.setCursor(12,0);
  lcd.print("Z=");
  lcd.print(saat);
  
  double n=0;
  n=sayac/60;
  EEPROM.write(0,saat);
  delay(10);
  EEPROM.write(1,n);
  delay(10);
  hizli=0;
  EEPROM.write(2,0);
  delay(10);
  while(1){
    digitalWrite(A3,HIGH);
    delay(500);
    digitalWrite(A3,LOW);
    delay(15000);
  }
}




 

  

 

ghistmanzero

Alıntı yapılan: mg1980 - 15 Şubat 2018, 15:55:53
Kodun tamamını sunuyorum. C diline daha hakim olanlar daha pratik hale getirebilirler.Ben bu kadar yapabildim.Kolay gelsin..
#include <LiquidCrystal.h>  //CD4051 ANALOG SWİÇ İLE  VOLTAJ KADEMESİ OTOMATİK SEÇİMİ
#include <TimerOne.h>       // 07.11.2017
#include <EEPROM.h>
#include <MsTimer2.h>

LiquidCrystal lcd(7,6,5,4,3,2);// 7=RS,6=E,5=D4,4=D5,3=D6,2=D7

const byte VOLC=A0;
const byte AMPOLC=A1;
const byte ROLE=8;

const byte YUK=9;
const byte BUTON=A4;
const byte BUTON1=12;
boolean durum; //BUTON için
boolean durum1; //BUTON1 için
byte saat=0;
int sayac=0;

double pwmv=0;
double girisVoltaji=0.0;
double toplam=0.0;
double ort=0.0;
byte i=0;
int t=0;
int mVperAmp=66;// 30A ACS712 için 5A için 185 olacak.
int okunanmV=0;
int ACSoffset=2500; // ölçüm olmadığında mevcut sabit voltaj
double Voltage=0;
double Amps=0;
double ortlm=0;
double toplamamp=0;
byte sarjsuresi;
double srjsuredk;
int c=1200; // Normal süre peryodu=24 dk.(Kontrol+akimolc peryodu=0,5 sn)
int d=1200; //Hızlı süre peryodu=24 dk.
byte hizli=0;
int seviye;
int y=0;

byte x=0;
byte m=0;
double okunan[20];  // volt için
double temp;
double okunanA[20]; // amper için
double tempA;



void setup() //*************************************************************
{ 
  delay(500);
  lcd.begin(16,2);
  pinMode(VOLC,INPUT);
  pinMode(AMPOLC,INPUT);
  
  pinMode(ROLE,OUTPUT); // ŞARJ AKIMINI AÇMA -KAPAMA
  pinMode(YUK,OUTPUT); // AMPUL DEVREYE ALARAK VOLTAJ ÖLÇME
  pinMode(BUTON,INPUT_PULLUP); //A4 pin
  pinMode(BUTON1,INPUT_PULLUP);//12.pin
  pinMode(11,OUTPUT);  // 
  pinMode(13,OUTPUT);  // 
  pinMode(A2,OUTPUT);  //
  pinMode(A3,OUTPUT);  //Buzer
  pinMode(A5,OUTPUT);  // Flash için.şarj olduğu ikazı
  digitalWrite(A2,LOW); //
  //Timer1.initialize(1000000); //Timer1 kesmesinde PWM çalışmıyor.PWM bu timeri kullanıyor.
  //Timer1.attachInterrupt(zaman);
  MsTimer2::set(1000, zaman);  //Timer2 için .Zaman takipine lazım.
  MsTimer2::start();
  
  digitalWrite(A3,HIGH);
  delay(100);
  digitalWrite(A3,LOW);
  delay(100);
  digitalWrite(A3,HIGH);
  delay(100);
  digitalWrite(A3,LOW);
  
  lcd.setCursor(0,0);
  lcd.print("AKU SARJI");
  lcd.setCursor(0,1);
  lcd.print("BEKLEYIN........");
  delay(1500);

  hizli=EEPROM.read(2);
  sarjsuresi=EEPROM.read(0);
  srjsuredk=EEPROM.read(1);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("SRJ Z=");
  lcd.print(sarjsuresi);
  lcd.print("s.");
  
  lcd.setCursor(0,1);
  lcd.print("SRJ Z=");
  lcd.print(srjsuredk,1);
  lcd.print("dk.");
  delay(5000);
  
}

void loop() //**********************************************************
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("NORMAL..> 7Ah");
  lcd.setCursor(0,1);
  lcd.print("HIZLI..> * BAS!");
  delay(2000);
  
  for(t=0;t<70;t++)
  {
    durum=digitalRead(BUTON);
    if (durum==0)
    {
      while(1)
      {
        EEPROM.write(0,0);
        delay(10);
        EEPROM.write(1,0);
        delay(10);
        hizli=0;
        EEPROM.write(2,0);
        delay(10);
        sarj();
        
      }
    }
    
    durum1=digitalRead(BUTON1);
    if (durum1==0)
    {
      while(1)
      {
        EEPROM.write(0,0);
        delay(10);
        EEPROM.write(1,0);
        delay(10);
        hizli=1;
        EEPROM.write(2,1);
        delay(10);
        hizlisarj();
        
      }
    }
    digitalWrite(A3,HIGH);
    delay(20);
    digitalWrite(A3,LOW);
    delay(80);
  }
  while(1)
    {
     EEPROM.write(0,0);
     delay(10);
     EEPROM.write(1,0);
     delay(10);
     if(hizli==1) hizlisarj(); //DİKKAT.hizlisarj konumunda elk.kesilirse oradan devam için.
     hizli=0;
     EEPROM.write(2,0);
     delay(10);
     sarj();
    }
}

void sarj()  //**********************************************************************************************
{
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("NORMAL SARJ");
      lcd.setCursor(0,1);
      lcd.print("OLCUYOR...");
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      delay(100);
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      
      digitalWrite(YUK,HIGH); // AMPUL DEVREDE VOLTAJ ÖLÇ
      delay(2000);                                  //3500
      

     for(i=0;i<20;i++) {                           // 20 kez voltaj ölçüm numunesi alınıyor.Ortalaması alınacak
        girisVoltaji=analogRead(VOLC)*0.0049*3;   // 3 katsayısı gerilim bölücü ile 14,1v 4.7v  ölçüldüğü için
        okunan[i]=girisVoltaji;                  // ...DİZİ İÇİNE ÖLÇÜM SIRASINA GÖRE YERLEŞTİRME..
        delay(5);                               // 5 idi.
     }
      
      
      for(x=0;x<20;x++) {                    //Dizi elemanlarının KÜÇÜKTEN BÜYÜĞE sıralanması
        for(m=x+1;m<20;m++) {
          if(okunan[x]>okunan[m]) {
            temp=okunan[x];
            okunan[x]=okunan[m];
            okunan[m]=temp;
          }
        }
        
      }
      
       toplam=0;
        for(x=2;x<18;x++){  //En küçük iki değer ile en büyük iki değeri eliyoruz
         toplam=toplam+okunan[x]; // Kalan 16 değeri topluyoruz.
        }
        ort=toplam/16;
         
    
     digitalWrite(YUK,LOW); //Ampul ve ölçme devre dışı
     delay(1000);
     if(ort>13.4){          // Akü voltajı 14V ise şarjı kes.
      while(1){
        bitti();
      }
     }
     else if(ort<12)
     {
      pwmv=12.7;
      seviye=0;
      duzenle(seviye);
     }
     else if(ort>=12 && ort<12.5)
     {
      pwmv=13;
      seviye=1;
      duzenle(seviye);
     }
     
     else if(ort>=12.5 && ort<13)
     {
      pwmv=13.5;
      seviye=2;
      duzenle(seviye);
     }
     else if(ort>=13 && ort<13.5)
     {
      pwmv=14;
      seviye=3;
      duzenle(seviye);
     }
     else if(ort>=13.2 && ort<14)
     {
      pwmv=14.5;
      seviye=4;
      duzenle(seviye);
     }
     else if(ort>=13.3 && ort<14)
     {
      pwmv=15;
      seviye=5;
      duzenle(seviye);
     }
     else if(ort>=13.4 && ort<14)
     {
      pwmv=15.5;
      seviye=6;
      duzenle(seviye);
     }
     else if(ort>=12.5 && ort<13)
     {
      pwmv=16.5;
      seviye=7;
      duzenle(seviye);
     }
    else
    {
     while(1){
      bitti();
     } 
    }
}

void hizlisarj()     //***************************************************************************************
{
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("HIZLI SARJ");
      lcd.setCursor(0,1);
      lcd.print("OLCUYOR...");
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      delay(100);
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      
      digitalWrite(YUK,HIGH); // AMPUL DEVREDE VOLTAJ ÖLÇ
      delay(2000);
      

     for(i=0;i<20;i++) {                           // 20 kez voltaj ölçüm numunesi alınıyor.Ortalaması alınacak
        girisVoltaji=analogRead(VOLC)*0.0049*3;   // 3 katsayısı gerilim bölücü ile 14,1v 4.7v  ölçüldüğü için
        okunan[i]=girisVoltaji;                  // ...DİZİ İÇİNE ÖLÇÜM SIRASINA GÖRE YERLEŞTİRME..
        delay(5);                               // 5 idi.
     }
      
      
      for(x=0;x<20;x++) {                    //Dizi elemanlarının KÜÇÜKTEN BÜYÜĞE sıralanması
        for(m=x+1;m<20;m++) {
          if(okunan[x]>okunan[m]) {
            temp=okunan[x];
            okunan[x]=okunan[m];
            okunan[m]=temp;
          }
        }
        
      }
      
       toplam=0;
        for(x=2;x<18;x++){  //En küçük iki değer ile en büyük iki değeri eliyoruz
         toplam=toplam+okunan[x]; // Kalan 16 değeri topluyoruz.
        }
        ort=toplam/16;
         
     
     digitalWrite(YUK,LOW); //Ampul ve ölçme devre dışı
     delay(1000);
     if(ort>13.4){          // Akü voltajı 14V ise şarjı kes.
      while(1){
       bitti();
      }
     }
     else if(ort<12)
     {
      pwmv=12.7;
      seviye=0;
      duzenlehizli(seviye);
     }
     else if(ort>=12 && ort<13)
     {
      pwmv=14;
      seviye=1;
      duzenlehizli(seviye); 
     }
     else if(ort>=12.5 && ort<13)
     {
      pwmv=15;
      seviye=2;
      duzenlehizli(seviye);
     }
     else if(ort>=12.7 && ort<13.5)
     {
      pwmv=16.5;
      seviye=3;
      duzenlehizli(seviye);
     }
     else
      {
       while(1){
        bitti();
       }
      }
}

void duzenle(int seviye)
{
  switch(seviye)
  {
    case 0:                       //12.7v..0.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=12.7;
           break;
    case 1:                      //13v.....1.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=13;
           break;
    case 2:                     //13.5v.....4.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=13.5;
           break;         
    case 3:                     //14v.......3.KANAL
           
           digitalWrite(11,LOW);  //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=14;
           break;
    case 4:                     //14.5v......2.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=14.5;
           break;   
    case 5:                    //15v..........5.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=15;
           break;
    case 6:                    //15.5v.........7.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=15.5;
           break;   
    case 7:                    // 16.5v.........6.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=16.5;
           break;
  }
  
  kontrol(c);
}

void duzenlehizli(int seviye)   
{
  switch(seviye)
  {
    case 0:                       //12.7v..0.KANAL
           
           digitalWrite(11,HIGH); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=12.7;
           break;
    /*case 1:                      //13v.....1.KANAL
           digitalWrite(A2,LOW); //A  CD4051 pini
           digitalWrite(11,HIGH); //B  CD4051 pini
           digitalWrite(13,HIGH); //C  CD4051 pini
           pwmv=13;
           kontrol(d);
           break;
    case 2:                     //13.5v.....4.KANAL
           digitalWrite(A2,HIGH); //A  CD4051 pini
           digitalWrite(11,HIGH); //B  CD4051 pini
           digitalWrite(13,LOW); //C  CD4051 pini
           pwmv=13.5;
           kontrol(d);
           break;  */
    case 1:                     //14v.......3.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,HIGH); //C  CD4051 pini
           pwmv=14;
           break;
    /*case 4:                     //14.5v......2.KANAL
           digitalWrite(A2,HIGH); //A  CD4051 pini
           digitalWrite(11,LOW); //B  CD4051 pini
           digitalWrite(13,HIGH); //C  CD4051 pini
           pwmv=14.5;
           kontrol(d);
           break; */
    case 2:                    //15v..........5.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,HIGH); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=15;
           break;
    /*case 6:                    //15.5v.........7.KANAL
           digitalWrite(A2,LOW); //A  CD4051 pini
           digitalWrite(11,LOW); //B  CD4051 pini
           digitalWrite(13,LOW); //C  CD4051 pini
           pwmv=15.5;
           kontrol(d);
           break;  */
    case 3:                    // 16.5v.........6.KANAL
           
           digitalWrite(11,LOW); //A  CD4051 pini
           digitalWrite(13,LOW); //B  CD4051 pini
           digitalWrite(A2,LOW); //C  CD4051 pini
           pwmv=16.5;
           break;
  }
  
  kontrol(d);
}

void lcd_Yaz()      //****************************************************************************
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("AKU=");              
  lcd.print(ort,1);     //(ort,1) buradaki 1 ifadesi virgülden sonra 1 hane yazmak için               
  lcd.print("v");
  
  if(hizli==1) {
    lcd.setCursor(11,0);
    lcd.print("*");   
  }
  lcd.setCursor(12,0);
  lcd.print("Z=");              
  lcd.print(saat);  
  lcd.setCursor(0,1);
  lcd.print("SRJ=");              
  lcd.print(pwmv,1);
  lcd.print("v");
  lcd.setCursor(10,1);
  lcd.print("I=");              
  lcd.print(ortlm,1);
  return;  
}
void zaman()  //Timer2 kesmesiyle zamanın takibi için.//*********************************************
{
 sayac++;
 if(sayac==3600)  //3600
 {
  saat++;
  sayac=0;
  if(saat==24) saat=0;
  lcd_Yaz();
 }
}



void kontrol(int s) //Bütün voltaj kademeleri için tek fonksiyon yazıldı.//*******************
{
      
      for(y=0;y<s;y++)          
      {
       digitalWrite(ROLE,HIGH); // ŞARJ akımını aç. Role mosfet Drain akımını akü (-) kutubuna verecek
       digitalWrite(A5,HIGH);  //DENEME
       delay(650);
       akimolc();
       lcd_Yaz();
       
       if(hizli==1)   // 72A için şarj akımı 2A'e düşerse
       {
        if(ortlm<3 && ortlm>1)
        {
        seviye=seviye+1;
        delay(50);
        digitalWrite(A3,HIGH);
        delay(100);
        digitalWrite(A3,LOW);
        if(seviye==4) bitti();
        duzenlehizli(seviye);
        }
       }
       else                    
       {
        if(ortlm<0.7 && ortlm>0.3)//şarj akımı 1A'den küçükse voltajı bir kademe yükselt.7A için
        {
         seviye=seviye+1;
         delay(50);
         digitalWrite(A3,HIGH);
         delay(100);
         digitalWrite(A3,LOW);
         if(seviye==5) bitti();
         duzenle(seviye); 
        }
       }
       
       if(ortlm>10) {   //AŞIRI AKIM KORUMA-Cihaz için
        
        digitalWrite(ROLE,LOW);
        digitalWrite(A5,LOW);
        digitalWrite(YUK,LOW);
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("**HATA**");
        lcd.setCursor(0,1);
        lcd.print("*ASIRI AKIM!!* ");
        
        while(1){
          digitalWrite(A3,HIGH);
          delay(100);
          digitalWrite(A3,LOW);
          delay(100);
        }
       }
       
       digitalWrite(A5,LOW);  //DENEME
       delay(450);
       if(ortlm>0.2 && ortlm<0.5) {
        bitti();
       }
       if(ortlm<0) {         
        
        digitalWrite(ROLE,LOW);
        digitalWrite(A5,LOW);
        digitalWrite(YUK,LOW);
        
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("**HATA**");
        lcd.setCursor(0,1);
        lcd.print("*AKU YOK!!* ");
        
        while(1){
          digitalWrite(A3,HIGH);
          delay(100);
          digitalWrite(A3,LOW);
          delay(100);
        }
      }   
                                 
      if(y==600) 
      {
       voltolc();
       lcd_Yaz();
      }
      
   }
   digitalWrite(ROLE,LOW);
                                 
   if(hizli==1) // sarj-hizlisarj fonksiyonundan duzenle-duzenlehizli'ye dallandığı için
   {
    hizlisarj();
   }
   else   //Bu bölüm 7Ah akü için
   {
    if(ortlm>3) {   //AŞIRI AKIM KORUMA.72Ah için yukarda yazılı.
        
        digitalWrite(ROLE,LOW);
        digitalWrite(A5,LOW);
        digitalWrite(YUK,LOW);
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("**HATA**");
        lcd.setCursor(0,1);
        lcd.print("*ASIRI AKIM!!* ");
        
        while(1){
          digitalWrite(A3,HIGH);
          delay(100);
          digitalWrite(A3,LOW);
          delay(100);
        }
       }
    sarj(); 
   }
   
}

void akimolc()   //***************************************************************************
{
  byte b;
  for(b=0;b<20;b++) {                           // 20 kez voltaj ölçüm numunesi alınıyor.Ortalaması alınacak
  okunanmV=analogRead(AMPOLC);
  Voltage=(okunanmV/1024.0)*5000;
  Amps=((Voltage-ACSoffset)/mVperAmp);
  okunanA[b]=Amps;
  delay(5);
  
}

  for(x=0;x<20;x++) {                    //Dizi elemanlarının KÜÇÜKTEN BÜYÜĞE sıralanması
        for(m=x+1;m<20;m++) {
          if(okunanA[x]>okunanA[m]) {
            tempA=okunanA[x];
            okunanA[x]=okunanA[m];
            okunanA[m]=tempA;
          }
        }
        
      }
      toplamamp=0;
      for(x=2;x<18;x++){  //En küçük iki değer ile en büyük iki değeri eliyoruz
         toplamamp=toplamamp+okunanA[x]; // Kalan 16 değeri topluyoruz.
        }
 ortlm=toplamamp/16;    
 
 return; 
}

void voltolc()
{
      digitalWrite(ROLE,LOW);
      delay(50);
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      delay(100);
      digitalWrite(A3,HIGH);
      delay(100);
      digitalWrite(A3,LOW);
      
      digitalWrite(YUK,HIGH); // AMPUL DEVREDE VOLTAJ ÖLÇ
      delay(2000);                                  //3500
            
     for(i=0;i<20;i++) {                           // 20 kez voltaj ölçüm numunesi alınıyor.Ortalaması alınacak
        girisVoltaji=analogRead(VOLC)*0.0049*3;   // 3 katsayısı gerilim bölücü ile 14,1v 4.7v  ölçüldüğü için
        okunan[i]=girisVoltaji;                  // ...DİZİ İÇİNE ÖLÇÜM SIRASINA GÖRE YERLEŞTİRME..
        delay(5);                               // 5 idi.
     }
      
      
      for(x=0;x<20;x++) {                    //Dizi elemanlarının KÜÇÜKTEN BÜYÜĞE sıralanması
        for(m=x+1;m<20;m++) {
          if(okunan[x]>okunan[m]) {
            temp=okunan[x];
            okunan[x]=okunan[m];
            okunan[m]=temp;
          }
        }
        
      }
      
       toplam=0;
        for(x=2;x<18;x++){  //En küçük iki değer ile en büyük iki değeri eliyoruz
         toplam=toplam+okunan[x]; // Kalan 16 değeri topluyoruz.
        }
        ort=toplam/16;
         
    
     digitalWrite(YUK,LOW); //Ampul ve ölçme devre dışı
     delay(200);
     digitalWrite(ROLE,HIGH);
     if(ort>13.4){          // Akü voltajı 14V ise şarjı kes.
      while(1){
        bitti();
      }
     }
     return;
}

void bitti()   //**********************************************************************
{
  digitalWrite(ROLE,LOW);
  digitalWrite(YUK,LOW);
  digitalWrite(11,LOW);
  digitalWrite(13,LOW);
  digitalWrite(A2,LOW);
  digitalWrite(A5,LOW);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("AKU=");               
  lcd.print(ort);                      
  lcd.print("v");
  lcd.setCursor(0,1);
  lcd.print("**SARJ TAMAM**");
  lcd.setCursor(12,0);
  lcd.print("Z=");
  lcd.print(saat);
  
  double n=0;
  n=sayac/60;
  EEPROM.write(0,saat);
  delay(10);
  EEPROM.write(1,n);
  delay(10);
  hizli=0;
  EEPROM.write(2,0);
  delay(10);
  while(1){
    digitalWrite(A3,HIGH);
    delay(500);
    digitalWrite(A3,LOW);
    delay(15000);
  }
}




 

  

 



paylaşımınız için çok teşekkürler.