Alvaro Morales
Published © GPL3+

Battery capacity tester

Battery tester using an ESP32, micro SD cards and Arduino

IntermediateFull instructions provided1 hour385
Battery capacity tester

Things used in this project

Story

Read more

Custom parts and enclosures

Frizzing schematics

Schematics

Connection Diagram

Code

Code

Arduino
/*Conexiones
//SDA 21
//SCL 22

 ** MOSI - pin 23
 ** MISO - pin 19
 ** SCK - pin 18
 ** CS - pin 5 (Pin reset 
*/

//Oled
#include <SPI.h>
#include <Wire.h> //Comunicacin I2C
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display ancho, en pixeles
#define SCREEN_HEIGHT 64 // OLED display alto, en pixeles
#define OLED_RESET -1 // para compartir el pin de reset con la ESP32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//INA219
#include <Wire.h> //No sera necesario ya que est declarado una vez
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;
float capacidad = 0;

//Pulsador
const int pulsador = 23;
int estado = 0;

//Timer
 unsigned long timer;
 unsigned long timerOn;

// Tarjeta SD
#include "FS.h"
#include "SD.h"
#include <SPI.h>
#define SD_CS 5 // Pin CS para la tarjeta SD
String dataMessage;
String tiempo;
String bus;
String shunt;
String carga;
String corriente;
String potencia;

//Rel
const int rele = 12;

//LM35
const int analogIn = 35;
int RawValue= 0;
float Voltage = 0;
float tempC = 0;
float media = 0;
float mediaT = 0;
int i;


void setup() {
  Serial.begin(115200);
  while (!Serial) {
      delay(1);}
  digitalWrite(rele, HIGH);   // Se cierra el rel 

//---------Inicializa pantalla OLED---------//
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); /* Se inicializa la pantalla con la direccin 0x3C */
  display.clearDisplay();  /* Se limpia la pantalla */
  display.setTextSize(1);  /* Tamao del texto */
  display.setTextColor(WHITE);  /* Color del texto, esta pantalla slo permite texto en blanco*/
//-----------------------------------------//


//---------Inicializa sensor INA219---------//  
  uint32_t currentFrequency; 
  // Se Comprueba que el sensor est conectado
  if (! ina219.begin()) {
    Serial.println("Sensor no conectado");
      display.setCursor(10,25);
      display.print("Sensor no conectado");
      display.display();
    while (1) { delay(10); }
  }
  Serial.println("Sensor iniciado");  
//-----------------------------------------//


//---------Iniciamos tarjeta SD y creamos fichero---------//  
  SD.begin(SD_CS);
  if (!SD.begin(SD_CS)) {
    Serial.println("Fallo montando SD");
    return;
  }
  uint8_t cardType = SD.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No hay tarjeta insertada");
    return;
    display.setCursor(15,25);
    display.print("No hay SD");
    display.display();
  }
  Serial.println("Iniciando tarjeta SD...");
  if (!SD.begin(SD_CS)) {
    Serial.println("ERROR iniciando la tarjeta SD");
    return;    // init failed
    display.setCursor(15,25);
    display.print("ERROR iniciando la SD");
    display.display();
  }


  File file = SD.open("/data.txt"); //Se abre el fichero data.txt
  if (!file) { //Si el fichero no existe se crea y se le aaden los cabeceros
    Serial.println("No existe el fichero");
    Serial.println("Creando fichero...");
    writeFile(SD, "/data.txt", "Tiempo, Bus, Shunt, Carga, Corriente, Potencia, Capacidad, Temeperatura \r\n"); //Cabeceros
//    writeFile(SD, "/data.txt", "Reading ID, Date, Hour, Temperature \r\n");
  }
  else {
    Serial.println("Existe el fichero");
  }
  file.close();
//--------------------------------------------------------//  

//---------Rel---------//  
  pinMode(rele, OUTPUT);  //definir pin como salida
//----------------------//  
  

//---------Iniciamos el programa con el botn---------//  
  pinMode(pulsador, INPUT); //Declaramos el pulsador como entrada

    display.setCursor(15,25);
    display.print("Pulsar bot");display.write(162);display.print("n para        iniciar");
    display.display();

  while(estado != 1){                //Hasta que no se pulsa el botn no se inicia el programa para asegurar
    estado = digitalRead(pulsador);  //que el montaje est preparado
  if(estado == HIGH){
    Serial.println("Pulsador pulsado");
    estado = 1;
    display.clearDisplay();
  } 
    
  }
  digitalWrite(rele, LOW);   // Se cierra el rel 
    delay(1000);
//----------------------------------------------------//


}

void loop() {

//---------Mediciones sensor---------//
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  capacidad = capacidad + (current_mA * 5/3600);
  
  Serial.print("Bus Voltaje:   "); Serial.print(busvoltage); Serial.println(" V"); //Nos interesa
  Serial.print("Shunt Voltaje: "); Serial.print(shuntvoltage); Serial.println(" mV");
  Serial.print("Carga Voltaje:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Corriente:       "); Serial.print(current_mA); Serial.println(" mA");
  Serial.print("Potencia:         "); Serial.print(power_mW); Serial.println(" mW");
  Serial.print("Tiempo en ejecucin: "); Serial.print(timerOn); Serial.println(" s");
  Serial.print("Capacidad: "); Serial.print(capacidad); Serial.println(" mA");
  Serial.println("");
//-----------------------------------//

//------------LM35------------//
  media = 0;
  mediaT = 0;
   for(i=0; i<10; i++){
  RawValue = analogRead(analogIn);
  media = (RawValue / 2048.0) * 4600;
  mediaT = ((mediaT + media)/10);
 }
  RawValue = analogRead(analogIn);
  Voltage = (RawValue / 2048.0) * 4600; // 5000 to get millivots.
  tempC = Voltage * 0.1;
  Serial.print("\t Temperature in C = ");
  Serial.print(tempC,1);
  Serial.print("\t Media = ");
  Serial.println(mediaT,1);
//----------------------------//


//---------Tiempo en ejecicin---------//
 if(estado == 1){
  timer = millis();
//  timerOn = millis() - timer;
  estado = 2;
 }
   timerOn = (millis() - timer)/1000;

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


//---------Mostrar datos OLED---------//
delay(10);
display.clearDisplay();
//    display.setTextSize(1);
    
display.setCursor(0,0);
    display.print("Temp: "); display.print(mediaT,1); display.print((char)247); display.println("C");
display.setCursor(0,10);
    display.print("Shunt Volt: "); display.print(shuntvoltage); display.println(" mV");
display.setCursor(0,20);
    display.print("Carga Volt: "); display.print(loadvoltage); display.println(" V");
display.setCursor(0,30);
    display.print("Corriente: "); display.print(current_mA); display.println(" mA");
display.setCursor(0,40);
    display.print("Pot: "); display.print(power_mW); display.println(" mW");
display.setCursor(0,50);
    display.print("Tiempo: "); display.print(timerOn); display.print(" s");
display.setCursor(90,50);
    display.print(capacidad);
    display.display();
//------------------------------------//

//---------Cargar datos SD---------//
  tiempo = timerOn;
  bus = busvoltage;
  shunt = shuntvoltage;
  carga = loadvoltage;
  corriente = current_mA;
  potencia = power_mW;
  capacidad;
  mediaT;
  logSDCard();
  
//---------------------------------//

//---------Proteccin bateria mediante rel---------//
while(loadvoltage <= 2.8){

  digitalWrite(rele, HIGH);   // Se abre el rel para proteger la bateria y evitar que se descargue ms
// horas(timerOn);
  int horas = (timerOn / 3600); //Pasamos los segndos a horas, minutos y segundos
int minutos = ((timerOn-horas*3600)/60);
int segundos = timerOn-(horas*3600+minutos*60);

 display.clearDisplay();
 display.setCursor(0,0);
    display.print("Capacidad: ");
 display.setCursor(0,15);
    display.print(capacidad); display.print(" mA");
 display.setCursor(0,30);
    display.print("Tiempo: "); 
 display.setCursor(0,45);
    display.print(horas); display.print(":"); display.print(minutos); display.print(":"); display.print(segundos);
 display.setCursor(55,30);
    display.print("Temperatura:"); 
 display.setCursor(55,45);
    display.print(mediaT); display.print((char)247); display.print("C");
    display.display();
    Serial.print("Capacidad: "); Serial.print(capacidad); Serial.println(" mA");
    Serial.print("Tiempo: "); Serial.print(horas); Serial.print(":"); Serial.print(minutos); Serial.print(":"); Serial.println(segundos);
    Serial.print("Temperatura: "); Serial.print(mediaT); Serial.println(" C");
    delay(100000);
}
//--------------------------------------------------//

  delay(5000);
}



//---------Funciones---------//
void logSDCard() {
  dataMessage = String(tiempo) + "," + String(bus) + "," + String(shunt) + "," + String(carga) + "," + String(corriente) + "," + String(potencia) + "," + String(capacidad) + "," + String(mediaT) +"\r\n";
  Serial.print("Save data: ");
  Serial.println(dataMessage);
  appendFile(SD, "/data.txt", dataMessage.c_str());
}

// Escribir en la tarjeta SD (NO MODIFICAR NADA)
void writeFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if (file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

// Aadir cosas a la tarjeta (NO MODIFICAR NADA)
void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

//void horas(int tiempo){
//  int horas = (tiempo / 3600);
//int minutos = ((tiempo-horas*3600)/60);
//int segundos = tiempo-(horas*3600+minutos*60);
//    Serial.print(horas); Serial.print(":"); Serial.print(minutos); Serial.print(":"); Serial.println(segundos);
//}
//---------------------------//

Credits

Alvaro Morales

Alvaro Morales

3 projects • 0 followers

Comments