board
Solar MPPT Power System
Public Unreviewedby TylerK
A 30 W solar battery charger with regulated 5 V and 3.3 V rails: an STM32G031 running perturb & observe MPPT and a CC/CV charge state machine, steering a TI LM5175 4-switch buck-boost through a single analog control input. Four-layer KiCad board, schematic and PCB generated from Python, with an electrothermal simulation run against the published board file.
main
#include "uart_telemetry.h"
#include "main.h" /* CubeMX-generated: huart1 handle */
#include <stdio.h>
#include <string.h>
static const char *state_name(charge_state_t s) {
switch (s) {
case CHG_STATE_BULK: return "BULK";
case CHG_STATE_ABSORPTION: return "ABSORPTION";
case CHG_STATE_FLOAT: return "FLOAT";
case CHG_STATE_FAULT: return "FAULT";
default: return "?";
}
}
/* Cortex-M0+ newlib-nano builds commonly ship without float printf support
* (it costs several KB of flash on a part with only 64KB total) -- format
* manually in millivolts/milliamps instead of linking a float formatter. */
static int fmt_milli(char *buf, int32_t milli) {
/* The sign has to be emitted separately. Integer division truncates
* toward zero, so for anything between -999 and -1 the whole part is 0
* and carries no sign of its own -- printing whole.frac would turn
* -0.250A of discharge into "0.250", reporting a battery that is being
* drained as one that is being charged. */
const char *sign = (milli < 0) ? "-" : "";
int32_t mag = (milli < 0) ? -milli : milli;
return sprintf(buf, "%s%ld.%03ld", sign, (long)(mag / 1000), (long)(mag % 1000));
}
void uart_telemetry_init(void) {
/* huart1 is brought up by CubeMX's MX_USART1_UART_Init(); nothing
* additional needed here. */
}
void uart_telemetry_send(uint32_t now_ms, const sensor_frame_t *s, const charge_control_t *cc) {
char line[160];
char vbatt_s[16], iin_s[16], ichg_s[16], cmd_s[16];
fmt_milli(vbatt_s, (int32_t)(s->vbatt * 1000.0f));
fmt_milli(iin_s, (int32_t)(s->iin * 1000.0f));
fmt_milli(ichg_s, (int32_t)(s->ichg * 1000.0f));
fmt_milli(cmd_s, (int32_t)(cc->commanded_vbatt * 1000.0f));
int n = snprintf(line, sizeof(line),
"t=%lu state=%s vbatt=%sV iin=%sA ichg=%sA cmd=%sV reason=%s pgood=%d,%d\r\n",
(unsigned long)now_ms, state_name(cc->state),
vbatt_s, iin_s, ichg_s, cmd_s, cc->limiting_reason,
s->bias_pgood, s->mppt_pgood);
if (n > 0) {
HAL_UART_Transmit(&huart1, (uint8_t *)line, (uint16_t)n, 20);
}
}