Hi all,i have a project using a lcd display,heres the code://-----------------------------------------------------Youtube Channel Sasiskas------------------------------------------------------------------------
//-----------------------------------------------------Battery Capacity tester and more V1.1-----------------------------------------------------------
#include <SPI.h>
#include <stdlib.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long previousMillis = 0;
unsigned long millisPassed = 0;
unsigned long BatFull = 0;
float BatVoltQuiescent = 0; // The battery voltage when there is no load on the battery
float Capacity = 0.0; // The calculated capacity of the battery, measured wile discharging
float mA=0;
float SetI = 0; // The setpoint for the discharging current. Remember you can adjust the discharging current using the 500K trimpot.
float ChargeI = 0;
float CurTP4056 = 0;
float ResTP4056 = 0;
float ratioRI = 0;
float BatLevel = 0; // The percentage of battery charge/level
float BatVoltCorrected = 0; // The voltage of the battery, measured based on the arduino internal reference
float A2VoltCorrected = 0;
float VoltTP4056Pin2 = 0;
float Rprog = 0;
float BatRes = 0; // The internal battery resistance
const float RES = 1; // Value of your resistor. Suggested Value is 1 Ohm. Change it, if you use a different resistor value
#define clk 2
#define dt 3
#define sw 4
#define MOSFET_Discharge 9 // It is an N-MOSFET, so HIGH is ON and LOW is OFF
#define MOSFET_Charge 8 // It is a P-MOSFET, so HIGH is OFF and LOW is ON
char screen = 0;
char arrowpos = 0;
char charging = 0;
char discharging = 0;
char storage = 0;
char storagecharge = 0;
char storagedischarge = 0;
char BatVoltQuiescentValue = 0; // Whether there is a value for "the battery voltage with no load" (BatVoltQuiescent) or not. 1 for yes and 0 for no.
//char nointermediate = 0;
const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
volatile boolean TurnDetected = false;
volatile boolean up = false;
volatile boolean button = false;
byte OhmChar[8] = {
B00000,
B01110,
B10001,
B10001,
B10001,
B01010,
B11011,
B00000
};
byte customChar1[8] = {
0b10000,
0b11000,
0b11100,
0b11110,
0b11110,
0b11100,
0b11000,
0b10000
};
ISR(PCINT2_vect) {
if (digitalRead(sw) == LOW) {
button = true;
}
}
void isr0 () {
TurnDetected = true;
up = (digitalRead(clk) == digitalRead(dt));
}
void setup() {
lcd.begin();
lcd.setCursor(0, 0);
pinMode(MOSFET_Discharge, OUTPUT);
pinMode(MOSFET_Charge, OUTPUT);
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
pinMode(sw, INPUT_PULLUP);
pinMode(clk, INPUT);
pinMode(dt, INPUT);
PCICR |= 0b00000100;
PCMSK2 |= 0b00010000; // turn o PCINT20(D4)
attachInterrupt(0, isr0, RISING);
lcd.createChar(0, customChar1);
lcd.createChar(1, OhmChar);
lcd.clear();
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
}
void loop() {
int in0 = analogRead(A0); //read the A0 pin value
int sensorValue1 = analogRead(A1); //read the A1 pin value
float val0 = in0 * 5.0 / 1024.0;
float supply = readVcc() / 1000.0;
SetI = sensorValue1 * (5.00 / 1024.00) / RES * 1000; // Calculate the discharge rate of the battery
if (SetI <= 1200){
SetI = SetI;
}
else{
SetI = 1200;
}
BatVoltCorrected = supply / 5 * val0 * 4.35; //In case you use different voltage dividers, you need to change the number 4.3 accordingly.
millisPassed = millis() - previousMillis;
previousMillis = millis();
//------------------------------------------------------------------- calculates the charging current ------------------------------------------------------------------------
int in2 = analogRead(A2); //read the A2 pin value
int in3 = analogRead(A3); //read the A3 pin value
float val2 = in2 * 5.0 / 1024.0;
float val3 = in3 * 5.0 / 1024.0;
A2VoltCorrected = supply / 5 * val2; //calculates reading of pin A2 based on internal voltage reference
VoltTP4056Pin2 = supply / 5 * val3; //calculates reading of pin A3 based on internal voltage reference
Rprog = 1220 + (A2VoltCorrected * 1220 / (VoltTP4056Pin2 - A2VoltCorrected)); //calculates the Rprog of TP4056 module
//calculates the Charging current based on numbers from TP4056 datasheet
if (Rprog >= 10000) {
CurTP4056 =130 ;
ResTP4056 =10000 ;
ratioRI = 0.107 ;
}
else if (Rprog < 10000 && Rprog >= 5000){
CurTP4056 = 250 ;
ResTP4056 = 5000 ;
ratioRI = 0.024 ;
}
else if (Rprog < 5000 && Rprog >= 4000){
CurTP4056 = 300 ;
ResTP4056 = 4000 ;
ratioRI = 0.050 ;
}
else if (Rprog < 40000 && Rprog >= 3000){
CurTP4056 = 400 ;
ResTP4056 = 3000 ;
ratioRI = 0.100 ;
}
else if (Rprog < 30000 && Rprog >= 2000){
CurTP4056 = 580 ;
ResTP4056 = 2000 ;
ratioRI = 0.180 ;
}
else if (Rprog < 20000 && Rprog >= 1660){
CurTP4056 = 690 ;
ResTP4056 = 1660 ;
ratioRI = 0.324 ;
}
else if (Rprog < 10000 && Rprog >= 1500){
CurTP4056 = 780 ;
ResTP4056 = 1500 ;
ratioRI = 0.563 ;
}
else if (Rprog < 10000 && Rprog >= 1330){
CurTP4056 = 900 ;
ResTP4056 = 1330 ;
ratioRI = 0.706 ;
}
else if (Rprog >= 1220){
CurTP4056 = 995 ;
ResTP4056 = 1220 ;
ratioRI = 0.864 ;
}
if (Rprog < 1220){
ChargeI = 1000 ;
}
else {
ChargeI = (CurTP4056 - ((Rprog - ResTP4056) * ratioRI));
}
if (ChargeI > 0){
ChargeI = ChargeI;
}
else{
ChargeI = 0;
}
//------------------------------------------------------------------- battery percentage - linear calculation based on voltage (linear does NOT represent the REAL percentage)
if (BatVoltCorrected < 2.5) {
BatLevel = 0;
}
else if (BatVoltCorrected > 4.2)
{BatLevel = 100;
}
else {BatLevel = (BatVoltCorrected - 2.5 ) / 1.7 * 100 ;
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------
if (BatVoltCorrected <= 3.70 && BatVoltCorrected >= 3.65){ // For 3400mAh batteries storage voltage is 3.6-3.7V, for batteries below 2600mAh it should be higher.
storagedischarge = 0;
storagecharge = 0;
}
if (BatVoltCorrected <= 3.75 && BatVoltCorrected > 3.7){ // Set these numbers +0.5V of your batteries storage voltage
storagedischarge = 1;
storage = 2;
storagecharge = 0;
}
if (BatVoltCorrected >= 3.6 && BatVoltCorrected < 3.65){ // Set these numbers -0.5V of your batteries storage voltage
storagecharge = 1;
storage = 2;
storagedischarge = 0;
}
if (BatVoltCorrected > 3.75 || BatVoltCorrected < 3.6){ // Set these numbers +0.5V and -0.5V of your batteries storage voltage
storage = 0;
storagedischarge = 0;
storagecharge = 0;
}
if (BatVoltCorrected <= 3.75 && BatVoltCorrected >= 3.6){ // Set these numbers +0.5V and -0.5V of your batteries storage voltage
storage = 1;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
if (screen == 0) {
//delay(500);
BatVoltQuiescent = BatVoltCorrected;
BatVoltQuiescentValue = 1;
BatFull = 0;
}
//----------------------------------------------------------------------------------------Capacity test mode-------------------------------------------------------
if (screen == 1) {
if (BatVoltCorrected <= 2.3){
Capacity = Capacity;
BatVoltQuiescentValue = 0;
digitalWrite(MOSFET_Discharge, LOW);
// buz();
lcd.setCursor(0,0);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(8,0);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
lcd.setCursor(0,1);
lcd.print("C:");
lcd.print(Capacity,0);
lcd.print("mAh ");
lcd.setCursor(10,1);
lcd.print("R:");
lcd.print(BatRes,0);
lcd.print("m");
lcd.print(char(1));
delay(100);
}
if (BatVoltCorrected > 2.3 && BatVoltQuiescentValue == 0 ) {
BatRes = (BatVoltQuiescent - BatVoltCorrected) / (BatVoltCorrected / SetI); //Calculates the internal battery resistance in mOhms
Capacity = Capacity + (SetI * (millisPassed / 3600000.0));
BatVoltQuiescent = BatVoltCorrected;
BatVoltQuiescentValue = 1;
digitalWrite(MOSFET_Discharge, HIGH);
lcd.setCursor(0,0);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(8,0);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
lcd.setCursor(0,1);
lcd.print("C:");
lcd.print(Capacity,0);
lcd.print("mAh ");
lcd.setCursor(10,1);
lcd.print("R:");
lcd.print(BatRes,0);
lcd.print("m");
lcd.print(char(1));
delay(500);
}
else if (BatVoltCorrected > 2.3 && BatVoltQuiescentValue == 1 ) {
BatRes = (BatVoltQuiescent - BatVoltCorrected) / (BatVoltCorrected / SetI); //Calculates the internal battery resistance in mOhms
Capacity = Capacity + (SetI * (millisPassed / 3600000.0));
digitalWrite(MOSFET_Discharge, HIGH);
lcd.setCursor(0,0);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(8,0);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
lcd.setCursor(0,1);
lcd.print("C:");
lcd.print(Capacity,0);
lcd.print("mAh ");
lcd.setCursor(10,1);
lcd.print("R:");
lcd.print(BatRes,0);
lcd.print("m");
lcd.print(char(1));
delay(500);
}
}
//----------------------------------------------------------------------------------------Charge mode-------------------------------------------------------
else if (screen == 2) {
if (BatVoltCorrected >= 4.15) {
lcd.setCursor(0,0);
lcd.print("Full Battery");
lcd.setCursor(12,0);
lcd.print("100% ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(8,1);
lcd.print("I:");
lcd.print(ChargeI,0);
lcd.print("mA ");
digitalWrite(MOSFET_Charge, HIGH);
delay(500);
BatFull = BatFull + 1;
}
else if (BatVoltCorrected == 0 ){
BatFull = 0;
lcd.setCursor(0,0);
lcd.print("No Battery ");
lcd.setCursor(12,0);
lcd.print(BatLevel,0);
lcd.print("% ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(9,1);
lcd.print("I:");
lcd.print(ChargeI,0);
lcd.print("mA ");
digitalWrite(MOSFET_Charge, HIGH);
//delay(9000);
//digitalWrite(MOSFET_Charge, HIGH);
delay(500);
}
else if (BatVoltCorrected < 4.15 && BatFull < 10 && BatVoltCorrected > 0 ) {
lcd.setCursor(0,0);
lcd.print("Charging... ");
lcd.setCursor(12,0);
lcd.print(BatLevel,0);
lcd.print("% ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(8,1);
lcd.print("I:");
lcd.print(ChargeI,0);
lcd.print("mA ");
digitalWrite(MOSFET_Charge, LOW);
//delay(9000);
//digitalWrite(MOSFET_Charge, HIGH);
delay(500);
}
else if (BatVoltCorrected < 4.15 && BatFull >= 10) {
lcd.setCursor(0,0);
lcd.print("Full Battery");
lcd.setCursor(12,0);
lcd.print("100% ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(8,1);
lcd.print("I:");
lcd.print(ChargeI,0);
lcd.print("mA ");
digitalWrite(MOSFET_Charge, HIGH);
delay(500);
}
}
//----------------------------------------------------------------------------------------Storage mode-----------------------------------------------------------------------------------------
// You need to adjust your voltages according to your batteries, for 3400mAh batteries storage voltage (50% capacity) is 3.6-3.7V, for batteries below 2600mAh it should be higher.
// For more info visit this:https://lygte-info.dk/info/BatteryChargePercent%20UK.html
else if (screen == 3) {
delay(100);
if (BatVoltCorrected <= 1.5 ) {
lcd.setCursor(0,0);
lcd.print("No battery ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
charging = 0;
discharging = 0;
storage = 0;
storagecharge = 0;
storagedischarge = 0;
}
else if (BatVoltCorrected > 3.75 && charging == 0) { // Checks if the "quiescent voltage" of the battery is above 3.7V and Starts the discharge.
lcd.setCursor(0,0);
lcd.print("Discharging ");
lcd.setCursor(0,1);
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(9,1);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
digitalWrite(MOSFET_Charge, HIGH);
delay(100);
discharging = 1;
digitalWrite(MOSFET_Discharge, HIGH);
delay(9000);
digitalWrite(MOSFET_Discharge, LOW);
}
else if (storagedischarge == 1 && discharging == 1){ // Intermediate step before stopping the discharge
lcd.setCursor(0,0);
lcd.print("RDY for storage");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
discharging = 1;
digitalWrite(MOSFET_Charge, HIGH);
delay(100);
digitalWrite(MOSFET_Discharge, HIGH);
delay(9000);
digitalWrite(MOSFET_Discharge, LOW);
}
else if (BatVoltCorrected >= 1.5 && BatVoltCorrected < 3.6) { // Checks if the "quiescent voltage" of the battery is between 1.5V and 3.6V
if (discharging == 1 && BatVoltCorrected < 3.0){ // Stops discharging if the "discharge voltage" of the battery is below 3.0V
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(9,1);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
digitalWrite(MOSFET_Discharge, LOW);
}
if (discharging == 1 && BatVoltCorrected > 2){ // Prevents from charging (continues discharging) even if the "quiescent voltage" is below 3.6V
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(9,1);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
}
else if (discharging == 0 && BatVoltCorrected < 3.6){ // Starts to charge the battery
lcd.setCursor(0,0);
lcd.print("Charging ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Discharge, LOW);
delay(100);
digitalWrite(MOSFET_Charge, LOW);
charging = 1;
delay(1000);
}
else { // used for debugging
lcd.setCursor(0,0);
lcd.print("error? ");
}
}
else if (storagecharge == 1 && charging == 1){ // Intermediate step before stopping the charge. (not actually stopping the charge)
lcd.setCursor(0,0);
lcd.print("RDY for storage");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
charging = 1;
//nointermediate = 1;
digitalWrite(MOSFET_Discharge, LOW);
delay(100);
digitalWrite(MOSFET_Charge, LOW);
delay(1000);
}
else if (charging == 1 && BatVoltCorrected > 3.65 ){ // Stops charge . This step is used if the Intermediate stop of charge was used.
lcd.setCursor(0,0);
lcd.print("RDY for storage");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
delay(1000);
}
else if (storage == 1 && charging == 0){ // For 3400mAh batteries sorage voltage is 3.6-3.7V, for batteries below 2600mAh it should be higher.
lcd.setCursor(0,0); // This step is used if the Intermediate stop of charge was NOT used. Or after intermadiate stop of discharge.
lcd.print("RDY for storage");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
delay(1000);
}
}
//-------------------------------------------------------------------------------- TURN -------------------------------------------------------------------------------------------------------
if (TurnDetected) {
delay(200);
switch (screen) {
case 0:
switch (arrowpos) {
case 0:
if (!up) {
screen0();
lcd.setCursor(0, 1);
lcd.write((uint8_t)0);
arrowpos = 1;
}
else {
screen0();
lcd.setCursor(8, 1);
lcd.write((uint8_t)0);
arrowpos = 2;
}
break;
case 1:
if (up) {
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
arrowpos = 0;
}
else {
screen0();
lcd.setCursor(8, 1);
lcd.write((uint8_t)0);
arrowpos = 2;
}
break;
case 2:
if (up) {
screen0();
lcd.setCursor(0, 1);
lcd.write((uint8_t)0);
arrowpos = 1;
}
else {
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
arrowpos = 0;
}
break;
}
break;
}
TurnDetected = false;
}
//-------------------------------------------------------------------------------------------- BUTTON PRESS --------------------------------------------------------------------------------------------
if (button) {
delay(200);
switch (screen) {
case 0:
if (arrowpos == 0) {
screen = 1;
screen1();
}
else if (arrowpos == 1){
screen = 2;
screen2();
}
else {
screen = 3;
screen3();
}
break;
case 1:
screen = 0;
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
break;
case 2:
screen = 0;
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
break;
case 3:
screen = 0;
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
break;
}
arrowpos = 0;
button = false;
}
}
//-----------------------------------------------------------------------------------------------------SCREENS-------------------------------------------------------------------------------------
void screen0() {
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Capacity test");
lcd.setCursor(1, 1);
lcd.print("Charge");
lcd.setCursor(9, 1);
lcd.print("Store");
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
charging = 0;
discharging = 0;
storage = 0;
storagecharge = 0;
storagedischarge = 0;
}
void screen1() {
lcd.clear();
}
void screen2() {
lcd.clear();
}
void screen3() {
lcd.clear();
}
//-------------------------------------------------------------------voltage based on internal reference-------------------------------------------------------------
long readVcc() {
long result;
// Read 1.1V reference against AVcc
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA, ADSC));
result = ADCL;
result |= ADCH << 8;
result = 1126400L / result; // Calculate Vcc (in mV); 1126400 = 1.1*1024*1000
return result;
}
//void buz()
// {
// digitalWrite(9, HIGH);
// delay(100);
// digitalWrite(9, LOW);
// delay(10);
//}
i want to use a 1.3 inch oled using i2c interface, sh1106,what do i need to change in the code to do this?,i already have all the libraies etc,thanks in advance.