FOSSASAT-1B
Loading...
Searching...
No Matches
power_control.cpp
1#include "power_control.h"
2
3powerConfigBits_t powerConfigBits = {
4 .lowPowerModeActive = LOW_POWER_MODE_ACTIVE,
5 .lowPowerModeEnabled = LOW_POWER_MODE_ENABLED,
6 .mpptTempSwitchEnabled = MPPT_TEMP_SWITCH_ENABLED,
7 .mpptKeepAliveEnabled = MPPT_KEEP_ALIVE_ENABLED,
8 .transmitEnabled = TRANSMIT_ENABLED
9};
10
11powerConfig_t powerConfig = {
12 .bits = powerConfigBits
13};
14
15void Power_Control_Load_Configuration() {
17}
18
19void Power_Control_Save_Configuration() {
21}
22
23void Power_Control_Charge(bool charge) {
24 FOSSASAT_VERBOSE_PRINT(F("MPPT "));
25 FOSSASAT_VERBOSE_PRINTLN(charge);
26
27 Power_Control_Load_Configuration();
28 if(powerConfig.bits.mpptKeepAliveEnabled) {
29 // force MPPT to float regardless of anything else
30 FOSSASAT_VERBOSE_PRINTLN('K');
32 } else if((Pin_Interface_Read_Temperature(BATTERY_TEMP_SENSOR_ADDR) < BATTERY_TEMPERATURE_LIMIT) && powerConfig.bits.mpptTempSwitchEnabled) {
33 // force MPPT low, only if temperature switch is enabled
34 FOSSASAT_VERBOSE_PRINTLN('L');
37 } else if(charge){
38 // set MPPT to float
40 } else {
41 // set MPPT to low
44 }
45}
46
47uint32_t Power_Control_Get_Sleep_Interval() {
48 // sleep interval in ms (default for battery > 3.7 V)
50
51 #ifdef ENABLE_INTERVAL_CONTROL
52 // get battery voltage
53 float batt = Power_Control_Get_Battery_Voltage();
54
55 if(batt > 4.05f) {
56 interval = (uint32_t)20 * (uint32_t)1000;
57 } else if(batt > 4.0f) {
58 interval = (uint32_t)35 * (uint32_t)1000;
59 } else if(batt > 3.9f) {
60 interval = (uint32_t)100 * (uint32_t)1000;
61 } else if(batt > 3.8f) {
62 interval = (uint32_t)160 * (uint32_t)1000;
63 } else if(batt > 3.7f) {
64 interval = (uint32_t)180 * (uint32_t)1000;
65 } else {
66 interval = (uint32_t)240 * (uint32_t)1000;
67 }
68 #endif
69
70 return(interval);
71}
72
73void Power_Control_Delay(uint32_t ms, bool sleep, bool sleepRadio) {
74 if(ms == 0) {
75 return;
76 }
77
78 // calculate number of required loops (rounded up)
79 float numLoops = 0.5f;
80 if(sleep) {
81 numLoops += (float)ms / 500.0;
82 } else {
83 numLoops += (float)ms / 50.0;
84 }
85
86 // set radio to sleep
87 if(sleepRadio) {
88 radio.sleep();
89 }
90
91 // perform all loops
92 for(uint32_t i = 0; i < (uint32_t)numLoops; i++) {
93 Pin_Interface_Watchdog_Heartbeat();
94 if(sleep) {
96 } else {
97 delay(50);
98 }
99
100 }
101
102 // wake up radio
103 if(sleepRadio) {
104 radio.standby();
105 }
106}
107
108void Power_Control_Setup_INA226() {
109 ina.begin(INA_ADDR);
111 ina.calibrate(INA_RSHUNT, INA_MAX_CURRENT);
112}
113
114bool Power_Control_INA226_Check() {
115 // attempt to read manufacturer ID register
116 Wire.beginTransmission(INA_ADDR);
118 Wire.endTransmission();
119 delay(1);
120
121 // try to read
122 Wire.requestFrom((uint8_t)INA_ADDR, (uint8_t)2);
123 if(Wire.available() != 2) {
124 return(false);
125 }
126
127 // check value
128 uint8_t vha = Wire.read();
129 uint8_t vla = Wire.read();
130 uint16_t value = vha << 8 | vla;
131
133 return(false);
134 }
135
136 return(true);
137}
138
139float Power_Control_Get_Battery_Voltage() {
140 // try to switch MPPT off (may be overridden by MPPT keep alive)
141 Power_Control_Charge(false);
142
143 // get voltage
144 float val = -999;
145 if(Power_Control_INA226_Check()) {
146 val = ina.readBusVoltage();
147 }
148
149 // try to switch MPPT on (may be overridden by temperature check)
150 Power_Control_Charge(true);
151
152 return(val);
153}
154
155float Power_Control_Get_Charging_Voltage() {
156 if(!Power_Control_INA226_Check()) {
157 return(-999.0);
158 }
159 return(ina.readBusVoltage());
160}
161
162float Power_Control_Get_Charging_Current() {
163 if(!Power_Control_INA226_Check()) {
164 return(-999.0);
165 }
166 return(ina.readShuntCurrent());
167}
168
169bool Power_Control_Check_Battery_Limit() {
170 // load power configuration from EEPROM
171 Power_Control_Load_Configuration();
172
173 // check battery voltage
174 bool checkPassed = true;
175 if((Power_Control_Get_Battery_Voltage() <= BATTERY_VOLTAGE_LIMIT) && powerConfig.bits.lowPowerModeEnabled) {
176 // activate low power mode
177 powerConfig.bits.lowPowerModeActive = 1;
178 checkPassed = false;
179 } else {
180 // deactivate low power mode
181 powerConfig.bits.lowPowerModeActive = 0;
182 checkPassed = true;
183 }
184
185 // save power configuration to EEPROM
186 Power_Control_Save_Configuration();
187 return(checkPassed);
188}
#define MPPT_KEEP_ALIVE_ENABLED
#define TRANSMIT_ENABLED
#define LOW_POWER_MODE_ENABLED
#define MPPT_TEMP_SWITCH_ENABLED
#define LOW_POWER_MODE_ACTIVE
#define EEPROM_POWER_CONFIG_ADDR
SX1268 radio
INA226 ina
#define INA_REG_MANUFACTURER_ID
#define INA_MAX_CURRENT
#define INA_MANUFACTURER_ID
#define INA_ADDR
#define INA_RSHUNT
#define DIGITAL_OUT_MPPT_PIN
#define BATTERY_VOLTAGE_LIMIT
#define BATTERY_TEMPERATURE_LIMIT
#define BATTERY_TEMP_SENSOR_ADDR
T Persistent_Storage_Read(uint16_t addr)
This function reads a value of type T from EEPROM.
Power configuration strutcture, each entry is one bit long. Total 1 byte, lowPowerModeActive is the l...
Union to quickly access power configuration bits or the entire single-byte value.