Se sei già registrato           oppure    

Orario: 24/04/2024 17:26:14  

 

Energia Alternativa ed Energia Fai Da Te > Arduino

VISUALIZZA L'ALBUM

Pagine: (3)   1   [2]   3    (Ultimo Msg)


tester della batteria Planté
FinePagina

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 20/09/2019 18:03:03

Emuland ESP ha un solo analogico, A0



---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 20/09/2019 18:15:02

capi32 lo hai visto il progetto di Righetz

Scarica allegato

Formatore_LCD_Keypad_V1.1.ino ( Numero download: 114 )



---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

capi32

Avatar
GigaWatt


Gruppo:Utente
Messaggi:846

Stato:



Inviato il: 20/09/2019 19:08:45

Emuland,
Non avevo capito ESP.
Ho cercato questo modulo e infatti il modulo esp32 potrebbe essere una buona soluzione. ma siccome l'hardware è già ordinato, il primo prototipo sarà su Arduino. Tengo le informazioni da parte per il futuro..

Claudio,
Ho appena letto il codice e non gestisce l'intensità o il risultato delle capacità (Ah).
aziona solo i relè per le modalità di carica e scarica a seconda della tensione e del tempo.
tutte le altre regolazioni e misure devono essere fatte manualmente e richiedono un sacco di lavoro quotidiano. Non voglio fare di nuovo questo lavoro ansioso.

Ho bisogno di arduino per sputare fuori le curve direttamente su di me, al fine di analizzarle facilmente.
siamo nel 2019 e non nel 1910, lasciate che le macchine funzionino per noi.



---------------
cugino della Francia
Inverter MPPsolar MPI 5.5Kw, 6480W pannelli, 4x100A PbCa e presto anche le batterie Planté ...

 

capi32

Avatar
GigaWatt


Gruppo:Utente
Messaggi:846

Stato:



Inviato il: 21/09/2019 00:22:57

stasera ho lavorato un po' sul codice.
Normalmente ho creato tutte le costanti e le variabili che mi saranno utili nel codice.
c'è solo la funzione di ricarica

il passo successivo sarà aggiunto:
la funzione di scarico
la funzione ciclo
la funzione di conteggio dei cicli
ecc.......

Scarica allegato

Arduino_Planté_cell_cycle_tester_1.ino ( Numero download: 105 )



---------------
cugino della Francia
Inverter MPPsolar MPI 5.5Kw, 6480W pannelli, 4x100A PbCa e presto anche le batterie Planté ...

 

emuland

Avatar
GigaWatt


Gruppo:Utente
Messaggi:4451

Stato:



Inviato il: 21/09/2019 07:02:23

CITAZIONE (Claudio, 20/09/2019 18:03:03 ) Discussione.php?215731&2#MSG15

Emuland ESP ha un solo analogico, A0


si, ho scritto alla interno del quote quindi é uscita na schifezza..



---------------
4A per mmq per Legge

 

capi32

Avatar
GigaWatt


Gruppo:Utente
Messaggi:846

Stato:



Inviato il: 20/10/2019 14:18:20

dopo alcune settimane di test e modifiche, finalmente ho una prima versione funzionale. la parte dei cicli di carica e scarica funziona ma l'alimentazione non è ancora gestita dal codice.

Non mi aspettavo che l'alimentazione tra la resistenza di potenza (r2) dovesse essere variabile e superiore alla tensione di carica della batteria per soddisfare il setpoint della corrente di carica.

Per testare il funzionamento, utilizzo batterie CR-2 Li-ion 3V 800Mah e INR18650-13Q 1300mAh agli ioni di litio . Ho aggiunto un ponte divisore di tensione (R9 R10 R11 R12) per poter gestire tensioni di carica superiori a 5v.

per i curiosi, fornisco il codice che utilizzo per il 18650 con un alimentatore esterno (ms-305d).


//Arduino_Planté_cell_cycle_tester_24.ino

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

// Definir les variables système
double           cellVolts;
double           cellVolts2;
int           chargeCurrent;
int           numberCycles;
int           currentState;
int           delayTimer;           
int           stateTimer;
unsigned long sampleDelay;
unsigned long cycleTime;



// Definir le  materiels
#define DISCHARGE                  8        // Relais de decharge
#define RECHARGE                   7        // Relais de recharge
#define VOLTS                     A1        // Tension de cellule
#define CURRENT                   A2        // CHARGE courant (pas de decharge ...jeca )
int gatePinC = 10;     // jeca - Câble de signal de sortie (pour le Mosfet) connecte à la Pin numerique 9
int gatePinD = 9;     // jeca - Câble de signal de sortie (pour le Mosfet) connecte à la Pin numerique 9
float resistance  =              6.0;     //resistance mesuree de la resistance R2 de puissance (+0.5pour le mosfet)
#define EXTERNDIV_NUM              2         // valeur x > diviseur de tension externe > pour abaisser les mesures de tension des batteries a moins de 5v ,pont  diviseur par 4
#define EXTERNDIV_DENOM            1         // valeur 1 > diviseur de tension externe > DENOM doit egale a 1
#define SAMPLE_DELAY_MILLIS     1000      // Nombre de mS entre les contrôles de tension
#define RECOVERYTIME              20        // Nombre de secondes entre la charge/decharge et la decharge/charge La valeur maximale est 32767
#define MAXSTATETIME            21600      // Nombre de secondes autorisees dans chaque etat (c'est-à-dire chargement ou dechargement) La valeur maximale est 32767.
#define ON                         1         // Mettre un relais en marche
#define OFF                        0         // Eteindre un relais Off
#define TolCurrent                 2        // plage de correction du courant en mA
#define VCCVOLTS                5010L     // Valeur reelle du rail 5 volts LAISSER LE SUFFIXE "L  car cette valeur doit être une valeur int longue


#define TempPin =                2     //Sonde_3 de Temperature connectee à la Pin analogique 2
float TempTc = 0;     //variable pour stocker la valeur de TempPin analogique
float tmp36Voltage = 0;     //calculated voltage at TempPin
float temperatureC = 0;     //temperature calculee de la sonde en degres C


//----------------------------   Definir les parametre  de la batterrie et des cycles de test

int batteryCapacity =          1300;     //capacite nominale de la batterie en mAh


// reglages pour la charge 
unsigned int MosfetCValue  = 1;      //valeur de demarage cycle 1 ;du signal de sortie PWM (pour le Mosfet)
unsigned int MosfetCStart  = 1;     //valeur recalcule suivant la capacite du cycle precedent
#define currentMin               100    //courant de charge minimale en mA
#define SpeedCharge              1.4      //Vitesse de charge > C7  > 7 = decharge en 7 heures
#define V_floating             4200     //tension de floating   (en 
#define cutoffcurrent            100     // intensite en mA de in de char
#define VoltageChargeMaxi      4210     //tension limite de securite > stop charge  (en mV)


//reglages pour la decharge
unsigned int MosfetDValue = 1;     //valeur de demarage cycle 1 ;du signal de sortie PWM (pour le Mosfet)
unsigned int MosfetDStart = 1;     //valeur recalcule suivant la capacite du cycle precedent
#define SpeedDisCharge           4  //Vitesse de decharge > C10  > 10 = decharge en 10 heures
#define V_MIN                  2500      // fin de decharge / Tension min de decharge (en mV) 


//reglages des cycles
#define NUMBEROFCYCLES           3        // Nombre de cycles à executer


//-------pour le calcul de la capacite--------
float mAh = 0.0;
boolean finished = false;
//unsigned long millis = 0;
unsigned long previousMillis = 0;
unsigned long millisPassed = 0;
int printStart = 0;
int interval = 5000;  //Interval (ms) between measurements

//--------

//-------------------------------------------------

// variables calcule par le code
double CurrentCharge = 0;     //courant charge calcule  (en mA)
double CurrentDisCharge = 0;     //courant decharge calcule (en mA)
double CibleCurrentCharge = batteryCapacity / SpeedCharge;     //courant de sortie cible (en mA) regle à C / 10 ou 1/10 de la capacite de la batterie par heure
double CibleCurrentDisCharge = batteryCapacity / SpeedDisCharge;     //courant de sortie cible (en mA) regle à C / 10 ou 1/10 de la capacite de la batterie par heure
double currentChargError = 0;     //difference entre le courant de consigne et le courant reel (en mA)
double currentDisChargError = 0;     //difference entre le courant de consigne et le courant reel (en mA)



// Machine d'etat
#define STATE_START             0         // Configurer et demarrer le cycle de charge
#define STATE_CHARGING          1         // Surveiller le cycle de charge
#define STATE_DISWAIT           2         // Delai avant et reglage pour la decharge
#define STATE_DISCHARGING       3         // Surveiller la decharge
#define STATE_CHGWAIT           4         // Delai avant de repeter le cycle
#define STATE_DONE              5         // Termine





// readVoltage()
// Lire la tension de la cellule et retourner la moyenne de 4 lectures.
// Le resultat est mis à l'echelle par la valeur d'etalonnage ainsi que par le diviseur externe.
// La valeur de retour est en milliVolts, c'est-à-dire 0 - 5000
int readVoltage()
{
 int temp = 0;

  for (int i = 0; i < 4; i++)
  {
    //Mettre à l'echelle la lecture A2D. L'A2D renvoie 0 à 1023 pour une tension
    // plage de 0 à la tension d'alimentation de l'Arduino (normalement 5v).
    temp += (int)(((long)analogRead(VOLTS) * VCCVOLTS) / 1024); // Scale the A2D result
    delay(20);              // Un court delai entre les lectures
  }
  return (temp*EXTERNDIV_NUM)/(EXTERNDIV_DENOM*4);  // Compenser le diviseur de tension externe
}

// readVoltage2()
// Lire la tension de la cellule apres la resitance et retourner la moyenne de 4 lectures.
// Le resultat est mis à l'echelle par la valeur d'etalonnage ainsi que par le diviseur externe.
// La valeur de retour est en milliVolts, c'est-à-dire 0 - 5000
int readVoltage2()
{
 int temp = 0;

  for (int i = 0; i < 4; i++)
  {
    //Mettre à l'echelle la lecture A2D. L'A2D renvoie 0 à 1023 pour une tension
    // plage de 0 à la tension d'alimentation de l'Arduino (normalement 5v).
    temp += (int)(((long)analogRead(CURRENT) * VCCVOLTS) / 1024); // Scale the A2D result
    delay(20);              // Un court delai entre les lectures
  }
  return (temp*EXTERNDIV_NUM)/(EXTERNDIV_DENOM*4);  // Compenser le diviseur de tension externe
}
  
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------

// Cette fonction configure les ports à utiliser et initialise certaines variables.
void setup()
 {
  // Configuration pour le debogage et l'enregistrement
// Print a message to the LCD.
  lcd.backlight();
        lcd.setCursor(0,0);
        lcd.print(" Testeur Cycles "); //Intro Message line 1
        lcd.setCursor(0,1); //Second line
        lcd.print("Batterie Plante"); //Intro Message line 2
         delay(3000);
         lcd.clear();
//-----
  Serial.begin(9600);
  Serial.println("Demarage Cycle");    // Ajoute un  CR - use Serial.print() pour aucun CR
  numberCycles = 1;
  Serial.println();

  currentState = STATE_START;
  Serial.println("STATE_START");
  Serial.println();

 lcd.init();                      // initialize the lcd 

  pinMode(DISCHARGE, OUTPUT);   // definit la broche de decharge comme sortie
  digitalWrite(DISCHARGE, OFF); // Desactive le relais de decharge
  pinMode(RECHARGE, OUTPUT);    // definit la broche de recharge comme sortie
  digitalWrite(RECHARGE, OFF);  // Desactive le relais de recharge

 

  cellVolts = readVoltage();    // Do first read pour initialiser le port

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

  digitalWrite(gatePinC, 0);
  digitalWrite(gatePinD, 0);

  // TODO - initialisez votre affichage





}

//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------

// Cette fonction est appelee à plusieurs reprises par le système d'exploitation, nous avons donc besoin de savoir où dans le fichier
// On est un cycle de decharge de charge, donc on utilise une machine d'etat.
void loop() 
{
  unsigned long now = millis();     // Obtenir la valeur actuelle de la minuterie en mS

  if (now - sampleDelay > SAMPLE_DELAY_MILLIS)
  {
    sampleDelay = now;              // Reinitialiser l'heure de base de l'echantillonnage

    switch (currentState)           // Aller à l'etat actuel
    {
//----------------------------
      case STATE_START:
        stateTimer = MAXSTATETIME;      // Valeur de temporisation de l'etat de configuration
        currentState = STATE_CHARGING;  // L'etat suivant est charge
            Serial.println("------------------------------------------------");
          Serial.print("CYCLE CHARGING Cycle # ");
          Serial.println(numberCycles);
            Serial.println("------------------------------------------------");
          Serial.println();
       
        cycleTime = now;                //  Heure de debut d'etat
        digitalWrite(RECHARGE, ON);     // Activer le relais de charge      
       
//        Serial.print("Cycle #");        // Logging
 //       Serial.println(numberCycles);
        
        // TODO update display
        break;

//----------------------------        
      case STATE_CHARGING:

        cellVolts = readVoltage();          // Faire une lecture
        cellVolts2 = readVoltage2();          // Faire une lecture

      MosfetCValue = MosfetCStart; 
       analogWrite(gatePinC, MosfetCValue);     //ecrit la nouvelle valeur de sortie

 
 CibleCurrentCharge = batteryCapacity / SpeedCharge;     //c
  CurrentCharge = (cellVolts2 - cellVolts ) / resistance;     //jeca calculer le courant de decharge
  currentChargError = CibleCurrentCharge - CurrentCharge;     //jeca difference between target current and measured current

 // Serial.print("batteryCapacity: ");     //
 // Serial.println(batteryCapacity);
 // Serial.println();  

  Serial.print("batterie (V): ");     //afficher la tension de la batterie
  Serial.println(cellVolts/1000); 
  Serial.print("Shunt    (V): ");
  Serial.println(cellVolts2/1000); 

  Serial.print("Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCValue); 
  Serial.print("Cible (mA): ");
  Serial.println(CibleCurrentCharge);
  Serial.print("Charge(mA): ");     //afficher le courant actuel
  Serial.println(CurrentCharge);  
  Serial.println();
  Serial.println(); 

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(numberCycles); 
  lcd.setCursor(4,0);
  lcd.print("Charg"); 
  lcd.setCursor(11,0);
  lcd.print(cellVolts/1000); 
  lcd.setCursor(15,0);
  lcd.print("V"); 

  lcd.setCursor(0,1);
  lcd.print("Mosf:"); 
  lcd.setCursor(5,1);
  lcd.print(MosfetCValue);
  lcd.setCursor(9,1);
  lcd.print(CurrentCharge); 
  lcd.setCursor(14,1);
  lcd.print("mA");

//Corrections Intensite  de charge
  if(MosfetCValue > 0) 
     {
   if( ((CurrentCharge + (TolCurrent + 1)) <= CibleCurrentCharge ) && (MosfetCValue < 255) )    //while
      {
      MosfetCValue = MosfetCValue + 1;
      MosfetCStart = MosfetCValue; 
       analogWrite(gatePinC, MosfetCValue);     //ecrit la nouvelle valeur de sortie
        Serial.print("Correction Charge + Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println(MosfetCValue); 

       }
   if( ((CurrentCharge - (TolCurrent + 1)) >= CibleCurrentCharge )  && (MosfetCValue > 0) )   //
     {
      MosfetCValue = MosfetCValue - 1;
      MosfetCStart = MosfetCValue; 
       analogWrite(gatePinC, MosfetCValue);     //ecrit la nouvelle valeur de sortie
        Serial.print("Correction Charge - Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
        Serial.println(MosfetCValue); 
    }
    }
    //info erreur
       if(MosfetCValue > 255)     //la sortie ne peut jamais depasser 255
        {
         MosfetCValue = 255;
         analogWrite(gatePinC, MosfetCValue);     //ecrit la nouvelle valeur de sortie
         Serial.print("Erreur calcul MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println();
        }

    // arrêt de charge > fin de charge
        if ( (cellVolts >= V_floating) && (CurrentCharge <= cutoffcurrent) && (MosfetCValue > 0) )
        {
          MosfetCValue = 0;
          analogWrite(gatePinC, MosfetCValue);     //ecrit la nouvelle valeur de sortie
            Serial.println("------------------------------------------------");
            Serial.println("Fin de charge (Floating)");
          Serial.print("MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
          Serial.println(MosfetCValue);
          digitalWrite(RECHARGE, OFF);  // Desactive le relais de charge
          currentState = STATE_DISWAIT; // L'etat suivant est en attente avant la decharge            
            Serial.println("------------------------------------------------");
            Serial.println("CYCLE DISWAIT");
            Serial.println("------------------------------------------------");
            Serial.println(); 
  Serial.print("MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCValue); 
  Serial.print("MosfetCStart: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCStart); 
  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
  Serial.print("MosfetDStart: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDStart); 
  Serial.print("MosfetCValue: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCValue); 
  Serial.print("MosfetDValue: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
                 Serial.println(); 



  Serial.print("Capacite (mAh): ");     //afficher 
  Serial.println(mAh);
  Serial.print("Temps: ");     //afficher 
  Serial.println(previousMillis);
 
          delayTimer = RECOVERYTIME;    // Interstate delay time
          Serial.print("Temps de charge: (S) ");   // Logging
          Serial.println((now - cycleTime)/1000);
          Serial.println(); 
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Charge fini");
            lcd.setCursor(0,1);
            lcd.print("Temps:");
            lcd.setCursor(8,1);
            lcd.print((now - cycleTime)/1000);
          
          // TODO update display
        }
     //  arrêt de charge >surcharge
          if(cellVolts >= VoltageChargeMaxi)    //arrêter la charge 
          {
          digitalWrite(RECHARGE, OFF);  // Desactive le relais de charge
           MosfetCValue = 0;
           analogWrite(gatePinC, MosfetCValue);     //ecrit la nouvelle valeur de sortie
           Serial.print("MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
           Serial.println(MosfetCValue);
 
           Serial.println("------------------------------------------------");
           Serial.print("Stop surcharge (VoltageChargeMaxi)");
            Serial.println(); 
             lcd.clear();
             lcd.setCursor(0,1);
             lcd.print("Stop surcharge");

           } 


     //  arrêt de charge > trop longtemps
        if (--stateTimer <= 0)
        {
          digitalWrite(RECHARGE, OFF);  // Desactive le relais de charge
          MosfetCValue = 0;
          analogWrite(gatePinC, MosfetCValue);     //ecrit la nouvelle valeur de sortie
          Serial.print("MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
          Serial.println(MosfetCValue);
          Serial.println("------------------------------------------------");
          Serial.print("Temps de Charge maxi depasse");
          Serial.println(); 
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Stop Charge");
            lcd.setCursor(0,1);
            lcd.print("Temps  maxi");

          currentState = STATE_DONE;        // L'etat suivant est fait
           Serial.println("CYCLE DONE 1"); 
            Serial.println(); 
// TODO update display
      }
        break;

//----------------------------
      case STATE_DISWAIT:
        if (--delayTimer <= 0)
        {
          digitalWrite(DISCHARGE, ON);      // Activer le relais de decharge


          currentState = STATE_DISCHARGING; // L'etat suivant est decharge
            Serial.println("------------------------------------------------");
            Serial.print("CYCLE DECHARGE Cycle # ");
          Serial.println(numberCycles);
            Serial.println("------------------------------------------------");
            Serial.println(); 



          stateTimer = MAXSTATETIME;        // Valeur de temporisation de l'etat de configuration
          cycleTime = now;                  // Heure de debut d'etat
        }
        // TODO update display
        break;

//----------------------------        
      case STATE_DISCHARGING:
        cellVolts = readVoltage();          // Faire une lecture
        cellVolts2 = readVoltage2();          // Faire une lecture

        MosfetDValue = MosfetDStart; 
        analogWrite(gatePinC, MosfetDValue);     //ecrit la nouvelle valeur de sortie


 CibleCurrentDisCharge = batteryCapacity / SpeedDisCharge;     //c
  CurrentDisCharge = (cellVolts - cellVolts2 ) / resistance;     //jeca calculer le courant de decharge
  currentDisChargError = CibleCurrentDisCharge - CurrentDisCharge;     //jeca difference between target current and measured current

      millisPassed = millis() - previousMillis;
//      mAh = mAh + (CurrentDisCharge * 1000.0) * (millisPassed / 3600000.0);
      mAh = mAh + (CurrentDisCharge) * (millisPassed / 3600000.0);




      previousMillis = millis();

  Serial.print("batterie(V):");     //afficher la tension de la batterie
  Serial.println(cellVolts/1000); 
  Serial.print("Shunt   (V):");
  Serial.println(cellVolts2/1000); 

  Serial.print("Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
  Serial.print("Cible (mA): ");
  Serial.println(CibleCurrentDisCharge);
  Serial.print("Decharge(mA): ");     //afficher le courant actuel
  Serial.println(CurrentDisCharge);  
  Serial.print("Capacite (mAh): ");     //afficher 
  Serial.println(mAh);
//  Serial.print("millisPassed: ");     //afficher 
//  Serial.println(millisPassed);
//  Serial.print("previousMillis: ");     //afficher 
//  Serial.println(previousMillis);
  Serial.println();     //des espaces supplementaires pour faciliter la lecture des donnees de debogage
  Serial.println();  

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(numberCycles); 
  lcd.setCursor(4,0);
  lcd.print("Dech."); 
  lcd.setCursor(11,0);
  lcd.print(cellVolts/1000); 
  lcd.setCursor(15,0);
  lcd.print("V"); 

  lcd.setCursor(0,1);
  lcd.print(mAh);
  lcd.setCursor(5,1);
  lcd.print("mAh"); 

  lcd.setCursor(9,1);
  lcd.print(CurrentDisCharge); 
  lcd.setCursor(14,1);
  lcd.print("mA");

//Corrections Intensite  de decharge
  if(MosfetDValue > 0) 
     {
   if( ((CurrentDisCharge + (TolCurrent + 1)) <= CibleCurrentDisCharge ) && (MosfetDValue < 255) )    //
      {
      MosfetDValue = MosfetDValue + 1;
      MosfetDStart = MosfetDValue; 
       analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie
        Serial.print("Correction decharge + Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println(MosfetDStart); 

       }
   if( ((CurrentDisCharge - (TolCurrent + 1)) >= CibleCurrentDisCharge )  && (MosfetDValue > 0) )   //while
     {
      MosfetDValue = MosfetDValue - 1;
      MosfetDStart = MosfetDValue; 
       analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie
        Serial.print("Correction decharge - Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
        Serial.println(MosfetDValue); 
    }
    }

    //info erreur
       if(MosfetDValue > 255)     //la sortie ne peut jamais depasser 255
        {
         MosfetDValue = 255;
         analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie
         Serial.print("Erreur calcul Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println();
        }




    // arrêt de decharge > si l' intensite de decharge ateint le seuil mini de decharge
       if (cellVolts < V_MIN)
        {
          digitalWrite(DISCHARGE, OFF);     // Desactive le relais de decharge

          MosfetDValue = 0;
          analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie

  Serial.print("MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCValue); 
  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue);

          currentState = STATE_CHGWAIT;     // L'etat suivant est en attente avant la charge
            Serial.println("CYCLE CHGWAIT");
            Serial.println(); 
          
          delayTimer = RECOVERYTIME;        // Inter state delay time > Temps de retard entre etats
          stateTimer = MAXSTATETIME;        // Valeur de temporisation de l'etat de configuration
            Serial.println("------------------------------------------------");
            Serial.print("Fin de decharge # ");
          Serial.println(numberCycles);
            Serial.println("------------------------------------------------");
          Serial.print("Temps de decharge: (S) ");  // Logg
          Serial.println((now - cycleTime)/1000);



                 Serial.println(); 
  Serial.print("MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCValue); 
  Serial.print("MosfetCStart: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCStart); 
  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
  Serial.print("MosfetDStart: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDStart); 
  Serial.print("MosfetCValue: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCValue); 
  Serial.print("MosfetDValue: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
                 Serial.println(); 
  Serial.print("Capacite Cycle  (mAh): ");     //afficher 
  Serial.println(mAh);
            Serial.println("-------------------------------------------------------------");
            Serial.println("-------------------------------------------------------------");
//  Serial.print("Temps: ");     //afficher 
//  Serial.println(millisPassed);



            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Decha. fini");
            lcd.setCursor(0,1);
            lcd.print("Capa:");
            lcd.setCursor(11,1);
            lcd.print(mAh);
            lcd.setCursor(14,1);
            lcd.print("mAh");
}

        if (--stateTimer <= 0)
        {
          digitalWrite(DISCHARGE, OFF);     // Desactive le relais de decharge

          MosfetDValue = 0;
          analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie


          Serial.print("Temps de Decharge maxi depasse");
          Serial.println(); 
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Stop Decharge");
            lcd.setCursor(0,1);
            lcd.print("Temps  maxi");

  Serial.print("MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCValue); 
  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue);

          currentState = STATE_DONE;        // L'etat suivant est fait
          Serial.println("CYCLE DONE 2");
          Serial.println(); 
}
        


     // TODO update display

        break;

//----------------------------
      case STATE_CHGWAIT:
        if (--delayTimer <= 0)
        {

          if (++numberCycles <= NUMBEROFCYCLES)
          {
            currentState = STATE_START;     // L'etat suivant est configure pour charger
            Serial.println("------------------------------------------------");
            Serial.println("CYCLE START");
            Serial.println("------------------------------------------------");
            Serial.println(); 

  Serial.print("Capacite precedente: ");     //
  Serial.println(batteryCapacity);

 batteryCapacity  = mAh;
 mAh = 0;
  Serial.print("Nouvelle Capacite: ");     //
  Serial.println(batteryCapacity);

}
          else
          {
              digitalWrite(DISCHARGE, OFF);  // Desactive le relais de decharge
             digitalWrite(RECHARGE, OFF);   // Desactive le relais de charge

            currentState = STATE_DONE;     // L'etat suivant est fait
          Serial.println("CYCLE DONE 3");
          Serial.println(); 

          MosfetDValue = 0;
          analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie
  Serial.print("MosfetC: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetCValue); 
  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue);
            Serial.println("------------------------------------------------");
             Serial.println("Cycles finished"); // Logging
            Serial.println("------------------------------------------------");
             Serial.println(); 
          }
        }
        
        // TODO update display
        break;

      case STATE_DONE:
        // TODO update display
        break;
    }
  }
//  delay(2000);     //delay x/1000 secondes avant la prochaine iteration
}




Immagine Allegata: Arduino_Planté_cell_cycle_tester_7.Jpg
 
ForumEA/U/Arduino_Planté_cell_cycle_tester_7.Jpg



Modificato da capi32 - 20/10/2019, 15:31:02


---------------
cugino della Francia
Inverter MPPsolar MPI 5.5Kw, 6480W pannelli, 4x100A PbCa e presto anche le batterie Planté ...

 

capi32

Avatar
GigaWatt


Gruppo:Utente
Messaggi:846

Stato:



Inviato il: 07/11/2019 23:34:47

attualizzazione

ora tutto funziona. (eccetto la misurazione della temperatura)

Ho rimosso il mosfet per la carica perché alla fine non è utile. L'intensità di carica viene regolata variando la tensione di carica con il potenziometro digitale MCP4132 e il regolatore LM317T.

Continuerò i test e perfezionerò la parte di carica perché a volte ho variazioni di +- 10 mA. L'ideale sarebbe rimanere a +- 5mA.



//Arduino_Planté_cell_cycle_tester_27.ino

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

#include <SPI.h>
const int ss = 10;
#define VMaxPower               9   //tension max du chargeur
#define SepstPot               129   //pas du potentiometer numerique
int ValuePot = 0;

// Definir les variables système
double           cellVolts;
double           cellVolts2;
double           cellVolts3;
double     CibleChargeShunt;
int           chargeCurrent;
int           numberCycles;
int           currentState;
int           delayTimer;           
int           stateTimer;
unsigned long sampleDelay;
unsigned long cycleTime;
//int MosfetCValue;
int MosfetDValue;


// Definir le  materiels
#define RELAIS_DISCHARGE                  8        // Relais de decharge
#define RELAIS_RECHARGE                   7        // Relais de RELAIS_RECHARGE
#define VOLTS                     A1        // Tension de cellule
#define CURRENT                   A2        // CHARGE courant (pas de decharge ...jeca )
#define VOLTSCHARGEUR             A6        // Tension du chargeur
int gatePinD = 9;     // jeca - Câble de signal de sortie (pour le Mosfet) connecte à la Pin numerique 9
float resistance  =              2.5;     //resistance mesuree de la resistance R2 de puissance (+0.5 pour le mosfet)
#define EXTERNDIV_NUM              2         // valeur x > diviseur de tension externe > pour abaisser les mesures de tension des batteries a moins de 5v ,pont  diviseur par 4
#define EXTERNDIV_DENOM            1         // valeur 1 > diviseur de tension externe > DENOM doit egale a 1
#define SAMPLE_DELAY_MILLIS     1000      // Nombre de mS entre les contrôles de tension
#define RECOVERYTIME              20        // Nombre de secondes entre la charge/decharge et la decharge/charge La valeur maximale est 32767
#define MAXSTATETIME            21600      // Nombre de secondes autorisees dans chaque etat (c'est-à-dire chargement ou dechargement) La valeur maximale est 32767.
#define ON                         1         // Mettre un relais en marche
#define OFF                        0         // Eteindre un relais Off
#define TolCurrent                 4        // plage de correction du courant en mA
#define VCCVOLTS                5010L     // Valeur reelle du rail 5 volts LAISSER LE SUFFIXE "L  car cette valeur doit être une valeur int longue


#define TempPin =                2     //Sonde_3 de Temperature connectee à la Pin analogique 2
float TempTc = 0;     //variable pour stocker la valeur de TempPin analogique
float tmp36Voltage = 0;     //calculated voltage at TempPin
float temperatureC = 0;     //temperature calculee de la sonde en degres C


//----------------------------   Definir les parametre  de la batterrie et des cycles de test

int batteryCapacity =          900;     //capacite nominale de la batterie en mAh


// reglages pour la charge 

#define currentMin               40    //courant de charge minimale en mA
#define Speed_CHARGE              10      //Vitesse de charge > C7  > 7 = decharge en 7 heures
#define V_floating             1400     //tension de floating   (en 
#define cutoffcurrent            90     // intensite en mA de in de char
#define VoltageChargeMaxi      1500     //tension limite de securite > stop charge  (en mV)


//reglages pour la decharge
//unsigned int MosfetDValue = 10;     //valeur de demarage cycle 1 ;du signal de sortie PWM (pour le Mosfet)
float MosfetDInit  = 10;     //valeur de demarage cycle
float MosfetDStart = 100;     //valeur recalcule 
#define currentMinD               40    //courant de decharge minimale en mA
#define Speed_DISCHARGE           10  //Vitesse de decharge > C10  > 10 = decharge en 10 heures
#define V_MIN                  1000      // fin de decharge / Tension min de decharge (en mV) 


//reglages des cycles
#define NUMBEROFCYCLES           3        // Nombre de cycles à executer


//-------pour le calcul de la capacite--------
float mAh = 0.0;
boolean finished = false;
unsigned long previousMillis = 0;
unsigned long millisPassed = 0;
int printStart = 0;
int interval = 5000;  //Interval (ms) between measurements

//--------

//-------------------------------------------------

// variables calcule par le code
double CurrentCharge = 0;     //courant charge calcule  (en mA)
double CurrentDischarge = 0;     //courant decharge calcule (en mA)
double CibleCurrentCharge = batteryCapacity / Speed_CHARGE;     //courant de sortie cible (en mA) regle à C / 10 ou 1/10 de la capacite de la batterie par heure


double CibleCurrentDISCHARGE = batteryCapacity / Speed_DISCHARGE;     //courant de sortie cible (en mA) regle à C / 10 ou 1/10 de la capacite de la batterie par heure
double CurrentDischargerror = 0;     //difference entre le courant de consigne et le courant reel (en mA)

int ValuePotStart = (VMaxPower / SepstPot) * (V_floating/1000) + ((CibleCurrentCharge/1000) * resistance );



// Machine d'etat
#define STATE_START             0         // Configurer et demarrer le cycle de charge
#define STATE_CHARGING          1         // Surveiller le cycle de charge
#define STATE_DISWAIT           2         // Delai avant et reglage pour la decharge
#define STATE_DISCHARGING       3         // Surveiller la decharge
#define STATE_CHGWAIT           4         // Delai avant de repeter le cycle
#define STATE_DONE              5         // Termine





// readVoltage()
// Lire la tension de la cellule et retourner la moyenne de 4 lectures.
// Le resultat est mis à l'echelle par la valeur d'etalonnage ainsi que par le diviseur externe.
// La valeur de retour est en milliVolts, c'est-à-dire 0 - 5000
int readVoltage()
{
 int temp = 0;

  for (int i = 0; i < 4; i++)
  {
    //Mettre à l'echelle la lecture A2D. L'A2D renvoie 0 à 1023 pour une tension
    // plage de 0 à la tension d'alimentation de l'Arduino (normalement 5v).
    temp += (int)(((long)analogRead(VOLTS) * VCCVOLTS) / 1024); // Scale the A2D result
    delay(20);              // Un court delai entre les lectures
  }
  return (temp*EXTERNDIV_NUM)/(EXTERNDIV_DENOM*4);  // Compenser le diviseur de tension externe
}

// readVoltage2()
// Lire la tension de la cellule apres la resitance et retourner la moyenne de 4 lectures.
// Le resultat est mis à l'echelle par la valeur d'etalonnage ainsi que par le diviseur externe.
// La valeur de retour est en milliVolts, c'est-à-dire 0 - 5000
int readVoltage2()
{
 int temp = 0;

  for (int i = 0; i < 4; i++)
  {
    //Mettre à l'echelle la lecture A2D. L'A2D renvoie 0 à 1023 pour une tension
    // plage de 0 à la tension d'alimentation de l'Arduino (normalement 5v).
    temp += (int)(((long)analogRead(CURRENT) * VCCVOLTS) / 1024); // Scale the A2D result
    delay(20);              // Un court delai entre les lectures
  }
  return (temp*EXTERNDIV_NUM)/(EXTERNDIV_DENOM*4);  // Compenser le diviseur de tension externe
}

int readVoltage3()
{
 int temp = 0;

  for (int i = 0; i < 4; i++)
  {
    //Mettre à l'echelle la lecture A2D. L'A2D renvoie 0 à 1023 pour une tension
    // plage de 0 à la tension d'alimentation de l'Arduino (normalement 5v).
    temp += (int)(((long)analogRead(VOLTSCHARGEUR) * VCCVOLTS) / 1024); // Scale the A2D result
    delay(20);              // Un court delai entre les lectures
  }
  return (temp*EXTERNDIV_NUM)/(EXTERNDIV_DENOM*4);  // Compenser le diviseur de tension externe
}
  
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------

// Cette fonction configure les ports à utiliser et initialise certaines variables.
void setValuePot(int value)
{
  digitalWrite(ss, LOW);
  SPI.transfer(0); // send command byte
  SPI.transfer(value); // send value (0~255)
  digitalWrite(ss, HIGH);
}

void setup()
 {
  // Configuration pour le debogage et l'enregistrement
// Print a message to the LCD.
  lcd.backlight();
        lcd.setCursor(0,0);
        lcd.print(" Testeur Cycles "); //Intro Message line 1
        lcd.setCursor(0,1); //Second line
        lcd.print("Batterie Plante"); //Intro Message line 2
         delay(3000);
         lcd.clear();
//-----
  Serial.begin(9600);
  Serial.println("Demarage Cycle");    // Ajoute un  CR - use Serial.print() pour aucun CR
  numberCycles = 1;
  Serial.println();

  currentState = STATE_START;
  Serial.println("STATE_START");
  Serial.println();

 lcd.init();                      // initialize the lcd 

  pinMode(RELAIS_DISCHARGE, OUTPUT);   // definit la broche de decharge comme sortie
  digitalWrite(RELAIS_DISCHARGE, OFF); // Desactive le relais de decharge
  pinMode(RELAIS_RECHARGE, OUTPUT);    // definit la broche de RELAIS_RECHARGE comme sortie
  digitalWrite(RELAIS_RECHARGE, OFF);  // Desactive le relais de RELAIS_RECHARGE

  pinMode(ss, OUTPUT); // we use this for SS pin
  SPI.begin(); // wake up the SPI bus.
  SPI.setBitOrder(MSBFIRST);
  // our MCP4162 requires data to be sent MSB (most significant byte) first
 

  cellVolts = readVoltage();    // Do first read pour initialiser le port

  pinMode(9, OUTPUT);


//  digitalWrite(gatePinC, 0);
  digitalWrite(gatePinD, 0);

    setValuePot(ValuePotStart);
    delay(1000);
cellVolts3 = readVoltage3();          // Faire une lecture
  Serial.print("pot:");
  Serial.println(ValuePotStart);  
  Serial.print("v:");
  Serial.println(cellVolts3/1000);   
  Serial.println();


  // TODO - initialisez votre affichage





}



//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------

// Cette fonction est appelee à plusieurs reprises par le système d'exploitation, nous avons donc besoin de savoir où dans le fichier
// On est un cycle de decharge de charge, donc on utilise une machine d'etat.
void loop() 
{
  unsigned long now = millis();     // Obtenir la valeur actuelle de la minuterie en mS

  if (now - sampleDelay > SAMPLE_DELAY_MILLIS)
  {
    sampleDelay = now;              // Reinitialiser l'heure de base de l'echantillonnage

    switch (currentState)           // Aller à l'etat actuel
    {
//----------------------------
      case STATE_START:
        stateTimer = MAXSTATETIME;      // Valeur de temporisation de l'etat de configuration
        currentState = STATE_CHARGING;  // L'etat suivant est charge
            Serial.println("------------------------------------------------");
          Serial.print("CYCLE CHARGING Cycle # ");
          Serial.println(numberCycles);
            Serial.println("------------------------------------------------");
          Serial.println();
       
        cycleTime = now;                //  Heure de debut d'etat


   
       
//        Serial.print("Cycle #");        // Logging
 //       Serial.println(numberCycles);
        
        // TODO update display
        break;

//----------------------------        
      case STATE_CHARGING:

        digitalWrite(RELAIS_RECHARGE, ON);     // Activer le relais de charge   

        cellVolts = readVoltage();          // Faire une lecture
        cellVolts2 = readVoltage2();          // Faire une lecture
        cellVolts3 = readVoltage3();          // Faire une lectur




//      MosfetCValue = MosfetCStart; 
//       analogWrite(gatePinC, MosfetCValue);     //ecrit la nouvelle valeur de sortie

 

  if(CibleCurrentCharge < currentMin) 
     {
      CibleCurrentCharge = currentMin;
    }


  CurrentCharge = (cellVolts2 - cellVolts ) / resistance;     //jeca calculer le courant de decharge

 // Serial.print("batteryCapacity: ");     //
 // Serial.println(batteryCapacity);
 // Serial.println();  

  Serial.print("batterie (V): ");     //afficher la tension de la batterie
  Serial.println(cellVolts/1000); 
  Serial.print("Shunt Cible : ");
  Serial.println(CibleChargeShunt); 
  Serial.print("Shunt    (V): ");
  Serial.println(cellVolts2/1000); 


  Serial.print("Charge Cible : ");
  Serial.println(CibleCurrentCharge);
  Serial.print("Charge   (mA): ");     //afficher le courant actuel
  Serial.println(CurrentCharge);  
  Serial.println();
  Serial.println(); 

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(numberCycles); 
  lcd.setCursor(4,0);
  lcd.print("Charge"); 
  lcd.setCursor(11,0);
  lcd.print(cellVolts/1000); 
  lcd.setCursor(15,0);
  lcd.print("V"); 

  lcd.setCursor(0,1);
  lcd.print("Curent:"); 
  lcd.setCursor(9,1);
  lcd.print(CurrentCharge); 
  lcd.setCursor(14,1);
  lcd.print("mA");

//Corrections Intensite  de charge
  if(cellVolts <V_floating)
     {
    CibleChargeShunt = (cellVolts/1000) + ((CibleCurrentCharge/1000) * resistance );     //
   if( ((CurrentCharge + (TolCurrent + 1)) <= CibleCurrentCharge ) && (ValuePot < SepstPot) )    //while
      {
      ValuePot = ValuePot + 1;
    setValuePot(ValuePot);
        Serial.print("Correction Charge + Pot: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println(ValuePot); 

       }
   if( ((CurrentCharge - (TolCurrent + 1)) >= CibleCurrentCharge )  && (ValuePot > 0) )   //
     {
      ValuePot = ValuePot - 1;
    setValuePot(ValuePot);
        Serial.print("Correction Charge - Pot: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println(ValuePot); 
    }
    }
    //info erreur
       if(ValuePot > SepstPot)     //la sortie ne peut jamais depasser 255
        {
         ValuePot = SepstPot;
    setValuePot(ValuePot);
         Serial.print("Erreur calcul Pot: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println();
        }

    // arrêt de charge > fin de charge
        if ( (cellVolts >= V_floating) && (CurrentCharge <= cutoffcurrent) )
        {


            Serial.println("------------------------------------------------");
            Serial.println("Fin de charge (Floating)");

          digitalWrite(RELAIS_RECHARGE, OFF);  // Desactive le relais de charge
    setValuePot(ValuePotStart);
          currentState = STATE_DISWAIT; // L'etat suivant est en attente avant la decharge            
            Serial.println("------------------------------------------------");
            Serial.println("CYCLE DISWAIT");
            Serial.println("------------------------------------------------");
            Serial.println(); 
 
  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
  Serial.print("MosfetDStart: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDStart); 

  Serial.print("MosfetDValue: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
                 Serial.println(); 



  Serial.print("Capacite (mAh): ");     //afficher 
  Serial.println(mAh);
  Serial.print("Temps: ");     //afficher 
  Serial.println(previousMillis);
 
          delayTimer = RECOVERYTIME;    // Interstate delay time
          Serial.print("Temps de charge: (S) ");   // Logging
          Serial.println((now - cycleTime)/1000);
          Serial.println(); 
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Charge fini");
            lcd.setCursor(0,1);
            lcd.print("Temps:");
            lcd.setCursor(8,1);
            lcd.print((now - cycleTime)/1000);
          
          // TODO update display
        }
     //  arrêt de charge >surcharge
          if(cellVolts >= VoltageChargeMaxi)    //arrêter la charge 
          {
          digitalWrite(RELAIS_RECHARGE, OFF);  // Desactive le relais de charge
    setValuePot(ValuePotStart);
 
           Serial.println("------------------------------------------------");
           Serial.print("Stop surcharge (VoltageChargeMaxi)");
            Serial.println(); 
             lcd.clear();
             lcd.setCursor(0,1);
             lcd.print("Stop surcharge");
          currentState = STATE_DISWAIT; // L'etat suivant est en attente avant la decharge   
           } 


     //  arrêt de charge > trop longtemps
        if (--stateTimer <= 0)
        {
          digitalWrite(RELAIS_RECHARGE, OFF);  // Desactive le relais de charge
    setValuePot(ValuePotStart);
          Serial.println("------------------------------------------------");
          Serial.print("Temps de Charge maxi depasse");
          Serial.println(); 
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Stop Charge");
            lcd.setCursor(0,1);
            lcd.print("Temps  maxi");

          currentState = STATE_DISWAIT; // L'etat suivant est en attente avant la decharge   
           Serial.println("CYCLE DISWAIT"); 
            Serial.println(); 
// TODO update display
      }
        break;

//----------------------------
      case STATE_DISWAIT:
        if (--delayTimer <= 0)
        {
          digitalWrite(RELAIS_DISCHARGE, ON);      // Activer le relais de decharge


          currentState = STATE_DISCHARGING; // L'etat suivant est decharge
            Serial.println("------------------------------------------------");
            Serial.print("CYCLE DECHARGE Cycle # ");
          Serial.println(numberCycles);
            Serial.println("------------------------------------------------");
            Serial.println(); 



          stateTimer = MAXSTATETIME;        // Valeur de temporisation de l'etat de configuration
          cycleTime = now;                  // Heure de debut d'etat
        }
        // TODO update display
        break;

//----------------------------        
      case STATE_DISCHARGING:
        cellVolts = readVoltage();          // Faire une lecture
        cellVolts2 = readVoltage2();          // Faire une lecture

        MosfetDValue = MosfetDStart; 
        analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie


 CibleCurrentDISCHARGE = batteryCapacity / Speed_DISCHARGE;     //c
  if(CibleCurrentDISCHARGE < currentMinD) 
     {CibleCurrentDISCHARGE = currentMinD;
    }
  CurrentDischarge = (cellVolts - cellVolts2 ) / resistance;     //jeca calculer le courant de decharge
  CurrentDischargerror = CibleCurrentDISCHARGE - CurrentDischarge;     //jeca difference between target current and measured current

      millisPassed = millis() - previousMillis;
//     mAh = mAh + (CurrentDischarge * 1000.0) * (millisPassed / 3600000.0);
      mAh = mAh + (CurrentDischarge) * (millisPassed / 3600000.0);




      previousMillis = millis();

  Serial.print("batterie(V):");     //afficher la tension de la batterie
  Serial.println(cellVolts/1000); 
  Serial.print("Shunt   (V):");
  Serial.println(cellVolts2/1000); 

  Serial.print("Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
  Serial.print("Decharge Cible: ");
  Serial.println(CibleCurrentDISCHARGE);
  Serial.print("Decharge(  mA): ");     //afficher le courant actuel
  Serial.println(CurrentDischarge);  
  Serial.print("Capacite (mAh): ");     //afficher 
  Serial.println(mAh);
//  Serial.print("millisPassed: ");     //afficher 
//  Serial.println(millisPassed);
//  Serial.print("previousMillis: ");     //afficher 
//  Serial.println(previousMillis);
  Serial.println();     //des espaces supplementaires pour faciliter la lecture des donnees de debogage
  Serial.println();  

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(numberCycles); 
  lcd.setCursor(4,0);
  lcd.print("Dech."); 
  lcd.setCursor(11,0);
  lcd.print(cellVolts/1000); 
  lcd.setCursor(15,0);
  lcd.print("V"); 

  lcd.setCursor(0,1);
  lcd.print(mAh);
  lcd.setCursor(5,1);
  lcd.print("mAh"); 

  lcd.setCursor(9,1);
  lcd.print(CurrentDischarge); 
  lcd.setCursor(14,1);
  lcd.print("mA");

//Corrections Intensite  de decharge
  if(cellVolts >= V_MIN) 
     {
   if( ((CurrentDischarge + (TolCurrent + 1)) <= CibleCurrentDISCHARGE ) && (MosfetDValue < 255) )    //
      {
      MosfetDValue = MosfetDValue + 1;
      MosfetDStart = MosfetDValue; 
       analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie
        Serial.print("Correction decharge + Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println(MosfetDStart); 

       }
   if( ((CurrentDischarge - (TolCurrent + 1)) >= CibleCurrentDISCHARGE )  && (MosfetDValue > 0) )   //while
     {
      MosfetDValue = MosfetDValue - 1;
      MosfetDStart = MosfetDValue; 
       analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie
        Serial.print("Correction decharge - Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
        Serial.println(MosfetDValue); 
    }
    }

    //info erreur
       if(MosfetDValue > 255)     //la sortie ne peut jamais depasser 255
        {
         MosfetDValue = 255;
         analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie
         Serial.print("Erreur calcul Mosfet: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
         Serial.println();
        }




    // arrêt de decharge > si l' intensite de decharge ateint le seuil mini de decharge
       if (cellVolts < V_MIN)
        {
          digitalWrite(RELAIS_DISCHARGE, OFF);     // Desactive le relais de decharge

          MosfetDValue = 0;
          analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie
//          MosfetDStart = MosfetDInit;

  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue);

          currentState = STATE_CHGWAIT;     // L'etat suivant est en attente avant la charge
            Serial.println("CYCLE CHGWAIT");
            Serial.println(); 
          
          delayTimer = RECOVERYTIME;        // Inter state delay time > Temps de retard entre etats
          stateTimer = MAXSTATETIME;        // Valeur de temporisation de l'etat de configuration
            Serial.println("------------------------------------------------");
            Serial.print("Fin de decharge # ");
          Serial.println(numberCycles);
            Serial.println("------------------------------------------------");
          Serial.print("Temps de decharge: (S) ");  // Logg
          Serial.println((now - cycleTime)/1000);



                 Serial.println(); 

  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
  Serial.print("MosfetDStart: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDStart); 

  Serial.print("MosfetDValue: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue); 
                 Serial.println(); 
  Serial.print("Capacite Cycle  (mAh): ");     //afficher 
  Serial.println(mAh);
            Serial.println("-------------------------------------------------------------");
            Serial.println("-------------------------------------------------------------");
//  Serial.print("Temps: ");     //afficher 
//  Serial.println(millisPassed);



            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Decha. fini");
            lcd.setCursor(0,1);
            lcd.print("Capa:");
            lcd.setCursor(11,1);
            lcd.print(mAh);
            lcd.setCursor(14,1);
            lcd.print("mAh");
}

        if (--stateTimer <= 0)
        {
          digitalWrite(RELAIS_DISCHARGE, OFF);     // Desactive le relais de decharge

          MosfetDValue = 0;
          analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie


          Serial.print("Temps de Decharge maxi depasse");
          Serial.println(); 
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Stop Decharge");
            lcd.setCursor(0,1);
            lcd.print("Temps  maxi");

 
  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue);

          currentState = STATE_DONE;        // L'etat suivant est fait
          Serial.println("CYCLE DONE 2");
          Serial.println(); 
}
        


     // TODO update display

        break;

//----------------------------
      case STATE_CHGWAIT:
        if (--delayTimer <= 0)
        {

          if (++numberCycles <= NUMBEROFCYCLES)
          {
            currentState = STATE_START;     // L'etat suivant est configure pour charger
            Serial.println("------------------------------------------------");
            Serial.println("CYCLE START");
            Serial.println("------------------------------------------------");
            Serial.println(); 

  Serial.print("Capacite precedente: ");     //
  Serial.println(batteryCapacity);

 batteryCapacity  = mAh;
 mAh = 0;
  Serial.print("Nouvelle Capacite: ");     //
  Serial.println(batteryCapacity);

}
          else
          {
              digitalWrite(RELAIS_DISCHARGE, OFF);  // Desactive le relais de decharge
             digitalWrite(RELAIS_RECHARGE, OFF);   // Desactive le relais de charge

            currentState = STATE_DONE;     // L'etat suivant est fait
          Serial.println("CYCLE DONE 3");
          Serial.println(); 

          MosfetDValue = 0;
          analogWrite(gatePinD, MosfetDValue);     //ecrit la nouvelle valeur de sortie

  Serial.print("MosfetD: ");     //afficher les valeurs de sortie pour la surveillance avec un ordinateur
  Serial.println(MosfetDValue);
            Serial.println("------------------------------------------------");
             Serial.println("Cycles finished"); // Logging
            Serial.println("------------------------------------------------");
             Serial.println(); 
          }
        }
        
        // TODO update display
        break;

      case STATE_DONE:
        // TODO update display
        break;
    }
  }
//  delay(2000);     //delay x/1000 secondes avant la prochaine iteration
}




Immagine Allegata: Arduino_Planté_cell_cycle_tester_9.Jpg
 
ForumEA/U/Arduino_Planté_cell_cycle_tester_9.Jpg



Modificato da capi32 - 08/11/2019, 13:33:29


---------------
cugino della Francia
Inverter MPPsolar MPI 5.5Kw, 6480W pannelli, 4x100A PbCa e presto anche le batterie Planté ...

 

capi32

Avatar
GigaWatt


Gruppo:Utente
Messaggi:846

Stato:



Inviato il: 10/11/2019 21:21:17

attualizzazione

modifica della funzione di carica per avere un carico di corrente costante (CC), poi un carico di tensione costante (CV).
il tester è quasi pronto per la produzione.....



Immagine Allegata: Arduino_Planté_cell_cycle_tester_9b.Jpg
 
ForumEA/U/Arduino_Planté_cell_cycle_tester_9b.Jpg


Scarica allegato

Arduino_Planté_cell_cycle_tester_31.ino ( Numero download: 93 )



---------------
cugino della Francia
Inverter MPPsolar MPI 5.5Kw, 6480W pannelli, 4x100A PbCa e presto anche le batterie Planté ...

 

capi32

Avatar
GigaWatt


Gruppo:Utente
Messaggi:846

Stato:



Inviato il: 18/11/2019 08:40:29

attualizzazione
aggiunta di "efficienza energetica" dei cicli.
Penso di aver integrato tutte le impostazioni e le funzioni possibilmente in questo test della batteria.
ovvero tutti i parametri che saranno utili per l'analisi di una batteria Planté in funzione della sua intera vita utile (compresa la formazione).

il passo successivo sarà la creazione automatica di curve di analisi (capacità, efficienza, ecc.)

ps:Vi ricordo anche che questo tester è anche un tester universale e può essere utilizzato senza modifiche per 18650 batterie.

Scarica allegato

Arduino_Planté_cell_cycle_tester_34.ino ( Numero download: 113 )



---------------
cugino della Francia
Inverter MPPsolar MPI 5.5Kw, 6480W pannelli, 4x100A PbCa e presto anche le batterie Planté ...

 

RAUNARDE
GigaWatt


Gruppo:Utente
Messaggi:1225

Stato:



Inviato il: 19/11/2019 09:48:31

complimenti vedo che vai avanti bello spedito!
Bravissimo!

 

capi32

Avatar
GigaWatt


Gruppo:Utente
Messaggi:846

Stato:



Inviato il: 20/11/2019 00:39:47

grazie per il commento

anche se questo progetto non entusiasma la folla (o forse si sta nascondendo Faccine/bye1.gif e aspettando il risultato finale.... ), continuo a dare tutto il mio lavoro.

e come mio primo Arduino, posso assicurarti che sto lottando parecchio.
un esempio dalla versione 34, ho avuto grossi bug alla minima modifica del codice e mi ci sono voluti 4 giorni per capire che i log di debug stavano travolgendo la mia memoria.

ora che tutto è stato risolto, posso passare alla creazione automatica delle curve di analisi.

ps:Ricordo inoltre che questo progetto, grazie alla sua totale libertà di funzioni e parametri, sarà lo strumento ideale per la formazione di batterie al piombo di tipo Planté.

Scarica allegato

Arduino_Planté_cell_cycle_tester_37.ino ( Numero download: 117 )



Modificato da capi32 - 20/11/2019, 00:55:57


---------------
cugino della Francia
Inverter MPPsolar MPI 5.5Kw, 6480W pannelli, 4x100A PbCa e presto anche le batterie Planté ...

 

AlessandroT

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:4424

Stato:



Inviato il: 20/11/2019 18:24:35

Capi tranquillo che ti seguiamo!



---------------
6 poly 250w. Bella stagione 4 sotto inverter pip 3024 e 2 sotto boiler 24v, inverno tutti sotto inverter. 12 batterie epzs 180ah con densità acido abbassata da 1,28 a 1,24

 

marcosnout

Avatar
GigaWatt


Gruppo:AMMINISTRATORE
Messaggi:3693

Stato:



Inviato il: 20/11/2019 18:43:24

Certo che ti seguiamo
bien sûr nous vous suivons



---------------
Laminox Hidra 24kw, pannello solare termico SunHeat open 200 lt, termoboiler 120 litri. Zona climatica D, Gradi-giorno 1427
Isola: 30 moduli SUNTECH 200wp, Inverter UPS PSW7 6048, regolatore di carica PCM8048, batterie 24 EPZS 810Ah (C10)

 

capi32

Avatar
GigaWatt


Gruppo:Utente
Messaggi:846

Stato:



Inviato il: 20/11/2019 20:24:38

Ok, prometto che smettero' di lamentarmi....Faccine/shutup.gif
e poi no.
un francese si lamenta e con 1/4 di italiano in più, sono un grande brontolone! Faccine/shaun.gif



---------------
cugino della Francia
Inverter MPPsolar MPI 5.5Kw, 6480W pannelli, 4x100A PbCa e presto anche le batterie Planté ...

 

marcosnout

Avatar
GigaWatt


Gruppo:AMMINISTRATORE
Messaggi:3693

Stato:



Inviato il: 20/11/2019 20:29:00

Faccine/roll1.gif



---------------
Laminox Hidra 24kw, pannello solare termico SunHeat open 200 lt, termoboiler 120 litri. Zona climatica D, Gradi-giorno 1427
Isola: 30 moduli SUNTECH 200wp, Inverter UPS PSW7 6048, regolatore di carica PCM8048, batterie 24 EPZS 810Ah (C10)

 
 InizioPagina
 

Pagine: (3)   1   [2]   3    (Ultimo Msg)

Versione Mobile!

Home page       TOP100-SOLAR      Home page forum