This project is a datalogger to check the capacity of 18650 batteries by determining if they are in good condition or they must be discarded.
The data that is logged in the sd card is: correct, power, voltage, LM35 temperature and execution time.
In order to not discharge the battery without having conected all the components, there is a button to start the discharge of the batery. Once the button is pressend, the relay closes, the battery starts to discharge and the data is logged eery 5 seconds on the sd card.
When the battery is bellow 2.8V, the relay opens to prevent over discharging the 18650 battery and also appears a new display showing the principal data adquired by the ESP32.
New displayAlso, to operate with the oled display, there is a pushbutton with a resistor in pull-down conection.
For any questions, do not hesitate to contact me :)
DataloggerThen, all the data can be shown by Matlab to create graphics to compare with other batteries.
/*Conexiones //SDA 21 //SCL 22 ** MOSI - pin 23 ** MISO - pin 19 ** SCK - pin 18 ** CS - pin 5 (Pin reset */ //Oled #include #include //Comunicacin I2C #include #include #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 //No sera necesario ya que est declarado una vez #include 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 #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; i10; 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); //> //---------------------------//