638 lines
34 KiB
C++
638 lines
34 KiB
C++
/* PROJECT FUGU FIRMWARE V1.10 (DIY 1kW Open Source MPPT Solar Charge Controller)
|
||
By: TechBuilder (Angelo Casimiro)
|
||
FIRMWARE STATUS: Verified Stable Build Version
|
||
(Contact me for the experimental beta versions)
|
||
-----------------------------------------------------------------------------------------------------------
|
||
DATE CREATED: 02/07/2021
|
||
DATE MODIFIED: 30/08/2021
|
||
-----------------------------------------------------------------------------------------------------------
|
||
CONTACTS:
|
||
GitHub - www.github.com/AngeloCasi (New firmware releases will only be available on GitHub Link)
|
||
Email - casithebuilder@gmail.com
|
||
YouTube - www.youtube.com/TechBuilder
|
||
Facebook - www.facebook.com/AngeloCasii
|
||
-----------------------------------------------------------------------------------------------------------
|
||
PROGRAM FEATURES:
|
||
- MPPT Perturbed Algorithm With CC-CV
|
||
- WiFi & Bluetooth BLE Blynk Phone App Telemetry
|
||
- Selectable Charger/PSU Mode (can operate as a programmable buck converter)
|
||
- Dual Core ESP32 Unlocked (using xTaskCreatePinnedToCore(); )
|
||
- Precision ADC Tracking Auto ADS1115/ADS1015 Detection (16bit/12bit I2C ADC)
|
||
- Automatic ACS712-30A Current Sensor Calibration
|
||
- Equipped With Battery Disconnect & Input Disconnect Recovery Protection Protocol
|
||
- LCD Menu Interface (with settings & 4 display layouts)
|
||
- Flash Memory (non-volatile settings save function)
|
||
- Settable PWM Resolution (8bit-16bit)
|
||
- Settable PWM Switching Frequency (1.2kHz - 312kHz)
|
||
-----------------------------------------------------------------------------------------------------------
|
||
PROGRAM INSTRUCTIONS:
|
||
1.) Watch YouTube video tutorial first before using
|
||
2.) Install the required Arduino libraries for the ICs
|
||
3.) Select Tools > ESP32 Dev Board Board
|
||
4.) Do not modify code unless you know what you are doing
|
||
5.) The MPPT's synchronous buck converter topology is code dependent, messing with the algorithm
|
||
and safety protection protocols can be extremely dangerous especially when dealing with HVDC.
|
||
6.) Install Blynk Legacy to access the phone app telemetry feature
|
||
7.) Input the Blynk authentication in this program token sent by Blynk to your email after registration
|
||
8.) Input WiFi SSID and password in this program
|
||
9.) When using WiFi only mode, change "disableFlashAutoLoad = 0" to = 1 (LCD and buttons not installed)
|
||
this prevents the MPPT unit to load the Flash Memory saved settings and will load the Arduino variable
|
||
declarations set below instead
|
||
-----------------------------------------------------------------------------------------------------------
|
||
GOOGLE DRIVE PROJECT LINK: coming soon
|
||
INSTRUCTABLE TUTORIAL LINK: coming soon
|
||
YOUTUBE TUTORIAL LINK: www.youtube.com/watch?v=ShXNJM6uHLM
|
||
GITHUB UPDATED FUGU FIRMWARE LINK: github.com/AngeloCasi/FUGU-ARDUINO-MPPT-FIRMWARE
|
||
-----------------------------------------------------------------------------------------------------------
|
||
ACTIVE CHIPS USED IN FIRMWARE:
|
||
- ESP32 WROOM32
|
||
- ADS1115/ADS1015 I2C ADC
|
||
- ACS712-30A Current Sensor IC
|
||
- IR2104 MOSFET Driver
|
||
- CH340C USB TO UART IC
|
||
- 16X2 I2C Character LCD
|
||
|
||
OTHER CHIPS USED IN PROJECT:
|
||
- XL7005A 80V 0.4A Buck Regulator (2x)
|
||
- AMS1115-3.3 LDO Linear Regulator
|
||
- AMS1115-5.0 LDO Linear Regulator
|
||
- CSD19505 N-ch MOSFETS (3x)
|
||
- B1212 DC-DC Isolated Converter
|
||
- SS310 Diodes
|
||
*/
|
||
//================================ MPPT FIRMWARE LCD MENU INFO =====================================//
|
||
// The lines below are for the Firmware Version info displayed on the MPPT's LCD Menu Interface //
|
||
//==================================================================================================//
|
||
String
|
||
firmwareInfo = "V2.10",
|
||
firmwareDate = "23/06/2022",
|
||
firmwareContactR1 = "www.youtube.com/",
|
||
firmwareContactR2 = "TechBuilder ";
|
||
|
||
//====================== ARDUINO LIBRARIES (ESP32 Compatible Libraries) ============================//
|
||
// You will have to download and install the following libraries below in order to program the MPPT //
|
||
// unit. Visit TechBuilder's YouTube channel for the "MPPT" tutorial. //
|
||
//============================================================================================= ====//
|
||
#include <EEPROM.h> //SYSTEM PARAMETER - EEPROM Library (By: Arduino)
|
||
#include <Wire.h> //SYSTEM PARAMETER - WIRE Library (By: Arduino)
|
||
#include <SPI.h> //SYSTEM PARAMETER - SPI Library (By: Arduino)
|
||
#include <WiFi.h> //SYSTEM PARAMETER - WiFi Library (By: Arduino)
|
||
#include <WiFiClient.h> //SYSTEM PARAMETER - WiFi Library (By: Arduino)
|
||
//#include <BlynkSimpleEsp32.h> //SYSTEM PARAMETER - Blynk WiFi Library For Phone App
|
||
#define BLINKER_WIFI
|
||
#define BLINKER_ALIGENIE_OUTLET
|
||
#define BLINKER_WITHOUT_SSL
|
||
#define BLINKER_ALIGENIE_SENSOR
|
||
#include <Blinker.h> //#define BLINKER_ESP_SMARTCONFIG
|
||
#include <LiquidCrystal_I2C.h> //系统参数 - ESP32 LCD 兼容库(作者:Frank de Brabander)
|
||
#include <ArduinoOTA.h>
|
||
//#include <Adafruit_ADS1X15.h> //SYSTEM PARAMETER - ADS1115/ADS1015 ADC Library (By: Adafruit)
|
||
#include <INA226.h>
|
||
LiquidCrystal_I2C lcd(0x27, 20, 4); //系统参数 - 配置 LCD RowCol 大小和 I2C 地址
|
||
TaskHandle_t Core2; //SYSTEM PARAMETER - Used for the ESP32 dual core operation
|
||
//Adafruit_ADS1015 ads; //SYSTEM PARAMETER - ADS1015 ADC Library (By: Adafruit) Kindly delete this line if you are using ADS1115
|
||
//Adafruit_ADS1115 ads; //SYSTEM PARAMETER - ADS1115 ADC Library (By: Adafruit) Kindly uncomment this if you are using ADS1115
|
||
INA226 ina1;
|
||
INA226 ina2;
|
||
#include <time.h>
|
||
#define timezone 8
|
||
|
||
BlinkerNumber Num1("num-9y2");
|
||
BlinkerNumber Num2("num-m2k");
|
||
BlinkerNumber Num3("num-5up");
|
||
BlinkerNumber Num4("num-ahb");
|
||
BlinkerNumber Num5("num-l24");
|
||
BlinkerNumber Num6("num-3bm");
|
||
BlinkerNumber Num7("num-rgu");
|
||
BlinkerNumber Num8("num-ao5");
|
||
BlinkerNumber Num9("num-ycz");
|
||
|
||
BlinkerButton Button1("btn-e6n");
|
||
BlinkerButton Button2("btn-e3t");
|
||
BlinkerButton Button3("btn-ogw");
|
||
BlinkerButton Button4("btn-q4l");
|
||
|
||
|
||
//====================================== USER PARAMETERS ===========================================//
|
||
//下面的参数是没有MPPT充电器设置时使用的默认参数 //
|
||
//通过 LCD 菜单界面或手机 WiFi 应用程序设置或保存。这里的一些参数//
|
||
//将允许您覆盖或解锁高级用户的功能(不在 LCD 菜单上的设置)//
|
||
//==================================================================================================//
|
||
#define backflow_MOSFET 27 //SYSTEM PARAMETER - Backflow MOSFET
|
||
#define buck_IN 33 //SYSTEM PARAMETER - Buck MOSFET Driver PWM Pin
|
||
#define buck_EN 32 //SYSTEM PARAMETER - Buck MOSFET Driver Enable Pin
|
||
#define LED 2 //SYSTEM PARAMETER - LED Indicator GPIO Pin
|
||
#define FAN 16 //SYSTEM PARAMETER - Fan GPIO Pin
|
||
//#define ADC_ALERT 35 //SYSTEM PARAMETER - ADC_ALERT GPIO Pin
|
||
#define INA1_ALERT 35 //SYSTEM PARAMETER - INA226 Alert GPIO Pin
|
||
#define INA2_ALERT 34 //SYSTEM PARAMETER - INA226 Alert GPIO Pin
|
||
#define TempSensor 39 //SYSTEM PARAMETER - Temperature Sensor GPIO Pin
|
||
#define buttonLeft 18 //SYSTEM PARAMETER -
|
||
#define buttonRight 19 //SYSTEM PARAMETER -
|
||
#define buttonBack 17 //SYSTEM PARAMETER -
|
||
#define buttonSelect 23 //SYSTEM PARAMETER -
|
||
|
||
#define eeprom_size 4096
|
||
|
||
#define MPPT_Mode_add 2448 // charging mode setting
|
||
#define voltageBatteryMax_add 2449 // Max Battery Voltage (whole)
|
||
#define voltageBatteryMax2_add 2450 // Max Battery Voltage (decimal)
|
||
#define voltageBatteryMin_add 2451 // Min Battery Voltage (whole)
|
||
#define voltageBatteryMin2_add 2452 // Min Battery Voltage (decimal)
|
||
#define currentCharging_add 2453 // Charging Current (whole)
|
||
#define currentCharging2_add 2454 // Charging Current (decimal)
|
||
#define enableFan_add 2455 // Fan Enable (Bool)
|
||
#define temperatureFan_add 2456 // Fan Temp (Integer)
|
||
#define temperatureMax_add 2457 // Shutdown Temp (Integer)
|
||
#define enableWiFi_add 2458 // Enable WiFi (Boolean)
|
||
#define flashMemLoad_add 2459 // Enable autoload (on by default)
|
||
#define output_Mode_add 2460 // Charger/PSU Mode Selection (1 = Charger Mode)
|
||
#define backlightSleepMode_add 2461 // LCD backlight sleep timer (default: 0 = never)
|
||
|
||
//========================================= WiFi SSID ==============================================//
|
||
// This MPPT firmware uses the Blynk phone app and arduino library for controls and data telemetry //
|
||
// Fill in your WiFi SSID and password. You will also have to get your own authentication token //
|
||
// from email after registering from the Blynk platform. //
|
||
//==================================================================================================//
|
||
char
|
||
auth[] = "InputBlynkAuthenticationToken", // USER PARAMETER - Input Blynk Authentication Token (From email after registration)
|
||
ssid[] = "", // USER PARAMETER - Enter Your WiFi SSID
|
||
pass[] = ""; // USER PARAMETER - Enter Your WiFi Password
|
||
const char *blinker_id = ""; //Blinker ID
|
||
//====================================== USER PARAMETERS ==========================================//
|
||
//下面的参数是没有MPPT充电器设置时使用的默认参数 //
|
||
//通过 LCD 菜单界面或手机 WiFi 应用程序设置或保存。这里的一些参数//
|
||
//将允许您覆盖或解锁高级用户的功能(不在 LCD 菜单上的设置)//
|
||
//=================================================================================================//
|
||
bool
|
||
MPPT_Mode = 1, // USER PARAMETER - 启用 MPPT 算法,当禁用充电器时使用 CC-CV 算法
|
||
output_Mode = 1, // USER PARAMETER - 0 = PSU 模式, 1 = 充电器模式
|
||
disableFlashAutoLoad = 0, // USER PARAMETER - 强制 MPPT 不使用闪存保存的设置,启用此“1”默认为已编程的固件设置
|
||
enablePPWM = 1, // USER PARAMETER - 启用预测 PWM,这加快了调节速度(仅适用于电池充电应用)
|
||
enableWiFi = 1, // USER PARAMETER - 启用 WiFi 连接
|
||
enableFan = 1, // USER PARAMETER - 启用冷却风扇
|
||
enableBluetooth = 1, // USER PARAMETER - 启用蓝牙连
|
||
enableLCD = 1, // USER PARAMETER - 启用 接LCD 显示
|
||
enableLCDBacklight = 1, // USER PARAMETER - 启用 LCD 显示器的背光
|
||
overrideFan = 0, // USER PARAMETER - 风扇始终开启
|
||
enableDynamicCooling = 0; // USER PARAMETER - 启用 PWM 冷却控制
|
||
int
|
||
serialTelemMode = 1, // USER PARAMETER - 选择串行遥测数据馈送(0 - 禁用串行,1 - 显示所有数据,2 - 显示基本,3 - 仅数字)
|
||
pwmResolution = 11, // USER PARAMETER - PWM 位分辨率
|
||
pwmFrequency = 39000, // USER PARAMETER - PWM 开关频率 - Hz(用于降压)
|
||
temperatureFan = 60, // USER PARAMETER - 风扇开启的温度阈值
|
||
temperatureMax = 90, // USER PARAMETER - 过热,超过时系统关闭(摄氏度)
|
||
telemCounterReset = 0, // USER PARAMETER - 每隔一次重置 Telem 数据(0 = 从不,1 = 日,2 = 周,3 = 月,4 = 年)
|
||
errorTimeLimit = 1000, // USER PARAMETER - 重置错误计数器的时间间隔(毫秒)
|
||
errorCountLimit = 5, // USER PARAMETER - 最大错误数
|
||
millisRoutineInterval = 250, // USER PARAMETER - 例程函数的时间间隔刷新率 (ms)
|
||
millisSerialInterval = 5, // USER PARAMETER - USB 串行数据馈送的时间间隔刷新率 (ms)
|
||
millisLCDInterval = 1000, // USER PARAMETER - LCD 显示器的时间间隔刷新率 (ms)
|
||
millisWiFiInterval = 1000, // USER PARAMETER - WiFi 遥测的时间间隔刷新率 (ms)
|
||
millisLCDBackLInterval = 1000, // USER PARAMETER - 用户参数 - WiFi 遥测的时间间隔刷新率 (ms)
|
||
backlightSleepMode = 2, // USER PARAMETER - - 0 = 从不, 1 = 10 秒, 2 = 5 分钟, 3 = 1 小时, 4 = 6 小时, 5 = 12 小时, 6 = 1 天, 7 = 3 天, 8 = 1 周, 9 = 1个月
|
||
baudRate = 500000; // 用户参数 - USB 串行波特率 (bps)
|
||
|
||
float
|
||
voltageBatteryMax = 12.6000, // USER PARAMETER - 最大电池充电电压(输出 V)
|
||
voltageBatteryMin = 3.0000, // USER PARAMETER - 最小电池充电电压(输出 V)
|
||
currentCharging = 1.0000, // USER PARAMETER - 最大充电电流(A - 输出)
|
||
electricalPrice = 0.6000; // USER PARAMETER - 每千瓦时的输入电价
|
||
|
||
|
||
//================================== CALIBRATION PARAMETERS =======================================//
|
||
//可以调整以下参数以设计您自己的 MPPT 充电控制器。只修改 //
|
||
//如果你知道你在做什么,下面的值。以下值已针对 // 进行了预校准
|
||
// TechBuilder (Angelo S. Casimiro) 设计的 MPPT 充电控制器 // //
|
||
//=================================================================================================//
|
||
const bool
|
||
ADS1015_Mode = 1; // CALIB PARAMETER - Use 1 for ADS1015 ADC model use 0 for ADS1115 ADC model
|
||
const int
|
||
ADC_GainSelect = 2, // 校准参数 - ADC 增益选择 (0→±6.144V 3mV/bit, 1→±4.096V 2mV/bit, 2→±2.048V 1mV/bit)
|
||
avgCountVS = 3, // 校准参数 - 电压传感器平均采样计数(推荐:3)
|
||
avgCountCS = 4, // 校准参数 - 电流传感器平均采样计数(推荐:4)
|
||
avgCountTS = 500; // 校准参数 - 温度传感器平均采样计数
|
||
float
|
||
inVoltageDivRatio = 2.9784, // 校准参数 - 输入分压器传感器比率(更改此值以校准电压传感器)
|
||
outVoltageDivRatio = 2.8275, // 校准参数 - 输出分压器传感器比率(更改此值以校准电压传感器)
|
||
vOutSystemMax = 80.0000, // 校准参数 - 最大输入电压
|
||
cOutSystemMax = 50.0000, // 校准参数 - 最大输出电压
|
||
ntcResistance = 10000.00, // 校准参数 - NTC 温度传感器的电阻。如果您使用 10k NTC,请更改为 10000.00
|
||
voltageDropout = 1.0000, // 校准参数 - 降压稳压器的压降电压(由于最大占空比限制而存在 DOV)
|
||
voltageBatteryThresh = 1.5000, // 校准参数 - 达到此电压时断电(输出 V)
|
||
currentInAbsolute = 31.0000, // 校准参数 - 系统可以处理的最大输入电流(A - 输入)
|
||
currentOutAbsolute = 50.0000, // 校准参数 - 系统可以处理的最大输出电流(A - 输入)
|
||
PPWM_margin = 99.5000, // 校准参数 - 预测 PWM 的最小工作占空比 (%)
|
||
PWM_MaxDC = 97.0000, // 校准参数 - 最大工作占空比 (%) 90%-97% 是好的
|
||
efficiencyRate = 1.0000, // 校准参数 - 理论降压效率(十进制百分比)
|
||
currentMidPoint = 2.5250, // 校准参数 - 电流传感器中点 (V)
|
||
currentSens = 0.0000, // 校准参数 - 电流传感器灵敏度 (V/A)
|
||
currentSensV = 0.0330, // 校准参数 - 电流传感器灵敏度 (mV/A)
|
||
vInSystemMin = 8.000; // 校准参数 - 系统识别最低电压
|
||
|
||
//===================================== SYSTEM PARAMETERS =========================================//
|
||
//不要更改本节中的参数值。下面的值是系统使用的变量 //
|
||
//进程。更改值可能会损坏 MPPT 硬件。请保持原样!然而, //
|
||
//您可以访问这些变量来获取您的模组所需的数据。//
|
||
//=================================================================================================//
|
||
bool
|
||
buckEnable = 0, // SYSTEM PARAMETER - Buck Enable Status
|
||
fanStatus = 0, // SYSTEM PARAMETER - Fan activity status (1 = On, 0 = Off)
|
||
bypassEnable = 0, // SYSTEM PARAMETER -
|
||
chargingPause = 0, // SYSTEM PARAMETER -
|
||
lowPowerMode = 0, // SYSTEM PARAMETER -
|
||
buttonRightStatus = 0, // SYSTEM PARAMETER -
|
||
buttonLeftStatus = 0, // SYSTEM PARAMETER -
|
||
buttonBackStatus = 0, // SYSTEM PARAMETER -
|
||
buttonSelectStatus = 0, // SYSTEM PARAMETER -
|
||
buttonRightCommand = 0, // SYSTEM PARAMETER -
|
||
buttonLeftCommand = 0, // SYSTEM PARAMETER -
|
||
buttonBackCommand = 0, // SYSTEM PARAMETER -
|
||
buttonSelectCommand = 0, // SYSTEM PARAMETER -
|
||
settingMode = 0, // SYSTEM PARAMETER -
|
||
setMenuPage = 0, // SYSTEM PARAMETER -
|
||
boolTemp = 0, // SYSTEM PARAMETER -
|
||
flashMemLoad = 0, // SYSTEM PARAMETER -
|
||
confirmationMenu = 0, // SYSTEM PARAMETER -
|
||
WIFI = 0, // SYSTEM PARAMETER -
|
||
BNC = 0, // SYSTEM PARAMETER -
|
||
REC = 0, // SYSTEM PARAMETER -
|
||
FLV = 0, // SYSTEM PARAMETER -
|
||
IUV = 0, // SYSTEM PARAMETER -
|
||
IOV = 0, // SYSTEM PARAMETER -
|
||
IOC = 0, // SYSTEM PARAMETER -
|
||
OUV = 0, // SYSTEM PARAMETER -
|
||
OOV = 0, // SYSTEM PARAMETER -
|
||
OOC = 0, // SYSTEM PARAMETER -
|
||
OTE = 0; // SYSTEM PARAMETER -
|
||
int
|
||
inputSource = 0, // SYSTEM PARAMETER - 0 = MPPT 没有电源,1 = MPPT 使用太阳能作为电源,2 = MPPT 使用电池作为电源
|
||
avgStoreTS = 0, // SYSTEM PARAMETER - 温度传感器使用非侵入式平均,这是用于平均平均的累加器
|
||
temperature = 0, // SYSTEM PARAMETER -
|
||
sampleStoreTS = 0, // SYSTEM PARAMETER - TS AVG 第 n 个样本
|
||
pwmMax = 0, // SYSTEM PARAMETER -
|
||
pwmMaxLimited = 0, // SYSTEM PARAMETER -
|
||
PWM = 0, // SYSTEM PARAMETER -
|
||
PPWM = 0, // SYSTEM PARAMETER -
|
||
pwmChannel = 0, // SYSTEM PARAMETER -
|
||
batteryPercent = 0, // SYSTEM PARAMETER -
|
||
errorCount = 0, // SYSTEM PARAMETER -
|
||
menuPage = 0, // SYSTEM PARAMETER -
|
||
subMenuPage = 0, // SYSTEM PARAMETER -
|
||
ERR = 0, // SYSTEM PARAMETER -
|
||
conv1 = 0, // SYSTEM PARAMETER -
|
||
conv2 = 0, // SYSTEM PARAMETER -
|
||
intTemp = 0; // SYSTEM PARAMETER -
|
||
float
|
||
VSI = 0.0000, // SYSTEM PARAMETER - 原始输入电压传感器 ADC 电压
|
||
VSO = 0.0000, // SYSTEM PARAMETER - 原始输出电压传感器 ADC 电压
|
||
CSI = 0.0000, // SYSTEM PARAMETER - 原始电流传感器 ADC 电压
|
||
CSO = 0.0000, // SYSTEM PARAMETER - Raw current sensor ADC voltage
|
||
CSI_converted = 0.0000, // SYSTEM PARAMETER - 实际电流传感器 ADC 电压
|
||
CSO_converted = 0.0000, // SYSTEM PARAMETER - Actual current sensor ADC voltage
|
||
TS = 0.0000, // SYSTEM PARAMETER - 原始温度传感器 ADC 值
|
||
powerInput = 0.0000, // SYSTEM PARAMETER - 输入功率(太阳能)以瓦特为单位
|
||
powerInputPrev = 0.0000, // SYSTEM PARAMETER - 先前存储的 MPPT 算法的输入功率变量(瓦特)
|
||
powerOutput = 0.0000, // SYSTEM PARAMETER - 输出功率(电池或充电功率,以瓦特为单位)
|
||
energySavings = 0.0000, // SYSTEM PARAMETER - 法定货币(比索、美元、欧元等)的能源节约
|
||
voltageInput = 0.0000, // SYSTEM PARAMETER - 输入电压(太阳能电压)
|
||
voltageInputPrev = 0.0000, // SYSTEM PARAMETER - 先前存储的 MPPT 算法的输入电压变量
|
||
voltageOutput = 0.0000, // SYSTEM PARAMETER - 输入电压(电池电压)
|
||
currentInput = 0.0000, // SYSTEM PARAMETER - 输出功率(电池或充电电压)
|
||
currentOutput = 0.0000, // SYSTEM PARAMETER - 输出电流(电池或充电电流,以安培为单位)
|
||
TSlog = 0.0000, // SYSTEM PARAMETER - NTC 热敏电阻热感应代码的一部分
|
||
ADC_BitReso = 0.0000, // SYSTEM PARAMETER - 系统检测 ADS1015/ADS1115 ADC 的适当位分辨率因子
|
||
daysRunning = 0.0000, // SYSTEM PARAMETER - 存储 MPPT 设备自上次通电以来运行的总天数
|
||
Wh = 0.0000, // SYSTEM PARAMETER - 存储收集到的累积能量(瓦特小时)
|
||
kWh = 0.0000, // SYSTEM PARAMETER - 存储收集到的累积能量(千瓦时)
|
||
MWh = 0.0000, // SYSTEM PARAMETER - 存储收集到的累积能量(兆瓦时)
|
||
loopTime = 0.0000, // SYSTEM PARAMETER -
|
||
outputDeviation = 0.0000, // SYSTEM PARAMETER - 输出电压偏差 (%)
|
||
buckEfficiency = 0.0000, // SYSTEM PARAMETER - 测量降压转换器功率转换效率(仅适用于我的双电流传感器版本)
|
||
floatTemp = 0.0000,
|
||
vOutSystemMin = 0.0000; // CALIB PARAMETER -
|
||
unsigned long
|
||
currentErrorMillis = 0, //SYSTEM PARAMETER -
|
||
currentButtonMillis = 0, //SYSTEM PARAMETER -
|
||
currentSerialMillis = 0, //SYSTEM PARAMETER -
|
||
currentRoutineMillis = 0, //SYSTEM PARAMETER -
|
||
currentLCDMillis = 0, //SYSTEM PARAMETER -
|
||
currentLCDBackLMillis = 0, //SYSTEM PARAMETER -
|
||
currentWiFiMillis = 0, //SYSTEM PARAMETER -
|
||
currentMenuSetMillis = 0, //SYSTEM PARAMETER -
|
||
prevButtonMillis = 0, //SYSTEM PARAMETER -
|
||
prevSerialMillis = 0, //SYSTEM PARAMETER -
|
||
prevRoutineMillis = 0, //SYSTEM PARAMETER -
|
||
prevErrorMillis = 0, //SYSTEM PARAMETER -
|
||
prevWiFiMillis = 0, //SYSTEM PARAMETER -
|
||
prevLCDMillis = 0, //SYSTEM PARAMETER -
|
||
prevLCDBackLMillis = 0, //SYSTEM PARAMETER -
|
||
timeOn = 0, //SYSTEM PARAMETER -
|
||
loopTimeStart = 0, //SYSTEM PARAMETER - 用于循环循环秒表,记录循环开始时间
|
||
loopTimeEnd = 0, //SYSTEM PARAMETER - 用于循环循环秒表,记录循环结束时间
|
||
secondsElapsed = 0; //SYSTEM PARAMETER -
|
||
|
||
//====================================== MAIN PROGRAM =============================================//
|
||
// The codes below contain all the system processes for the MPPT firmware. Most of them are called //
|
||
// from the 8 .ino tabs. The codes are too long, Arduino tabs helped me a lot in organizing them. //
|
||
// The firmware runs on two cores of the Arduino ESP32 as seen on the two separate pairs of void //
|
||
// setups and loops. The xTaskCreatePinnedToCore() freeRTOS function allows you to access the //
|
||
// unused ESP32 core through Arduino. Yes it does multicore processes simultaneously! //
|
||
//=================================================================================================//
|
||
|
||
void dataRead(const String &data)
|
||
{
|
||
BLINKER_LOG("Blinker readString: ", data);
|
||
}
|
||
|
||
void heartbeat()
|
||
{
|
||
Num1.print(powerInput);
|
||
Num2.print(voltageInput);
|
||
Num3.print(currentInput);
|
||
Num4.print(batteryPercent);
|
||
Num5.print(voltageOutput);
|
||
Num6.print(currentOutput);
|
||
Num7.print(Wh/1000);
|
||
Num8.print(electricalPrice);
|
||
Num9.print(temperature);
|
||
|
||
if(buckEnable==1){Button1.print("off");}else{Button1.print("on");}
|
||
if(batteryPercent >= 99){Button2.print("off");}else{Button2.print("on");}
|
||
if(batteryPercent <= 10){Button3.print("off");}else{Button3.print("on");}
|
||
if(IUV == 0){Button4.print("off");}else{Button4.print("on");}
|
||
|
||
}
|
||
void dataStorage()
|
||
{
|
||
Blinker.dataStorage("data-1", powerInput); //数据组件名,数据值
|
||
Blinker.dataStorage("data-2", voltageInput);
|
||
Blinker.dataStorage("data-3", currentInput);
|
||
Blinker.dataStorage("data-4", powerOutput);
|
||
Blinker.dataStorage("data-5", voltageOutput);
|
||
Blinker.dataStorage("data-6", currentOutput);
|
||
}
|
||
|
||
//================= CORE0: SETUP (DUAL CORE MODE) =====================//
|
||
void coreTwo(void * pvParameters) {
|
||
setupWiFi(); //TAB#7 - WiFi Initialization
|
||
//================= CORE0: LOOP (DUAL CORE MODE) ======================//
|
||
while (1) {
|
||
Wireless_Telemetry(); //TAB#7 - Wireless telemetry (WiFi & Bluetooth)
|
||
|
||
}
|
||
}
|
||
//================== CORE1: SETUP (DUAL CORE MODE) ====================//
|
||
void setup() {
|
||
|
||
//SERIAL INITIALIZATION
|
||
Serial.begin(baudRate); //Set serial baud rate
|
||
Serial.println("> Serial Initialized"); //Startup message
|
||
BLINKER_DEBUG.stream(Serial);
|
||
|
||
//GPIO PIN INITIALIZATION
|
||
pinMode(backflow_MOSFET, OUTPUT);
|
||
pinMode(buck_EN, OUTPUT);
|
||
pinMode(LED, OUTPUT);
|
||
pinMode(FAN, OUTPUT);
|
||
pinMode(TS, INPUT);
|
||
//pinMode(ADC_ALERT,INPUT);
|
||
pinMode(INA1_ALERT, INPUT);
|
||
pinMode(INA2_ALERT, INPUT);
|
||
pinMode(buttonLeft, INPUT);
|
||
pinMode(buttonRight, INPUT);
|
||
pinMode(buttonBack, INPUT);
|
||
pinMode(buttonSelect, INPUT);
|
||
|
||
//PWM INITIALIZATION
|
||
ledcSetup(pwmChannel, pwmFrequency, pwmResolution); //Set PWM Parameters
|
||
ledcAttachPin(buck_IN, pwmChannel); //Set pin as PWM
|
||
ledcWrite(pwmChannel, PWM); //Write PWM value at startup (duty = 0)
|
||
pwmMax = pow(2, pwmResolution) - 1; //Get PWM Max Bit Ceiling
|
||
pwmMaxLimited = (PWM_MaxDC * pwmMax) / 100.000; //Get maximum PWM Duty Cycle (pwm limiting protection)
|
||
|
||
//ADC INITIALIZATION
|
||
//ADC_SetGain(); //Sets ADC Gain & Range
|
||
//ads.begin(); //Initialize ADC
|
||
Serial.println("Initialize INA226 Slave1 0x40 A1 GND A0 GND");
|
||
Serial.println("-----------------------------------------------");
|
||
|
||
// Default INA226 address is 0x40
|
||
ina1.begin();
|
||
|
||
// Configure INA226
|
||
ina1.configure(INA226_AVERAGES_4, INA226_BUS_CONV_TIME_588US, INA226_SHUNT_CONV_TIME_588US, INA226_MODE_SHUNT_BUS_CONT);
|
||
|
||
// Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A
|
||
ina1.calibrate(0.002, 40);
|
||
|
||
// Display configuration
|
||
checkConfig(ina1);
|
||
|
||
Serial.println("-----------------------------------------------");
|
||
|
||
Serial.println("Initialize INA226 Slave2 0x41");
|
||
Serial.println("-----------------------------------------------");
|
||
|
||
// Default INA226 address is 0x40
|
||
ina2.begin(0x41);
|
||
|
||
// Configure INA226
|
||
ina2.configure(INA226_AVERAGES_4, INA226_BUS_CONV_TIME_588US, INA226_SHUNT_CONV_TIME_588US, INA226_MODE_SHUNT_BUS_CONT);
|
||
|
||
// Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A
|
||
ina2.calibrate(0.002, 40);
|
||
|
||
// Display configuration
|
||
checkConfig(ina2);
|
||
|
||
Serial.println("-----------------------------------------------");
|
||
|
||
//GPIO INITIALIZATION
|
||
buck_Disable();
|
||
|
||
//ENABLE DUAL CORE MULTITASKING
|
||
xTaskCreatePinnedToCore(coreTwo, "coreTwo", 10000, NULL, 0, &Core2, 0);
|
||
|
||
//INITIALIZE AND LIOAD FLASH MEMORY DATA
|
||
EEPROM.begin(eeprom_size);
|
||
Serial.println("> FLASH MEMORY: STORAGE INITIALIZED"); //Startup message
|
||
initializeFlashAutoload(); //Load stored settings from flash memory
|
||
Serial.println("> FLASH MEMORY: SAVED DATA LOADED"); //Startup message
|
||
|
||
//LCD INITIALIZATION
|
||
if (enableLCD == 1) {
|
||
lcd.begin(16, 2);
|
||
lcd.setBacklight(HIGH);
|
||
lcd.setCursor(0, 0);
|
||
lcd.print("MPPT INIT");
|
||
lcd.setCursor(0, 1);
|
||
lcd.print("FIRMWARE ");
|
||
lcd.print(firmwareInfo);
|
||
delay(1500);
|
||
lcd.clear();
|
||
}
|
||
|
||
uint32_t chipId = 0;
|
||
for (int i = 0; i < 17; i = i + 8) {
|
||
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||
}
|
||
Serial.printf("Chip ID: %d\r\n", chipId);
|
||
|
||
Serial.printf("ESP32 Chip ID = %04X", (uint16_t)(ESP.getEfuseMac() >> 32)); //print High 2 bytes
|
||
Serial.printf("%08X\r\n", (uint32_t)ESP.getEfuseMac()); //print Low 4bytes.
|
||
|
||
Serial.printf("Chip model = %s Rev %d\r\n", ESP.getChipModel(), ESP.getChipRevision());
|
||
Serial.printf("This chip has %d cores CpuFreqMHz = %u\r\n", ESP.getChipCores(), ESP.getCpuFreqMHz());
|
||
Serial.printf("get Cycle Count = %u\r\n", ESP.getCycleCount());
|
||
Serial.printf("SDK version:%s\r\n", ESP.getSdkVersion()); //获取IDF版本
|
||
|
||
//获取片内内存 Internal RAM
|
||
Serial.printf("Total heap size = %u\t", ESP.getHeapSize());
|
||
Serial.printf("Available heap = %u\r\n", ESP.getFreeHeap());
|
||
Serial.printf("Lowest level of free heap since boot = %u\r\n", ESP.getMinFreeHeap());
|
||
Serial.printf("Largest block of heap that can be allocated at once = %u\r\n", ESP.getMaxAllocHeap());
|
||
|
||
//SPI RAM
|
||
Serial.printf("Total Psram size = %u\t", ESP.getPsramSize());
|
||
Serial.printf("Available Psram = %u\r\n", ESP.getFreePsram());
|
||
Serial.printf("Lowest level of free Psram since boot = %u\r\n", ESP.getMinFreePsram());
|
||
Serial.printf("Largest block of Psram that can be allocated at once = %u\r\n", ESP.getMinFreePsram());
|
||
|
||
byte mac[6];
|
||
WiFi.macAddress(mac);
|
||
printf("macAddress 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||
|
||
//以下是启动OTA,可以通过WiFi刷新固件
|
||
ArduinoOTA.setHostname("ESP32_MPPT");
|
||
// No authentication by default
|
||
// ArduinoOTA.setPassword("admin");
|
||
|
||
// Password can be set with it's md5 value as well
|
||
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
|
||
ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
|
||
ArduinoOTA.onStart([]() {
|
||
String type;
|
||
if (ArduinoOTA.getCommand() == U_FLASH) {
|
||
type = "sketch";
|
||
} else { // U_SPIFFS
|
||
type = "filesystem";
|
||
}
|
||
|
||
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
|
||
Serial.println("Start updating " + type);
|
||
});
|
||
ArduinoOTA.onEnd([]() {
|
||
Serial.println("\nEnd");
|
||
});
|
||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||
});
|
||
ArduinoOTA.onError([](ota_error_t error) {
|
||
Serial.printf("Error[%u]: ", error);
|
||
if (error == OTA_AUTH_ERROR) {
|
||
Serial.println("Auth Failed");
|
||
} else if (error == OTA_BEGIN_ERROR) {
|
||
Serial.println("Begin Failed");
|
||
} else if (error == OTA_CONNECT_ERROR) {
|
||
Serial.println("Connect Failed");
|
||
} else if (error == OTA_RECEIVE_ERROR) {
|
||
Serial.println("Receive Failed");
|
||
} else if (error == OTA_END_ERROR) {
|
||
Serial.println("End Failed");
|
||
}
|
||
});
|
||
ArduinoOTA.begin();
|
||
Serial.println("OTA Ready");
|
||
|
||
|
||
//设置时间格式以及时间服务器的网址
|
||
configTime(timezone * 3600, 0, "pool.ntp.org", "time.nist.gov");
|
||
Serial.println("\nWaiting for time");
|
||
while (!time(nullptr)) {
|
||
Serial.print(".");
|
||
delay(1000);
|
||
}
|
||
|
||
//SETUP FINISHED
|
||
Serial.println("> MPPT HAS INITIALIZED"); //Startup message
|
||
|
||
}
|
||
unsigned long TenthSecondsSinceStart = 0;
|
||
unsigned long LastMillis = 0;
|
||
char DateTimeStr[20];
|
||
|
||
void OnSecond()
|
||
{
|
||
time_t now = time(nullptr); //获取当前时间
|
||
|
||
//转换成年月日的数字,可以更加自由的显示。
|
||
struct tm* timenow;
|
||
timenow = localtime(&now);
|
||
unsigned char tempHour = timenow->tm_hour;
|
||
unsigned char tempMinute = timenow->tm_min;
|
||
unsigned char tempSecond = timenow->tm_sec;
|
||
unsigned char tempDay = timenow->tm_mday;
|
||
unsigned char tempMonth = timenow->tm_mon + 1;
|
||
unsigned int tempYear = timenow->tm_year + 1900;
|
||
unsigned char tempWeek = timenow->tm_wday;
|
||
|
||
//生成 年月日时分秒 字符串。
|
||
sprintf(DateTimeStr, "%d-%02d-%02d %02d:%02d:%02d"
|
||
, tempYear
|
||
, tempMonth
|
||
, tempDay
|
||
, tempHour
|
||
, tempMinute
|
||
, tempSecond
|
||
);
|
||
|
||
}
|
||
|
||
void OnTenthSecond() // 100ms 十分之一秒
|
||
{
|
||
|
||
if (TenthSecondsSinceStart % 3 == 0) //0.3S刷新数据,
|
||
{
|
||
//读取采样数据1
|
||
|
||
//voltageInput = ina1.readBusVoltage()*(R1_VOLTAGE1+R2_VOLTAGE1)/R1_VOLTAGE1;
|
||
//voltageOutput = ina2.readBusVoltage()*(R1_VOLTAGE2+R2_VOLTAGE2)/R1_VOLTAGE2;
|
||
|
||
//读取采样数据2
|
||
|
||
//CSI_converted = ina1.readShuntCurrent();
|
||
//CSO_converted = ina2.readShuntCurrent();
|
||
}
|
||
|
||
if (TenthSecondsSinceStart % 10 == 0) //10次为1秒
|
||
{
|
||
OnSecond();
|
||
}
|
||
}
|
||
|
||
void TenthSecondsSinceStartTask() //100ms
|
||
{
|
||
unsigned long CurrentMillis = millis();
|
||
if (abs(int(CurrentMillis - LastMillis)) > 100)
|
||
{
|
||
LastMillis = CurrentMillis;
|
||
TenthSecondsSinceStart++;
|
||
OnTenthSecond();
|
||
}
|
||
}
|
||
|
||
//================== CORE1: LOOP (DUAL CORE MODE) ======================//
|
||
void loop() {
|
||
ArduinoOTA.handle();
|
||
|
||
TenthSecondsSinceStartTask();
|
||
|
||
Read_Sensors(); //TAB#2 - Sensor data measurement and computation
|
||
Device_Protection(); //TAB#3 - Fault detection algorithm
|
||
System_Processes(); //TAB#4 - Routine system processes
|
||
Charging_Algorithm(); //TAB#5 - Battery Charging Algorithm
|
||
Onboard_Telemetry(); //TAB#6 - Onboard telemetry (USB & Serial Telemetry)
|
||
LCD_Menu(); //TAB#8 - Low Power Algorithm
|
||
}
|