public override void CanPacketReceived(CanPacket cp) { // Elcon uses big endian cp.IsLittleEndian = false; Boolean gotStatusMessage = false; try { switch (cp.CanIdBase10) { case ELCON_CAN_STATUS: // 0x18FF50E5 ActualVoltage = (float)cp.GetUint16(0) / 10.0f; ActualCurrent = (float)cp.GetUint16(1) / 10.0f; // Calculate and send updated dynamic current limit based on pack voltage if (ActualVoltage > 0.0f) { ChargerCurrentLimit = ChargerPowerLimit / ActualVoltage; if (ChargerCurrentLimit > ELCON_CURRENT_LIMIT) { ChargerCurrentLimit = ELCON_CURRENT_LIMIT; } } // Get status flags ChargerStatus = cp.GetUint8(4); gotStatusMessage = true; break; } } catch { //Let it go, let it go. Can't hold it back anymore... } if (chargeOutputOn && gotStatusMessage) { // We use the receipt of the status message to send the charger the latest power details CanPacket elconCommand = new CanPacket(ELCON_CAN_COMMAND) { IsLittleEndian = false }; // Update voltage requested by the ChargeService elconCommand.SetUint16(0, (UInt16)(RequestedVoltage * 10)); // Update current requested by the ChargeService elconCommand.SetUint16(1, (UInt16)(RequestedCurrent * 10)); ComponentCanService.SendMessage(elconCommand); } UpdateStatus(); }
private void UpdateStatus() { state = CanReceivingNode.STATE_NA; stateMessage = ""; if (!ComponentCanService.IsPacketCurrent(ELCON_CAN_STATUS, ELCON_CAN_WAIT_TIME)) { state = CanReceivingNode.STATE_NA; stateMessage = "N/A - No CanBus data"; return; } if (ChargerStatus != 0) { state = CanReceivingNode.STATE_FAILURE; if (!IsHardwareOk) { stateMessage += "(Hardware Issue) "; } if (!IsTempOk) { stateMessage += "(Temp Issue) "; } if (!IsCommsOk) { stateMessage += "(Comms Issue) "; } if (!IsACOk) { stateMessage += "(AC Issue) "; } if (!IsDCOk) { stateMessage += "(DC Issue) "; } } if (IsCharging) { state = CanReceivingNode.STATE_ON; stateMessage = CanReceivingNode.STATE_ON_TEXT; } else { state = CanReceivingNode.STATE_IDLE; stateMessage = CanReceivingNode.STATE_IDLE_TEXT; } }
public override void StopCharge() { StopReceivingCan(); // We use the receipt of the status message to send the charger the latest power details CanPacket elconCommand = new CanPacket(ELCON_CAN_COMMAND) { IsLittleEndian = false }; // Update voltage requested to 0 elconCommand.SetUint16(3, (UInt16)(0)); // Update current requested to 0 elconCommand.SetUint16(2, (UInt16)(0)); ComponentCanService.SendMessage(elconCommand); chargeOutputOn = false; }
private void UpdateState() { state = CanReceivingNode.STATE_NA; stateMessage = CanReceivingNode.STATE_NA_TEXT; if (!ComponentCanService.IsPacketCurrent(BaseAddress, BMU_CAN_WAIT_TIME)) { state = CanReceivingNode.STATE_NA; stateMessage = "N/A - No CanBus data"; return; } stateMessage = ""; if ((ExtendedStausFlag & BMU.STATUS_CELL_OVER_VOLTAGE) != 0) { state = CanReceivingNode.STATE_FAILURE; stateMessage = stateMessage + "(Cell over voltage) "; } if ((ExtendedStausFlag & BMU.STATUS_CELL_UNDER_VOLTAGE) != 0) { state = CanReceivingNode.STATE_FAILURE; stateMessage = stateMessage + "(Cell under voltage) "; } if ((ExtendedStausFlag & BMU.STATUS_CELL_OVER_TEMPERATURE) != 0) { state = CanReceivingNode.STATE_FAILURE; stateMessage = stateMessage + "(Cell over temp) "; } if ((ExtendedStausFlag & BMU.STATUS_MEASUREMENT_UNTRUSTTED) != 0) { state = CanReceivingNode.STATE_WARNING; stateMessage = stateMessage + "(Measurement Untrusted) "; } if ((ExtendedStausFlag & BMU.STATUS_CMU_COMMUNICATIONS_TIMEOUT) != 0) { state = CanReceivingNode.STATE_FAILURE; stateMessage = stateMessage + "(CMU Comms Timeout) "; } if ((ExtendedStausFlag & BMU.STATUS_VEHICLE_COMMUNICATIONS_TIMEOUT) != 0) { state = CanReceivingNode.STATE_FAILURE; stateMessage = stateMessage + "(Vehicle Comms Timeout) "; } if ((ExtendedStausFlag & BMU.STATUS_BMU_IN_SETUP_MODE) != 0) { state = CanReceivingNode.STATE_WARNING; stateMessage = stateMessage + "(BMU in setup mode) "; } if ((ExtendedStausFlag & BMU.STATUS_CMU_CAN_BUS_POWER_STATUS) == 0) { state = CanReceivingNode.STATE_WARNING; stateMessage = stateMessage + "(CMU CanBus Power Status) "; } if ((ExtendedStausFlag & BMU.STATUS_PACK_ISOLATION_TEST_FAILURE) != 0) { state = CanReceivingNode.STATE_FAILURE; stateMessage = stateMessage + "(Pack Isolation Failure) "; } if ((ExtendedStausFlag & BMU.STATUS_SOC_MEASUREMENT_IS_NOT_VALID) != 0) { state = CanReceivingNode.STATE_WARNING; stateMessage = stateMessage + "(SOC Measurement not valid) "; } if ((ExtendedStausFlag & BMU.STATUS_CAN_12V_SUPPLY_LOW) != 0) { state = CanReceivingNode.STATE_WARNING; stateMessage = stateMessage + "(CanBus 12v Supply Low) "; } if ((ExtendedStausFlag & BMU.STATUS_CONTACTOR_STUCK) != 0) { state = CanReceivingNode.STATE_FAILURE; stateMessage = stateMessage + "(Contactor Stuck) "; } if ((ExtendedStausFlag & BMU.STATUS_CMU_HAS_DETECTED_EXTRA_CELL) != 0) { state = CanReceivingNode.STATE_FAILURE; stateMessage = stateMessage + "(Detected extra cell) "; } if (state != CanReceivingNode.STATE_NA) { return; } if (PrechargeState == PRECHARGE_STATUS_ERROR) { state = CanReceivingNode.STATE_FAILURE; stateMessage = "(Precharge Error)"; return; } if (PrechargeState == PRECHARGE_STATUS_IDLE || PrechargeState == PRECHARGE_STATUS_MEASURE || PrechargeState == PRECHARGE_STATUS_PRECHARGE) { state = CanReceivingNode.STATE_IDLE; stateMessage = "(Precharge Idle)"; return; } if (PrechargeState == PRECHARGE_STATUS_RUN && !Contactor1DriverOutput) { state = CanReceivingNode.STATE_OFF; stateMessage = "(Contactors Closed)"; return; } if (PrechargeState == PRECHARGE_STATUS_RUN && Contactor1DriverOutput) { state = CanReceivingNode.STATE_ON; stateMessage = "(On and Ready)"; return; } }