V tomto článku ukážeme, jak napájet Raspberry Pi Pico z Li-on akumulátoru. Při napájení z akumulátoru je potřeba zabezpečit, abychom nepřekročili napájecí napětí Pica 5.5V a dále abychom akumulátor nevybili pod kritickou mez. To nám zabezpečí nabíjecí modul Li-ion s obvodem TP4056 (cena okolo 18 Kč). Akumulátor Li-POL budeme napájet buď ze solárního panelu, anebo z 5V USB zdroje. Budeme měřit napětí na akumulátoru VSYS a napětí na solárním panelu. Nabíječka TP4056 funguje z 5V a podle datasheetu snese maximálně 8V a to bychom na tak malém panelu i při plném slunečním svitu neměli dosáhnout.
Osvědčilo se mi toto zapojení:
Obvod TP4056 slouží jako nabíječka Li-ION nebo Li-Pol článku, obvod DW01A spolu s FS8205 je ochrana baterie proti přebití a podbití.
Program
Program jenom demonstruje měření na pinu VSYS a také měření napětí na solárním panelu pomocí ADC2. Měření na pinu VSYS (GPIO29) je měření napětí akumulátoru. K tomu je určen na Raspberry Pi Pico ADC3.
Toto řešení nebude fungovat na PicoW, protože pin GPIO29 je společný pro Wifi kartu (chip select). Lepší je udělat rezistorový dělič napětí z VSYS na ADC1 20k a z ADC1 na GND 20k.
/* Měření napájecího napětí VSYS a napětí na solárním panelu
* (c) Jirka Chráska 2026, <jirka@lixis.cz>
* BSD 3 clause licence
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"
#include "hardware/i2c.h"
#include "lib/ssd1306.h"
#include "lib/font_spleen_8x5.h"
#include "lib/font_spleen_16x8a.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "pico/time.h"
#include "pico/types.h"
// pin pro měření napětí na baterii
#define PIN_BATT_LVL 29
// pin pro měření napětí na panelu
#define PIN_PANEL_LVL 28
#define DISPLAY_WIDTH 128
#define DISPLAY_HEIGHT 32
#define I2C_ADDRESS 0x3C
#define I2C_FREQ 100000
#define SDA_PIN 4
#define SDC_PIN 5
#define I2C i2c0
ssd1306_t disp;
// nastavení I2C sběrnice
void setup_i2c(void)
{
// nelze použít i2c_default -- aplikace bude chodit nekorektně (zajímavá chyba)
i2c_init(I2C, I2C_FREQ);
gpio_set_function(SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(SDC_PIN, GPIO_FUNC_I2C);
// Pull-up rezistory jsou v displeji, netřeba nastavovat
}
void zapnuti_displeje( void )
{
ssd1306_init(&disp, DISPLAY_WIDTH, DISPLAY_HEIGHT, I2C_ADDRESS, I2C); // inicializace
ssd1306_poweron(&disp); // zapnutí displeje
ssd1306_clear(&disp); // vymazání displeje
ssd1306_contrast(&disp,0x50);
ssd1306_draw_string_with_font(&disp, 0, 0, 1, font_spleen_16x8a, "Mereni aku.");
ssd1306_show(&disp); // zobrazíme písmenka na displeji
}
int main()
{
char buf1[128];
char buf2[128];
float batt_voltage;
float batt_voltage_old;
float panel_voltage;
float panel_voltage_old;
memset(buf1,'\0',128);
memset(buf2,'\0',128);
// nastavení displeje SSD1306
setup_i2c();
zapnuti_displeje();
sleep_ms(10);
// nastavení ADC
adc_init();
adc_gpio_init(PIN_BATT_LVL);
adc_gpio_init(PIN_PANEL_LVL);
adc_select_input(3);
printf("Měření napětí VSYS.\n");
// hodnota napětí na VSYS je počítána v milivoltech
batt_voltage_old = round(adc_read() * 9875 / (1 << 12) - 20);
adc_select_input(2);
// 10.7 je dělící poměr oporového děliče na panelu
panel_voltage_old = adc_read() * 10.7f / (1 << 12);
sprintf(buf1, "VSYS: %5.2f V", batt_voltage_old/1000);
sprintf(buf2, "PANEL: %5.2f V", panel_voltage_old);
// výstup na displej
ssd1306_clear(&disp);
ssd1306_draw_string_with_font(&disp, 0, 0, 1, font_spleen_16x8a, buf1);
ssd1306_draw_string_with_font(&disp, 0, 16, 1, font_spleen_16x8a, buf2);
ssd1306_show(&disp); // zobrazíme písmenka na displeji
while ( true ) {
adc_select_input(3);
batt_voltage = round(adc_read() * 9875 / (1 << 12) - 20);
adc_select_input(2);
panel_voltage = adc_read() * 10.7f / (1<<12);
if( batt_voltage != batt_voltage_old || panel_voltage != panel_voltage_old) {
sprintf(buf1, "VSYS: %5.2f V", batt_voltage/1000);
sprintf(buf2, "PANEL: %5.2f V", panel_voltage);
// výstup na displej
ssd1306_clear(&disp);
ssd1306_draw_string_with_font(&disp, 0, 0, 1, font_spleen_16x8a, buf1);
ssd1306_draw_string_with_font(&disp, 0, 16, 1, font_spleen_16x8a, buf2);
ssd1306_show(&disp); // zobrazíme písmenka na displeji
}
batt_voltage_old = batt_voltage;
panel_voltage = panel_voltage_old;
sleep_ms(1000);
}
}
cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# initialize the SDK based on PICO_SDK_PATH
# note: this must happen before project()
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(napajeni C CXX ASM)
# initialize the Raspberry Pi Pico SDK
pico_sdk_init()
# rest of your project
add_executable(napajeni
main.c
lib/ssd1306.c
)
target_link_libraries(napajeni
pico_stdlib
hardware_adc
hardware_i2c
)
pico_add_extra_outputs(napajeni)
pico_enable_stdio_usb(napajeni 0)
pico_enable_stdio_uart(napajeni 0)
cd napajeni_z_akumulatoru
mkdir build
cd build
cmake ..
make
Celý projekt ke stažení: ../napajeni_z_akumulatoru.tar.cz
Obrázky prototypu


Poznámky ke konstrukci
Nepájivé pole slouží jenom jako podložka, všechny spoje jsem pájel, protože jsem musel několikrát řešit nepěkné kontaktní problémy.
Možná bude dobré na vstup nabíječky zapojit jako ochranu 1W zenerovu diodu 6.2V. Solární panel dává maximální zkratový proud 221 mA, výstupní proud 200 mA a napětí naprozdno 6.1V. Zenerova dioda bude jenom pro případné napěťové špičky.
Odporový dělič pro měření napětí na panelu má dělící poměr 10.7, takže na ADC 2 se nedostane vyšší napětí než 3.3V i když na panelu bude 10V.
Proudový odběr Pica s displejem kolísá mezi 22mA a 24mA (v závislosti na tom, zda se kreslí na displej nebo ne).
| součástka | kde koupit | poznámka |
|---|---|---|
Raspberry Pi Pico |
kdekoliv: Rpishop |
nejlepší je kupovat v Botlandu 101 Kč, Čechách jsou drahé) |
OLED displej SSD1603 128x38 |
kdekoliv na ALiexpresu (v Čechách jsou ukrutně drahé), stačí dát ve vyhledávači ssd1306 oled display |
|
Nabíječka Li-ion článku TP4056 s ochranou USB-C |
https://www.laskakit.cz/nabijecka-li-ion-clanku-tp4056-s-ochranou-usb-c/ |
cca 18Kč |
akumulátor Li-Ion 3.7V |
kdekoliv |
bude to fungovat s jakýmkoliv akumulátorem 18650, já jsem vypáral Li-Pol z vyhozené notebookové baterie |
rezistor 33k |
kdekoliv |
|
rezistor 68k |
kdekoliv |
|
solární panel 5V 1W |
||
zenerova dioda 6.2V 1W |
Botland |
volitelné |
