EnergiAlternativa

Page Index Toggle Pages: 1 ... 6 7 [8]  Send TopicPrint
Hot Topic (More than 100 Replies) Dummy Load con Arduino (Read 53998 times)
ElettroshockNow
Forum Administrator
*****
Offline


yottawatt

Posts: 3920
Location: Roma
Gender: Male
Zodiac sign: Gemini
Re: Dummy Load con Arduino
Reply #105 - 18.06.16 at 16:25:34
Print Post  
Buonasera a tutti e grazie UFOSTUFO per la collaborazione nel progetto..
Oltre alla infinita pazienza dimostrata Wink

Di seguito è allegato il CODICE ARDULAB VER 1.0 e le librerie
I problemi riscontrati non sono stati pochi ,alcuni risolvibili ,altri no.

Il progetto nasce come Dummy Load ,ma visto l'ottimo comportamento nei test preliminari abbiamo osato spingerci oltre introducendo altre funzioni utili in un piccolo laboratorio,ma ne potremo aggiungere anche altre.


A voi il codice scritto di facile comprensione e con possibilità di personalizzazioni

Code (C++)
Select All
//
//LISTATO ARDULAB MEGA VER 1.0
//
//Prodotto da ElettroshockNow & UFOSTUFO (ElettroshockNow@gmail.com)
//Condiviso su http://WWW.EnergiAlternativa.org
//
//Eventuali condivisioni su alri canali/Forum devono specificare
//il forum di origine http://WWW.ENERGIALTERNATIVA.ORG e la licenza
//di seguito specificata
//
//ATTENZIONE:
//
//CC BY-NC-SA 4.0
//Uso non commerciale, modificabile, con obbligo di condivisione-
//http://creativecommons.org/licenses/by-nc-sa/4.0/deed.it
//


//Librerie
#include <Wire.h>
#include <PCF8574_HD44780_I2C.h>
#include <Thermistor.h>
#include <EEPROMex.h>
#include <EEPROMvar.h>

//Configurazione Pin Arduino Mega2560
//USCITA PWM PWM_shunt PIN10
//USCITA PWM PWM_buck PIN9
//Ingressi Analogici
#define V_in_Pin 2               
#define V_out_Pin 3
#define I_out_Pin 4          
#define I_shunt_Pin 5
#define V_set_Pin 8
#define I_set_Pin 9
#define Key_Pin 10
//Ingressi/Uscite Digitali
#define Led_supply_Pin 2
#define Led_load_Pin 3
#define Led_shunt_Pin 4
#define Stab_Pin 8
#define Reset 9
#define Led_fault_Pin 10
#define Buzzer_Pin 18

//Definizione Costanti
#define menu 5
#define Num_Letture 20
#define Fattore_Corrente_Buck 0.075
#define Fattore_Corrente_Shunt 0.071 //0.0775
#define Fattore_Voltage 0.055
#define Kp_V 5//Gain Feedback Proporzionale //10
#define Ki_V 0 //Gain Feedback Integrale //0
#define Kd_V 0 //Gain Feedback Derivata //2
#define Kp_I 2//Gain Feedback Proporzionale
#define Ki_I 0//Gain Feedback Integrale
#define Kd_I 4//Gain Feedback Derivata


// Indirizzo LCD I2C 0x27, 20*4
PCF8574_HD44780_I2C lcd(0x27, 20, 4);
Thermistor temp(6);
//Variabili
int Temperatura,Offset_I_out,Offset_I_shunt;
unsigned long refresh,check,Start_charge,Time_charge,Last_millis;
float PWM_shunt,PWM_buck,I_out,I_shunt,V_out,V_in,I_max,V_max,Energia;
float errore_V,ePrec_V,eIntegr_V,errore_I,ePrec_I,eIntegr_I;
byte limita,Key,Set,memorizzare,ON;

//SETTAGGIO valori di DEFAULT (1°PowerUp)
int Screen = 20;//pagina di default "DUMMY LOAD"
byte Fuse = 25;
byte Vpot_min = 5;
byte Vpot_max = 30;
byte Ipot_min = 0;
byte Ipot_max = 20;
byte Ipot_min_Dum = 0;
byte Ipot_max_Dum = 20;
byte Ipot_min_Lim = 0;
byte Ipot_max_Lim = 10;
byte Stato_Buzzer = 1;
float VBat_charge = 14.7;
float IBat_charge = 5;
float VBat_discharge = 10.5;
float IBat_discharge = 5;
float VRef = 0.0;
byte clearlcd = 0;
byte sottomenu = 0;
byte Fault = 0;
byte Protezione = 0;
byte Allert = 0;
byte charge = 0 ;



void setup() {
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(Led_supply_Pin, OUTPUT);
  pinMode(Led_load_Pin, OUTPUT);
  pinMode(Led_shunt_Pin, OUTPUT);
  pinMode(Led_fault_Pin, OUTPUT);
  pinMode(Buzzer_Pin, OUTPUT);
  pinMode(Stab_Pin, OUTPUT);
  pinMode(Reset, INPUT);

  digitalWrite(6, LOW);
  digitalWrite(Led_supply_Pin, LOW);
  digitalWrite(Led_load_Pin, LOW);
  digitalWrite(Led_shunt_Pin, LOW);
  digitalWrite(Led_fault_Pin, LOW);
  digitalWrite(Stab_Pin, LOW);
  digitalWrite(Reset, HIGH);


  // Doppia uscita PWM (BUCK&SHUNT) a 31.2Khz ,511 step
  TCCR4A = _BV(COM4A1) | _BV(COM4A0) | _BV(COM4B1) | _BV(COM4B0) | _BV(WGM41); //Fast PWM, 10-bit
  TCCR4B = _BV(CS40) | _BV(WGM42); //Prescaler a 1
  OCR4A = 511;
  OCR4B = 511;
  Serial.begin(9600) ;
  lcd.init();          
  lcd.backlight();      
  lcd.clear();
  //MESSAGGIO DI BENVENUTO         
  lcd.setCursor(1, 0);
  lcd.print("ArduLab Vers. 1.0");
  lcd.setCursor(9, 1);
  lcd.print("By");
  lcd.setCursor(1, 2);
  lcd.print("EnergiAlternativa");
  lcd.setCursor(2, 3);
  lcd.print("CC BY-NC-SA 4.0");
  delay(2500);
  lcd.clear();
  lcd.setCursor(8, 1);
  lcd.print("WWW.");
  lcd.setCursor(1, 2);
  lcd.print("ENERGIALTERNATIVA");
  lcd.setCursor(8, 3);
  lcd.print(".ORG");
  delay(3000);
  lcd.clear();



 
  Offset_I_out  = analogRead(I_out_Pin);
  Offset_I_shunt  = analogRead(I_shunt_Pin);

  if (EEPROM.read(0) != 255) { //SALVATAGGIO DATI IN EEPROM
    Vpot_min = EEPROM.read(0);
    Vpot_max = EEPROM.read(1);
    Ipot_min = EEPROM.read(2);
    Ipot_max = EEPROM.read(3);
    Ipot_min_Dum = EEPROM.read(4);
    Ipot_max_Dum = EEPROM.read(5);
    Ipot_min_Lim = EEPROM.read(6);
    Ipot_max_Lim = EEPROM.read(7);
    Stato_Buzzer = EEPROM.read(8);
    VBat_charge = EEPROM.readFloat(20);
    IBat_charge = EEPROM.readFloat(24);
    VBat_discharge = EEPROM.readFloat(28);
    IBat_discharge = EEPROM.readFloat(32);
  }

    if (Stato_Buzzer) {
    digitalWrite(Buzzer_Pin, HIGH);
    delay(500);
    digitalWrite(Buzzer_Pin, LOW);
  }
 
}

void loop() {
  ArduLab(); //Subroutine misure e PWM
  Tastiera();//Subroutine la Tastiera
  Display();//Subroutine il Display
}





void Display() { //Subroutine visualizzazione su Display LCD 20*4

  if (millis() > (refresh + 500))
  {
    refresh = millis();
    if (clearlcd) {
      lcd.clear();
      clearlcd = 0;
    }

    if (Fault) { //AVARIA
      digitalWrite(Led_fault_Pin, HIGH);
      lcd.setCursor(0, 0);
      lcd.print("FAULT");
      lcd.setCursor(0, 1);
      switch (Fault) {
        case 1://CORTOCIRCUITO
          lcd.print("CORTO");
          break;
        case 2:
          lcd.print("FUSE SEZIONE BUCK");
          break;
        case 3:
          lcd.print("Vin Bassa Tensione");
          break;
        case 4:
          lcd.print("Vin Alta Tensione ");
          break;
        case 5:
          lcd.print("FUSE SEZIONE SHUNT");
          break;
        case 6:
          lcd.print("Temperatura Limite");
          break;
        case 7:
          break;
        case 8:
          break;
        case 9:
          break;
        case 10:
          break;


      }


    }

    else { //NORMAL

      lcd.setCursor(0, 0);
      if (Set == 1)
      {
        lcd.print("SET");
        memorizzare = 1;
      }

      else if (ON == 0)
      {
        lcd.print("OFF");
        if (memorizzare) {


          EEPROM.write(0, Vpot_min);
          EEPROM.write(1, Vpot_max);
          EEPROM.write(2, Ipot_min);
          EEPROM.write(3, Ipot_max);
          EEPROM.write(4, Ipot_min_Dum);
          EEPROM.write(5, Ipot_max_Dum);
          EEPROM.write(6, Ipot_min_Lim);
          EEPROM.write(7, Ipot_max_Lim);
          EEPROM.write(8, Stato_Buzzer);
          EEPROM.writeFloat(20, VBat_charge);
          EEPROM.writeFloat(24, IBat_charge);
          EEPROM.writeFloat(28, VBat_discharge);
          EEPROM.writeFloat(32, IBat_discharge);
          memorizzare = 0;


        }
      }
      else lcd.print("ON");



      switch (Screen) {
        case 0://MENU
          sottomenu = 2;
          lcd.setCursor(7, 0);
          lcd.print("MENU");
          lcd.setCursor(0, 1);
          lcd.print("Temp=");
          lcd.print(Temperatura, 1);
          lcd.print("C");
          lcd.setCursor(0, 2);
          lcd.print("Buzzer=");
          if (Stato_Buzzer)lcd.print("ON");
          else lcd.print("OFF");
          break;
        case 1:
          sottomenu = 2;
          lcd.setCursor(7, 0);
          lcd.print("SILENZIA");
          lcd.setCursor(0, 2);
          lcd.print("Buzzer=");
          if (Stato_Buzzer)lcd.print("ON");
          else lcd.print("OFF");
          break;
        case 2:
          sottomenu = 2;
          lcd.setCursor(0, 0);
          lcd.print("IL PROGETTO ARDULAB");
           lcd.setCursor(0, 1);
          lcd.print("VIENE RILASCIATO");
           lcd.setCursor(0, 2);
          lcd.print("CON LICENZA COMMONS");
           lcd.setCursor(0, 3);
          lcd.print("CC BY-NC-SA 4.0");
          break;

        case 10: //ALIMENTATORE
          sottomenu = 2;
          digitalWrite(Stab_Pin, HIGH);
          V_max = float(analogRead(V_set_Pin) * (Vpot_max - Vpot_min)) / 1023 + Vpot_min;
          I_max = float(analogRead(I_set_Pin) * (Ipot_max - Ipot_min)) / 1023 + Ipot_min;
          digitalWrite(Led_supply_Pin, HIGH);
          digitalWrite(Led_load_Pin, HIGH);
          digitalWrite(Led_shunt_Pin, LOW);
          lcd.setCursor(4, 0);
          lcd.print("ALIMENTATORE");
          lcd.setCursor(0, 1);
          lcd.print("Vin=");
          lcd.print(V_in, 1);
          lcd.print("V ");
          lcd.setCursor(10, 1);
          lcd.print("Vout=");
          lcd.print(V_out, 1);
          lcd.print("V ");
          lcd.setCursor(0, 2);
          lcd.print("Pout=");
          lcd.print((V_out * I_out), 0);
          lcd.print("W");
          lcd.setCursor(10, 2);
          lcd.print("Iout=");
          lcd.print(I_out, 1);
          lcd.print("A ");
          lcd.setCursor(0, 3);
          lcd.print("Vs=");
          lcd.print(V_max, 1);
          lcd.print("V ");
          lcd.setCursor(10, 3);
          lcd.print("Is=");
          lcd.print(I_max, 1);
          lcd.print("A ");
          break;
        case 11:
          lcd.setCursor(4, 0);
          lcd.print("ALIMENTATORE");
          lcd.setCursor(0, 1);
          lcd.print("Range Pot Tensione ");
          lcd.setCursor(0, 2);
          lcd.print("min=");
          lcd.print(Vpot_min);
          lcd.print("V");
          lcd.setCursor(10, 2);
          lcd.print("max=");
          lcd.print(Vpot_max);
          lcd.print("V");
          lcd.setCursor(0, 3);
          //lcd.print("Vset=");
          //lcd.print(V_max, 1);
          //lcd.print("V");
          break;
        case 12:
          lcd.setCursor(4, 0);
          lcd.print("ALIMENTATORE");
          lcd.setCursor(0, 1);
          lcd.print("Range Pot Corrente ");
          lcd.setCursor(0, 2);
          lcd.print("min=");
          lcd.print(Ipot_min);
          lcd.print("A");
          lcd.setCursor(10, 2);
          lcd.print("max=");
          lcd.print(Ipot_max);
          lcd.print("A");
          lcd.setCursor(0, 3);
          lcd.print("Iset=");
          lcd.print(I_max, 1);
          lcd.print("A");
          break;
        case 20: //DUMMY LOAD
          sottomenu = 1;
          digitalWrite(Stab_Pin, LOW);
          V_max = 32;
          I_max = float(analogRead(I_set_Pin) * (Ipot_max_Dum - Ipot_min_Dum)) / 1023 + Ipot_min_Dum;
          digitalWrite(Led_supply_Pin, HIGH);
          digitalWrite(Led_load_Pin, LOW);
          digitalWrite(Led_shunt_Pin, HIGH);
          lcd.setCursor(5, 0);
          lcd.print("DUMMY LOAD");
          lcd.setCursor(0, 1);
          lcd.print("Vin=");
          lcd.print(V_in, 1);
          lcd.print("V ");
          lcd.setCursor(10, 1);
          lcd.print("Iout=");
          lcd.print(I_shunt, 1);
          lcd.print("A ");
          lcd.setCursor(0, 2);
          lcd.print("Ref=");
          lcd.print(VRef, 1);
          lcd.print("V ");
          lcd.setCursor(10, 2);
          lcd.print("Pout=");
          lcd.print((V_out * I_shunt), 0);
          lcd.print("W");
          lcd.setCursor(0, 3);
          //lcd.print(Asc(223));
          lcd.print("DV=");
          lcd.print(V_in-VRef, 1);
          lcd.print("V ");         
          lcd.setCursor(10, 3);
          lcd.print("Is=");
          lcd.print(I_max, 1);
          lcd.print("A ");
          break;
        case 21:
          lcd.setCursor(5, 0);
          lcd.print("DUMMY LOAD");
          lcd.setCursor(0, 1);
          lcd.print("Range Pot Corrente ");
          lcd.setCursor(0, 2);
          lcd.print("min=");
          lcd.print(Ipot_min_Dum);
          lcd.print("A");
          lcd.setCursor(10, 2);
          lcd.print("max=");
          lcd.print(Ipot_max_Dum);
          lcd.print("A");
          lcd.setCursor(0, 3);
          break;
        case 22:
          lcd.setCursor(0, 0);
          lcd.print("22");
          break;
        case 30://LIMITER
          sottomenu = 1;
          digitalWrite(Stab_Pin, LOW);
          V_max = 32;
          I_max = float(analogRead(I_set_Pin) * (Ipot_max_Lim - Ipot_min_Lim)) / 1023 + Ipot_min_Lim;
          digitalWrite(Led_supply_Pin, HIGH);
          digitalWrite(Led_load_Pin, HIGH);
          digitalWrite(Led_shunt_Pin, LOW);
          lcd.setCursor(6, 0);
          lcd.print("LIMITER");
          lcd.setCursor(0, 1);
          lcd.print("Vin=");
          lcd.print(V_in, 1);
          lcd.print("V ");
          lcd.setCursor(10, 1);
          lcd.print("Vout=");
          lcd.print(V_out, 1);
          lcd.print("V ");
          lcd.setCursor(0, 2);
          lcd.print("Pout=");
          lcd.print((V_out * I_out), 0);
          lcd.print("W");
          lcd.setCursor(10, 2);
          lcd.print("Iout=");
          lcd.print(I_out, 1);
          lcd.print("A ");
          lcd.setCursor(0, 3);
          lcd.setCursor(10, 3);
          lcd.print("Is=");
          lcd.print(I_max, 1);
          lcd.print("A ");
          break;
        case 31:
          lcd.setCursor(6, 0);
          lcd.print("LIMITER");
          lcd.setCursor(0, 1);
          lcd.print("Range Pot Corrente ");
          lcd.setCursor(0, 2);
          lcd.print("min=");
          lcd.print(Ipot_min_Lim);
          lcd.print("A");
          lcd.setCursor(10, 2);
          lcd.print("max=");
          lcd.print(Ipot_max_Lim);
          lcd.print("A");
          lcd.setCursor(0, 3);
          break;
        case 32:
          lcd.setCursor(0, 0);
          lcd.print("32");
          break;
        case 40://Carica Batteria
          sottomenu = 1;
          digitalWrite(Stab_Pin, LOW);
          V_max = VBat_charge;
          I_max = IBat_charge;
          digitalWrite(Led_supply_Pin, HIGH);
          digitalWrite(Led_load_Pin, HIGH);
          digitalWrite(Led_shunt_Pin, LOW);
          lcd.setCursor(4, 0);
          lcd.print("CARICA BATTERIA");
          lcd.setCursor(0, 1);
          lcd.print("V=");
          lcd.print(V_out, 1);
          lcd.print("V ");
          lcd.setCursor(10, 1);
          lcd.print("I=");
          lcd.print(I_out, 1);
          lcd.print("A ");
          lcd.setCursor(0, 2);
          lcd.print("T=");
          lcd.print(Time_charge/60);
          lcd.print("min");
          lcd.setCursor(10, 2);
          lcd.print("E=");
          lcd.print(Energia / 3600/1000, 1);
          lcd.print("Ah");
          lcd.setCursor(0, 3);
          if (ON && charge == 0)charge = 1;
          if (charge) {
            if (ON) {
              lcd.print("IN CARICA...");
              Time_charge = (millis() - Start_charge) / 1000;
              Energia += (millis() - Last_millis) * I_out;
              Last_millis = millis();
            }
            else
              lcd.print("CARICA TERMINATA");
          }
          else {
            Start_charge = millis();
            Last_millis = millis();
          }
          if (V_out >= (VBat_charge - 0.1) && I_out < (IBat_charge / 5) && ON) {
            ON = 0;
            if (Stato_Buzzer) {
              digitalWrite(Buzzer_Pin, HIGH);;
              delay(100);
              digitalWrite(Buzzer_Pin, LOW);
              delay(100);
              digitalWrite(Buzzer_Pin, HIGH);;
              delay(1000);
              digitalWrite(Buzzer_Pin, LOW);
            }
          }
          break;
        case 41:
          lcd.setCursor(0, 0);
          lcd.setCursor(4, 0);
          lcd.print("CARICA BATTERIA");
          lcd.setCursor(4, 1);
          lcd.print("IMPOSTAZIONI");
          lcd.setCursor(0, 2);
          lcd.print("V=");
          lcd.print(VBat_charge);
          lcd.print("V");
          lcd.setCursor(10, 2);
          lcd.print("I=");
          lcd.print(IBat_charge);
          lcd.print("A");
          break;
        case 42:
          break;
        case 50://Scarica Batteria
          sottomenu = 1;
          digitalWrite(Stab_Pin, LOW);
          digitalWrite(Led_supply_Pin, LOW);
          digitalWrite(Led_load_Pin, HIGH);
          digitalWrite(Led_shunt_Pin, HIGH);
          lcd.setCursor(4, 0);
          lcd.print("SCARICA BATTERIA");
          lcd.setCursor(0, 1);
          lcd.print("V=");
          lcd.print(V_out, 1);
          lcd.print("V ");
          lcd.setCursor(10, 1);
          lcd.print("I=");
          lcd.print(I_shunt, 1);
          lcd.print("A ");
          lcd.setCursor(0, 2);
          lcd.print("T=");
          lcd.print(Time_charge/60);
          lcd.print("min");
          lcd.setCursor(10, 2);
          lcd.print("E=");
          lcd.print(Energia / 3600/1000, 1);
          lcd.print("Ah");
          lcd.setCursor(0, 3);
          if (ON && charge == 0)charge = 1;
          if (charge) {
            if (ON) {
              lcd.print("IN SCARICA...");
              Time_charge = (millis() - Start_charge) / 1000;
              Energia += (millis() - Last_millis) * I_shunt;
              Last_millis = millis();
            }
            else
              lcd.print("SCARICA TERMINATA");
          }
          else {
            Start_charge = millis();
            Last_millis = millis();
          }
          if (V_out < VBat_discharge && ON) {
            ON = 0;
            if (Stato_Buzzer) {
              digitalWrite(Buzzer_Pin, HIGH);;
              delay(1000);
              digitalWrite(Buzzer_Pin, LOW);
              delay(100);
              digitalWrite(Buzzer_Pin, HIGH);;
              delay(100);
              digitalWrite(Buzzer_Pin, LOW);
            }
          }

          break;
        case 51:
          lcd.setCursor(4, 0);
          lcd.print("SCARICA BATTERIA");
          lcd.setCursor(4, 1);
          lcd.print("IMPOSTAZIONI");
          lcd.setCursor(0, 2);
          lcd.print("V=");
          lcd.print(VBat_discharge);
          lcd.print("V");
          lcd.setCursor(10, 2);
          lcd.print("I=");
          lcd.print(IBat_discharge);
          lcd.print("A"); ;
          break;
        case 52:
          lcd.setCursor(0, 0);
          lcd.print("52");
          break;
        case 60:
          lcd.setCursor(0, 0);
          lcd.print("60");
          break;
        case 61:
          lcd.setCursor(0, 0);
          lcd.print("61");
          break;
        case 62:
          lcd.setCursor(0, 0);
          lcd.print("62");
          break;
        default:
          break;
      }
    }
  }
}




void ArduLab() {  //Subroutine misure e controllo PWM
  Temperatura = temp.getTemp();
  V_in = (analogRead(V_in_Pin) * Fattore_Voltage);
  I_out = 0;
  V_out = 0;
  for (int i = 0; i < Num_Letture; i++) {
    I_out = I_out + ((analogRead(I_out_Pin) - Offset_I_out));
    I_shunt = I_shunt + ((analogRead(I_shunt_Pin) - Offset_I_shunt));
    V_out = V_out + (analogRead(V_out_Pin) );
  }
  I_out = I_out / Num_Letture * Fattore_Corrente_Buck;
  I_shunt = I_shunt / Num_Letture * Fattore_Corrente_Shunt;
  V_out = V_out / Num_Letture * Fattore_Voltage;

  if (I_shunt < 0)I_shunt = 0;
  if (I_out < 0)I_out = 0;


  if (Screen >= 10 && Screen < 20 | Screen >= 30 && Screen < 50) { //GESTIONE PWM ALIMENTATORE & LIMITER
    PWM_shunt = 0;
    //if (I_out < 0)I_out = 0;
    if (I_out > I_max)limita = 1;
    if (V_out > V_max)limita = 0;
    errore_V = V_max - V_out;
    errore_I = I_max - I_out;
    if (limita)PWM_buck += ((Kp_I * errore_I) + (Ki_I * eIntegr_I) + (Kd_I * ePrec_I));
    else PWM_buck += ((Kp_V * errore_V) + (Ki_V * eIntegr_V) + (Kd_V * ePrec_V));
    /*
    {
      if (V_out>V_max)PWM_buck=0;
      else PWM_buck=511;
    }
    */
    eIntegr_V += errore_V;
    ePrec_V = errore_V;
    eIntegr_I += errore_I;
    ePrec_I = errore_I;
    if (PWM_buck > 511)PWM_buck = 511;
    else if (PWM_buck < 0)PWM_buck = 0;
  }

  if (Screen >= 20 && Screen < 30 ) { //GESTIONE PWM DUMMY LOAD
    PWM_buck = 511;
    limita = 1;
    //if (I_shunt < 0)I_out = 0;
    errore_I = I_max - I_shunt;
    PWM_shunt += ((Kp_I * errore_I) + (Ki_I * eIntegr_I) + (Kd_I * ePrec_I));
    eIntegr_I += errore_I;
    ePrec_I = errore_I;
    if (PWM_shunt > 511)PWM_shunt = 511;
    else if (PWM_shunt < 0)PWM_shunt = 0;
  }

  if (Screen >= 50 && Screen < 60 ) { //GESTINE PWM SCARICA BATTERIA
    PWM_buck = 0;
    errore_I = IBat_discharge - I_shunt;
    PWM_shunt += ((Kp_I * errore_I) + (Ki_I * eIntegr_I) + (Kd_I * ePrec_I));
    eIntegr_I += errore_I;
    ePrec_I = errore_I;
    if (PWM_shunt > 511)PWM_shunt = 511;
    else if (PWM_shunt < 0)PWM_shunt = 0;
  }





  //CONTROLLO USCITE


  if (ON == 0 | Fault) { //SPENTO o in Fault
    ON = 0;
    OCR4A = 511;
    OCR4B = 511;
    errore_V = 0;
    eIntegr_V = 0;
    ePrec_V = 0;
    errore_I = 0;
    eIntegr_I = 0;
    ePrec_I = 0;
    PWM_shunt = 0;
    PWM_buck  = 0;

  }
  else { //ACCESO e OPERATIVO
    OCR4A = 511 - PWM_shunt;
    OCR4B = 511 - PWM_buck;
  }


  //PROTEZIONI VARIE

  if (ON) {
    if (I_out > Fuse)Fault = 2; //MAX corrente 25A sezione Buck
    if (I_shunt > Fuse)Fault = 5;//MAX corrente 25A sezione Shunt
    if (V_in < 5)Fault = 3; //Tensione in ingresso bassa
    if (V_in > 35)Fault = 4; //Tensione in ingresso alta
    if (Temperatura > 70)Fault = 6; //Temperatura
    if (Fault)clearlcd = 1; //pulisci il display per visualizzare fault
  }

}




void Tastiera() {//Selezione Pagine e gestione Variabili
  if (digitalRead(Reset) == 0 && Screen==20)VRef=V_in;
  if (digitalRead(Reset) == 0 && ON == 0) { //Resetta il Fault e charge
    Energia = 0;
    charge = 0;
    Time_charge = 0;
    Fault = 0;
    clearlcd = 1;
    digitalWrite(Led_fault_Pin, LOW);
  }
  if (Fault == 0) { //disattiva Tastiera se in Fault
    byte decine = Screen / 10;
    byte unita = Screen - (decine * 10);
    int Key_Read = analogRead(Key_Pin);
    Key = 0;
    if (Key_Read < 880)Key = 1;
    if (Key_Read < 620)Key = 2;
    if (Key_Read < 414)Key = 3;
    if (Key_Read < 233)Key = 4;
    if (Key_Read < 70)Key = 5;
    if (Key > 0)clearlcd = 1;
    if (Key == 1 && unita == 0) {
      if (ON)ON = 0;
      else ON = 1;
    }
    if (Key == 1 && unita > 0) {
      if (Set == 0) {
        Set = 1;
        ON = 0;
      }
      else {
        Set = 0;
        ON = 0;
        Screen = decine * 10;
      }
    }
    if (Set == 0) { //modalità navigazione menù
      if (unita < sottomenu && Key == 3)Screen++;
      if (unita > 0 && Key == 4)Screen--;
      if (unita == 0 && decine < (menu + 1) && Key == 2) {
        Screen += 10;
        if (Screen == 10)Screen += 10; //SALTA FUNZIONE ALIMENTATORE
        ON = 0;
      }
      if (Screen == ((menu + 1) * 10))Screen = 0;
      if (unita == 0 && decine > 0 && Key == 5) {
        Screen -= 10;
        if (Screen == 10)Screen -= 10; //SALTA FUNZIONE ALIMENTATORE
        ON = 0;
      }
      //if (Screen < 0)Screen = (menu * 10);
    }
    else switch (Screen) {
        case 1:
          if (Stato_Buzzer < 1 && Key == 2)Stato_Buzzer++;
          if (Stato_Buzzer > 0 && Key == 5)Stato_Buzzer--;
          break;
        case 10:
          break;
        case 11:
          if (Vpot_max < 32 && Key == 2)Vpot_max++;
          if (Vpot_max > 0 && Key == 5)Vpot_max--;
          if (Vpot_min < Vpot_max && Key == 4)Vpot_min++;
          if (Vpot_min > 0 && Key == 3)Vpot_min--;
          break;
        case 12:
          if (Ipot_max < 20 && Key == 2)Ipot_max++;
          if (Ipot_max > 0 && Key == 5)Ipot_max--;
          if (Ipot_min < Vpot_max && Key == 4)Ipot_min++;
          if (Ipot_min > 0 && Key == 3)Ipot_min--;
          break;
        case 20:
          break;
        case 21:
          if (Ipot_max_Dum < 20 && Key == 2)Ipot_max_Dum++;
          if (Ipot_max_Dum > 0 && Key == 5)Ipot_max_Dum--;
          if (Ipot_min_Dum < Vpot_max && Key == 4)Ipot_min_Dum++;
          if (Ipot_min_Dum > 0 && Key == 3)Ipot_min_Dum--;
          break;
        case 22:
          break;
        case 30:
          break;
        case 31:
          if (Ipot_max_Lim < 20 && Key == 2)Ipot_max_Lim++;
          if (Ipot_max_Lim > 0 && Key == 5)Ipot_max_Lim--;
          if (Ipot_min_Lim < Vpot_max && Key == 4)Ipot_min_Lim++;
          if (Ipot_min_Lim > 0 && Key == 3)Ipot_min_Lim--;
          break;
        case 32:
          break;
        case 40:
          break;
        case 41:
          if (VBat_charge < 32 && Key == 4)VBat_charge += 0.1;
          if (VBat_charge > 0 && Key == 3)VBat_charge -= 0.1;
          if (IBat_charge < 20 && Key == 2)IBat_charge += 0.1;
          if (IBat_charge > 0 && Key == 5)IBat_charge -= 0.1;
          break;
        case 42:
          break;
        case 50:
          break;
        case 51:
          if (VBat_discharge < 32 && Key == 4)VBat_discharge += 0.1;
          if (VBat_discharge > 0 && Key == 3)VBat_discharge -= 0.1;
          if (IBat_discharge < 20 && Key == 2)IBat_discharge += 0.1;
          if (IBat_discharge > 0 && Key == 5)IBat_discharge -= 0.1;
          break;
        default:
          break;
      }
  }



  while (analogRead(Key_Pin) < 880) {//BEEP
    if (Stato_Buzzer)digitalWrite(Buzzer_Pin, HIGH);
  };
  delay(50);
  if (Stato_Buzzer)digitalWrite(Buzzer_Pin, LOW);
}
 

  

libraries.zip ( 524 KB | Downloads )

Il Tempo non lo vede nessuno,il lavoro lo vedono tutti (Mamma)
Impara a rubare con gli occhi (Papà)
Back to top
YouTube  
IP Logged
 
ElettroshockNow
Forum Administrator
*****
Offline


yottawatt

Posts: 3920
Location: Roma
Gender: Male
Zodiac sign: Gemini
Re: Dummy Load con Arduino
Reply #106 - 18.06.16 at 17:08:38
Print Post  
In Allegato ZIP contenente PCB e schemi nella versione 2.1
  

ArduLab_V2_1.zip ( 261 KB | Downloads )
Ardulab_Schema_V2_1.jpg ( 185 KB | Downloads )
Ardulab_Schema_V2_1.jpg
Ardulab_PCB_V2_1.jpg ( 134 KB | Downloads )
Ardulab_PCB_V2_1.jpg

Il Tempo non lo vede nessuno,il lavoro lo vedono tutti (Mamma)
Impara a rubare con gli occhi (Papà)
Back to top
YouTube  
IP Logged
 
Hugo
Full Member
***
Offline


Full EALab Member

Posts: 228
Location: Brasil
Gender: Male
Zodiac sign: Libra
Re: Dummy Load con Arduino
Reply #107 - 10.07.16 at 03:14:55
Print Post  
Olá! Pode ser usado para fazer a formação de material ativo nas placas de uma bateria Planté? Uma bateria totalmente caseira? Cheesy
  
Back to top
 
IP Logged
 
fly1971
New Member
*
Offline


--------

Posts: 9
Gender: Male
Re: Dummy Load con Arduino
Reply #108 - 11.12.21 at 17:35:55
Print Post  
Ciao a tutti
Ho verificato che con lo stesso login dei energialternativa.info posso accedere anche a questo , chiedo mai 2 forum sono completamente distaccati ho hanno qualcosa in comune ?
Mi complimento per questo progetto e su come è stato implementato e a riguardo ho alcune domande da porvi.
Stavo cercando un dummy load o carico fittizio come vogliamo chiamarlo da usare soprattutto per le batterie e misurare la loro capacità, ma ho trovato un po di difficoltà perché  il mio caricabatteria universale da modellismo IMAX6B è limitato come potenza di scarica a 5W e poi per i pacchi delle celle al Litio richiede  il connettore di bilanciamento e qualche volta non ho potuto testare pacchi batterie di utensili, i quali hanno già la loro scheda BMS.
Allora stavo cercando qualche progetto da costruimi, su i vari siti cinesi , si trovano prodotti e a buon prezzo che hanno queste funzioni , ma se si rompono difficili da riparare, invece quacosa costruito da me è  più facile  da gestire un guasto, e nella ricerca è comparso questo progetto piu attinente alle mie esigenze.
Ho letto tutto di questo progetto e lo trovo un progetto completo  mi sono chiesto se  si puo sviluppare una versione light, con le sole funzioni di dummy load e scarica batteria con delle modifiche sul codice.
Ho visto lo schema, queta versione più leggera  si può fare eliminando la sezione si step/down, induttanza e componenti a dx e sx , lasciando i sensori ACS per la I out e I shunt. In alcuni progetti in rete sulla sezione shunt montano piccole resistenze da 5-10W e poi i mosfet li collegano a dissipatori con ventola.  Quindi  un ulteriore modifica potrebbe essere quella di una resistenza da 20W  e aggiungere un secondo mosfet e collegare tutto a un dissipattore con ventola, cosi si elimina l’uscita SHUNT, correggetemi se le mie soluzioni possono essere sbagliate. A riguardo del LM317 non capito bene il funzionamento , per limitare la corrente?
A riguardo dei 2 sensori di corrente ACS712 sul progetto non vedo le resistenze da 2mOhm.
Passiamo alla sezione codice e qui c’è la nota dolente, ho una buona  dimistichezza con la parte di elettronica di base ma poco con i codici di arduino, recentemente ho ternimato una puntatrice con Mot e arduino nano, avevo trovato un codice dove tramite un potenziometro potevo regolare i 2 impulsi e la pausa, e poi tramite un tasto di avvio mi faceva partire gli impulsi, volevo aggiungerci una funzione manuale  e far ein modo che  il MOT restava acceso per tutto il tempo che tenevo premuto il pulsante di avvio , dopo un po di sbattimenti sono riuscito a fare una modifica anche se poco elegante ma mi funziona.
Sicuramente il codice sarà ridotto a quello che avete pubblicato, alcune varibili e valori possono essere eliminati perché inerenti allo step/down e alla sezione carica batteria, nella sezione scarica batteria è stato impostato come fisso la Vbatt-discharge e Ibatt-discharge, questi 2 valori dovrebbero essere impostati variabili, e poter scegliere la V di cut-off per ogni tipologia di pacco batteria e anche la corrente di scarica, e se poteva implemtare anche su arduino nano.
Provo a stamparmi il codice cosi da poterlo leggerlo con calma e capire dove  fare qualche modifica.
Scusate per il mio intervento molto prolisso e spero che mi potete aiutare.
Un saluto
  
Back to top
 
IP Logged
 
fly1971
New Member
*
Offline


--------

Posts: 9
Gender: Male
Re: Dummy Load con Arduino
Reply #109 - 14.12.21 at 15:52:52
Print Post  


MI  sono letto il codice e ho fatto alcune modifiche, ho eliminato alcune sezioni , alimentatore e carica batteria, ho ci sono alcune cose che non mi tornano e tra queste la più importante a riguardo della sezioen scarica batteria, ma la VBatt_discharge e IBatt-discharge sono valori che posso impostare io a seconda del pacco batteria e la corrente di scarica?
le parti che non ho capito e sono evidenziate in Verde e riguardano la parte del PWM e le sue uscite, anche perchè vorrei tentare di adatatrlo ad arduino nano se è possibile, mi sembra che con ilnumero di uscite ed ingressi siano sufficienti quelli di arduino nano. Si aggiunge  la parte iniziale della sub routine misure controlli  e la part ecentrale della routine tasiera.
Le parti in giallo sono da cancellare
Le parti in azzurro sono le modfiche fatte.
sicuyramente ci saranno degli errori , se qualcuno mi puo aiutare a correggerli.
Alla prossima.
Ho inserito il codice con la finestra specifica di C++ e ho provato a evidenziar ele varie parti , ma all'anteprima non mi evidenza i vari colori , sono contretto a inserirlo come listato in word , dove sono evidenziate le varie parti in colore modificate.
  

codice1_1.doc ( 96 KB | Downloads )
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1 ... 6 7 [8] 
Send TopicPrint
 

TOP100-SOLAR Galleria Immagini EnergiAlternativa