🔆

ソラーパネル用Buck DC/DC(ゼロから設計自作) | Buck DC/DC for solar panel (from zero)

に公開

以下はテスト電源入力でDC/DCはスマートフォンの電池を充電させる写真です。
DC/DC converter charging a smartphone.

Input voltage || 入力電圧: > 40 V
Power|| 出力電力: > 25 W (depending on USB charging)
Best efficiency || 最高効率: > 92% (Buck DC/DC stage)
Best efficiency || 最高効率: > 77% (Buck DC/DC + internal power supply from solar panel)


Output voltage and current during soft start to PI control transitions, DC/DC converter PCB and solar panel (Pictures above)

以下は最初実験から二番目の試作の進化のオバービューです。

最初試作は入力24V,降圧動作で出力9V,10Ωの負荷モーターを駆動中の出力電圧の波形です。
二番目試作は追加の出力MOSFETウイッチ(安全)、PIフィードバック制御、保護回路が含まれています。

【内容 || Contents】

■ Rise and fall times of a photocoupler gate driver are significant || フォトカプラ絶縁ゲートドライバのon、off時間が長いすぎ
→ Photocoupler gate drivers may not be suitable for high PWM frequency swithcing || フォトカプラ・ゲートドライバは高周波PWM駆動には不向きな場合があります

■ CMM or DCM power transfer mode depends on the load || 負荷によるCMMやDCM伝送モード (最初試作、PCBなし)
→ CMM buck mathematics do not work in DCM. Output voltage in DCM (low load) stays close to input voltage unless the PWM duty is extremely low

■ TA4422 Gate driver has different paths for MOSFET charge and discharge || MOSFETの充電と放電パスの独立化
→ Datasheet information is not explicit and critical details are not easy to spot, causing design mistakes || データシートの重要な詳細を見落としやすく、設計ミスを招

■ The non-obvious, BIG drawback with low side switching || ローサイドスイッチングにおける「見落としがちな」重大な問題
→ Why high-side is normally preferred despite needing more complex, expensive MOSFET driver circuits || 高価格・複雑なゲートドライバ回路が必要でも、一般的にハイサイドスイッチングが選ばれる理由

■ Bootstrap current leaks into the load through the pull down resistor || Bootstrap電流はpull down抵抗体をで負荷に流れる

■ GNDリターン経路のdi/dtが電圧測定に与える影響 || Voltage measurement errors caused by ground return di/dt
→ Analog (dedicated) ground return and filter is needed || 専用アナロググラウンドとフィルター必要
→ Additionally, measurement averaging is needed → implementation in firmtware for digital control || 測定値平滑も必要。デジタル制御firmawareでの実装

■ Soft-start実装による過電流・オーバーシュート対策 || Soft-start to mitigate over-current and overshoot

■ 理想電源とソラーパネル電源の違いと内部電源ディカプリングの困難 || Ideal power supply and solar panel supply difference and dificulties with the internal supply decoupling

■ Digital control and hardware adjustments for input voltage and load large fluctuations || 入力電圧・負荷の急激変動のデジタル制御や回路調整
→ USB fast charging and solar panel irregular behavior requires a specific control strategy, PI controller adjustment and adjustments in capacitance/ESR || USB高速充電やソーラーパネルの不規則な挙動に対しては、特定の制御戦略に加え、PIコントローラの調整やコンデンサ容量・ESRの最適化が必要です。
→ Voltage → Current control (double control loop) is often prefered over pure voltage control due to faster response and smoother transition from DCM ↔ CCM despite higher complexity and price || 回路の複雑化やコスト増を伴うものの、応答速度の速さやDCM ↔ CCM間のスムーズな遷移を考慮し、純粋な電圧制御よりも電圧・電流の「2巡系制御(ダブルループ制御)」が一般に優先されます。

【1.安全 Safety】

⚠️電解コンデンサは破裂・ガス放出の恐れがあります。Electrolytic capacitors tend to release hot gases when excessive or reverse voltage is applied.

【2.回路 Hardware】

Schematics of the latest version (rev.3) of the Buck converter.

For this version, I used a MOSFET on the high side. As I learned with my second prototype, using a MOSFET on the low side while the microcontroller is powered with the Vin GND and measuring Vout without insulation causes the loop to close through the micontrocontroller while the MOSFET is turned off.
Using the knowledge gained from earlier protoypes, I made sure I include a pull down resistor on both the gate driver input and the MOSFET gate to avoid false turn on.
I also included TVS diode on the input to protect the buck converter against overvoltage from the solar panel.

This time, the microcontroller has voltage dividers protected with Zener diodes and current measurement through 0.1Ω resistor and LM358 OPAMP to regulate voltage and also monitor current to detect Discontinous Conduction Mode. The 0.1Ω reistor is placed on the GND to avoid difficulties of common mode if it were to be placed on the Vin side.
Note that there is one PGND (Power Ground) and one GND (used for both Analog AGND and Digital DGND). PGND and GND join at the input bulk capacitor (-) pin, to ensure that the sensitivty sensor currents do not share the ground path with the high current, high di/dt of the power circuit that creates voltage spikes affecting the measurements reference to GND (AGND). EasyEDA does not allow to automatically create separated paths or provide specific tools for ensuring clean, not noisy grounding. I tried to do this during the PCB layout design and, later on, while building and debugging the PCB, sometimes soldering wires manually in the protoype PCB (the last section of this article includes some experimentation with grounding debugging EMC issues like huge voltage spikes on the ADC sensing).

⚠Note that I added a 220 μF capacitor in parallel to the 0.1 μF ceramic capacitor on ESP32 3_3V power supply pin, as the solar panel alone was sometimes not enough to fully boot up the ESP32 microcotroller board. Similarly, I needed to add a 47 μF, a 3.3 μF and a ceramic 0.1 μF capacitor very close to the LM317 (LDO) to be able to have enough decoupling and buffer energy to boot the microcontroller when powering from the sonal panel (long wires, high inductance).

⚠The 220 ohm resistor at the DC/DC output is for avoiding DCM huge voltage oscillations due to PI control that happen when there is no significant load connected to the output.

Here is PCB layout seen from the top layer.

Here the second inner layer with the Power GND (PGND) routed through the Shunts.

Below the 3D view of the EasyEDA CAD tool.

主要部品 Main components

■MOSFET Nチャンネル ➡ IRFZ44N
■ダイオード,20 A, Schottky ➡ 20SQ045
■インダクタ 47μH(いわゆる「コイル」や「リアクトル」)
https://jp.rs-online.com/web/p/leaded-inductors/7360970P
■マイクロコントローラ開発ボード Freenove ESP32 WROOMを使いました
https://www.amazon.co.jp/your-orders/pop?ref=ppx_yo2ov_mob_b_pop&orderId=249-4099411-5967043&lineItemId=jismnuilroowqry&shipmentId=D26fKkTL8&packageId=1&asin=B0C9THDPXP
■ゲートドライバ(Low sideのみ) ➡ TA4420
T_on_delay (max) = 75 ns + 60 = 135 ns T_off_delay (max) = 75 + 60 ns = 135 ns
⚠ゲートドライバAT350 → 不向き T_on_delay (max) = 500 ns T_off_delay (max) = 500 nsでPWM周波数 f=100 kHz duty=20 % を想定して → T_on_PWM = 2000 ns
https://www.amazon.co.jp/dp/B09G2NY8Y9?ref=ppx_yo2ov_dt_b_fed_asin_title
■ゲートドライバ Half bridge for bootstrapping ➡ FAN7382
■LDO(LowDropoutIC)➡ LM317
https://www.amazon.co.jp/-/en/dp/B07RYCXLY7?ref=ppx_yo2ov_dt_b_fed_asin_title
⚠ソラーパネルの40~50V(メーカーの仕様による最大70Vと規定されていますが、経験したことがありません)から5V、12V、3.3Vなどに降圧することはLDOよりスイッチングコンバーター(SRH05シリーズ等)のほうが、効率がよく、入力電圧が広いです。ただし、SRH05をESP32やGateDriverに接続したら、停電になってしまいました。現在、入力電圧はLM317の40Vに制限されています。
Bucking 40 V to 50 V from the solar panel (according to the maker 70 V max. though I have never observed that high voltage) to 5V, 12V, 3.3V required a DC/DC like the SRH05 for higher efficiency and wider input voltage range, however, this did not work and blacked out the rail. Currently, the input voltage is limted to the LM317's 40 V max.
■24 V 出力電源(任意、実験する際に非常に便利) 24 V power supply (optional, strongly recommended for debugging and developing)
amazon.co.jp/dp/B0BTLYM29L?ref=ppx_yo2ov_dt_b_fed_asin_title

⚠ 教訓:ESP32のGNDを分散させると破壊につながる。必ず一点集中で配線すること。
「作成中」

【3.ソフトウエア Software】

【3.1 IDEインストール、ESP32準備】

作業用ノートPCに Espressif-IDE をインストールしました。インストール先には Downloads フォルダを使用しました。
Eclipse IDE はプラグインや各種調整が必要だったため、使用を断念しました。

Espressif-IDE に含まれるモニター機能(ターミナルとは別の機能)を使って、ESP32 が UART/USB 経由で送信する “printf()” のデータ(例:Tx ピンでの LED 点滅)を取得しようとしましたが、うまく動作せずトラブルシュートもできませんでした。原因は、インストールフォルダに activate.bat が存在せず、Python の仮想環境を有効化できないためです。PuTTY も職場PCでは動作しませんでした。

代わりに Tera Term を使用できました。ただし、ボーレートを ESP32 の標準値である 115200 に設定する必要があります(Tera Term のデフォルトは 9600 で、そのままだと Hello World プログラムを書き込んだ ESP32 からの出力が文字化けします)。Windows の「デバイス マネージャー > ポート (COMとLPT) > USB Serial CH32 (COM4)」で、ドライバのボーレートも 9600 から 115200 に変更しました。

ESP32 にソフトウェアを書き込む際は、ターゲットを設定したうえで Tera Term を閉じる(または接続を切る) 必要があります。その後、IDE で「Run」をクリックするとフラッシュできます。

ESP32 は特に操作しなくても Windows に自動的に認識され、デバイスマネージャー上で 「USB Serial CH340」 として表示されます。
もし表示されない場合は、問題がある可能性があります(以前試した ESP32-C3 mini ではこのような不具合がありました)。

【3.2 ソフトウェア設計及びソースコード Software design and source code】

以下は大まかなソフトウェアの振る舞い図を表すState chart.
Below is the software behavior state chart diagram.

⚠割り込みは1msごとに設定すると、Tera Termなどで(USB通信)でWatchdogの以下の警告メッセージが出ることがありました。10 msに設定すると、問題が直りました。
If the interrupt timer is set to 1 ms, there are times when the following error message appears in Tera Terms, etc USB communication. It got fixed by setting it to 10 ms.

E (10333) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time: E (10333) task_wdt: - IDLE0 (CPU 0) E (10333) task_wdt: Tasks currently running: E (10333) task_wdt: CPU 0: esp_timer E (10333) task_wdt: CPU 1: IDLE1 E (10333) task_wdt: Print CPU 0 (current core) backtrace Backtrace: 0x400D899B:0x3FFB0FC0 0x400D8D60:0x3FFB0FE0 0x40083149:0x3FFB1010 0x4000BFED:0x3FFB3ED0 0x400867BB:0x3FFB3EE0 0x400862AC:0x3FFB3F00 0x400828C4:0x3FFB3F40 0x400829AD:0x3FFB3F70 0x400DAE86:0x3FFB3F90 0x400DAF5E:0x3FFB3FB0 0x40082D61:0x3FFB3FF0 0x400D9865:0x3FFB4010 0x400D98AD:0x3FFB4040 0x40086419:0x3FFB4060

ChatGPT explanation to this error log is:
"ESP32 is booting, but it’s getting stuck in a way that starves the IDLE task, so the Task Watchdog (WDT) fires. This is almost never “damage from reflashing”; it’s almost always software config or a callback that runs too long / too often."

Espressif IDE向けのソースコードは以下です。
Below is the C source code on Espressif IDE.

#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
#include "driver/adc_types_legacy.h"
#include "driver/gpio.h"
#include "hal/adc_types.h"
#include "hal/ledc_types.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "driver/adc.h"
#include "driver/ledc.h"
#include "esp_err.h"
#include "soc/gpio_num.h"
#include "esp_timer.h"

#define buck_controller_KP 0.003
#define buck_controller_KI 0.0001
#define time_sampling_ms 10
#define time_sampling_seconds 1
#define adc_to_V_out 309.2
#define adc_to_V_in 28.15
#define adc_to_I 862.0
#define no_adc_samples 10.0

#define PWM_FREQUENCY 200000 // low frequency switching frequency for simple PWM tests with LED as output
#define PWM_RESOLUTION LEDC_TIMER_8_BIT // set to 8 bit to allow higher frequency, at 10 bit the clock cannot output
#define MAX_DUTY 255 // Need to adjust depending on PWM resolution, which is lowered to allow higher PWM freq
#define DUTY_LIMIT 0.8
#define VOUT_TARGET 5.0
#define VOUT_TARGET_SOFT_START 4.5
#define VOUT_MAX_START_SOFT_START 2.0
#define VOUT_OVERVOLTAGE_LIMIT 5.5
#define VIN_MAX_LIMIT 40.0
#define VIN_MIN_LIMIT 7.0

int raw_ADC_GPIO32=0;
int raw_ADC_GPIO34=0;
float float_V_in=0;
float float_V_out=0;
float float_V_out_averaged=0;
float float_V_in_averaged=0;
float float_current_avg_3=0;
float PWM_duty=0;
bool bool_V_out_overvoltage=0;

//Interrupt triggered by internal timer to detect output overvoltage and turn off FET
// DO NOT INCLUDE PRINTF in the interrupt, it locks forever
static void IRAM_ATTR safety_timer_callback(void* arg)
{
float_V_out_averaged = 0;
for (int i=0; i < no_adc_samples; i++){
float_V_out_averaged = float_V_out_averaged + adc1_get_raw(ADC1_CHANNEL_6)/adc_to_V_out/no_adc_samples;
}

	if (float_V_out > VOUT_OVERVOLTAGE_LIMIT){
		PWM_duty = PWM_duty * 0.9;
		bool_V_out_overvoltage = 1;
} 

}

void app_main(void)
{

/Configure and set GPIO4 as the Vout safety switch, default shall be turned off/
gpio_reset_pin(GPIO_NUM_4); // Optional, but good to reset to default state
gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_4, 0);

/Configure analog input/
//
adc1_config_width(ADC_WIDTH_BIT_12); // 12-bit resolution
adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0); // ADC1 channel 0 (GPIO32), voltage measurement ADC

adc1_config_width(ADC_WIDTH_BIT_12);  // 12-bit resolution
adc1_config_channel_atten(ADC1_CHANNEL_5, ADC_ATTEN_DB_0); // ADC1 channel 0 (GPIO33), current measurement ADC

adc1_config_width(ADC_WIDTH_BIT_12);  // 12-bit resolution
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_0); // ADC1 channel 0 (GPIO34), voltage measurement ADC

// Create periodic timer
const esp_timer_create_args_t timer_args = {
.callback = &safety_timer_callback,
.name = "safety_timer"
};
esp_timer_handle_t safety_timer;
esp_timer_create(&timer_args, &safety_timer);
esp_timer_start_periodic(safety_timer, 10000); // µs → 1 ms period

/Configure PWM output channel for buck converter/
// Configure LEDC timer
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_HIGH_SPEED_MODE, // Use high-speed mode
.timer_num = LEDC_TIMER_0, // Timer 0 for both channels
.duty_resolution = PWM_RESOLUTION, // Set PWM resolution
.freq_hz = PWM_FREQUENCY, // Set frequency
.clk_cfg = LEDC_AUTO_CLK // Use automatic clock selection
};
ledc_timer_config(&ledc_timer);

// Configure PWM1 (Q1)
ledc_channel_config_t ledc_channel1 = {
    .gpio_num = 17,
    .speed_mode = LEDC_HIGH_SPEED_MODE,
    .channel = LEDC_CHANNEL_0,
    .timer_sel = LEDC_TIMER_0,
    .duty = 0, 
    .hpoint = 0
};
ledc_channel_config(&ledc_channel1);


float buck_PIcontroller_error = 0;
float buck_PIcontroller_output = 0;
float buck_PIcontroller_integral = 0;
uint32_t main_loop_counter = 0;

/Main loop/
while(1){
/Getting raw ADC values/

    float_V_in_averaged = 0;
    	for (int i=0; i < no_adc_samples; i++){
			float_V_in_averaged = float_V_in_averaged + adc1_get_raw(ADC1_CHANNEL_4)/adc_to_V_in/no_adc_samples;
		}
    
    float_V_out_averaged = 0;
    for (int i=0; i < no_adc_samples; i++){
		float_V_out_averaged = float_V_out_averaged + adc1_get_raw(ADC1_CHANNEL_6)/adc_to_V_out/no_adc_samples;
		}
    
	if(bool_V_out_overvoltage == 1) printf("Interrupt timmer triggered overvoltage protection and reduced PWM duty by 0.9 factor\n");
	if(bool_V_out_overvoltage == 0) printf("Interrupt timer has NOT detected overvoltage\n");
	
	if(float_V_out_averaged < VOUT_MAX_START_SOFT_START)	PWM_duty = 0;
	if(float_V_out_averaged > VOUT_OVERVOLTAGE_LIMIT)		PWM_duty = 0;
	if(float_V_in_averaged < VIN_MIN_LIMIT)					PWM_duty = 0;
	if(float_V_in_averaged > VIN_MAX_LIMIT) 				PWM_duty = 0;
	
	
	while (float_V_out_averaged < VOUT_TARGET_SOFT_START && float_V_in_averaged > VIN_MIN_LIMIT && float_V_in_averaged < VIN_MAX_LIMIT) {
		
		printf("ENTERED SOFT START ROUTINE float_V_out_averaged = %f\n", float_V_out_averaged);
		bool_V_out_overvoltage = 0;	
		float_V_out_averaged = 0; //reset averaged measurement to 0 so that it can be calculated again
		float_V_in_averaged = 0; //reset averaged measurement to 0
		
		if (PWM_duty < DUTY_LIMIT)
			PWM_duty = PWM_duty + 0.001;
		
		float_V_out_averaged = 0;
    	for (int i=0; i < no_adc_samples; i++){
			float_V_out_averaged = float_V_out_averaged + adc1_get_raw(ADC1_CHANNEL_6)/adc_to_V_out/no_adc_samples;
		}
    	printf("SOFT START ROUTINE RUNNING float_V_out_averaged = %f\n", float_V_out_averaged);
    	
    	float_V_in_averaged = 0;
    	for (int i=0; i < no_adc_samples; i++){
			float_V_in_averaged = float_V_in_averaged + adc1_get_raw(ADC1_CHANNEL_4)/adc_to_V_in/no_adc_samples;
		}
         	
    	float_current_avg_3 = adc1_get_raw(ADC1_CHANNEL_5)/3.0/adc_to_I + adc1_get_raw(ADC1_CHANNEL_5)/3.0/adc_to_I + adc1_get_raw(ADC1_CHANNEL_5)/3.0/adc_to_I;  // Read ADC value
    	
    	printf("Soft-starting, Vin_avg = %f, Vout_avg = %f, I_avg = %f\n", float_V_in_averaged, float_V_out_averaged, float_current_avg_3);
    	printf("Soft-starting, PWM duty = %f\n", PWM_duty);
    	printf("Overvoltage flag: %d\n", bool_V_out_overvoltage);
    	ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, (uint32_t)(PWM_duty * MAX_DUTY));
    	
		ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
		vTaskDelay(pdMS_TO_TICKS(time_sampling_ms));
}

// PI controller (used if Vout has reached a normal operation value (> 5.0 V) after soft start)
while (float_V_out_averaged > VOUT_TARGET_SOFT_START && float_V_in_averaged > VIN_MIN_LIMIT && float_V_in_averaged < VIN_MAX_LIMIT) {
float_V_out_averaged = 0;
for (int i=0; i < no_adc_samples; i++){
float_V_out_averaged = float_V_out_averaged + adc1_get_raw(ADC1_CHANNEL_6)/adc_to_V_out/no_adc_samples;
}
printf("ENTERED PI CONTROL MODE\n");
printf("Average measured V_out voltage is %f\n", float_V_out_averaged);
printf("Average measured V_in voltage is %f\n", float_V_in_averaged);
buck_PIcontroller_error = VOUT_TARGET - float_V_out_averaged; //Target output voltage - loop feedback
buck_PIcontroller_integral = buck_PIcontroller_integral + buck_controller_KI * buck_PIcontroller_error * time_sampling_ms;
if (buck_PIcontroller_integral > 0.1) buck_PIcontroller_integral = 0.1;
if (buck_PIcontroller_integral < -0.1) buck_PIcontroller_integral = -0.1;
buck_PIcontroller_output = buck_controller_KP * buck_PIcontroller_error + buck_PIcontroller_integral;
PWM_duty = PWM_duty + buck_PIcontroller_output;
printf("PI Controller: Error = %f, Integral = %f, PI_out = %f, PWM duty = %f\n", buck_PIcontroller_error, buck_PIcontroller_integral, buck_PIcontroller_output, PWM_duty);

        if (PWM_duty > DUTY_LIMIT){
			printf("PWM_duty = %f\n", PWM_duty);
			PWM_duty = DUTY_LIMIT; //set limit
			printf("Duty limit reached, clamped to DUTY_LIMIT\n");
			vTaskDelay(pdMS_TO_TICKS(1500));
			}
        
        if (PWM_duty < 0.0) {
			PWM_duty = 0.0;
			printf("PI controller set PWM_duty to 0.0 by PI controller as calculated PWM_duty < 0\n");
			vTaskDelay(pdMS_TO_TICKS(1500));
			}
			
		if (float_V_out_averaged < VOUT_TARGET) bool_V_out_overvoltage = 0;	 

        
    	ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, (uint32_t)(PWM_duty * MAX_DUTY));
		ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);

    	    	
        main_loop_counter++; //increase counter of finalized loops, this is tracked to sent printf messages every few cycles not to overload the communication terminal or controller
        if (main_loop_counter == 1){
			    //printf("GPIO032 ADC Reading: %d\n", raw_ADC_GPIO32);
		        printf("GPIO032 V_in - Reading in volts: %f\n", float_V_in_averaged);
		        //printf("GPIO033 Current - Reading in amps: %f\n", float_current_avg_3);
	            //printf("GPIO034 buck DC/DC output - Reading in volts: %f\n", float_V_out_averaged);
	            //printf("PWM duty: %f\n", PWM_duty);
	            //printf("buck duty PI regulator: %f | buck_PIcontroller_error: %f | buck_PIcontroller_integral: %f\n", PWM_duty, buck_PIcontroller_error,buck_PIcontroller_integral);
	            main_loop_counter = 0;
	            
		}
        vTaskDelay(pdMS_TO_TICKS(time_sampling_ms));  // Delay milliseconds
        }
        }
}

【3.3 制御に関わる注意点】

⚠️ ESP32のPWMは周波数と分解能のトレードオフに注意

高いPWM周波数を使うときは、分解能を下げる必要があります。私はこれで痛い目を見ました。
「78 kHzでは正常 / 79 kHzで異常」となったのは、ESP32-WROOM(FreenoveのクラシックESP32)でもledc(C言語のPWM出力機能)の分解能限界によるものです。

ESP32のLEDCタイマは80 MHzクロック駆動です。
10ビット分解能の場合の最大周波数は:

𝑓max=80 MHz / 2^10 = 78,125 Hz

79 kHzを指定すると、ドライバが自動的に分解能を落とすか、duty計算がオーバーフロー/アンダーフローしてしまいます。その結果、要求したdutyが極端に小さくなり、出力が約1.5 Vになったのです。

これは**デジタル的な限界(クリフ現象)**であり、インダクタの飽和ではありません。

【4.開発日記、Debuggin || Development diary and debugging】

「Stripboardの最初実験」

試作基板(Stripboardで作りました)

実験ログ:出力電圧(Vout)計測とDuty不一致の原因推定

計測方法
出力電圧 Vout を抵抗分圧で測定。実際の電圧はスコープ値 ×43 倍に換算。
→ リップル波形はきれいに観測できた。

観測された問題
Duty と Vout が一致しない。
特に Duty <40% では、本来 3 V になるはずが 実際は 9 V 出力。

💡

初期実験:Gate Driver信号 || Initial try: gate driver signal

実験ログ:Vgsリンギングと実効周波数ずれ

【BreadboardでDC/DCの実験】
10 mHのインダクタを利用してBreadboadで作り直した。
MOSFETをIRF520Nに変換しました。

10 kHz,90/255 dutyのPWM信号でも出力コンデンサ電圧は20 Vに到達しました。
MOSFETのVgsの波形が以前よりスムーズに見えます。

50 kHZ → 出力コンデンサ電圧は13.5 V

寄生インダクタンスにより信号の遅れが確認しました。
Duty 35% で出力電圧はおよそ8Vを予想されます。

R_gate = 10 Ωのままで、Gate driverからMOSFETのgateまでの距離をさらに短くしました。

f=30 kHz d=35%(90/255) Vout=18.1 V
f=50 kHz d=90/255 Vout=13.5 V
f=70 kHz d=90/255 Vout=11.4 V
f=90 kHz d=90/255 Vout=13.5 V
f=110 kHz d=90/255 Vout=15.9 V

💡ゲートドライバAT350 → 不向き T_on_delay (max) = 500 ns T_off_delay (max) = 500 nsでPWM周波数 f=100 kHz duty=20 % を想定して → T_on_PWM = 2000 ns
実際には T_on_delay < T_off_delay ことが多いという情報を拝見し、実際のGate driver出力PWMは、低いDutyは特に、Gate driver入力PWM dutyよりも高くなる可能性が高いと思います。

MOSFET Miller効果の誤解とGate Driverの誤使用 || Miller effect confusion and improper gate driver

💡ゲートドライバTA4422 → T_on_delay (max) = 75 ns + 60 = 135 ns T_off_delay (max) = 75 + 60 ns = 135 ns

T4420ゲートドライバに変換しました。
⚠️MOSFET IRF520NのゲートにPull down抵抗体を配置しないと電流をながしてしまう経験がありました。ゲートとGNDの間に10kΩの抵抗体を追加しました。

ESP32マイコンの出力PWMを接続したら、DC/DCのVout=Vinになってしまいました。
オシロで監察したVgsの波形は以下となります。オフ期間は0Vではなく、9Vになってしまいます(異常)。オン期間は18Vに到達します(正常)

ゲートドライバのVdd-Veeは安定した16VでVee-GNDも安定した0Vを監察しました。

ゲートとGND(Pull down)抵抗体を10kΩから2kΩに変換してみました。オフタイムは0Vにかなり近づきましたが、Voutはまだ23.5Vに固定されています(Vin=Vout)

1kΩも足りないですが、Voutは19Vに達しました。
外部電源ケーブルの寄生インダクタンスを抑制するために、BreadboardのVccとGND(電圧入力)にも10μFのコンデンサを配置してみましたが、効果が監察されませんでした。

IRF520N MOSFETのゲートチャージは16 nC,GSのゲートチャージは4.4 nC。
ゲートを速やかに放電するように以下の構成を試してみます。

ゲートドライバのVddを10Vに調整しても、Vgsは6~10Vとなります。
VddをLDOから外しても、MOSFETのVgsは1.8~2Vに固定されています。TC44220の内部保護ダイオードと思います。

仮説:ESP32マイコンのGND接続は長いワイヤーで実装され、ESP32のPWM信号はオフでも十数mVになり、ゲートドライバ出力を6Vに固定する。
→マイコンとドライバのGNDを短く繋げる。
✗ほぼ影響なし
→Pull down TC4420 IN
✗ゲートドライバINのVoffは0.2Vから0Vに変わりました。ほぼ影響なし

仮説:TC4420はオフでも数Vを出す→MOSFETを外してからOutとVeeの電圧を確認。
MOSFETを外しますと、ゲートドライバTC4420のOUT波形はINより若干崩れていますが、オフのタイムは0Vになります。MOSFETスイッチIRF520Nをもう一度配置すると、オフのタイムは6Vに達します。こういた理由でMOSFETのMiller効果が原因であるという仮説が強くなります。

GateとSourceの間に10 pF, 100 pFのコンデンサも入れてみましたが、影響なし。1 nFを入れると、V_gs波形の最低値は7Vになりました(悪化)

ゲートとゲートドライバのOUTの間にダイオード(Schottkyではなかったと思いますが確認できませんでした。V_diodeは0.5Vを測りました。V_gsの波形に影響なし。
ドライバのVeeとGNDのワイヤーの寄生インダクタンスを下げるために2本を追加してみました。V_gsの波形に影響なし。

ゲートとGNDの間に220 Ωの抵抗体を入れて、V_gsの波形のオフタイムは、やっと、0Vになりました。但し、220 ΩはPull downとして過剰に低いです。(10 V)^2 / 220 Ω はほぼ0.5 Wになります!
ゲートドライバを給電している LDO(電圧レギュレータ)を触ったら当然温度が非常に高かったです。

V_dsの波形は0Vから1.13Vという結果になりました。ほぼ0VからほぼVin(24V)に到達するべきです。VoutもVinとほぼ同じになりました。IRF520NスイッチMOSFETはターンオフしていない恐れがあります。

3つのIRF520Nをてみましたが、V_gsとV_dsの波形は全く同じでした。
220ΩのPull downを外したら(10 kΩのPull down抵抗体はまだゲートとGNDと繋がっています)V_dsはずっと0Vに近いです(ターンオフしない)。

ESP32マイコンをUSBでパソコンにつなげて24V電源はオフでも(LDO入力なし)。ゲートドライバのVddとVeeの間に3.3V。入力と出力コンデンサは4.4Vに達しました。V_gsは以下となります。

PWM周波数を20kHzに変換します。V_gs最低値1Vを超えています。
PWM周波数を10kHz。V_gs最低値は0.81V。V_gs↓

上がる時間は短く、下がる時間は非常にながいです。R_gs = 10 Ω。ゲートドライバのOUTとMOSFETゲートの間に、R_gsと並列でダイオードもあります。

ダイオードを外してみたら、少ししか変わりません。V_gs以下(ゲートドライバOUTとMOSFETゲートの間のダイオードなし)

V_dsを計測して最高値は13Vで、MOSFETは完全にOFFにならない。

💡The experimentation and debugging went too long for this section. As spoiler, the issue was not due to Miller effect, just a misuse of the TC442x which needs some appraently redundant duplicated pins to be connected.

PCB設計と基板発注 || PCB design and fabrication

EasyEDAでPCBを設計しました。
ESP32マイコンのフートプリントを挿入することがかなり手間がかかって、多数ピンのESP32をはんだでつけてから外すのは大変で、GND以外にESP32の接続は反映させませんでした。

0.2μFセラミックコンデンサと50μFの電解コンデンサをドライバーのVddとVeeの間に入れる、Vinにも50μFの電解コンデサを入れてみました(基板を設計した際に抜けてしまいました)。
🎉MOSFETのVgs信号が綺麗になりました。

但し、Voutは0.2V〜0.3Vに到達しました。
周波数を10kHzでも70kHzでもDuty20%でも100%でも変わりません。
Vdsは-0.64V〜+0.3VでMOSFETはオフにならないという結果です。

TC4420の2つのOut(重複ピン6とピン7)を両方を繋げてVgsの波形は正しくなりました。さらに、TC4420のピン1とピン8(Vddの重複ピン)、ピン4とピン5(GNDの重複ピン)を繋げてみました。但し、Vinに24Vを印加してみたら、VoutはVinになり、PWMのdutyは0%でも、MOSFETのVdsは0Vから始まり(完全にオン状態、ゆっくり24ボルトに上がります(オフ状態)。
Gate抵抗体を外したら、MOSFETは最初からオフ状態でした。
Gate抵抗体を直して、TC4420のInputピンの抵抗体を外したら、前の問題が発生しました。
TC4420のIn(ピン2)に3.3KのPull down抵抗体を入れてみたら、PWMのdutyは0%にしたらVoutはほぼOVになりました。(LMT317のLDOのバックフィードで電圧がVoutに少し印加)。

出力電圧が固定される課題(DCM)|| Output voltage clamped due to DCM

但し、dutyを30%程度にしてみたら、MOSFETのVdsはほぼ0Vで(オフにならない)、5V程度のピークをオシロ拝見しました。

MOSFETとDriverは大丈夫だと思いますが、出力バルクコンデンサがVinに充電され、MOSFETのVdsはゼロになることに関して以下の仮説があります:
1)出力バルクコンデンサの容量と負荷の割合が多すぎる 以下テスト0~2番
2)47μHコイルが飽和状態になってしまう 以下テスト3~番
3)LDOのLM317のバックフィードが原因

以下は最初の試作の入力電圧24V,出力電圧9V。TC4420の重複ピン、PullDown抵抗体を直したら、10Ωの負荷(プロペラ付きモーター)を接続成功しました。以下の写真で出力電圧の波形(オシロスコープ)、基板と負荷が表示されます。
I finally succeeded after connecting all duplicated pins of TC4420 and the pull down resistor, as well connecting a 10 Ω load (motor with a propeller). The picture below shows the output voltage wave, the PCB and load (motor).

『最初試作(動作可能)No feedback control 熟成度:=低い First prototype (Functioning)』

テスト、課題などについて「「補足」開発日記や失敗 Development diary and failures」をご参照ください。
Regarding tests, challenges I faced, refer to chapter 「補足」開発日記や失敗 Development diary and failures」.


 マイコンのADC入力を守るために電圧測定箇所にZenerダイオードを配置しました。過電圧があった場合、マイコンのADC入力ピンの電圧が約3.3Vに固定されるように設計しました。
I protected the microcontroller ESP32-C3 with Zener diodes on the inputs to prevent overvoltages by clamping the voltage to 3.3V


 設計ルールを事前に設定することがおすすめです。最低距離と特に同線の最大幅。
下側にGround planeを配置しました。2層基板となり、Through holeの部品ばかりで、Ground planeとして大きな四角形などを入れることが難しいですが、広い同線を傾向で配置することでGround loopやノイズ、EMCの問題を予防するように設計しました。
It is recommended to set the design rules previously. Minimum distance andm especially the maximum width for the traces.
I created a ground plan on the bottom side. It is a 2 layer PCB using through hole components, so it is difficult to make a big rectangular area for the ground plane.

EMCの観点から、パワー電線と信号電線ができる範囲で平行で流れず、平行で流れても遠く配置することがおすすめです。
From the EMC perspective, it is recommended to place the power lines and signals lines not parallelly and, if possible, far from each other.

以下は最初の試作の入力電圧24V,出力電圧9V。TC4420の重複ピン、PullDown抵抗体を直したら、DCMを予防するために、10Ωの負荷(おもちゃのモーター)を接続して成功しました!!
Below in the first protoype functional test result, with input voltage of 24 V and output voltage of 9 V. I finally succeeded making the DC/DC converter work by fixing the issue with the TC4420 gate driver duplicated pins, adding a pull down resistor on the gate dirver input, and using a toy motor of 10Ω as a load to prevent DCM.

2番目の試作は最初24Vを印加した際に、ゲートドライバのためのLDO「LM317」による過電流が発生して、入力電源がカットしました。12VレールのコンデンサのESRが低すぎ、突入電流が起きているという仮説があります。LM317のPin2のセラミックコンデサを外しても過電流の問題が続きました。突入過電流の問題であるかを確認するために、LM317のPin1(入力電圧)に100Ωの抵抗体に入れてみました。やはり、電源がカットしませんでしたが、煙が出ました(抵抗体の過剰な電圧降下で発熱と思います。電圧降下は17.4Vとなります)。10Ω抵抗体を入れたら、抵抗体の計測電圧降下は6.4Vに達しました。

ゲートドライバの12Vレールの10μF電解コンデンサを外してみても、電源が同様にカットしました。測れた電圧降下は連続でしたため、突入電流で電源がカットという仮説を仮に否定します。
12VレールのLM317のpin3(Adj)とGNDの間に約400Ωを測りましたが、Pin3とGNDの間に2.2kΩの抵抗体しか入れていないと思っていました。ゲッタードライバーTC4420のVddとVeeは約300Ωを測りましたが、100nFのセラミックしかないと思っていました。MOSFETのSourceとTC4420のVeeの間にPull down抵抗体も配置され、MOSFET「Q2」のSourceとドライバのVeeは60kΩですが、Q1は10Ωでした。抵抗体の抵抗値は正しかったですが、TC4420を外したら、Pin5とPin6との抵抗値は非常に低かったです(10Ω程度)

MOSFET Q1のGateにVgs=0Vを印加してもVdsは7Vで、出力コンデンサは16Vに達します。GateのPull down抵抗体を20Kでも1Kでも同じ結果です。MOSFETを外してSourceの基板の穴とDrainの基板の穴の電圧も同じ結果です。MOSFETが取り除いた状況でも、Sourceの基板の穴Drainの基板の穴の間32kΩを測りました。Vinから出力コンデンサ1Ωよりも低くく、出力コンデンサからMOSFETもほぼ0Ωでした。

電子回路のCAD(EDA)図面は以下の画像です。

基板を設計・建設する際に注意点 PCB design and key points for construction

ESP32で電圧を計測する際に、抵抗による分圧回路をESP32側の電圧が0.1Vより高い電圧が印加されるようにしてください。0.1Vが印加された場合、0Vが読み間違いされます。
入力条件
Vcc–Vee間に18 Vを印加し、0.1 µFのセラミックコンデンサを並列に配置。

⚠ゲートドライバのVccとVee(GND)の間、必ずしも近くにに0.1μFのセラミックコンデンサ(数十μFの電解コンデンサも必要となる場合があります)を配置する必要があります。でなければ、寄生インダクタンスなどで、高周波数でMOSFETをONにすることが不可能。

⚠TC4420のゲートドライバーのややこしいpinout【見逃しやすい❕】

大きな課題になってしまいました。綿密にデータシートを読まず、以上の「Duplicated pins must be connected for proper operation」の備考を見逃しました。そのため、MOSFETのゲートの放電が遅すぎ、MOSFETがずっとON状態になってしまいました。気づくまでに、大変長い時間がかかり、MOSFET IRF520NやIRFZ44N、MOSFETのGとSの代わりに 10 nFのセラミックコンデンサでも試してみましたが、確かに容量(C_gate)が高いほどMOSFETのT_offが長いという結果でした。
例えば、

⚠️Low side種のBuck DC/DC出力測定や負荷接続の注意
Low side種Buck方式は、入力GNDと出力GNDが違い、出力電圧は必ず「コンデンサ両端」で測定すること。

テスト用には24 V出力のACアダプタを強く推奨
→ ソーラーパネル不要で安定・制御された電圧が得られる。
→ 当初SRH05(12 V出力)を使ったが不具合があり、LDOを抵抗3本(例:210 Ωなど)で設定して18 Vを出力する構成に変更。

3.3Vか5V系の供給について
元々はSRH05スイッチングコンバータでゲートドライバとESP32を駆動していたが、ESP32が大きく電圧降下するか0 Vになる現象が発生(SRH05の自己保護動作の可能性大)。そのため、LM317TのLDOを採用することにしました。

『SECOND PROTOTYPE 二番目試作🚧』 教科書に出ない問題:Low-side BuckのGND経路と測定ミス(MCU破壊) || Non-textbook issue: low-side buck ground path and measurement errors (MCU damage)

二番目の試作の電子回路のCAD(EDA)図面は以下の画像です。 Below are the the CAD (EDA) schematics for the second prototype.
⚠☠ しかし、大きな設計のミスを起こしてしまいました。However, I made a major design mistake with the second prototype. As you can see in the picture below, I used a low side MOSFET buck converter, which relies on "separating" the input and ouput ground for functioning. The output voltage is measured with a voltage divider without insulation referenced to the output voltage, and the ESP32-C3 microcontroller used the input ground (different ground). This causes that the MOSFET of the power circuit is overidden, the current from Vin flowing thorugh the microcontroller to the Vin ground, which makes the DC/DC not work and even break.

ESP32-WROOM-C3 (Freenove)はEasyEDAで存在しませんので、カストマイズのFootprintを造りました。以下のデフォルト開発ボードをベースから再設計し、ピンを2個(1x1)増やし、幅も2.55mmも増やしました。

最初は、コイルのFootprintをカストマイズすることになります(以下の画像)。
コイルはThrough Holeとなり、穴を作るために必ず"Pad"をトップメニューで選択し、Object propertiesで「Hole」が反映されていることを確認。外形の線を作るために、Top Silk Layerを選択することで、コイルの直径などに合わせてCircleを設計。

Circleの線がsilkscreenであるかを確認する必要があります(赤色ではなく、EasyEDAのPCB viewやFootprint editorで黄色で表示されます)

EasyEDAか他にCADツールでちょこちょこSchematicsからPCBを移す(Design > Upgrade PCB to schematics)、部品を少しずつ配置することがおすすめです。でなかければ、経験を踏まえ、一気に多くの部品を整理したり、配置したりすることがややこしく、ミスが多い。
次は、主回路の高電流電線を設計することが推奨します。かなり広い(4mm程度幅、MOSFETのピンの近くの電線は2mm幅)電線となり、他の電線と干渉しやすくなりますので、事前に設計したほうが、順調です(以下の画像)。

続きまして、Ground planeを下の表面(bottom layer)などで設計すること推奨。四角形の銅エリアや広い電線を導入することで、Ground loopやノイズのトラブルを一定程度予防することができます(以下の画像)。

最後は、Auto-routingを仕様してもかまいませんが、理想的に慎重に配線することで、EMCのトラブルを可能な範囲で予防したほうがおすすめです。今回は、量産製品でなく、安くて早く開発を進むことを優先していて2 layerPCB(一番価格の安い)信号電線とグラウンドプレーンは最適化されていません(以下の画像)

基板の寸法を100x100 mm、FR-4素材、2 layerにすることで、非常に安い価格で造ることが可能です。
以下の画像でご覧の通り、500円程度でPCBを製造、+発送料金で2000円程度で注文できます。

LDO LM317出力にセラミックコンデンサを配置し、入力電圧を印加してみました。過電流の不具合で入力電圧が自動的にカットされました。セラミックコンデサのESRは低すぎ、LM317の電圧制御ループで入力過電流の懸念点。

『THIRD PROTOTYPE 三番目試作🚧 』

Bootstrap回路による負荷への電流漏れ || Bootstrap current leaking into the load

Below is the first significant issue when debugging the third prototype on 2025-11-13 (this time, it is a high side MOSFET buck DC/DC converter).
I tried the FAN7382 as bootstrap gate driver for the thrid prototype. It seemed to work in the beginning, when IN = 13 V the Vout of the buck DCDC was close to Vcc and when IN = 0 V, the Vout of the buck DCDC was close to 0 V. However, after adding more components to the PCB, I found that even when the MOSFET had a pull down resistor between gate to source of 10K, and even disconnecting the gate from everywhere, and the source was connected to the FAN7382 Vs (pin 6), the MOSFET conducts and has a Vds = 16 V and the Vout of the DCDC is 7 V. The voltage on bootstrap capacitor is 6.7 V and the voltage from bootstrap capacitor and FAN7382 Vs (pin 6) to GND is 7.2 V. HIN Pin 2 (high side input of the gate driver) has a 47K pull down resistor to GND, and LIN and Pin 3 (low side input) has 10 K pull down reistor. FAN7832 LO (pin 5) is not connected (floating). See image below for shcematics and measurements done to debug this issue.

If I disconnect 7482 driver Vs (pin 5) from MOSFET source, the MOSFET does not conduce and Vout = 0 V, so I rule out and issue with the MOSFET or power main circuit connection. I think the issue could be like the bootstrap capacitor is partly floating, either by the LO (pin 3) due to a weak pull down or the VS (pin 5) being floating, unconnected. However, I put 47K pull down in LO to COM (GND) and replaced the 47K pull down resistor in HIN by a 1K resistor. Vout stays, bootstrap capacitor voltage is 6.2, Vout is 7 V (same result as before, nothing has changed)
The current flow from DC/DC Vin to gate driver and bootstrap capacitor would look like in the diagram below.

I suspect the 7482 driver got damaged while doing some initial tests, likely I accidentally put too high voltage on HIN V_HIN > Vcc + 0.3 V as specified. However, it may be an issue of LDO powering on the output through the bootstrap.

I tried replacing the 7482 driver, and the output voltage on the DCDC is 2.5 V (lower than below) and bootstrap capacitor voltage is 10 V (Being VCC around 13 V) regardless on if disconnected the driver Vs from the MOSFET source, I fully remove the MOSFET, or even disconnect the driver HO. Also, it does not change anything if I connected the 7482 to PGND or GND (GND is connected to PGND through two 0.1Ω resitors used to measure current, I assume it is not significantly affecting anyways), or I connected HIN to GND or PGND directly instead of through a pull down resistor).

💡However, putting a 220 Ω bleeding resistor on the output made the output voltage drop to almost 0 V. There were already 10 K + blue LED as bleeding load, which may not suffice. A tiny leakage current was likely making the output capacitor charge more than intended.

以下は7482ドライバーのHOとスイッチングノードの間の電圧(MOSFETのV_gsとほぼ等しい電圧)(オレンジ色の線)とMOSFETのV_ds(水色の線)。負荷は220Ωです。想定せれている電流は0.1Aです。ゲートがオフになった後のVdsのリンギングが大きいですが、系負荷の影響でDCMモードに入り、異常ではない想定です。
Below is the voltage between 7482 gate driver HO (very close to MOSFET V_gs) (orange color line) and MOSFET V_ds (blue line). The load is 220 Ω. Assumed current is 7 V / 220 Ω = 0.03 A. Ringing in the displayed Vds after the gate turning off is very significant (Vds drop very low, close to 0 V), I believe due to DCM at low load, so not an abnormal behavior.
以下のオシロスコープがオフセット誤差があります(特にCh1の誤差が非常に大きい)

以下は7482ドライバーのHOとスイッチングノードの間の電圧(MOSFETのV_gsとほぼ等しい電圧)(とMOSFETのV_ds。負荷は10Ωです。想定せれている電流は 7 V / 10 Ω = 0.7Aです。ゲートがオフになった後のVdsの大きなリンギングがありません。
以下のオシロスコープがオフセット誤差があります(特にCh1の誤差が非常に大きい)。
Below is the switching waveform at 0.7 A. There is no major ringing for V_DS in this case.

以下は 10 Ω 負荷抵抗体(電力 = 5 W)に印加された電圧波形。
Below a picture of the applied voltage at a 10 Ω load (power = 5 W) with a 4.7 μF output capacitor. Significant ripple can be seen.

OPAMPの最初テストの結果は以下です。回路図面でご覧の通り、元の設計でLM358 OPAMPの-V(電源ー、(R_senseのhigh side)電位は入力信号IN-の電位より高くて、出力信号の波形(以下の左写真)は奇妙で、OPAMPのGain=10設定を考慮して0.7 A負荷に相当しません。右側の写真と回路図面で、OPAMPのGNDを変更してから出力波形を表しています。
Below are the results of the first OP-AMP test. As you can see in the schematic, in the original design the LM358 OP-AMP’s negative supply (–V, which is the high-side potential of the R_sense) was at a higher potential than the input signal IN–. Because of this, the output waveform (left photo below) looked strange and did not correspond to a 0.7 A load, even considering the OP-AMP gain setting of 10.
The right photo and schematic show the output waveform after changing the OP-AMP’s ground reference.

GNDリターン経路のdi/dtが電圧測定に与える影響 || Voltage measurement errors caused by ground return di/dt

ESP32マイコンのADCが読み込んでいるVinとVoutは非常に変動する。
The ESP32 microcontroller’s ADC readings for Vin and Vout fluctuate significantly.

上側の分圧抵抗は220Kと100Kで、47pFセラミックコンデンサのフィルターの算出されたカットオフ周波数は15kHz~34kHzです。PWM周波数は200kHzとなります。ただしマイコンとPCBを長いワイヤーで仮に接続しましたので、寄生インダクタンせの問題可能性もあると思います。ESP32のADCは電流を長いワイヤー(高い寄生インダクタンス)で引き、フィルターコンデンサーが遠くて共振の影響で波形が崩れているかと思います。以下の写真で計測箇所とオシロスコープの波形。
The upper-side resistor divider uses 220 kΩ and 100 kΩ, and with the 47 pF ceramic capacitor, the calculated cutoff frequency is around 15 kHz to 34 kHz. The PWM switching frequency is 200 kHz. However, since I temporarily connected the microcontroller and PCB with long wires, I suspect that parasitic inductance may also be affecting the readings. The ESP32 ADC draws current through long wires (with high parasitic inductance), and because the filter capacitor is far away, resonance may cause waveform distortion. The following image shows the measurement point and the oscilloscope capture:

47pFコンデンサーを10nFに変換してみたら、ESP32が読み込む電圧数値が以前よりも安定していますが、入力電圧はまだ少し不安定なふるまいを表しています(上側分圧抵抗値220kΩ)。
After replacing the 47 pF capacitor with a 10 nF ceramic capacitor, the voltage measured by the ESP32 became more stable than before, but the input voltage still behaves slightly unstably (220 kΩ upper resistor).


但し、仮に長いワイヤーを使いっていて、寄生インダクタンスも影響をがある可能性です。
However, since this setup uses long temporary wiring, there is a possibility that parasitic inductance is also affecting the result.

以下の画像で10nFフィルタセラミックコンデンサーとワイヤやESP32の電圧波形が確認できます。非常に高いピークが表示されます。10nFが容量が足りなくて、ESP32のADCが放電させ、仮のワイヤーの寄生インダクタンスなどで共振が発生しているとい仮説を立てました。
In the image below, you can see the voltage waveform at the 10 nF filter capacitor, along with the wires and the ESP32. Very high peaks appear. My hypothesis is that 10 nF is insufficient, so the ESP32 ADC draws charge from the capacitor, and due to the parasitic inductance of the temporary wiring, resonance occurs and distorts the signal.

ESP32のADCピンとGNDの間、可能な限り近くで追加で10nFのコンデンサをbreadboardに入れてみたら、波形が大きく変わり、電圧最大値がかなり低くなりました。
When I added an extra 10 nF capacitor on the breadboard as close as possible between the ESP32’s ADC pin and GND, the waveform changed significantly and the maximum voltage became much lower.
100nFに変換してみたら、読み込み電圧がか大きく安定化されました。
The read voltage got much more stable when I replaced the 10 nF by 100 nF.

Fixing measured voltage by re-scaling in software:
12 bit resolution ADC --> 2^12-1 = 4095 --> max. read value for I_meas and Vin and Vout channels.
Espressif(ESP32メーカ)の公式サイトによると(にも続いて)DB0 Attenuationで最大入力電圧は950mVです。
950 mV = 0.95 V = 4095 (dec) in ESP32 variable for Vin, Vout and I_meas. ⇔ x4,310 factor.
https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32/api-reference/peripherals/adc.html

Vin 分圧ファクターは 4700/(220000+4700) = 0.0209167779
Vout分圧ファクターは 4700/(100000+4700) = 0.0448901624
V_current_OPAMP_out = 1 A x 0.1 Ω x Gain(2) = 0.2 V per 1 A current through R_sense.

The conversion factor I will use in my C code will be then
Vin(physical float) = 90.15 x Vin(ADC int)
Vout(physical float) = 193.4 x Vout(ADC int)
I(physical float) = 0.0011600928 x I(ADC int) (V 1 A -> 0.2 V (ADC pin) -> 4095/0.95)

While running the firmware, it seems the IRAM timed interrupt wrongly detects output overvoltage during soft start, based on the console printouts, see below (based on printf function). During soft start, even before reaching PWM duty = 0.05 the measured Vout is already > 4 V. I suspect the ADC reading for Vout is still not correct.

Also, Vin is wrongly read as >40 V sometimes, other times around 18 V, when the Vin is 23~24 V. This erratic measurement does not happen for Vout, I believe it is likely due to a too high resistance (220 kΩ), for the Vin measurement compared to Vout (100 kΩ), that does not let enough current to be drawn by the ADC.
After some tests, I also experienced an overvoltage is triggered either by the software or by the output 5.1 V rated Zener diode (Vin drops suddenly/intermittently, I believe due to the ouput clamping Zener start conducing and overcurrent happening, therefore the test power supply drops voltage). Even if implemented a soft start strategy, at d=0.03 the output overvoltage seems to occur.
Next steps(fixes):

Soft-start実装による過電流・オーバーシュート対策 || Soft-start to mitigate over-current and overshoot

Below oscilloscope show V_out and I_out without Zener diode and without software overcurrent/overvoltage protection. As it can be seen in image, V_out drops to 0 V when the current spike beggings, with a peak > 1 A, so I believe the test power supply which is limited to 500 mA is shutting down with each PWM duty change so V_out drops from 1.7 V to zero. The oscilloscope shows a clear current resonance (ringing). Note that current is measured through voltage drop on the R_sense and that the oscilloscope has a large offset error which I compensated in my estimations.

I changed the Vin voltage diveder resistors from R5 220 kΩ -> 100 kΩ & R6 4.7 kΩ -> 1 kΩ. Vin ADC measurement are much more stable over time now, though I still see erratic ADC mesurements at the beginning of the soft start of the buck DC/DC converter. I have the hypothesis it is perhaps due to a combination of Vin drops due to current ringing/overshoot during soft-starting and noise inherit to the ADC and resistors R5 and R6.

I implemented a provisional soft-start firmware code (below), that "printf" values for debugging with large enough delays of 1.5 seconds to visualize the program execution for debugging. This time, with very slow duty increases every time of d = 0.001, even though I still observe current ringing, V_out ends up estabilizing at around 3.1 V and d = 0.11. During this soft start, V_out ADC measurements seem much more estable (I had to do a major recalibration based on emperic measurements), but V_in ADC measurements look unstable, oscillating wildly from 9 V to 13 V approx, sometimes even 2 V to 21 V for an oscilloscope measured V_out of approximately 3.1 V.

while(true) {
//while (float_V_out < 4.0) {

		if (buck_duty < 0.11 && (float_V_in < 40) && (float_V_in > 8))
			buck_duty = buck_duty + 0.001;
		
		int raw_ADC_GPIO34 = adc1_get_raw(ADC1_CHANNEL_6);  // Read ADC value
    	float_V_out = raw_ADC_GPIO34 / adc_to_V_out;
    	
    	int raw_ADC_GPIO32 = adc1_get_raw(ADC1_CHANNEL_4);  // Read ADC value
    	float_V_in = raw_ADC_GPIO32 / adc_to_V_in;
    	
    	printf("Soft-starting, Vin = %f, Vout = %f\n", float_V_in, float_V_out);
    	printf("Soft-starting, PWM duty = %f\n", buck_duty);
    	printf("Output overvoltage detected during run [0=No, 1=Yes, OV detected at some point]: %d\n", bool_V_out_overvoltage);
    	ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, (uint32_t)(buck_duty * MAX_DUTY));
		ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
		vTaskDelay(pdMS_TO_TICKS(1500));
}

I modifed the delay from 1500 ms to 10 ms for soft start and restarted operation, this time the V_out also rose and establized correctly.
However, I measured voltage on ADC channel input for Vin and Vout and found large voltage increase and decrease spikes, though there is surely a flat voltage baseline. See below image, where the blue line is V_in voltage and the orange like is V_out.

I measured the current on the (-) side of the load of the DC/DC converter and the ESP32 ADC V_in voltage simultaneously to compare them (below picture, left side). I also measured the current on the (-) side of the load of the DC/DC converter and the ESP32 GND relative to the DC/DC converter PCB input GND. As you can see in the oscilloscope pictures, there are big voltage spikes on both ESP32 ADC Vin and ESP32 GND related to input GND, that happens exactly when there are current oscillation (ringing) on the load, due to high di/dt.

I experimented placing a 1 nF, 10 nF and 100 nF ceramic capacitor close to the ESP32 ADC pin (currently EPS32 is provisionally connected through long wires and breadboard to the PCB 100 nF capacitors, so it is important to nore that the results from the test done with the ESP32 on breadboard will differ from the real PCB with ESP32 soldered test results, due to shorter distances and different measurement point of the oscilloscope). 10 nF and 100 nF close to the ESP32 ADC indeed make the voltage spikes sinificantly lower. 1 nF lowers the spikes too, to a lesser degree. Therefore, I think the Vin and Vout spikes issue will be mitigated when I solder the ESP32 to the PCB, and I hope I can further mitigate by adding measurement averageing or digital filtering and/or an additional 10 nF ceramic capacitor in parallel with the 100 nF (10 nF likely has lower ESR and lower ESL, so it might filter the some of the high frequency spikes more effectively than the 100 nF capacitor).

I also realized the grounding of the ESP32 MCU is not be ideal, and share part of the high di/dt of the power ground path (PGND), which is likely causing this GND potential reference on the MCU. I plan to modify the ESP32 ground connecting by manually soldering a wire following a ground return path to the DC/DC input bulk capacitor as indicated in the picture below.
.
As it can be seen in the image the V_out ADC input voltage still has noticeable spikes, though the voltage decreases from the spike to baseline voltage smoothly (like an RC discharge), while the V_out ADC input voltage has even larger spikes than before.
Below is comparison of V_in and V_out measured with oscilloscope on the ESP32 ADC pin, the left one with GND sharing a large part of the power ground return path, the right one with GND of the ESP32 directly connected to the DC/DC input capacitor (-).

After soldering the ESP32 to the PCB, I still see massive voltage spikes on Vin ans Vout ADC input pins (picture below showing the oscilloscope screen and PCB with measurement points). This time, I have a 100 nF ceramic cap in Vin ADC and another one in Vout ADC pins.

電圧平均化とPI制御チューニング || Voltage averaging and PI control tuning

I finally mitigated the voltage spikes issue on the ADC input ESP32 pin by adding 1 μF in the input, and using much lower resistance values for the voltage divider (5K1 and 510 Ω). Also, it was needed to do voltage measurement averaging on software to mitigate the spikes, I used 10 samples average (not moving average). Below is the piece of code I used for the avergaing of the ADC samples. Later I used 20 samples, it improved the estability of PI control and misdetecting of overvoltage.

float_V_out_averaged = 0;
for (int i=0; i < no_adc_samples; i++){
float_V_out_averaged = float_V_out_averaged + adc1_get_raw(ADC1_CHANNEL_6)/adc_to_V_out/no_adc_samples;
}

If this is not properly, the soft-start, PI controller and overvoltage detection (interrupt programmed in the microcontroller) produced hunting, unstable behavior, unintended shut down and even uncontroller re-starting after the DC/DC shuts down to do misdetected overvoltage (below a picture of the output voltage shuttin down due to this, which was fixed later.)

Below the output voltage waveform (V_out) of the test with the V_out sensor wrongly calibrated to inject an overvoltage fault and verify the reaction of the output TVS diode (rated 6 V, intended to be a redundant, last resource overvoltage protection). As you can see, V_out drops to 0 V after it surpasses 6.3 V.
💡Resistor values of the V_out voltage divider drift over time due to aging and thermal stress. There is a concern that over time the V_out will need recalibration, due to risk of over/undervoltage.

Below is the output voltage (V_out) waveform with soft-start and transitioning to PI, controller. There is some voltage overshoot at 5.42 V peak (within 5.5 V, which is the upper limit for charging a smartphone by USB typically), then voltage is estabilized quickly by the PI controller (Kp = 0.001 Ki = 0.0001) at 5.0 V.

As written above, the issues were fixed and did the first test charging a smartphone battery by USB cable with the DC/DC converter (below photo)

軽負荷(DCM)動作中の電圧オーバーシュート対策 || Countermeasure for voltage overshoot at low load operation (DCM)

Below the output voltage after removing the load (empty test). The current is assumed to be almost 0, so DCM is ensured. The output voltage peaks at 5.9 V, charging the output capacitor from 3.2 V to 5.9 in around 100 ms. It later reduces voltage following a typical RC discharge curve from 5.9 V to 3.2 V in around 2 seconds. For this test, a test power supply (24 V) was used instead of a solar panel.

Resistance between V_out(+) and V_out(-) pins with no load connected is measured at 3.8 kΩ (The output LED current limiter resistor is 10 K). This a fairly high discharge resistance value during DCM operation (no load), consuming V^2/R = 5^2/3.8 = 6.6 mW (Negligible compared to the 5 W of minimum charging power). In order to establize the output voltage during DCM (no load) operation and avoid an overvoltage applied right the load is connected to the USB charging port, it might be possible to decrease the PI controller K_p constant to decrease the overshoot. However, since the "no load" current is really low, the output capacitor may charge too much even if the PI controlller is perfectly tuned, as the PWM pulses may be too long. One option could be implementing a specific "burst mode", but this would be need a fine tuned transition strategy from DCM to CCM operation with proper detection. A simpler measure could be to just decrease the V_out (+) to V_out (-) pin resistance further, to allow the ouput capacitor to discharge enough during the off PWM semicycle during DCM (no load operation).

Below is the input voltage waveform in blue, and the ouput voltage waveform in orange, after soldering a 220 Ω resistor in parallel with the output capacitor, resulting in 188 Ω (total). The big voltage oscillations due to DCM have disappeared, at the expense of having 0.13 W power losses.

理想電源とソラーパネル電源の違いと内部電源ディカプリングの困難  || Ideal power supply and solar panel supply difference and dificulties with the internal supply decoupling

Below a picture of the the first test charging a phone with a solar panel. The blue line in the oscilloscope shows the solar panel voltage (input), and the orange the output voltage.

Below a pictured zoomed in, where the voltage curves can be seen with higher resolution. Input voltage (solar panel) oscillates from around 7 V to 12 V. Naturally, the buck converter output shuts down multiple times due to too low voltage (programmed to do soft-start from 8 V input as a minimum), and it stays significantly below the 5 V output target. At times, the phone connected by USB to the DC/DC converter charges/powers up briefly.

The test is done on 2026-01-17 in Tokyo between 15h and 16h.
Based on forecasts for January 17, 2026, the global solar radiation ((W/m^{2})) in Tokyo is low due to winter, with peak values typically occurring around midday. Morning (Approx. 9:00 AM): ~16 (W/m^{2}).Daytime Peaks: Ranges between 150-300 (W/m^{2}) depending on cloud cover and exact location (e.g., Haneda vs. Central Tokyo).
I am using 「Quarue 12V Solar Panel Kit 30W」. Assuming at 1000 W/m^2 it outputs 30 W, and an efficiency of 80% (MPPT is not implemented), the solar panel would be outping less than 7.2 W (likely much less), which is likely not enough to charge a phone. This explains the results of the test.

I conducted another test on 2026-01-27 in tokyo at 12 h, in a fairly sunny day in the winter. The The ESP32 board was only powering the "ON" internal LED, and not the "TX" LED as with a test power supply (even if I measured 3.1 V on its 3_3V pin, which is sufficient for powering it on). The DC/DC input LED was also powered. However, there was no PWM signal at the gate of the MOSFET (which was working when tested with a 24 V test power supply instead of the solar ponel). The "TX" LED not blinking suggests that the ESP32 is not booting correctly when powered from a solar panel. I scoped the voltage at the ESP32 3_3V pin and GND pins, and I could not observe any sudden voltage drop that indicates brown out, the voltage waveform looks perfectly flat even at a time scale ranging of 10 ns, 50 ns, 500 ns, 10 μs, 500 μs,1 ms up to 10 seconds. However, there is slight difference between voltage measured by the oscilloscope (2.8 V on average) and voltage measured with the multimeter (3.1 V). I measured at almost the same point with both devices and as close as possible to the ESP32 board MCU. My multimeter tends to have much more accuracy, but there is the possibility that voltage is permanently too low for the ESP32. I also did the exact same measurement with the test power supply instead of solar panel, with identical measurements, which suggest the actual average voltage applied to the ESP32 is correct, though I suspect there might be attempts to draw current from the solar panel that cause some undervoltage instant that I cannot capture with the oscilloscope. I also measured the ESP32 EN pin (constantly high) and GPIO 17 (PWM output), which was indeed constantly low, both from very low time scale (<1 ms to seconds).
Below is a picture of the oscilloscope and DCDC converter. The blue line is the Vcc input of the DCDC, coming from the solar panel (seems faily stable at 18 V, so UVLO is discarded), and the orange one is the voltage measured at 3_3V pin.

💡ESP32の3_3V電源ピンに0.1μF既存セラミックコンデンサを維持し、220μFの電解コンデンサも入れました。これを行うことでソラーパネルでもESP32がきちんと起動できました。DC/DCの出力電圧も円滑にあがりました。
I kept the 0.1 μF ceramic capacitor and added 220 μF electrolytic capacitor at the ESP32 3_3V supply pin. By doing that, the ESP32 could start even if connected only to the solar panel. The DC/DC output voltage also rose smoothly.

On 2026-01-30 I did an uninterrupted test with solar panel input (around 20 V) during 11:30 h and 12:00 h in Tokyo on a winter sunny day. The ESP32 "TX" LED did not turn on, and the DC/DC output was again at almost 0 V. I observed that if I deactivate the solar panel by removing sun radiation from it and power it on with the test power supply, it works. However, it does not work if I connect both the solar panel (around 20 V) and the test power supply (24 V) at the input of the DC/DC converter even if each one is connected through a power Schottky diode to the common Vcc input of the DC/DC converter (This could be the test power supply which is designed to shut down if the output voltage mismatches de 24 V output, not necessarily a design failure). I measured almost no reisstance between the 220 μF capacitor leads to the ESP32 3.3V and GND terminals, so there should not be any connection issue. Also, the LM317 powering the ESP32 from Vcc (solar panel / test power supply) was fairly hot, I could keep my finger indefinetely touching its heatsink, but feeling quite hot, which suggest there was a significant current flowing towards the ESP32 and 220 + 0.1 μF capacitors (there is no other load connected to the LM317 of the 3.1 V rail).

On 2026-02-01 at 14 h in Tokyo I did another round of tests, one adding a 3.3 μF at the input of the LM317, which failed, and another one adding 47 μF (50 μF in total at the input of the LM317, which is supoosedly enough to counter the inductance of the long cable from the solar panel. This time, there was an unexpected behavior, in which the "16" LED of the ESP32 turned on with a very bright blue light, and the "TX" LED was blinking in red color. The DC/DC converter output was still at almost 0 V (not working).
Adding a 100 nF ceramic capacitor and exposing the solar panel to the sun again at 14.30 h makes the "16" LED turn bright blue and sometimes green or orange. After soldering the 100 nF capacitor pin closer to GND, the DC/DC converter finally worked and output 5 V when power purely by the solar panel at 14h50m in Tokyo in winter. Below is a picture of the provisionally soldered 3 capacitors.

💡Indeed, the very long wires of the solar panel require low ESR/ESL decoupling at the LDOs input to handle current peaks (not only at the MCU), which I had not planned during the design phase.
💡The fact that I could not oberve any voltage drop during power up hints at an oscilloscope setup that may be hidding it, perhaps also related to the ESP32 board pins are far enough from the built in ESP32 MCU and the measuring point is far enough to affect the masurement due to stray inductance/capacitance.
💡I also regret having used only LDOs to reduce from >20 V to 3.1 V. This causes a very large power loss. I could have designed for using the DC/DC output of 5 V to power the LDO or even the ESP32 microcontroller board directly, and having another LDO just to do the initial boot of the microcontroller, for example. Initally, I tried with an auxiliary switching converter, which failed as documented previously in the article.

長時間のUSB充電テスト、過温度の課題 || Long duration USB charge test and excessive heating

震度なし、基板を全く動かずDCDCはきちんと動くケースもあり、DCDCのVinのLEDはきちんとオンになるが、Voutはほぼ0Vというケースもあります。基板の両面は何とも接していない状態でも、オシロスコープなどでも測っても測らなくても変わりません。不思議な振る舞いです。原因はまだ突き当たり出ていません。

数分動作で、LM317はかなり熱くなりました。Thermal cameraなどはありませんが、指で触った際、1秒も維持できないほど暑かったです。そのため、ヒートシンクを付けました(以下の写真)。
24 V → 3.1 V、ESP32の消費電流は最大60mA想定で、電力損失は1.3Wに達する。LM317にとって厳しくて、ヒートシンクで耐えられる可能性が高い。

以下はオシロスコープで測定したV_DSとV_GSとなります。オシロスコープのGNDクリップはダイオード(Switching node)、他はMOSFETのDrain(ヒートシンク)とMOSFETのSourceピン。

古いスマートフォン(負荷なしと同じ波形)

Sony Xperia

【5.総合機能試験 || Overall functional test】

Solar panel input

東京で2026年2月3日の12時半ごろにソラーパネルのみに接続し、USB出力でスマホを充電できました。
以下の写真でセットアップと充電Appの充電電流や電力が表示されます。
I could charge a smartphone by USB in Tokyo on 2026-02-03 at around 12.30 h from a solar panel. The picture below shows the setup and app displaying charging current and power.

Efficiency test

Measurement results (6 Ω load)

V_{in} [V] I_{in} [A] P_{in} [W] V_{out} [V] I_{out} [A] P_{out} [W] Efficiency
12.0 0.54 6.48 5.48 0.91 5.00 77.2 %
15.0 0.46 6.90 5.49 0.92 5.04 73.0 %
18.0 0.40 7.20 5.49 0.92 5.04 70.0 %
20.0 0.37 7.40 5.49 0.92 5.04 68.1 %
24.0 0.32 7.68 5.49 0.92 5.04 65.6 %
30.0 PSU shutdown

Note: Input voltage values correspond to the PSU setting.

  • Output voltage remained well regulated at ~5.49 V up to 24 V input.
  • Input current decreased with increasing V_{in}, as expected for a buck converter.
  • Efficiency decreased at higher input voltage (likely switching + conduction losses).
  • At 30 V input, the PSU shut down abruptly.

測定結果(6 Ω負荷, 無負荷補正あり)

無負荷時(LED・LDO等のみ)の入力電流は全電圧で約 0.09 A であり、これを待機電力として補正効率も算出した。

Vin [V] Iin [A] Pin [W] Vout [V] Iout [A] Pout [W] η ηcorr
12.0 0.09 1.08 - - - - -
15.0 0.09 1.35 - - - - -
18.0 0.09 1.62 - - - - -
20.0 0.09 1.80 - - - - -
24.0 0.09 2.16 - - - - -
12.0 0.54 6.48 5.48 0.91 5.00 77.2 % 92.6 %
15.0 0.46 6.90 5.49 0.92 5.04 73.0 % 90.8 %
18.0 0.40 7.20 5.49 0.92 5.04 70.0 % 90.2 %
20.0 0.37 7.40 5.49 0.92 5.04 68.1 % 89.8 %
24.0 0.32 7.68 5.49 0.92 5.04 65.6 % 91.1 %

※補正効率は P_{in}-P_{idle} を用いて算出

結論:軽負荷での効率低下は主に待機電力(LDO・LED等)によるものであり、補正後は約90%前後と高効率である。一方で入力電圧上昇に伴う効率低下は導通損失やスイッチング損失の増加による。

Thermal observation and loss estimation (Vin = 13.8 V)

Measured voltage drops

Path Voltage drop [V] Estimated current [A] Power loss [W]
Inductor 0.011 0.91 0.010
Inductor → Output trace 0.005 0.91 0.005
Output GND → Input GND 0.021 0.91 0.019
Total (measured conduction losses) ~0.034 W

Thermal observations

  • LDO temperature: ~40°C
  • Inductor: ~ambient
  • MOSFET: ~ambient

Interpretation

  • Conduction losses in the power stage are extremely low (~34 mW total)
  • No significant heating in inductor or MOSFET confirms:
    • Low DCR in inductor
    • Low R_{DS(on)} or low current stress
  • The only component showing noticeable heating is the LDO

Root cause of LDO heating

The LDO dissipates:

P_{LDO} = (V_{in} - V_{out,LDO}) \cdot I_{LDO}

Even with small current, the voltage drop from 13.8 V makes it the dominant loss source.

Conclusion

At Vin = 13.8 V:

  • Power stage is highly efficient and not thermally stressed
  • Losses are dominated by auxiliary circuitry (LDO)
  • Overall efficiency degradation at higher Vin is likely driven by:
    • LDO dissipation
    • Switching losses (not captured in DC drop measurements)

Modelling the DC/DC in LTspice simulation || LTspiceでモデル化

[LTspice simulation] inrush current and overshoot without soft-start || 突入電流・電圧再現

以下はSoft-startなし、Open loopモデル(LTspice)になります。R1(6mΩ)、R2(21mΩ)、L1のDCR値(12mΩ)を以前測定された電流と電圧降下で算出。

負荷6Ωの場合,(10Ω、10kΩ同様)、入力コンデンサー容量47μFで、電源から0.8 A以上引かれるという結果。以前確認した(リンク以下)Soft startなしのテスト電源過電流検出による遮断挙動を再現できました。 || I could replicate the behavior observed of the buck DC/DC without soft-start triggering the test power supply overcurrent detection shutdown (more than 0.8 A inrush, power supply used initially was 500 mA).
https://zenn.dev/okadda1/articles/f2be90f321acd7#soft-start実装による過電流・オーバーシュート対策-||-soft-start-to-mitigate-over-current-and-overshoot

[LTspice simulation] output voltage clamping due to DCM || DCMモード出力電圧再現

負荷1000Ωでも(25 mW)DCMをLTspiceで再現できました。インダクタ(L1)電流は当面瞬時的に2.4Aをに達しまた。定常状態でインダクタ電流は約0.1Aになり、V_outはほぼV_inと同じになりました。

https://zenn.dev/okadda1/articles/f2be90f321acd7#出力電圧が固定される課題(dcm)||-output-voltage-clamped-due-to-dcm

[LTspice simulation] efficiency measurements|| 負荷の送電効率測定を再現


Simulation vs. Real-World Results with IRFZ44N and LTspice models

Parameters LTspice (MBR745 diode) Physical Prototype (20SQ040) Delta
Efficiency @ 12V In 92.42% 92.60% -0.18%
Efficiency @ 18V In 90.81% 90.20% +0.61%
評価条件 LTspice (MBRB2545CT diode)) 実機プロトタイプ (20SQ040) 誤差 (Delta)
効率 @ 12V 入力 92.89% 92.60% +0.29%
効率 @ 18V 入力 91.29% 90.20% +1.09%

Efficiency simulations and real sample measurements (https://zenn.dev/okadda1/articles/f2be90f321acd7#測定結果(6-ω負荷%2C-無負荷補正あり)) are really close → ✅The LTspice model DC/DC buck plant model is validated for later efficiency simulations

Control (PI) tuning || 制御PIチューニング

PI control tunning with a controlled lab power supply

Solar panel output voltage can swing significantly during operation due to clouds or other metheorologic phonema. Thus, the output voltage must stay relatively stable and close to target output voltage in the event of large input voltage rises and falls. The initial Kp and Ki parameters seem to be too mild based on some simple manually done lab test varying input voltage (orange line in oscilloscope, blue line is output), where output voltage rises above allowed voltage (5.5 V).

Kp is the parameter that influences fast response the most

Kp = 0.1; Ki(unit) = 0.0001(1/ms) = 0.1 (1/s); time_sampling_ms = 1; VOUT 5.0
Just after soft-start, DC/DC output stays at around 5 to 5.5 volts and shuts down soon after →recovers in soft start →shuts down... (continuosly). Overshooting was not observed in oscilloscope.

Kp = 0.01; Ki(unit) = 0.0001(1/ms) = 0.1 (1/s); time_sampling_ms = 1; VOUT 5.0

Output voltage seems stable, though input voltage fluctuations drive output voltage up and down excessively.

Kp = 0.03; Ki(unit) = 0.0001(1/ms) = 0.1 (1/s); time_sampling_ms = 1; VOUT 5.0

After soft start, DC/DC shut down a few times, but kept in normal operation for minutes. Output voltage converges to 5.0 V much faster at heavy input voltage fluctuations.
Below a test done for 110 seconds, where sudden input voltage steps up/down (blue line) are manually generated with a power supply and output voltage is observed (orange). The DC/DC ouput shuts down and recovers several times during the test, though not due to input voltage fluctuations, but during steady state is theoretically achieved. Some "bumps" in output voltage during steady state are observed.

Above output voltage fluctuations and unstable behavior are likely caused by an overreaction to accumulated calculated error (V_ref - V_out) due to excessive Ki in the PI controller. To investigate it, I did the following tests:

Kp = 0.03; Ki(unit) = 0.00001(1/ms) = 0.01 (1/s); time_sampling_ms = 1; VOUT 5.0
#define buck_controller_KI 0.00001

Shows comparable or even less stability than before. However, it could be due to the microcontroller numerical calculation failing due to extremelly small numbers and float variables used (partly confirmed by the next test case).

Kp = 0.03; Ki(unit) = 0.0001; time_sampling_ms = 10; VOUT 5.0
#define time_sampling_ms 10
#define buck_controller_KI 0.0001

✅ Much more stable after returning to the original Ki=0.0001 but increasing the sampling time for the integrator controller to reach from 1 ms to 10 ms. This is equivalent to reducing the physical K_i (as in the test case before), by keeping constant the digital Ki and increasing the time of the intervals at which the Ki is actually applied to the regulator.

Test the tuned controller with a real solar panel

In this test, I observed actual solar panel voltage variations on Tokyo 2026-04-03 at 11:36~12:00h on a sunny day. Total solar radiation: 6661 wh/m2.

Load = 6 Ω resistor (4.2 W)

Above oscilloscope picture shows how the DC/DC outputs a maximum of 4.2 V and shutd down repeatedly during almost two minutes (not reaching the required 5.0V +/-0.5 and shuts down due to sudden input voltage drops from the solar panel. The solar panel is not generating enough power for this test.
💡The ESP32 MCU board does not boot up correctly if the solar panel does not output voltage fast enough (MCU stays with only one LED blinking in idle state). IT was required to cover the solar panel and uncover it very quickly to make the MCU boot up correctly.

Load = real smartphone + 0.1Ω current measurement resistor in series

Current measured on 0.1Ω series resistor (voltage drop) below.

The current injected to the smartphone charging input (USB) does not look continous, but has large peaks. RMS measured values over more than 1 minutes is 0.03 V drop (equivalent to 0.3 A on the 0.1Ω resistor). However, the measurement may be contaminated with voltage noise and voltage spikes, happening due to di/dt and the inductance of the measurement resistor, which is a long, cement resistor with thin wires rather than a proper shunt resistor.
Below the same measurement than on a test power supply instead of solar panel for comparing the charging current (there seems to be a large 50~100 ns period component (20~40MHz).

✅ The smartphone charges (SoC estimated by the phone itself) increased slowly overtime, so charging is assumed to happen succesfully, though at a very limited power.

💡In order to make the start up of the ESP32 MCU from solar panel, I have added even more capacitance at the input, which clearly allowed to start up the DC/DC from the solar panel more easily. I also added more capacitance at the output to further improve stability.

Solar panel charging test || ソーラパネル充電評価

Smartphone USB charging from the solar panel for hours at around 400~500 W/m2 || ソラーパネル入力(約400~500 W/m2)で数時間スマートフォンUSB充電

Increasing charging power with USB-C and USB-A || USB-CやUSB-Aによる充電電力増加

To increase the charging power over USB-C, I added two 20 kΩ pull-up resistors from the 5 V output to the CC1 and CC2 pins.

However, the charging power remained very limited. Right after the smartphone was plugged in, both CC1 and CC2 were briefly pulled down close to 0 V. They were then pulled up to an intermediate voltage and finally rose further, settling near 4.1 V.

Below are the output voltage (orange) and one CC line (blue).

Below are the waveforms of both CC1 and CC2.

In USB Type-C, a source advertises available current through pull-up termination (Rp) on the CC pins, while a sink presents Rd on both CC pins. In a normal receptacle-to-device connection, only one CC path should become active depending on cable orientation. The fact that both CC1 and CC2 show similar behavior, and that the final voltage stays high near 4.1 V, suggests that the smartphone detects some activity on the CC lines but does not complete a normal strong source attachment.

Therefore, the limitation is likely not caused only by the control loop or output-voltage regulation. It is more likely related to the USB-C source implementation itself, such as connector topology, CC wiring, or VBUS behavior during attachment.

I realized USB-C is not supported by the current cable, which only has D+ and D- (USB-A). I connected both D+ and D- together (shorted) and tried to charge a phone. I measured 0.9 V at D+/D- against input ground. Charging power seems very limited or stopped, as V_out drops from 5.0 V to 3.8 V momentarily and repeatedly when plugging the phone to the DC/DC USB output (verified doubly with oscilloscope -below- and with DMM). Oscilloscope blue line is voltage drop across current sense, though the spikes occur regardless on if the load connected or not, so it is assumed to be coupling noise.

Adding 10μF ceramic did not significantly affect.
Adding 1500μF electrolytic (removing the ceramic) together to the exisiting 220μF one caused the following behavior: sudden drop of around 1 V, recovery with mild overshoot, slow but huge voltage drop followed by an even slower recovery.

電流3A適正USBケーブルに交換すると、全く同じ挙動。負荷なし定常状態→6Ω負荷テストをすると、電圧はほぼ0Vになり、ソフトスタートで電圧復帰。ソフトスタート中に6Ωの負荷を外すと、電圧サージ(overshoot)発生。

Smartphone tries to pull some current and observes the bus voltage drop. It was needed to modify the microcontroller control startegy (below code) to allow deeper voltage drops (from 4.5 V to 3.0 V as minimum condition) while staying in PI control.

#define VOUT_MIN_OPERATION 3.0

...
// PI controller (used if Vout has reached a normal operation value (> 5.0 V) after soft start)

while (float_V_out_averaged > VOUT_MIN_OPERATION && float_V_in_averaged > VIN_MIN_LIMIT && float_V_in_averaged < VIN_MAX_LIMIT) {

...

Output voltage experiences realtively big swings 5.0 V (very low current, DCM mode, very low duty) → 3.2 V (CCM mode due to larger current and duty rising to keep voltage at 5.0) → 6.2 V (voltage overshoot) → 5.0 V. The behavior does not cleary change with Kp = 0.03 or 0.05.

Adding a 10μF ceramic appears to change the behavior significantly (disclaimer measurement point differs) though redoing the tests with the same conditions gives different results at times (below picture). Charging though USB happens, though at much lower current than the target USB-A 1 A ~ 1.5 A (estimated 200 mA ~ 600 mA). The smartphone seems to still not recognize it as source capable of higher power, likely due to excessive voltage drop. Higher output capacitance, lower ESR / path resistance can reduce the voltage drop momentarily and allow the USB charging system at the smartphone to work at higher power. Digital PI controller faster response may also help to reducte the voltage drop.

Load transient test with increased output capacitance

Test conditions:

  • 220 µF ×2 + 10 µF ceramic ×2
  • Smartphone load (USB-A, D+ shorted to D−)
  • Same setup, wiring, probe position and conditions for all measurements

Observed behavior (same conditions, different responses, regardless of measurement point at the ceramic capacitor or output connector):

Note:
High-frequency spikes and oscillations may be partially affected by measurement coupling (probe ground loop / EMI pickup).

Conclusion:
Non-deterministic behavior → interaction between control, restart logic and dynamic load. Not only capacitance.

ADC feedback vs actual Vout during load transient

Test conditions:

  • Smartphone connected to USB output
  • Same probe position and wiring for all measurements

ADC input voltage closely tracks actual Vout during the transient. ADC feedback distortion due to EMI is not the dominant cause of instability.

Firmware param allows higher charge power || ファームウエアパラメーター変更でより高い充電力

#define VOUT_TARGET 5.2
#define VOUT_MIN_OPERATION 2.0

Charging remaimed unstable and slow as before. Suddenly, after rougly 1 minute, the test PSU started drawing much more current (before 0.10~0.11 A, after 0.19~0.20 A). No load consumption is 0.09 A, so 0.10~0.11 A of charging, at V_in 16~17 V, charging power of 1.6 W ~ 1.9 W was achieved.

Next improvement ideas

  • Replace LDO with a small buck converter (major efficiency gain)
  • Replace the microcontroller ESP32 board by a lower consumption ASIC tonincrease efficiency
  • Implement a double, nested PI control based on peak or average current and target voltage, rather than purely on output voltage for fast resposne and state of the art control.

Discussion