Esempio n. 1
0
        //New system here:
        //synchronous functions for background thread.

        void BmsUpdate(BatteryWriteDataStruct write_data)
        {
            BatteryReadDataStruct read_data = null;


            if (!String.IsNullOrEmpty(BmsComPort) && BmsCom.Open(BmsComPort))
            {
                try
                {
                    //usually throws a timeout if the FTDI part has power and is connected but 48V is off.
                    read_data = BmsCom.BmsUpdate(write_data);
                }
                catch (Exception ex)
                {
                    //we still need to close the comport if we left it open, so the next attempt works properly.
                    if (BmsCom.IsOpen())
                    {
                        BmsCom.Close();
                    }
                    throw ex; //rethrow, so the top catches it.
                }

                BmsCom.Close();
            }


            if (read_data != null)
            {
                BatteryReadData = read_data;
                Dispatcher.BeginInvoke((Action)(() => { BmsUpdateGui(); }));
            }
        }
Esempio n. 2
0
        public BatteryReadDataStruct BmsUpdate(BatteryWriteDataStruct write_struct)
        {
            var write_data = write_struct.Serialize();

            byte[] rx_buffer = RoundTripCommand(write_data, BatteryReadDataStruct.Size, NormalCellTimeout);

            BatteryReadDataStruct read_data = BatteryReadDataStruct.Deserialize(rx_buffer);

            return(read_data);
        }
Esempio n. 3
0
        void LogCellVoltages()
        {
            BatteryReadDataStruct read_data = BatteryReadData;
            string line = DateTime.Now.ToString() + ", ";

            line += String.Join(", ", read_data.CellVoltages.Select(x => x.ToString("0.00")));
            line += ", ";
            line += String.Join(", ", read_data.CellTemperatures.Select(x => x.ToString("0.00")));
            line += ", ";
            line += String.Join(", ", BatteryWriteData.GetCellCurrents().Select(x => x.ToString("0.00")));

            WriteLineToCellLog(line);
        }
Esempio n. 4
0
        private void UpdateCellStats()
        {
            double total_voltage = 0;
            double min_voltage   = 0;
            double max_voltage   = 0;

            BatteryReadDataStruct read_data = BatteryReadData;



            total_voltage = read_data.CellVoltages.Take(CellCount).Sum(x => x);
            min_voltage   = read_data.CellVoltages.Take(CellCount).Min(x => x);
            max_voltage   = read_data.CellVoltages.Take(CellCount).Max(x => x);

            double delta = max_voltage - min_voltage;
            double mean  = total_voltage / CellCount;

            PackVoltageDeltaLbl.Content = "Pack Δ " + delta.ToString("0.00") + "V";
            PackMeanVoltageLbl.Content  = "x̄ Cell: " + mean.ToString("0.00") + "V";

            foreach (BatteryViewControl bat in BatteryViews)
            {
                if (bat.Voltage < 2.7 || bat.Voltage > 3.6)
                {
                    bat.IsCritical = true;
                }
                else
                {
                    bat.IsCritical = false;
                }

                if (bat.Temp > 100)
                {
                    bat.IsOverheated = true;
                }
                else
                {
                    bat.IsOverheated = false;
                }
            }
        }
Esempio n. 5
0
        void ChargeUpdate()
        {
            TimeSpan discharge_time        = TimeSpan.FromMinutes(5);
            double   cell_bleed_voltage    = 3.61;
            double   cell_finished_voltage = 3.45;
            int      cell_count            = BatteryWriteData.CellCount;
            //double cell_bleed_current = 1.0;

            BatteryReadDataStruct read_data = BatteryReadData;

            if (ChargeActive == false)
            {
                AbortCharge();
                return;
            }


            if (DischrageInProgress)
            {
                if (DateTime.Now >= DichargeEndTime)
                {
                    //discharge done, reconnect the charger!
                    WriteLineToCellLog("Discharge timer complete, enableing charge relay again");
                    Console.WriteLine("Bleed cycle complete");
                    DischrageInProgress = false;
                    BatteryWriteData.StopCellDischarges();
                    SetChargeRelay(true);
                }
            }
            else
            {
                bool          all_unbled_cells_done = true;
                List <int>    cells_to_bleed        = new List <int>();
                List <double> cell_bleed_currents   = new List <double>();
                for (int i = 0; i < cell_count; ++i)
                {
                    double cell_bleed_current = 0;
                    double cell_voltage       = read_data.CellVoltages[i];
                    if (cell_voltage > 3.50)
                    {
                        if (cell_voltage < 3.6)
                        {
                            cell_bleed_current = (cell_voltage - 3.50) * 5.0;
                        }
                        else
                        {
                            cell_bleed_current = .5;
                        }
                    }
                    cell_bleed_currents.Add(cell_bleed_current);


                    if (CellDischargeCount[i] == 0 && read_data.GetCellVoltage(i) < cell_finished_voltage)
                    {
                        all_unbled_cells_done = false;
                    }

                    if (read_data.GetCellVoltage(i) > cell_bleed_voltage)
                    {
                        cells_to_bleed.Add(i);
                    }
                }

                if (all_unbled_cells_done == true)
                {
                    //DONE!

                    int non_bled_cell_count = CellDischargeCount.Count(x => x == 0);
                    Console.WriteLine("Charge Complete. " + non_bled_cell_count + " cells never bled");
                    //todo: set charge button
                    string unbled_cells = "";
                    for (int i = 0; i < CellDischargeCount.Count(); ++i)
                    {
                        if (CellDischargeCount[i] == 0)
                        {
                            unbled_cells += i.ToString() + ", ";
                        }
                        CellDischargeCount[i] = 0;
                    }
                    WriteLineToCellLog("All unbled cells complete! Ending Charge. Unbled Cells: " + unbled_cells);
                    ChargeActive        = false;
                    DischrageInProgress = false;
                    SetChargeRelay(false);
                    ChargeBtn.Content = "Start Charge";
                    return;
                }

                if ((all_unbled_cells_done == false) && (cells_to_bleed.Any()))
                {
                    //start bleeding
                    WriteLineToCellLog("bleed started: " + String.Join(",", cells_to_bleed));
                    Console.WriteLine("starting to bleed cells " + String.Join(",", cells_to_bleed));
                    DischrageInProgress = true;
                    SetChargeRelay(false);
                    DichargeEndTime = DateTime.Now + discharge_time;

                    foreach (int i in cells_to_bleed)
                    {
                        CellDischargeCount[i]++;
                        //BatteryWriteData.SetCellCurrent( i, cell_bleed_current );
                    }
                    string log = "starting discharge: ";
                    for (int i = 0; i < cell_count; ++i)
                    {
                        BatteryWriteData.SetCellCurrent(i, cell_bleed_currents[i]);
                        log += i + "(" + cell_bleed_currents[i].ToString("F") + "A), ";
                    }

                    Console.WriteLine(log);

                    return;
                }

                //stay in bulk charge, no discharging.
            }
        }
Esempio n. 6
0
        public static BatteryReadDataStruct Deserialize(byte[] data)
        {
            List <byte> dat = new List <byte>(data);

            if (!(data.Last() != 0xDE))
            {
                //throw execption?
                Console.WriteLine("Failed to deserialize Battery Read Data Struct.");
                return(null);
            }

            BatteryReadDataStruct read_data = new BatteryReadDataStruct();

            for (int i = 0; i < CELL_COUNT; ++i)
            {
                read_data.mCellVoltages[i] = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
                dat.RemoveRange(0, 2);
            }

            for (int i = 0; i < CELL_COUNT; ++i)
            {
                read_data.mCellTemperatures[i] = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
                dat.RemoveRange(0, 2);
            }

            for (int i = 0; i < RELAY_COUNT; ++i)
            {
                read_data.mPrechargeVoltages[i] = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
                dat.RemoveRange(0, 2);
            }


            //SWAPPED BECUASE ADC 2 is not working, and we want charge!
            read_data.MasterCurrent = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
            dat.RemoveRange(0, 2);

            read_data.ChargeCurrent = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
            dat.RemoveRange(0, 2);

            read_data.PackVoltage = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
            dat.RemoveRange(0, 2);

            read_data.MasterTemperature = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
            dat.RemoveRange(0, 2);

            read_data.MasterHumidity = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
            dat.RemoveRange(0, 2);

            read_data.ValidCellReadCount = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);
            dat.RemoveRange(0, 2);

            read_data.CriticalFlags = BitConverter.ToUInt16(dat.Take(2).ToArray(), 0);     //enums are 16 bit on MSP430.
            dat.RemoveRange(0, 2);

            read_data.CoulombCount = BitConverter.ToInt64(dat.Take(8).ToArray(), 0);
            dat.RemoveRange(0, 8);

            if (dat.Count() > 0)
            {
                throw new Exception("padding detected.");
            }

            if (read_data.mCellVoltages.Any(x => x == 0xFFFF) || read_data.mCellTemperatures.Any(x => x == 0xFFFF))
            {
                //issue detected.
                Console.WriteLine("cell read error detected");
            }

            return(read_data);
        }