//2BAT 充電器 By Fareeha
//OLED
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, 4);
#include <Wire.h>//IIC庫
//INA226
//#include <INA226.h>
//INA226 ina;
//INA226 INA2;
//Fareeha LOGO
static const unsigned char PROGMEM str_FareehaLOGO[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x30, 0x00, 0x00, 0x7F, 0x20, 0x07, 0xFF, 0xC0,
0x00, 0x7F, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x7F, 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0x03, 0xFF,
0xFF, 0xFE, 0x00, 0x7F, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0x07, 0xFF, 0xFF, 0xFF, 0x10, 0x7F,
0x0F, 0xFF, 0xFF, 0xFF, 0x3C, 0x7F, 0x1F, 0xFF, 0xFF, 0xFF, 0x3C, 0x7F, 0x1F, 0xFF, 0xFF, 0xFF,
0xFE, 0x7F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0x3F, 0xEF,
0xE7, 0xFF, 0xFE, 0x7F, 0x7F, 0xE7, 0xC3, 0xFF, 0xFF, 0x7F, 0x7F, 0xC7, 0xC1, 0xFF, 0xFF, 0x7F,
0x7F, 0xC7, 0xC0, 0xFF, 0xFF, 0x7F, 0x7E, 0x87, 0x80, 0x7F, 0xFF, 0x7F, 0x7E, 0x07, 0x82, 0x3F,
0xFF, 0x7F, 0x7E, 0x07, 0x83, 0x9F, 0xF7, 0x7F, 0x7E, 0x03, 0x03, 0xFF, 0xF7, 0x7F, 0x3E, 0x01,
0x07, 0x3F, 0xF7, 0x7F, 0x3E, 0x00, 0x07, 0x1E, 0x77, 0x7F, 0x3E, 0x00, 0x05, 0x1E, 0x77, 0x7F,
0x3E, 0x00, 0x00, 0x1E, 0x47, 0x7F, 0x1E, 0x00, 0x00, 0x3E, 0x47, 0x7F, 0x1C, 0x00, 0x00, 0x3C,
0x07, 0x7F, 0x1C, 0x00, 0x00, 0x3C, 0x84, 0x7F, 0x1C, 0x00, 0x00, 0x3E, 0x00, 0x7F, 0x0E, 0x00,
0x00, 0x38, 0x00, 0x7F, 0x06, 0x00, 0x00, 0x60, 0x00, 0x7F, 0x02, 0x00, 0x03, 0x80, 0x00, 0x7F,
0x01, 0x01, 0xFF, 0x80, 0x00, 0x7F, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x7F, 0x00, 0x1F, 0x3F, 0xC0,
0x00, 0x7F, 0x00, 0x3E, 0x7F, 0xE0, 0x00, 0x7F, 0x00, 0x7C, 0x7F, 0xE0, 0x00, 0x7F, 0x00, 0xFC,
0xFF, 0xF0, 0x00, 0x7F, 0x01, 0xF9, 0xFF, 0xF0, 0x00, 0x7F, 0x01, 0xFB, 0xE3, 0xF0, 0x00, 0x7F,
0x03, 0x18, 0x83, 0xF0, 0x00, 0x7F, 0x03, 0x10, 0x83, 0xF0, 0x00, 0x7F, 0x03, 0xF0, 0xFF, 0xF0,
0x00, 0x7F, 0x07, 0xB0, 0xFF, 0xF0, 0x00, 0x7F, 0x07, 0xB8, 0xCF, 0xF0, 0x00, 0x7F, 0x07, 0x38,
0xCF, 0xF0, 0x00, 0x7F, 0x03, 0x38, 0xC7, 0xF0, 0x00, 0x7F, 0x03, 0x3C, 0x47, 0xF0, 0x00, 0x7F,
0x06, 0x3C, 0x47, 0xF8, 0x00, 0x7F, 0x06, 0x7C, 0x63, 0xF8, 0x00, 0x7F, 0x06, 0x7E, 0x23, 0xF8,
0x00, 0x7F, 0x07, 0xFF, 0x23, 0xF8, 0x00, 0x7F, 0x0F, 0xFF, 0x31, 0xF8, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
};
//變量聲明區
float Voltage_1,//電壓1
Current_1,//電流1
Voltage_2,//電壓2
Current_2,//電流2
Temperature;//溫度
int Status_1,//狀態1
Status_2,//狀態2
Status_OLED = 1; //啟用狀態
int TempNOW;//溫度記錄
const double BETA = 3380.0;//B值
const double BALANCE_RESISTOR = 10000.0; //分压电阻值
const double MAX_ADC = 1023.0;//ADC最大输入
double ROOM_TEMP_Kelvin;//常温_开尔文
const double ROOM_TEMP_Celsius = 25;//常温_摄氏度
const double RESISTOR_ROOM_TEMP = 10000.0;//NTC室温阻值
int NTC_INPUT_PIN = A6; //ADC输入引脚
int LOCK70C = 0;
void setup()
{
ROOM_TEMP_Kelvin = ROOM_TEMP_Celsius + 273.15;
pinMode(NTC_INPUT_PIN, INPUT);//ADC输入
pinMode(8, INPUT_PULLUP); //OLED開關按鈕
pinMode(A0, INPUT_PULLUP); //BAT開關按鈕
//pinMode(A1, INPUT_PULLUP); //BAT2開關按鈕
pinMode(A2, INPUT_PULLUP); //CHRG_2監測
pinMode(A3, INPUT_PULLUP); //STDBY_2監測
pinMode(6, INPUT_PULLUP); //STDBY_1監測
pinMode(7, INPUT_PULLUP); //CHRG_1監測
Serial.begin(9600);
// ina.begin(0x40);//初始化 INA226,地址0x44
// ina.configure(INA226_AVERAGES_16, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);//配置INA226
//ina.calibrate(0.01, 4);//校準 INA226,R分流器 = 0.01 ohm, Max excepted current = 4A
// INA2.begin(0x44);//初始化 INA226,地址0x44
// INA2.configure(INA226_AVERAGES_16, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);//配置INA226
// INA2.calibrate(0.01, 4);//校準 INA226,R分流器 = 0.01 ohm, Max excepted current = 4A
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setTextColor(WHITE);//开像素点发光
display.clearDisplay();//清屏
display.setTextSize(1); //字号
display.setCursor(70, 48); //开始坐标
display.println("Powed By");
display.setCursor(73, 56); //开始坐标
display.println("Fareeha");
display.drawBitmap(5, 0, str_FareehaLOGO, 41, 64, 1); //在坐标X:26 Y:16的位置显示中文字符
display.setTextSize(2); //字号
display.setCursor(67, 7); //开始坐标
display.println("2BAT");
display.setCursor(55, 24); //开始坐标
display.println("Chager");
display.display();
display.display();//开显示
delay(1500);
}
void loop()
{
//读取電壓&電流
//Voltage_1 = ina.readBusVoltage() ;
//Current_1 = abs(ina.readShuntCurrent());
//Voltage_2 = INA2.readBusVoltage());
//Current_2 = abs(INA2.readShuntCurrent());
Voltage_1 = 4.1345;
Current_1 = 0.5456;
Voltage_2 = 3.2875;
Current_2 = 0.7563;
Temperature = CalculateTemperature();
//Temperature = 25.00;
//电压归零
if (Voltage_2 < 0.1)
{
Voltage_2 = 0;
}
if (Voltage_1 < 0.1)
{
Voltage_1 = 0;
}
//按键事件
if (digitalRead(8) == LOW)//开关显示屏
{
Status_OLED = Status_OLED + 1;
if (Status_OLED == 3)
{
Status_OLED = 0;
display.clearDisplay(); //清屏
display.display(); //刷新
}
delay (500);
}
if (digitalRead(A0) == LOW)//开关BAT1
{
if (Status_OLED == 1)
{
if (Status_1 != 0)
{
Status_1 = 0;
digitalWrite(9, LOW);
}
else
{
Status_1 = 2;
digitalWrite(9, HIGH);
}
}
if (Status_OLED == 2)
{
if (Status_2 != 0)
{
Status_2 = 0;
digitalWrite(10, LOW);
}
else
{
Status_2 = 2;
digitalWrite(10, HIGH);
}
}
delay (500);
}
//讀取4056狀態
if (Status_1 != 0)
{
if (digitalRead(6) == LOW)//STDBY_1狀態
{
Status_1 = 2;
}
if (digitalRead(7) == LOW)//CHRG_1狀態
{
Status_1 = 1;
}
}
if (Status_2 != 0)
{
if (digitalRead(A2) == LOW)//CHRG_2狀態
{
Status_2 = 1;
}
if (digitalRead(A3) == LOW)//STDBY_2狀態
{
Status_2 = 2;
}
}
if (Status_2 == 2 || Status_1 == 2)
{
digitalWrite(13, HIGH);
}
else
{
digitalWrite(13, LOW);
}
switch (Status_OLED)
{
case 1:
DispalyUpdate(Voltage_1, Current_1, Status_1);
return;
case 2:
DispalyUpdate(Voltage_2, Current_2, Status_2);
return;
}
// delay(1000);
}
void DispalyUpdate(float D_Voltage, float D_Current, int D_Status)
{
display.clearDisplay();//清屏
display.setCursor(0, 0); //开始坐标
display.setTextSize(3); //设置字体大小
display.print(D_Voltage, 4); //输出字符
display.println("V"); //输出字符
display.print(D_Current, 4); //输出字符
display.println("A"); //输出字符
display.setTextSize(2); //设置字体大小
if (Status_OLED == 1)
{
display.print("S1:"); //输出字符
}
if (Status_OLED == 2)
{
display.print("S2:"); //输出字符
}
switch (D_Status)//狀態判斷
{
case 0:
display.print(" OFF "); //输出字符
break;
case 1:
display.print("CHRG "); //输出字符
break;
case 2:
display.print("STDBY"); //输出字符
break;
}
display.setTextSize(1); //设置字体大小
display.print(abs(Temperature), 1); //输出字符
display.print("C");
display.setCursor(96, 57); //开始坐标
display.print(D_Voltage * D_Current, 2); //输出字符
display.print("W"); //输出字符
display.display();//更新显示
}
void SerialPrint()
{
Serial.print("Voltage_1:");
Serial.print(Voltage_1, 5);
Serial.println(" V");
Serial.print("Current_1:");
Serial.print(Current_1, 5);
Serial.println(" A");
Serial.print("Voltage_2:");
Serial.print(Voltage_2, 5);
Serial.println(" V");
Serial.print("Current_2:");
Serial.print(Current_2, 5);
Serial.println(" A");
Serial.println("--------------");
}
double CalculateTemperature()
{
double rThermistor = 0;
double tKelvin = 0; //计算结果_开尔文
double tCelsius = 0; //计算结果_摄氏度
double ADC_Results = 0; //ADC采样结果
ADC_Results = analogRead(NTC_INPUT_PIN);//采样
rThermistor = BALANCE_RESISTOR * ( (MAX_ADC / ADC_Results) - 1);
tKelvin = (BETA * ROOM_TEMP_Kelvin) / (BETA + (ROOM_TEMP_Kelvin * log(rThermistor / RESISTOR_ROOM_TEMP)));
tCelsius = tKelvin - 273.15;//将开尔文换算成摄氏度
return tCelsius;//返回
}