void part3_ex2_noise_generator(void)
{
lv_obj_t *scr = lv_screen_active();
lv_obj_set_style_bg_color(scr, lv_color_hex(0x0a0a1e), 0);
/* สร้าง Clean signal ครั้งเดียว */
generate_clean_signal();
/* ===== Title ===== */
lv_obj_t *title = lv_label_create(scr);
lv_label_set_text(title, "Part 3 Ex2: Noise Generator & SNR");
lv_obj_set_style_text_color(title, lv_color_hex(0x00ff88), 0);
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 5);
/* ===== Chart ===== */
ex2_chart = lv_chart_create(scr);
lv_obj_set_size(ex2_chart, 400, 150);
lv_obj_align(ex2_chart, LV_ALIGN_TOP_MID, 0, 30);
lv_chart_set_type(ex2_chart, LV_CHART_TYPE_LINE);
lv_chart_set_point_count(ex2_chart, DISPLAY_POINTS);
lv_chart_set_range(ex2_chart, LV_CHART_AXIS_PRIMARY_Y, 0, 100);
lv_chart_set_div_line_count(ex2_chart, 4, 5);
/* Dark oscilloscope style */
lv_obj_set_style_bg_color(ex2_chart, lv_color_hex(0x001a00), 0);
lv_obj_set_style_line_color(ex2_chart, lv_color_hex(0x003300), LV_PART_MAIN);
lv_obj_set_style_border_color(ex2_chart, lv_color_hex(0x006600), 0);
lv_obj_set_style_border_width(ex2_chart, 1, 0);
lv_obj_set_style_size(ex2_chart, 0, 0, LV_PART_INDICATOR);
/* Clean signal series (สีเขียว) */
clean_series = lv_chart_add_series(ex2_chart,
lv_color_hex(0x00ff00), LV_CHART_AXIS_PRIMARY_Y);
/* Noisy signal series (สีแดง) */
noisy_series = lv_chart_add_series(ex2_chart,
lv_color_hex(0xff4444), LV_CHART_AXIS_PRIMARY_Y);
/* ===== Noise Level Slider ===== */
lv_obj_t *noise_lbl = lv_label_create(scr);
lv_label_set_text(noise_lbl, "Noise Level:");
lv_obj_set_style_text_color(noise_lbl, lv_color_hex(0xaaaaaa), 0);
lv_obj_align(noise_lbl, LV_ALIGN_LEFT_MID, 10, 50);
lv_obj_t *noise_slider = lv_slider_create(scr);
lv_slider_set_range(noise_slider, 0, 1000);
lv_slider_set_value(noise_slider, noise_amplitude, LV_ANIM_OFF);
lv_obj_set_width(noise_slider, 200);
lv_obj_align(noise_slider, LV_ALIGN_CENTER, 20, 50);
lv_obj_add_event_cb(noise_slider, noise_slider_cb,
LV_EVENT_VALUE_CHANGED, NULL);
noise_val_label = lv_label_create(scr);
lv_label_set_text_fmt(noise_val_label, "%d", (int)noise_amplitude);
lv_obj_set_style_text_color(noise_val_label, lv_color_hex(0xff6666), 0);
lv_obj_align(noise_val_label, LV_ALIGN_RIGHT_MID, -15, 50);
/* ===== SNR and RMS Labels ===== */
snr_label = lv_label_create(scr);
lv_label_set_text(snr_label, "SNR: -- dB");
lv_obj_set_style_text_color(snr_label, lv_color_hex(0x00ffff), 0);
lv_obj_set_style_text_font(snr_label, &lv_font_montserrat_16, 0);
lv_obj_align(snr_label, LV_ALIGN_BOTTOM_LEFT, 10, -40);
rms_label = lv_label_create(scr);
lv_label_set_text(rms_label, "RMS(S): -- RMS(N): --");
lv_obj_set_style_text_color(rms_label, lv_color_hex(0x888888), 0);
lv_obj_align(rms_label, LV_ALIGN_BOTTOM_RIGHT, -10, -40);
/* ===== Control Buttons ===== */
/* Start/Stop */
lv_obj_t *btn_ss = lv_btn_create(scr);
lv_obj_set_size(btn_ss, 80, 30);
lv_obj_align(btn_ss, LV_ALIGN_BOTTOM_LEFT, 10, -5);
lv_obj_add_event_cb(btn_ss, start_stop_cb, LV_EVENT_CLICKED, NULL);
btn_label = lv_label_create(btn_ss);
lv_label_set_text(btn_label, "Stop");
lv_obj_center(btn_label);
/* Gaussian/Uniform toggle */
lv_obj_t *btn_gauss = lv_btn_create(scr);
lv_obj_set_size(btn_gauss, 100, 30);
lv_obj_align(btn_gauss, LV_ALIGN_BOTTOM_LEFT, 100, -5);
lv_obj_add_event_cb(btn_gauss, gaussian_toggle_cb,
LV_EVENT_CLICKED, NULL);
lv_obj_t *gauss_lbl = lv_label_create(btn_gauss);
lv_label_set_text(gauss_lbl, "Uniform");
lv_obj_center(gauss_lbl);
/* ===== Timer ===== */
noise_timer = lv_timer_create(noise_timer_cb, 100, NULL);
/* แสดงผลครั้งแรก */
update_display();
}