{ "metadata": { "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" }, "orig_nbformat": 4, "kernelspec": { "name": "python3", "display_name": "Python 3.8.10 64-bit" }, "interpreter": { "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" } }, "nbformat": 4, "nbformat_minor": 2, "cells": [ { "cell_type": "code", "execution_count": 27, "source": [ "# Current sense aplifier preliminary design \n", "\n", "supply_voltage = 4.2\n", "max_current = 2.0\n", "acceptable_power_loss = 0.1 #watts\n", "amp_ratios = [50,100,200]\n", "sense_voltage = 3.3\n", "\n", "adc_resolution = 4096\n", "divider_R1 = 100 # kilo-ohms\n", "\n", "max_power = supply_voltage * max_current\n", "\n", "acceptable_voltage_drop = acceptable_power_loss / supply_voltage\n", "print(\"Acceptable voltage drop: {}V\".format(round(acceptable_voltage_drop,2)))\n", "power_loss_percentage = acceptable_power_loss/max_power*100\n", "print(\"Power loss percentage: {}%\".format(round(power_loss_percentage,2)))\n", "\n", "amp_ratios.sort()\n", "\n", "print(\"--------------- Full - range ---------------\")\n", "for ratio in amp_ratios:\n", " ideal_resistor = supply_voltage / ratio / max_current\n", " power_loss = ideal_resistor * max_current**2\n", "\n", " print(\"Ideal resistor: {}R\".format(ideal_resistor))\n", " print(\"Power loss: {}W\".format(power_loss))\n", " print(\"--------------------------------------------\")\n", "\n", "if sense_voltage < supply_voltage:\n", " divider_R2 = round((sense_voltage * divider_R1) / (supply_voltage - sense_voltage),3)\n", " print(\"Output voltage divider: R1 = {} kΩ, R2 = {} kΩ\".format(divider_R1,divider_R2))\n", "\n", "max_output_voltage = min(supply_voltage, supply_voltage)\n", "resolution = round(max_current/adc_resolution*1000,2)\n", "print(\"Resolution: {}mA\".format(resolution))\n", "\n", "print(\"---------------- Acceptable ----------------\")\n", "acceptable_resistor = acceptable_voltage_drop/max_current\n", "power_loss = acceptable_resistor * max_current**2\n", "\n", "ideal_ratio = None\n", "for ratio in amp_ratios:\n", " if acceptable_voltage_drop * ratio < supply_voltage:\n", " ideal_ratio = ratio\n", " else:\n", " break\n", "\n", "max_output_voltage = acceptable_voltage_drop * ideal_ratio\n", "print(\"Maximal output voltage: {}V\".format(max_output_voltage))\n", "\n", "if sense_voltage < max_output_voltage:\n", " divider_R2 = round((sense_voltage * divider_R1) / (max_output_voltage - sense_voltage),3)\n", " print(\"Output voltage divider: R1 = {} kΩ, R2 = {} kΩ\".format(divider_R1,divider_R2))\n", "\n", "resolution = round(max_current/adc_resolution*1000,2)\n", "\n", "print(\"Ideal ratio: {}\".format(ideal_ratio))\n", "print(\"Ideal resistor: {}R\".format(acceptable_resistor))\n", "print(\"Power loss: {}W\".format(power_loss))\n", "print(\"Resolution: {}mA\".format(resolution))" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Acceptable voltage drop: 0.02V\n", "Power loss percentage: 1.19%\n", "--------------- Full - range ---------------\n", "Ideal resistor: 0.042R\n", "Power loss: 0.168W\n", "--------------------------------------------\n", "Ideal resistor: 0.021R\n", "Power loss: 0.084W\n", "--------------------------------------------\n", "Ideal resistor: 0.0105R\n", "Power loss: 0.042W\n", "--------------------------------------------\n", "Output voltage divider: R1 = 100 kΩ, R2 = 366.667 kΩ\n", "Resolution: 0.49mA\n", "---------------- Acceptable ----------------\n", "Maximal output voltage: 2.380952380952381V\n", "Ideal ratio: 100\n", "Ideal resistor: 0.011904761904761904R\n", "Power loss: 0.047619047619047616W\n", "Resolution: 0.49mA\n" ] } ], "metadata": {} }, { "cell_type": "code", "execution_count": 4, "source": [ "# Current sense aplifier design evaluating\n", "\n", "supply_voltage = 2.8\n", "sense_voltage = 3.3\n", "sense_resistor = 0.01\n", "amp_ratio = 50\n", "divider_R1 = 100 # kilo-ohms\n", "selected_R2 = 270 # kilo-ohms\n", "\n", "adc_resolution = 4096\n", "\n", "max_current = supply_voltage / sense_resistor / amp_ratio\n", "power_disipation = sense_resistor * max_current**2\n", "voltage_drop = sense_resistor * max_current\n", "resolution = round(max_current/adc_resolution*1000,3)\n", "\n", "\n", "print(\"Maximal current: {}A\".format(round(max_current,2)))\n", "print(\"Maximal power disipation: {}W\".format(round(power_disipation,2)))\n", "print(\"Maximal voltage drop: {}V\".format(round(voltage_drop,2)))\n", "\n", "if sense_voltage > supply_voltage:\n", " resolution *= 1 / (supply_voltage/sense_voltage)\n", "\n", "print(\"Resolution: {} mA\".format(round(resolution,2)))\n", "\n", "if sense_voltage < supply_voltage:\n", " divider_R2 = round((sense_voltage * divider_R1) / (supply_voltage - sense_voltage),2)\n", " print(\"Output voltage divider: R1 = {} kΩ, R2 = {} kΩ\".format(divider_R1,divider_R2))\n", " divider_leakage = supply_voltage / ((divider_R1 + divider_R2)*1000)\n", " print(\"Maximum divider leakage: {} uA\".format(round(divider_leakage*1000000),2))\n", "\n", "print(\"---------------- Selected divider ----------------\")\n", "maximum_divider_voltage = supply_voltage * (selected_R2 / (selected_R2 + divider_R1))\n", "print(\"Maximum divider voltage: {} V\".format(round(maximum_divider_voltage,2)))\n", "resolution *= 1 / (maximum_divider_voltage/sense_voltage)\n", "print(\"Resolution: {} mA\".format(round(resolution,2)))" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Maximal current: 2.8A\n", "Maximal power disipation: 0.08W\n", "Maximal voltage drop: 0.03V\n", "Resolution: 0.81 mA\n", "---------------- Selected divider ----------------\n", "Maximum divider voltage: 2.04 V\n", "Resolution: 1.3 mA\n" ] } ], "metadata": {} }, { "cell_type": "code", "execution_count": 1, "source": [ "# Battery heating wire calculator\n", "import math\n", "\n", "bat_diameter = 21 # in mm\n", "heating_power = 2 # watts\n", "voltage = 3.7\n", "wire_resistance = 5.5 # per meter\n", "\n", "wrap_length = bat_diameter * math.pi / 1000\n", "current = heating_power / voltage\n", "resistance = voltage / current\n", "length = resistance / wire_resistance\n", "wraps = length / wrap_length\n", "\n", "print(\"Length: {}\".format(length))\n", "print(\"Wraps: {}\".format(wraps))" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Length: 1.2445454545454548\n", "Wraps: 18.86433914223418\n" ] } ], "metadata": {} }, { "cell_type": "code", "execution_count": 24, "source": [ "# LTC4231\n", "\n", "# Voltage settings\n", "undervoltage_rising = 3\n", "undervoltage_falling = 2.9\n", "overvoltage_falling = 4.4\n", "input_voltage = 3.7\n", "\n", "# Design parameters\n", "resistance_total = 2000000\n", "overcurrent_threshold = 5\n", "soa_time = 0.0005\n", "\n", "# Sence voltage constants from LTC4231 datasheet\n", "sense_voltage_slow = 0.05\n", "sense_voltage_min = 0.065\n", "sense_voltage_fast = 0.08\n", "sense_voltage_max = 0.09\n", "\n", "R4 = (0.795/overvoltage_falling) * resistance_total\n", "R3 = ((overvoltage_falling/undervoltage_rising) - 1) * R4\n", "R2 = ((undervoltage_rising/undervoltage_falling) - 1) * (overvoltage_falling/undervoltage_rising) * R4\n", "R1 = ((overvoltage_falling/0.795) - 1) * R4 - R3 - R2\n", "\n", "print(\"R4 value = {}k\".format(round(R4/1000)))\n", "print(\"R3 value = {}k\".format(round(R3/1000)))\n", "print(\"R2 value = {}k\".format(round(R2/1000)))\n", "print(\"R1 value = {}k\".format(round(R1/1000)))\n", "\n", "divider_leakage = input_voltage/(R1 + R2 + R3 + R4)\n", "sense_resistor = sense_voltage_slow/overcurrent_threshold\n", "current_limit_fast = sense_voltage_fast / sense_resistor\n", "sense_resistor_power = sense_resistor * current_limit_fast**2\n", "current_limit_max = sense_voltage_max/sense_resistor\n", "\n", "print(\"Divider leakage = {} uA\".format(divider_leakage*1000000))\n", "print(\"Sensing resistor = {} mR\".format(sense_resistor*1000))\n", "print(\"Sensing resistor power dissipation = {} W\".format(sense_resistor_power))\n", "print(\"Worst case current = {} A\".format(current_limit_max))\n", "\n", "load_capacitor_charge = (0.0001 * input_voltage) / (sense_voltage_min / sense_resistor)\n", "mosfet_dissipation = input_voltage * current_limit_max\n", "overcurrent_triptime = (soa_time - load_capacitor_charge)/4 + load_capacitor_charge\n", "timer_capacitor = overcurrent_triptime/input_voltage\n", "\n", "print(\"OC timer charge = {} ms\".format(round(load_capacitor_charge*1000,2)))\n", "print(\"MOSFET power dissipation = {} W\".format(round(mosfet_dissipation,2)))\n", "print(\"Time to OC protection trip = {} ms\".format(round(overcurrent_triptime*1000,2)))\n", "print(\"Timer capacitor C_T value = {} nF\".format(round(timer_capacitor*1000000,2)))" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "R4 value = 361k\n", "R3 value = 169k\n", "R2 value = 18k\n", "R1 value = 1452k\n", "Divider leakage = 1.85 uA\n", "Sensing resistor = 10.0 mR\n", "Sensing resistor power dissipation = 0.64 W\n", "Worst case current = 9.0 A\n", "OC timer charge = 0.06 ms\n", "MOSFET power dissipation = 33.3 W\n", "Time to OC protection trip = 0.17 ms\n", "Timer capacitor C_T value = 45.32 nF\n" ] } ], "metadata": {} }, { "cell_type": "code", "execution_count": 22, "source": [ "#BQ25798\n", "\n", "## Termistor settings\n", "# JEITA profile temperature points\n", "temp_T1 = 0 # °C\n", "temp_T5 = 60\n", "\n", "# NTC resistance at temperature points\n", "termistor_at_T1 = 29250.0\n", "termistor_at_T5 = 2900.0\n", "\n", "# Voltage of temperature level in fraction of REGN voltage\n", "temp_T1_threshold = 0.733\n", "temp_T5_threshold = 0.342\n", "\n", "resistor_RT2 = (termistor_at_T1*termistor_at_T5 * ((1.0/temp_T5_threshold)-(1.0/temp_T1_threshold))) / ((termistor_at_T1 * ((1.0/temp_T1_threshold) - 1))-(termistor_at_T5 * ((1.0/temp_T5_threshold) - 1)))\n", "resistor_RT1 = ((1.0/temp_T1_threshold) - 1) / ( (1.0 / resistor_RT2) + (1.0/termistor_at_T1) )\n", "\n", "print(\"Battery termistor resistor network\")\n", "print(\"RT1 = {} k\".format(round(resistor_RT1/1000,2)))\n", "print(\"RT2 = {} k\".format(round(resistor_RT2/1000,2)))\n", "\n", "## Input current limitation\n", "maximal_input_current_draw = 0.9 # in Amp\n", "divider_R1 = 100 # in kOhms\n", "\n", "voltage_REGN = 4.8\n", "\n", "voltage_ILIM = 1 + 0.8 * maximal_input_current_draw\n", "divider_R2 = round((voltage_ILIM * divider_R1) / (voltage_REGN - voltage_ILIM),3)\n", "print(\"ILIM voltage divider: R1 = {} kΩ, R2 = {} kΩ\".format(divider_R1,divider_R2))\n", "\n", "\n" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Battery termistor resistor network\n", "RT1 = 5.02 k\n", "RT2 = 26.07 k\n", "ILIM voltage divider: R1 = 100 kΩ, R2 = 55.844 kΩ\n" ] } ], "metadata": {} }, { "cell_type": "code", "execution_count": 42, "source": [ "# TPS6300\n", "\n", "output_voltages = [1.8,3.3,5.0]\n", "resistor_R2 = 200 # in kOhms, recommended 100-500 kR\n", "\n", "feedback_voltage = 0.5 # V\n", "\n", "for output_voltage in output_voltages:\n", " resistor_R1 = resistor_R2 * (output_voltage/feedback_voltage-1)\n", " print(\"Resistor R2 for output voltage {} V is: {} kΩ\".format(output_voltage, resistor_R1))\n" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Resistor R2 for output voltage 1.8 V is: 520.0 kΩ\n", "Resistor R2 for output voltage 3.3 V is: 1120.0 kΩ\n", "Resistor R2 for output voltage 5.0 V is: 1800.0 kΩ\n" ] } ], "metadata": {} } ] }