@@ -482,7 +482,7 @@ void Charger::run_state_machine() {
482482 // make sure we are enabling PWM
483483 if (not hlc_use_5percent_current_session) {
484484 auto m = get_max_current_internal ();
485- update_pwm_now_if_changed ( ampere_to_duty_cycle (m) );
485+ update_pwm_now_if_changed_ampere (m );
486486 } else {
487487 update_pwm_now_if_changed (PWM_5_PERCENT);
488488 }
@@ -569,12 +569,12 @@ void Charger::run_state_machine() {
569569 if (hlc_use_5percent_current_session) {
570570 update_pwm_now_if_changed (PWM_5_PERCENT);
571571 } else {
572- update_pwm_now_if_changed ( ampere_to_duty_cycle ( get_max_current_internal () ));
572+ update_pwm_now_if_changed_ampere ( get_max_current_internal ());
573573 }
574574 } else {
575575 // update PWM if it has changed and 5 seconds have passed since last update
576576 if (not hlc_use_5percent_current_session) {
577- update_pwm_max_every_5seconds ( ampere_to_duty_cycle ( get_max_current_internal () ));
577+ update_pwm_max_every_5seconds_ampere ( get_max_current_internal ());
578578 }
579579 }
580580 }
@@ -643,7 +643,7 @@ void Charger::run_state_machine() {
643643 } else {
644644 // update PWM if it has changed and 5 seconds have passed since last update
645645 if (not errors_prevent_charging_internal ()) {
646- update_pwm_max_every_5seconds ( ampere_to_duty_cycle ( get_max_current_internal () ));
646+ update_pwm_max_every_5seconds_ampere ( get_max_current_internal ());
647647 }
648648 }
649649 }
@@ -887,13 +887,15 @@ void Charger::process_cp_events_independent(CPEvent cp_event) {
887887 }
888888}
889889
890- void Charger::update_pwm_max_every_5seconds (float dc) {
890+ void Charger::update_pwm_max_every_5seconds_ampere (float ampere) {
891+ float dc = ampere_to_duty_cycle (ampere);
891892 if (dc not_eq internal_context.update_pwm_last_dc ) {
892893 auto now = std::chrono::steady_clock::now ();
893- auto timeSinceLastUpdate =
894+ auto time_since_last_update =
894895 std::chrono::duration_cast<std::chrono::milliseconds>(now - internal_context.last_pwm_update ).count ();
895- if (timeSinceLastUpdate >= 5000 ) {
896+ if (time_since_last_update >= IEC_PWM_MAX_UPDATE_INTERVAL ) {
896897 update_pwm_now (dc);
898+ internal_context.pwm_set_last_ampere = ampere;
897899 }
898900 }
899901}
@@ -919,17 +921,27 @@ void Charger::update_pwm_now_if_changed(float dc) {
919921 }
920922}
921923
924+ void Charger::update_pwm_now_if_changed_ampere (float ampere) {
925+ float dc = ampere_to_duty_cycle (ampere);
926+ if (internal_context.update_pwm_last_dc not_eq dc) {
927+ update_pwm_now (dc);
928+ internal_context.pwm_set_last_ampere = ampere;
929+ }
930+ }
931+
922932void Charger::pwm_off () {
923933 session_log.evse (false , " Set PWM Off" );
924934 shared_context.pwm_running = false ;
925935 internal_context.update_pwm_last_dc = 1 .;
936+ internal_context.pwm_set_last_ampere = 0 .;
926937 bsp->set_pwm_off ();
927938}
928939
929940void Charger::pwm_F () {
930941 session_log.evse (false , " Set PWM F" );
931942 shared_context.pwm_running = false ;
932943 internal_context.update_pwm_last_dc = 0 .;
944+ internal_context.pwm_set_last_ampere = 0 .;
933945 bsp->set_pwm_F ();
934946}
935947
@@ -1486,6 +1498,16 @@ float Charger::get_max_current_internal() {
14861498 return maxc;
14871499}
14881500
1501+ float Charger::get_max_current_signalled_to_ev_internal () {
1502+ // For basic charging, the max current signalled to the EV may be different from the actual current limit
1503+ // for up to 5 seconds as the PWM may only be updated every 5 seconds according to IEC61851-1.
1504+ if (not shared_context.hlc_charging_active ) {
1505+ return internal_context.pwm_set_last_ampere ;
1506+ } else {
1507+ return get_max_current_internal ();
1508+ }
1509+ }
1510+
14891511void Charger::set_current_drawn_by_vehicle (float l1, float l2, float l3) {
14901512 Everest::scoped_lock_timeout lock (state_machine_mutex,
14911513 Everest::MutexDescription::Charger_set_current_drawn_by_vehicle);
@@ -1495,8 +1517,9 @@ void Charger::set_current_drawn_by_vehicle(float l1, float l2, float l3) {
14951517}
14961518
14971519void Charger::check_soft_over_current () {
1520+
14981521 // Allow some tolerance
1499- float limit = (get_max_current_internal () + soft_over_current_measurement_noise_A) *
1522+ float limit = (get_max_current_signalled_to_ev_internal () + soft_over_current_measurement_noise_A) *
15001523 (1 . + soft_over_current_tolerance_percent / 100 .);
15011524
15021525 if (shared_context.current_drawn_by_vehicle [0 ] > limit or shared_context.current_drawn_by_vehicle [1 ] > limit or
@@ -1515,9 +1538,9 @@ void Charger::check_soft_over_current() {
15151538 internal_context.over_current = false ;
15161539 }
15171540 auto now = std::chrono::steady_clock::now ();
1518- auto timeSinceOverCurrentStarted =
1541+ auto time_since_over_current_started =
15191542 std::chrono::duration_cast<std::chrono::milliseconds>(now - internal_context.last_over_current_event ).count ();
1520- if (internal_context.over_current and timeSinceOverCurrentStarted >= SOFT_OVER_CURRENT_TIMEOUT) {
1543+ if (internal_context.over_current and time_since_over_current_started >= SOFT_OVER_CURRENT_TIMEOUT) {
15211544 auto errstr =
15221545 fmt::format (" Soft overcurrent event (L1:{}, L2:{}, L3:{}, limit {}) triggered" ,
15231546 shared_context.current_drawn_by_vehicle [0 ], shared_context.current_drawn_by_vehicle [1 ],
0 commit comments