├── .gitignore ├── LICENSE ├── Osterwood Teardown 2019.pdf ├── README.md ├── SenseTemp_Graph.ipynb ├── SenseTemp_TEC_Filtering.ipynb ├── USBHub_Current_Monitor.ipynb ├── USBHub_DC_Regulator.ipynb ├── USBHub_i2c_addresses.ipynb ├── i2c-addresses.yml └── resources ├── SMA6J.lib ├── image-fsw.png └── video-thumb.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | CapableRobot_USBHub_Driver 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # pyenv 79 | .python-version 80 | 81 | # celery beat schedule file 82 | celerybeat-schedule 83 | 84 | # SageMath parsed files 85 | *.sage.py 86 | 87 | # Environments 88 | .env 89 | .venv 90 | env/ 91 | venv/ 92 | ENV/ 93 | env.bak/ 94 | venv.bak/ 95 | 96 | # Spyder project settings 97 | .spyderproject 98 | .spyproject 99 | 100 | # Rope project settings 101 | .ropeproject 102 | 103 | # mkdocs documentation 104 | /site 105 | 106 | # mypy 107 | .mypy_cache/ 108 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Capable Robot 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Osterwood Teardown 2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CapableRobot/notebooks/ec143375765e4278bde95eafc23f014957018279/Osterwood Teardown 2019.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Better Electronics with Jupyter Notebooks 2 | 3 | These notebooks were presented by [Chris Osterwood](http://twitter.com/osterwood) at the 2019 [Crowd Supply Teardown Conference](http://crowdsupply.com/teardown/portland-2019). 4 | 5 | A video of the presentation is available on [YouTube](https://youtu.be/DFpwlkX7V5M?t=5495). 6 | 7 | [![](./resources/video-thumb.jpg)](https://youtu.be/DFpwlkX7V5M?t=5495) 8 | 9 | They use the following awesome Python libraries: 10 | 11 | |Library|Description| 12 | |---|---| 13 | |[Jupyter](https://jupyter.org)| The notebook runtime. | 14 | |[Jupyter Lab](https://jupyterlab.readthedocs.io) | A new front-end to Jupyter. | 15 | |[BqPlot](https://bqplot.readthedocs.io)| Plotting library which supports live graphs inside of Jupyter notebooks. | 16 | |[Pint](https://pint.readthedocs.io) | Adds physical-world units to numeric objects. | 17 | |[PySpice](https://pyspice.fabrice-salvaire.fr) | Wrapper around the SPICE electrical simulation tool. | 18 | |[Sympy](https://www.sympy.org) | Symbolic solver. Used to re-order some equations in the notebooks. | 19 | | [PySerial](https://pythonhosted.org/pyserial/) | Allows Python to read and write to serial ports.| 20 | |[nbconvert](https://nbconvert.readthedocs.io) | Tool which can convert & archive notebooks into static HTML and PDF documents. | 21 | 22 | The notebooks included here are: 23 | 24 | |Notebook|Description| 25 | |---|---| 26 | | USBHub\_i2c\_addresses | Used to determine address-pin settings on I2C devices to prevent address conflicts. | 27 | | USBHub\_DC\_Regulator | Aided in the design and component selection of the 6A 5V regulator on the Capable Robot USB Hub.| 28 | | USBHub\_Current\_Monitor | Displays live power data from the Capable Robot USB Hub and UI buttons allow per-port control of power and data lines. | 29 | | SenseTemp_Graph | Displays live temperature data from CapableRobot SenseTemp via a serial connection. | 30 | | SenseTemp\_TEC\_Filtering | Aided in the design and component selection of filters on the Capable Robot SenseTemp TEC. | 31 | 32 | Note these notebooks are intended to be a starting point for your own adaptation and use in your own electrical design work. They are not designed to be general purpose tools. 33 | 34 | If you find these useful please let me know, and also let me know if you publish your own notebooks publicly! I'd love to link to them and show the world more examples of notebooks aiding in product design and testing. 35 | 36 | 37 | ## Capable Robot Products 38 | 39 | These notebooks aided in the design, development, and testing of the following Capable Robot products, which are available for purchase on Crowd Supply. 40 | 41 | ### [Programmable USB Hub](https://www.crowdsupply.com/capable-robot-components/programmable-usb-hub) 42 | [![](https://www.crowdsupply.com/img/93fb/hub-housing-front.jpg)](https://www.crowdsupply.com/capable-robot-components/programmable-usb-hub) 43 | 44 | ### [SenseTemp](https://www.crowdsupply.com/capable-robot-components/sensetemp) 45 | [![](https://www.crowdsupply.com/img/d4eb/sensetemp-creaes_jpg_project-body.jpg)](https://www.crowdsupply.com/capable-robot-components/sensetemp) 46 | 47 | ### [SenseTemp TEC](https://www.crowdsupply.com/capable-robot-components/sensetemp) 48 | [![](https://www.crowdsupply.com/img/b339/sensetemp-tec-cr2erp_jpg_project-body.jpg)](https://www.crowdsupply.com/capable-robot-components/sensetemp) 49 | -------------------------------------------------------------------------------- /SenseTemp_Graph.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import time\n", 10 | "\n", 11 | "import bqplot as bq\n", 12 | "import numpy as np\n", 13 | "import pandas as pd\n", 14 | "\n", 15 | "from IPython.display import display" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "def live_plot(title, fields, x=\"\", y=\"\", history=30):\n", 25 | " global drop_count\n", 26 | " drop_count=0\n", 27 | " \n", 28 | " x_sc = bq.LinearScale()\n", 29 | " y_sc = bq.LinearScale()\n", 30 | "\n", 31 | " ax_x = bq.Axis(label=x, scale=x_sc, grid_lines='solid')\n", 32 | " ax_y = bq.Axis(label=y, scale=y_sc, orientation='vertical', grid_lines='solid')\n", 33 | "\n", 34 | " df = pd.DataFrame(columns=['time']+fields)\n", 35 | " \n", 36 | " pts = bq.Lines(x=df.index, y=[df[f].values for f in fields], display_legend=True, scales={'x': x_sc, 'y': y_sc})\n", 37 | " fig = bq.Figure(axes=[ax_x, ax_y], marks=[pts], labels=fields, legend_location='top-left', title=title)\n", 38 | " \n", 39 | " def cb(data):\n", 40 | " global drop_count\n", 41 | " \n", 42 | " if len(df) > history:\n", 43 | " df.drop([drop_count], inplace=True)\n", 44 | " drop_count += 1\n", 45 | " \n", 46 | " df.loc[len(df)+drop_count] = [time.time()] + data\n", 47 | " \n", 48 | " with pts.hold_sync():\n", 49 | " pts.x = df.index \n", 50 | " pts.y = [df[f] for f in fields]\n", 51 | " \n", 52 | " return fig, cb" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "data": { 62 | "application/vnd.jupyter.widget-view+json": { 63 | "model_id": "e5545c76c44d49dcbe0592ebebf5c064", 64 | "version_major": 2, 65 | "version_minor": 0 66 | }, 67 | "text/plain": [ 68 | "Figure(axes=[Axis(label='Time (sec)', scale=LinearScale()), Axis(label='Temperature (C)', orientation='vertica…" 69 | ] 70 | }, 71 | "metadata": {}, 72 | "output_type": "display_data" 73 | }, 74 | { 75 | "ename": "KeyboardInterrupt", 76 | "evalue": "", 77 | "output_type": "error", 78 | "traceback": [ 79 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 80 | "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", 81 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0mpoll\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 82 | "\u001b[0;32m\u001b[0m in \u001b[0;36mpoll\u001b[0;34m()\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mpoll\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mrow\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreadline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'UTF-8'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrow\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"[\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mcb\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloads\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 83 | "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pyserial-3.4-py3.7.egg/serial/serialposix.py\u001b[0m in \u001b[0;36mread\u001b[0;34m(self, size)\u001b[0m\n\u001b[1;32m 481\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 482\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 483\u001b[0;31m \u001b[0mready\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mselect\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mselect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfd\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpipe_abort_read_r\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime_left\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 484\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpipe_abort_read_r\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mready\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 485\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpipe_abort_read_r\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 84 | "\u001b[0;31mKeyboardInterrupt\u001b[0m: " 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "import serial \n", 90 | "import json\n", 91 | "\n", 92 | "device = serial.Serial(\"/dev/cu.usbmodem1411\", baudrate=115200)\n", 93 | "\n", 94 | "fields = [\"CH1\", \"CH2\", \"CH3\", \"CH4\"]\n", 95 | "fig, cb = live_plot(\"SenseTemp Temperatures\", fields, x=\"Time (sec)\", y=\"Temperature (C)\")\n", 96 | "\n", 97 | "def poll():\n", 98 | " row = device.readline().decode('UTF-8')\n", 99 | " if row[0] == \"[\":\n", 100 | " cb(json.loads(row))\n", 101 | "\n", 102 | "display(fig)\n", 103 | "\n", 104 | "while True:\n", 105 | " poll()" 106 | ] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": "py_37_env", 112 | "language": "python", 113 | "name": "py_37_env" 114 | }, 115 | "language_info": { 116 | "codemirror_mode": { 117 | "name": "ipython", 118 | "version": 3 119 | }, 120 | "file_extension": ".py", 121 | "mimetype": "text/x-python", 122 | "name": "python", 123 | "nbconvert_exporter": "python", 124 | "pygments_lexer": "ipython3", 125 | "version": "3.7.3" 126 | } 127 | }, 128 | "nbformat": 4, 129 | "nbformat_minor": 2 130 | } 131 | -------------------------------------------------------------------------------- /SenseTemp_TEC_Filtering.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 5, 6 | "metadata": { 7 | "collapsed": false, 8 | "inputHidden": false, 9 | "outputHidden": false 10 | }, 11 | "outputs": [ 12 | { 13 | "name": "stderr", 14 | "output_type": "stream", 15 | "text": [ 16 | "Warning: vinput: no DC value, transient time 0 value used\n" 17 | ] 18 | }, 19 | { 20 | "data": { 21 | "image/png": "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\n", 22 | "text/plain": [ 23 | "
" 24 | ] 25 | }, 26 | "metadata": { 27 | "needs_background": "light" 28 | }, 29 | "output_type": "display_data" 30 | } 31 | ], 32 | "source": [ 33 | "import math\n", 34 | "import numpy as np\n", 35 | "import matplotlib.pyplot as plt\n", 36 | "\n", 37 | "from PySpice.Unit import *\n", 38 | "\n", 39 | "from PySpice.Probe.Plot import plot\n", 40 | "from PySpice.Spice.Netlist import Circuit\n", 41 | "from PySpice.Spice.Library import SpiceLibrary\n", 42 | "from PySpice.Doc.ExampleTools import find_libraries\n", 43 | "\n", 44 | "spice_library = SpiceLibrary('./resources/')\n", 45 | "\n", 46 | "circuit = Circuit('TEC Model')\n", 47 | "circuit.include(spice_library['SMA6J12A'])\n", 48 | "\n", 49 | "# 100 us -> 10 kHz\n", 50 | "# 50 us -> 20 kHz\n", 51 | "source = circuit.PulseVoltageSource('input', 'pwm', circuit.gnd, \n", 52 | " initial_value=0@u_V, pulsed_value=12@u_V,\n", 53 | " pulse_width=10@u_us, period=50@u_us)\n", 54 | "\n", 55 | "## TEC is 12V, 5A -> 2.4 ohm\n", 56 | "r_tec = 2.4@u_Ω\n", 57 | "inductor = 10@u_uH\n", 58 | "\n", 59 | "Rtec = circuit.R('TEC', 'TECP', 'TECM', r_tec)\n", 60 | "L1 = circuit.L(1, 'pwm', 'TECP', inductor)\n", 61 | "L2 = circuit.L(2, circuit.gnd, 'TECM', inductor)\n", 62 | "\n", 63 | "C5 = circuit.C(5, 'TECP', 'TECM', 2*47@u_uF)\n", 64 | "\n", 65 | "circuit.X('D1', 'SMA6J12A', 'TECP', 'snub')\n", 66 | "circuit.X('D2', 'SMA6J12A', 'snub', 'TECM')\n", 67 | "\n", 68 | "Rtec.minus.add_current_probe(circuit)\n", 69 | "\n", 70 | "simulator = circuit.simulator(temperature=25, nominal_temperature=25)\n", 71 | "step_time = source.period / 100\n", 72 | "analysis = simulator.transient(step_time=step_time, end_time=source.period*10)\n", 73 | " \n", 74 | "figure = plt.figure(1, (20, 10))\n", 75 | "\n", 76 | "plot(analysis['pwm'], linewidth=2)\n", 77 | "plot(analysis['TECP'] - analysis['TECM'], linewidth=2)\n", 78 | "\n", 79 | "plt.title(\"Peltier Simulation\")\n", 80 | "plt.grid()\n", 81 | "plt.legend(('VIN', 'VTEC'), loc=(.8,.8))\n", 82 | "plt.tight_layout()\n", 83 | "plt.show()" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [] 92 | } 93 | ], 94 | "metadata": { 95 | "kernel_info": { 96 | "name": "python3" 97 | }, 98 | "kernelspec": { 99 | "display_name": "py_37_env", 100 | "language": "python", 101 | "name": "py_37_env" 102 | }, 103 | "language_info": { 104 | "codemirror_mode": { 105 | "name": "ipython", 106 | "version": 3 107 | }, 108 | "file_extension": ".py", 109 | "mimetype": "text/x-python", 110 | "name": "python", 111 | "nbconvert_exporter": "python", 112 | "pygments_lexer": "ipython3", 113 | "version": "3.7.3" 114 | }, 115 | "nteract": { 116 | "version": "0.11.9" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 4 121 | } 122 | -------------------------------------------------------------------------------- /USBHub_Current_Monitor.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 338, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os, sys, inspect\n", 10 | "import time\n", 11 | "\n", 12 | "lib_folder = os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0], 'CapableRobot_USBHub_Driver')\n", 13 | "lib_load = os.path.realpath(os.path.abspath(lib_folder))\n", 14 | "\n", 15 | "if lib_load not in sys.path:\n", 16 | " sys.path.insert(0, lib_load)\n", 17 | "\n", 18 | "import capablerobot_usbhub \n", 19 | "\n", 20 | "SIM = False\n", 21 | "\n", 22 | "# hub = capablerobot_usbhub.USBHub()\n", 23 | "# hub.i2c.enable()\n", 24 | "\n", 25 | "try:\n", 26 | " hub = capablerobot_usbhub.USBHub()\n", 27 | " hub.i2c.enable()\n", 28 | "except ValueError:\n", 29 | " SIM = True" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 339, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "import time\n", 39 | "\n", 40 | "import paho.mqtt.client as mqtt\n", 41 | "import bqplot as bq\n", 42 | "import numpy as np\n", 43 | "import pandas as pd\n", 44 | "\n", 45 | "from IPython.display import display\n", 46 | "\n", 47 | "def live_plot(title, fields, x=\"\", y=\"\", ylimit=None, history=50):\n", 48 | " global drop_count\n", 49 | " drop_count=0\n", 50 | " \n", 51 | " x_sc = bq.LinearScale()\n", 52 | " y_sc = bq.LinearScale()\n", 53 | " \n", 54 | " if ylimit is not None:\n", 55 | " y_sc.min = ylimit[0]\n", 56 | " y_sc.max = ylimit[1]\n", 57 | "\n", 58 | " ax_x = bq.Axis(label=x, scale=x_sc, grid_lines='solid')\n", 59 | " ax_y = bq.Axis(label=y, scale=y_sc, orientation='vertical', grid_lines='solid')\n", 60 | "\n", 61 | " df = pd.DataFrame(columns=['time']+fields)\n", 62 | " \n", 63 | " pts = bq.Lines(x=df.index, y=[df[f].values for f in fields], display_legend=True, scales={'x': x_sc, 'y': y_sc})\n", 64 | " fig = bq.Figure(axes=[ax_x, ax_y], marks=[pts], labels=fields, legend_location='top-left', title=title)\n", 65 | " \n", 66 | " def cb(data):\n", 67 | " global drop_count\n", 68 | " \n", 69 | " if len(df) > history:\n", 70 | " try:\n", 71 | " df.drop([drop_count], inplace=True)\n", 72 | " drop_count += 1\n", 73 | " except KeyError:\n", 74 | " pass\n", 75 | " \n", 76 | " df.loc[len(df)+drop_count] = [time.time()] + data\n", 77 | " \n", 78 | " with pts.hold_sync():\n", 79 | " pts.x = df.index \n", 80 | " pts.y = [df[f] for f in fields]\n", 81 | " \n", 82 | " return fig, cb" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 340, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "def print_currents():\n", 92 | " last = int(time.time() * 1000)\n", 93 | " \n", 94 | " while True:\n", 95 | " now = int(time.time() * 1000)\n", 96 | " print(str(now - last).rjust(3), \" \".join([(\"%.2f\" % v).rjust(7) for v in hub.power.measurements()]))\n", 97 | " last = now\n", 98 | " time.sleep(0.5)" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 341, 104 | "metadata": {}, 105 | "outputs": [ 106 | { 107 | "data": { 108 | "application/vnd.jupyter.widget-view+json": { 109 | "model_id": "2d1be32c0a2b4c72ac1beb182a981d0d", 110 | "version_major": 2, 111 | "version_minor": 0 112 | }, 113 | "text/plain": [ 114 | "Output()" 115 | ] 116 | }, 117 | "metadata": {}, 118 | "output_type": "display_data" 119 | } 120 | ], 121 | "source": [ 122 | "import ipywidgets as widgets\n", 123 | "import copy\n", 124 | "import random\n", 125 | "\n", 126 | "out = widgets.Output()\n", 127 | "display(out)\n", 128 | "\n", 129 | "## Since UI uses 'Button' instead of 'ToggleButton' objects,\n", 130 | "## default & current state of the buttons must be tracked.\n", 131 | "## Events fire on click, and don't have 'new' vs 'old' states\n", 132 | "## like ToggleButton objects do.\n", 133 | "\n", 134 | "power_states = [True, True, True, True] \n", 135 | "data_states = [\"on\", \"on\", \"on\", \"on\"]\n", 136 | "\n", 137 | "power_buttons = []\n", 138 | "data_buttons = []\n", 139 | "\n", 140 | "if not SIM:\n", 141 | " ## Get state upon connection and ignore last data state (it's the upstream link)\n", 142 | " power_states = hub.power.state()\n", 143 | " data_states = hub.data_state()[0:4]\n", 144 | "\n", 145 | "@out.capture()\n", 146 | "def power_change(button):\n", 147 | " \n", 148 | " port = int(button.description.split(\" \")[1])\n", 149 | " off = (power_states[port-1] == False)\n", 150 | " \n", 151 | " if off:\n", 152 | " power_states[port-1] = True\n", 153 | " color = 'lightgray'\n", 154 | " else:\n", 155 | " power_states[port-1] = False\n", 156 | " color = 'orange'\n", 157 | " \n", 158 | " power_buttons[port-1].style.button_color = color\n", 159 | " \n", 160 | " if not SIM:\n", 161 | " if off:\n", 162 | " hub.power.enable(ports=[port])\n", 163 | " else: \n", 164 | " hub.power.disable(ports=[port])\n", 165 | " \n", 166 | "\n", 167 | " \n", 168 | "@out.capture()\n", 169 | "def data_change(button):\n", 170 | "\n", 171 | " port = int(button.description.split(\" \")[1])\n", 172 | " off = (data_states[port-1] == \"off\")\n", 173 | " \n", 174 | " if SIM:\n", 175 | " if off:\n", 176 | " print(\"DATA ENABLE {}\".format(port))\n", 177 | " data_states[port-1] = \"on\"\n", 178 | " else:\n", 179 | " print(\"DATA DISABLE {}\".format(port))\n", 180 | " data_states[port-1] = \"off\"\n", 181 | " else:\n", 182 | " if off: \n", 183 | " hub.data_enable(ports=[port])\n", 184 | " data_states[port-1] = \"on\"\n", 185 | " else: \n", 186 | " hub.data_disable(ports=[port])\n", 187 | " data_states[port-1] = \"off\"\n", 188 | "\n", 189 | "def setup_ui():\n", 190 | "\n", 191 | " for idx in [1,2,3,4]:\n", 192 | " label = \"Port {}\".format(idx)\n", 193 | " \n", 194 | " button = widgets.Button(description=label, disabled=False, value=True)\n", 195 | " button.on_click(power_change)\n", 196 | " \n", 197 | " ## Set the initial button color based on the port power state\n", 198 | " if power_states[idx-1]:\n", 199 | " button.style.button_color = 'lightgray'\n", 200 | " else:\n", 201 | " button.style.button_color = 'orange'\n", 202 | " \n", 203 | " power_buttons.append(button)\n", 204 | " \n", 205 | " button = widgets.Button(description=label, disabled=False, value=True)\n", 206 | " button.on_click(data_change)\n", 207 | " data_buttons.append(button)\n", 208 | " \n", 209 | " power_label = widgets.Label(value=\"Power\", layout=widgets.Layout(width='20%'))\n", 210 | " power_row = widgets.HBox([power_label]+power_buttons)\n", 211 | " \n", 212 | " data_label = widgets.Label(value=\"Data\", layout=widgets.Layout(width='20%'))\n", 213 | " data_row = widgets.HBox([data_label]+data_buttons)\n", 214 | " \n", 215 | " display(widgets.VBox([data_row, power_row])) \n", 216 | " \n", 217 | "def graph_currents(do_stop):\n", 218 | " fields = [\"1\", \"2\", \"3\", \"4\"]\n", 219 | " lim = 1700\n", 220 | " if SIM:\n", 221 | " lim = 10\n", 222 | " fig, cb = live_plot(\"Port Current\", fields, x=\"Time (sec)\", y=\"Current (mA)\", ylimit=[0,lim])\n", 223 | "\n", 224 | " display(fig)\n", 225 | " \n", 226 | " while True:\n", 227 | " try:\n", 228 | " if SIM:\n", 229 | " cb([random.random(),random.random(),random.random(),random.random()])\n", 230 | " else:\n", 231 | " cb(hub.power.measurements())\n", 232 | " \n", 233 | " if len(data_buttons) < 4:\n", 234 | " continue\n", 235 | " \n", 236 | " speeds = hub.speeds()\n", 237 | "\n", 238 | " for idx,state in enumerate(hub.data_state()[0:4]):\n", 239 | " \n", 240 | " speed = speeds[idx]\n", 241 | " color = \"lightgray\"\n", 242 | " \n", 243 | " if speed == \"high\":\n", 244 | " color = \"white\"\n", 245 | " elif speed == \"full\":\n", 246 | " color = \"green\"\n", 247 | " elif speed == \"low\": \n", 248 | " color = \"blue\"\n", 249 | " elif state == \"off\":\n", 250 | " color = \"orange\"\n", 251 | "\n", 252 | " data_buttons[idx].style.button_color = color\n", 253 | " \n", 254 | " except ValueError as e:\n", 255 | " pass\n", 256 | "\n", 257 | " time.sleep(0.2)\n", 258 | " \n", 259 | " if do_stop():\n", 260 | " break" 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": 342, 266 | "metadata": {}, 267 | "outputs": [ 268 | { 269 | "data": { 270 | "application/vnd.jupyter.widget-view+json": { 271 | "model_id": "041461bcecca404b9b0663cbf67f3fa6", 272 | "version_major": 2, 273 | "version_minor": 0 274 | }, 275 | "text/plain": [ 276 | "VBox(children=(HBox(children=(Label(value='Data', layout=Layout(width='20%')), Button(description='Port 1', st…" 277 | ] 278 | }, 279 | "metadata": {}, 280 | "output_type": "display_data" 281 | }, 282 | { 283 | "data": { 284 | "application/vnd.jupyter.widget-view+json": { 285 | "model_id": "cdfe540984254157bd9f50f9d376fd3c", 286 | "version_major": 2, 287 | "version_minor": 0 288 | }, 289 | "text/plain": [ 290 | "Figure(axes=[Axis(label='Time (sec)', scale=LinearScale()), Axis(label='Current (mA)', orientation='vertical',…" 291 | ] 292 | }, 293 | "metadata": {}, 294 | "output_type": "display_data" 295 | } 296 | ], 297 | "source": [ 298 | "# print_currents()\n", 299 | "\n", 300 | "setup_ui()\n", 301 | "\n", 302 | "stop_threads = False\n", 303 | "\n", 304 | "def stop():\n", 305 | " global stop_threads\n", 306 | " stop_threads = True\n", 307 | "\n", 308 | "## Graphing must be done in a thread, if done in the main loop\n", 309 | "## it will block event observation of the UI buttons\n", 310 | "import threading\n", 311 | "thread = threading.Thread(target=graph_currents, args=(lambda: stop_threads, ))\n", 312 | "thread.start()" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 343, 318 | "metadata": {}, 319 | "outputs": [], 320 | "source": [ 321 | "# stop()" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": null, 327 | "metadata": {}, 328 | "outputs": [], 329 | "source": [] 330 | } 331 | ], 332 | "metadata": { 333 | "kernelspec": { 334 | "display_name": "py_37_env", 335 | "language": "python", 336 | "name": "py_37_env" 337 | }, 338 | "language_info": { 339 | "codemirror_mode": { 340 | "name": "ipython", 341 | "version": 3 342 | }, 343 | "file_extension": ".py", 344 | "mimetype": "text/x-python", 345 | "name": "python", 346 | "nbconvert_exporter": "python", 347 | "pygments_lexer": "ipython3", 348 | "version": "3.7.3" 349 | } 350 | }, 351 | "nbformat": 4, 352 | "nbformat_minor": 2 353 | } 354 | -------------------------------------------------------------------------------- /USBHub_DC_Regulator.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "inputHidden": false, 8 | "outputHidden": false, 9 | "slideshow": { 10 | "slide_type": "-" 11 | } 12 | }, 13 | "outputs": [], 14 | "source": [ 15 | "import math\n", 16 | "import bisect\n", 17 | "\n", 18 | "import pint\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "import numpy as np\n", 21 | "import sympy\n", 22 | "\n", 23 | "ureg = pint.UnitRegistry()\n", 24 | "ureg.default_format = '.2f'\n", 25 | "\n", 26 | "## Solves an expression for any variable within it\n", 27 | "## Evaluates the expression (in the current context) with a unit coversion\n", 28 | "def solve(exp, variable, unit):\n", 29 | " # Convert from string expression to symbol one \n", 30 | " # Solve the equaltion for the desired variable and convert to string\n", 31 | " # Evaluate the expression string with the desired unit conversion\n", 32 | " exp = sympy.sympify(exp)\n", 33 | " exp = sympy.sstr(sympy.solve(exp, variable)[0])\n", 34 | " return eval(\"(\" + exp + \").to(ureg.\" + unit + \")\")\n", 35 | "\n", 36 | "## Values for each decade of 1% resistors\n", 37 | "RESISTOR_DECADE = [\n", 38 | " 10.0, 10.2, 10.5, 10.7, 11.0, 11.3, 11.5, 11.8, 12.1, 12.4, 12.7, 13.0, 13.3, 13.7, 14.0, 14.3, \n", 39 | " 14.7, 15.0, 15.4, 15.8, 16.2, 16.5, 16.9, 17.4, 17.8, 18.2, 18.7, 19.1, 19.6, 20.0, 20.5, 21.0,\n", 40 | " 21.5, 22.1, 22.6, 23.2, 23.7, 24.3, 24.9, 25.5, 26.1, 26.7, 27.4, 28.0, 28.7, 29.4, 30.1, 30.9,\n", 41 | " 31.6, 32.4, 33.2, 34.0, 34.8, 35.7, 36.5, 37.4, 38.3, 39.2, 40.2, 41.2, 42.2, 43.2, 44.2, 45.2,\n", 42 | " 46.4, 47.5, 48.7, 49.9, 51.1, 52.3, 53.6, 54.9, 56.2, 57.6, 59.0, 60.4, 61.9, 63.4, 64.9, 66.5,\n", 43 | " 68.1, 69.8, 71.5, 73.2, 75.0, 76.8, 78.7, 80.6, 82.5, 84.5, 86.6, 88.7, 90.9, 93.1, 95.3, 97.6\n", 44 | "]\n", 45 | "\n", 46 | "## Generate a list of all 1% resistor values\n", 47 | "RESISTOR_DECADES = [1, 10, 100, 1000, 10000, 100000, 1000000]\n", 48 | "RESISTOR_VALUES = sum([[val*idx for val in RESISTOR_DECADE] for idx in RESISTOR_DECADES], [])\n", 49 | "\n", 50 | "## Binary search through resistor values for the nearest value\n", 51 | "def select_resistor(value):\n", 52 | " idx = bisect.bisect_left(RESISTOR_VALUES, value.to(ureg.Ω).magnitude)\n", 53 | " return RESISTOR_VALUES[idx]" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "## USB Hub System Definitions" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 2, 66 | "metadata": { 67 | "inputHidden": false, 68 | "outputHidden": false 69 | }, 70 | "outputs": [], 71 | "source": [ 72 | "Vinmax = 24 * ureg.V\n", 73 | "Vinmin = 12 * ureg.V\n", 74 | "Vout = 5 * ureg.V\n", 75 | "Ilim = 5.95 * ureg.A\n", 76 | "\n", 77 | "## Resistor divider determines operating frequency\n", 78 | "## Rup is between FREQ and VIN, Rdn is to GND\n", 79 | "## If FREQ connected to VIN (without a pull down resistor) then fsw will be 600 kHz\n", 80 | "\n", 81 | "# Rup = 100 * ureg.kΩ # Recommended value from datasheet\n", 82 | "# Rdn = 1000 * ureg.kΩ\n", 83 | "Rdn = False" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "## MIC45208 Device Properties\n", 91 | "\n", 92 | "#### Switching Frequency\n", 93 | "\n", 94 | "![](./resources/image-fsw.png)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 3, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "## Calculate switching frequency from Rup & Rdn\n", 104 | "if Rdn == False:\n", 105 | " fsw = 600 * ureg.kHz\n", 106 | "else:\n", 107 | " fsw = 600 * ureg.kHz * Rdn / (Rup + Rdn)\n", 108 | "\n", 109 | "## Device Properties (from datasheet)\n", 110 | "L = 1.0 * ureg.uH # Inductor is integrated into the package\n", 111 | "Rdson = 16 * ureg.mΩ # On-resistance of low-side power MOSFET\n", 112 | "Icl = 70 * ureg.uA # Current-limit source current\n", 113 | "Vcloffset = 14 * ureg.mV # Current-limit threshold\n", 114 | "Toffmin = 200 * ureg.ns # Minimum off time" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "## Calculations of duty cycle @ different operating voltages" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 4, 127 | "metadata": { 128 | "inputHidden": false, 129 | "outputHidden": false 130 | }, 131 | "outputs": [ 132 | { 133 | "name": "stdout", 134 | "output_type": "stream", 135 | "text": [ 136 | "FSW : 600.00 kilohertz\n", 137 | "Duty(max) : 0.88 dimensionless\n", 138 | "Toff(min) : 200.00 nanosecond\n", 139 | "\n", 140 | "-- VIN 6.00 volt --\n", 141 | " Ton : 1388.89 nanosecond\n", 142 | " Toff : 277.78 nanosecond\n", 143 | " Duty : 0.83 dimensionless\n", 144 | "\n", 145 | "-- VIN 12.00 volt --\n", 146 | " Ton : 694.44 nanosecond\n", 147 | " Toff : 972.22 nanosecond\n", 148 | " Duty : 0.42 dimensionless\n", 149 | "\n", 150 | "-- VIN 24.00 volt --\n", 151 | " Ton : 347.22 nanosecond\n", 152 | " Toff : 1319.44 nanosecond\n", 153 | " Duty : 0.21 dimensionless\n" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "Ton = lambda Vop: (Vout / (Vop*fsw)).to(ureg.ns)\n", 159 | "Tonmin = Ton(Vinmax)\n", 160 | "Tonmax = Ton(Vinmin)\n", 161 | "Ts = (1/fsw).to(ureg.ns)\n", 162 | "Dmax = (Ts - Toffmin) / Ts\n", 163 | "\n", 164 | "print(\"FSW :\", fsw.to(ureg.kHz))\n", 165 | "print(\"Duty(max) :\", Dmax)\n", 166 | "print(\"Toff(min) :\", Toffmin.to(ureg.ns))\n", 167 | "\n", 168 | "for Vop in [Vinmin/2, Vinmin, Vinmax]:\n", 169 | " Toff = Ts - Ton(Vop)\n", 170 | " D = Ton(Vop) / Ts\n", 171 | " print()\n", 172 | " print(\"-- VIN\", Vop, \"--\")\n", 173 | " print(\" Ton :\", Ton(Vop))\n", 174 | " print(\" Toff :\", Toff)\n", 175 | " print(\" Duty :\", D)\n", 176 | " \n", 177 | " if Toff < Toffmin*1.25:\n", 178 | " print(\" WARN : Toff close to or lower than Toffmin\")\n", 179 | " \n", 180 | " if D > min(0.85, Dmax):\n", 181 | " print(\" WARN : Tudy cycle exceeds specification max\")" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "## Component Selection\n", 189 | "### Current Limit Resistor\n", 190 | "\n", 191 | "Based on desired current limit and other operating points (inductor peak to peak current, MOSFET resistance, etc) the current limiting resistor between SW and ILIM is determined.\n", 192 | "\n", 193 | "The MOSFET RDS(ON) varies 30% to 40% with temperature; therefore, it is recommended to add a 50% margin to ILIM to avoid false current limiting due to increased MOSFET junction temperature rise. After finding the ideal Rlimit values, we contrain it to actual resistor values and calculate the resutling current limit." 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 5, 199 | "metadata": { 200 | "inputHidden": false, 201 | "outputHidden": false 202 | }, 203 | "outputs": [ 204 | { 205 | "name": "stdout", 206 | "output_type": "stream", 207 | "text": [ 208 | "Inductor peak to peak : 6.60 ampere\n", 209 | "Rlimit : changing from 1486.03 ohm to 1500.00 ohm\n", 210 | "Ilimit : 5.99 ampere\n", 211 | "Ilimit TC : 22.50 nanosecond\n" 212 | ] 213 | } 214 | ], 215 | "source": [ 216 | "ILpp = Vout * (Vinmax - Vout) / (Vinmax * fsw * L)\n", 217 | "print(\"Inductor peak to peak :\", ILpp.to(ureg.A))\n", 218 | "\n", 219 | "exp = \"((Ilim*1.5 - ILpp/2.0)*Rdson + Vcloffset)/Icl - Rlimit\"\n", 220 | "\n", 221 | "Rlimitideal = solve(exp, variable='Rlimit', unit='Ω')\n", 222 | "Rlimit = (select_resistor(Rlimitideal) * ureg.Ω).to(ureg.kΩ)\n", 223 | "\n", 224 | "if Rlimit != Rlimitideal:\n", 225 | " print(\"Rlimit : changing from \", Rlimitideal.to(ureg.Ω), \"to\", Rlimit.to(ureg.Ω))\n", 226 | "else:\n", 227 | " print(\"Rlimit :\", Rlimit)\n", 228 | " \n", 229 | "Ilimactual = solve(exp, variable='Ilim', unit='A')\n", 230 | "print(\"Ilimit :\", Ilimactual)\n", 231 | "\n", 232 | "# Climit value copied from EVM design guide\n", 233 | "Climit = 15 * ureg.pF\n", 234 | "tc = Rlimit * Climit\n", 235 | "print(\"Ilimit TC :\", tc.to(ureg.ns))\n", 236 | "\n", 237 | "if tc > Toffmin * 0.2:\n", 238 | " print(\"WARN : Current limit time constant too close to minimum off time\")" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": {}, 244 | "source": [ 245 | "### Input Capacitor Selection" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": 6, 251 | "metadata": { 252 | "collapsed": false, 253 | "inputHidden": false, 254 | "outputHidden": false 255 | }, 256 | "outputs": [ 257 | { 258 | "name": "stdout", 259 | "output_type": "stream", 260 | "text": [ 261 | "Cinsum: 33.00 microfarad\n", 262 | "\n", 263 | "Vin @ 12.00 volt\n", 264 | "Cin \n", 265 | " dV : 142.43 millivolt\n", 266 | " req : 40.61 microfarad\n", 267 | " I rms : 2.93 ampere\n", 268 | " P rms : 0.25 watt\n", 269 | "\n", 270 | "Vin @ 24.00 volt\n", 271 | "Cin \n", 272 | " dV : 193.30 millivolt\n", 273 | " req : 40.61 microfarad\n", 274 | " I rms : 2.42 ampere\n", 275 | " P rms : 0.17 watt\n" 276 | ] 277 | } 278 | ], 279 | "source": [ 280 | "## Build dict of [Value, ESR, Impedance] of caps at 12v\n", 281 | "CAPS = {}\n", 282 | "CAPS[\"0805_1u0\"] = [ 1.0*ureg.uF, 18.6, 288.0] ## C0805C105K5RAC\n", 283 | "CAPS[\"1206_4u7\"] = [ 4.7*ureg.uF, 13.1, 62.3] ## C1206C475K5PAC\n", 284 | "CAPS[\"2917_33u\"] = [33.0*ureg.uF, 29.3, 29.8] ## T521D336M035ATE065\n", 285 | "\n", 286 | "Cins = [\"2917_33u\"]\n", 287 | "# Cins = [\"1206_4u7\", \"1206_4u7\", \"0805_1u0\"] + [\"2917_33u\", \"2917_33u\"]\n", 288 | "\n", 289 | "f = fsw\n", 290 | "\n", 291 | "Zsum = 0\n", 292 | "Ceff = 0\n", 293 | "\n", 294 | "for key in Cins:\n", 295 | " cap = CAPS[key]\n", 296 | " \n", 297 | " Ceff += cap[0]\n", 298 | " esr = cap[1]*ureg.mΩ\n", 299 | " imp = cap[2]*ureg.mΩ * -1j\n", 300 | " \n", 301 | " ## Impedance for an idea cap. This is not accurate as bias voltage increases.\n", 302 | " ## Therefore, we use ESR from the SKU datasheets at 12v (listed above). \n", 303 | " # imp = (-1j / (2*math.pi*f*cap[0])).to(ureg.mΩ)\n", 304 | " \n", 305 | " Zsum += 1/(esr + imp) \n", 306 | "\n", 307 | "ESRCin = (1 / Zsum).real\n", 308 | "Cinsum = Ceff.to(ureg.uF)\n", 309 | "\n", 310 | "print(\"Cinsum:\", Cinsum)\n", 311 | "\n", 312 | "## Current increases with duty cycle, so calculate at VIN = 12\n", 313 | "## Load on cap increases as duty cycle drops, so calculate at VIN = 24\n", 314 | "for vin in [Vinmin, Vinmax]:\n", 315 | " D = Ton(vin) / Ts\n", 316 | " Icinrms = Ilim * math.sqrt(D*(1-D))\n", 317 | "\n", 318 | " ## Inductor current changes as vin does, so we need to recalculate it\n", 319 | " ILpp = Vout * (vin - Vout) / (vin * fsw * L)\n", 320 | " \n", 321 | " ## These require knowing the ESR of the input caps\n", 322 | " dVin = ILpp * ESRCin\n", 323 | " Cinreq = Ilim * (1-D) / (fsw * dVin)\n", 324 | " Pcinrms = Icinrms**2 * ESRCin\n", 325 | "\n", 326 | " print()\n", 327 | " print(\"Vin @ {}\".format(vin))\n", 328 | " print(\"Cin \")\n", 329 | " print(\" dV :\", dVin.to(ureg.mV))\n", 330 | " print(\" req :\", Cinreq.to(ureg.uF))\n", 331 | " print(\" I rms :\", Icinrms)\n", 332 | " print(\" P rms :\", Pcinrms.to(ureg.W))\n" 333 | ] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "metadata": {}, 338 | "source": [ 339 | "### Output Voltage Setting Components\n", 340 | "\n", 341 | "A typical value of RFB1 used on the standard evaluation board is 10 kΩ. If R1 is too large, it may allow noise to be introduced into the voltage feedback loop. If RFB1 is too small in value, it will decrease the efficiency of the power supply, especially at light loads. Once RFB1 is selected, RFB2 can be calculated." 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "execution_count": 7, 347 | "metadata": { 348 | "inputHidden": false, 349 | "outputHidden": false 350 | }, 351 | "outputs": [ 352 | { 353 | "name": "stdout", 354 | "output_type": "stream", 355 | "text": [ 356 | "RFB2 : changing from 1860.47 ohm to 1870.00 ohm\n", 357 | "Vout : changing from 5.10 volt to 5.08 volt\n" 358 | ] 359 | } 360 | ], 361 | "source": [ 362 | "Vfb = 0.8 * ureg.V\n", 363 | "RFB1 = 10 * ureg.kΩ\n", 364 | "\n", 365 | "# Boost 5v output a bit to compenstate for loss in downstream cabling\n", 366 | "Vout = Vout * 1.02\n", 367 | "\n", 368 | "RFB2ideal = Vfb * RFB1 / (Vout - Vfb)\n", 369 | "RFB2 = (select_resistor(RFB2ideal) * ureg.Ω).to(ureg.kΩ)\n", 370 | "\n", 371 | "if RFB2ideal != RFB2:\n", 372 | " print(\"RFB2 : changing from \", RFB2ideal.to(ureg.Ω), \"to\", RFB2.to(ureg.Ω))\n", 373 | "else:\n", 374 | " print(\"RFB2 :\", RFB2)\n", 375 | " \n", 376 | "Voutactual = Vfb * (1+ RFB1/RFB2)\n", 377 | "print(\"Vout : changing from \", Vout, \"to\", Voutactual)" 378 | ] 379 | } 380 | ], 381 | "metadata": { 382 | "jupytext_formats": "ipynb,py", 383 | "kernel_info": { 384 | "name": "python3" 385 | }, 386 | "kernelspec": { 387 | "display_name": "py_37_env", 388 | "language": "python", 389 | "name": "py_37_env" 390 | }, 391 | "language_info": { 392 | "codemirror_mode": { 393 | "name": "ipython", 394 | "version": 3 395 | }, 396 | "file_extension": ".py", 397 | "mimetype": "text/x-python", 398 | "name": "python", 399 | "nbconvert_exporter": "python", 400 | "pygments_lexer": "ipython3", 401 | "version": "3.7.3" 402 | }, 403 | "nteract": { 404 | "version": "0.12.3" 405 | } 406 | }, 407 | "nbformat": 4, 408 | "nbformat_minor": 4 409 | } 410 | -------------------------------------------------------------------------------- /USBHub_i2c_addresses.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": { 7 | "collapsed": false, 8 | "inputHidden": false, 9 | "outputHidden": false 10 | }, 11 | "outputs": [], 12 | "source": [ 13 | "import yaml\n", 14 | "import pystache\n", 15 | "from IPython.display import display, HTML \n", 16 | "\n", 17 | "def numeric_addr(bitlist):\n", 18 | " out = 0\n", 19 | " for bit in bitlist:\n", 20 | " out = (out << 1) | bit\n", 21 | " return out\n", 22 | "\n", 23 | "def bitfield(n):\n", 24 | " return [int(digit) for digit in bin(n)[2:]]\n", 25 | "\n", 26 | "def resolve(device, incr):\n", 27 | " idx = 0\n", 28 | " remap = {}\n", 29 | " \n", 30 | " if incr > device['adjustable_bits']**2:\n", 31 | " raise Exception(\"Not enough address pins\") \n", 32 | " \n", 33 | " bitlist = device['address_struct']\n", 34 | " \n", 35 | " if incr > 0:\n", 36 | " adjust = bitfield(incr)\n", 37 | " adjust.reverse()\n", 38 | " \n", 39 | " ## Replace strings with values from a bit representation of the increment\n", 40 | " for value in adjust:\n", 41 | " \n", 42 | " if \"A0\" in bitlist:\n", 43 | " key = \"A{}\".format(idx)\n", 44 | " if key not in bitlist:\n", 45 | " raise Exception(\"Expecting '{}' in address, not found\".format(key))\n", 46 | " remap[key] = value\n", 47 | " idx += 1\n", 48 | " \n", 49 | " else:\n", 50 | " for digit in reversed(bitlist):\n", 51 | " if not str(digit).isdigit():\n", 52 | " if digit not in remap.keys():\n", 53 | " remap[digit] = value\n", 54 | " else:\n", 55 | " raise Exception(\"Not enough address pins\") \n", 56 | " \n", 57 | " bitlist = [remap.get(n, n) for n in bitlist]\n", 58 | "\n", 59 | " ## Replace any strings left over with zeros\n", 60 | " return ([0 if isinstance(n, str) else n for n in bitlist], remap)\n", 61 | "\n", 62 | "class Devices:\n", 63 | "\n", 64 | " def __init__(self, path='./i2c-addresses.yml'):\n", 65 | "\n", 66 | " self.data = {}\n", 67 | " with open(path) as f:\n", 68 | " self.data = yaml.safe_load(f)\n", 69 | "\n", 70 | " self.devices = []\n", 71 | " self.taken = {}\n", 72 | " \n", 73 | " def add(self, name):\n", 74 | " if name in self.data:\n", 75 | " addr = self.data[name]\n", 76 | " data = dict(\n", 77 | " name=name, \n", 78 | " address_struct=addr, \n", 79 | " adjustable_bits = 7 - addr.count(0) - addr.count(1)\n", 80 | " )\n", 81 | " self.devices.append(data)\n", 82 | " else:\n", 83 | " raise Exception(\"Cannot find device: {}\".format(name))\n", 84 | "\n", 85 | " def solve(self, html=False, debug=False, stdout=False):\n", 86 | " ## Iterate through the selected devices by the number of adjustable bits\n", 87 | " self.devices = sorted(self.devices, key=lambda d: d['adjustable_bits'])\n", 88 | " \n", 89 | " for idx, dev in enumerate(self.devices):\n", 90 | " incr = 0\n", 91 | "\n", 92 | " while True:\n", 93 | " try:\n", 94 | " bits, remap = resolve(dev, incr)\n", 95 | " address = numeric_addr(bits) \n", 96 | " except Exception:\n", 97 | " if debug:\n", 98 | " print(\"WARN : Cannot resolve {} in slot {}, no free addresses\".format(dev['name'], idx))\n", 99 | " break\n", 100 | "\n", 101 | " if address not in self.taken:\n", 102 | " dev['bits'] = bits\n", 103 | " dev['address'] = numeric_addr(bits)\n", 104 | " dev['remap'] = remap\n", 105 | " self.taken[address] = dev\n", 106 | " break\n", 107 | "\n", 108 | " incr += 1\n", 109 | " \n", 110 | " if stdout:\n", 111 | " self.print()\n", 112 | " \n", 113 | " if html:\n", 114 | " self.print_html()\n", 115 | " \n", 116 | "\n", 117 | " def print(self):\n", 118 | " for addr, dev in self.taken.items():\n", 119 | " print(\"{} @ {}\".format(dev['name'], hex(addr)))\n", 120 | " print(\"\\t\", dev['address_struct'])\n", 121 | " print(\"\\t\", dev['bits'])\n", 122 | " print()\n", 123 | " \n", 124 | " def print_table(self):\n", 125 | " out = []\n", 126 | " out.append([\"IDX\", \"Name\", \"Address\", \"Configuration\"])\n", 127 | " \n", 128 | " for idx, dev in enumerate(self.devices):\n", 129 | " if 'address' in dev:\n", 130 | " addr = hex(dev['address'])\n", 131 | " else:\n", 132 | " addr = \"NONE\"\n", 133 | " \n", 134 | " out.append([idx, dev['name'], addr])\n", 135 | " \n", 136 | " return out\n", 137 | " \n", 138 | " def print_html(self, raw=False):\n", 139 | " template = u\"\"\"\n", 140 | " \n", 141 | " {{#device}}\n", 142 | " \n", 143 | " {{/device}}\n", 144 | "
IDX Device Address Address Struct Mapping
{{idx}} {{name}} {{{address_formatted}}} {{{address_string}}} {{mapping_string}}
\"\"\"\n", 145 | " \n", 146 | " out = []\n", 147 | " \n", 148 | " for idx,dev in enumerate(self.devices):\n", 149 | " \n", 150 | " if 'address' in dev:\n", 151 | " addr = hex(dev['address'])\n", 152 | " else:\n", 153 | " dev['bits'] = []\n", 154 | " addr = \"NONE\"\n", 155 | " \n", 156 | " dev['idx'] = idx\n", 157 | " dev['address_formatted'] = addr\n", 158 | " \n", 159 | " mapping = zip(dev['address_struct'], dev['bits'])\n", 160 | " mapping = [\"\" if a==b else \"{}:{}\".format(a,b) for (a,b) in list(mapping)]\n", 161 | " dev['mapping_string'] = \" \".join([str(b) for b in mapping])\n", 162 | " \n", 163 | " address = [str(b) for b in dev['address_struct']]\n", 164 | " address = [b if b.isdigit() else \"{}\".format(b) for b in address]\n", 165 | " dev['address_string'] = \" \".join(address)\n", 166 | " \n", 167 | " out.append(dev)\n", 168 | " \n", 169 | " html = pystache.render(template, dict(device=out))\n", 170 | " \n", 171 | " if raw:\n", 172 | " return html\n", 173 | " else:\n", 174 | " display(HTML(html))" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 4, 180 | "metadata": { 181 | "collapsed": false, 182 | "inputHidden": false, 183 | "outputHidden": false 184 | }, 185 | "outputs": [ 186 | { 187 | "data": { 188 | "text/html": [ 189 | "\n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | "
IDX Device Address Address Struct Mapping
0 UCS2113-1 0x57 1 0 1 0 1 1 1
1 UCS2113-2 0x58 1 0 1 1 0 0 0
2 ATECC508A 0x60 1 1 0 0 0 0 0
3 24AA025E48 0x50 1 0 1 0 0 A1 A0 A1:0 A0:0
4 MCP23008 0x20 0 1 0 0 A2 A1 A0 A2:0 A1:0 A0:0
5 MCP9808 0x18 0 0 1 1 A2 A1 A0 A2:0 A1:0 A0:0
6 TLC59116 0x61 1 1 0 A3 A2 A1 A0 A3:0 A2:0 A1:0 A0:1
7 TLC59116 0x62 1 1 0 A3 A2 A1 A0 A3:0 A2:0 A1:1 A0:0
" 209 | ], 210 | "text/plain": [ 211 | "" 212 | ] 213 | }, 214 | "metadata": {}, 215 | "output_type": "display_data" 216 | } 217 | ], 218 | "source": [ 219 | "devices = Devices()\n", 220 | "\n", 221 | "devices.add('TLC59116')\n", 222 | "devices.add('TLC59116')\n", 223 | "devices.add('UCS2113-1')\n", 224 | "devices.add('UCS2113-2')\n", 225 | "devices.add('MCP23008')\n", 226 | "devices.add('24AA025E48')\n", 227 | "devices.add('ATECC508A')\n", 228 | "devices.add('MCP9808')\n", 229 | "\n", 230 | "devices.solve(html=True)" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": null, 236 | "metadata": {}, 237 | "outputs": [], 238 | "source": [] 239 | } 240 | ], 241 | "metadata": { 242 | "kernel_info": { 243 | "name": "python3" 244 | }, 245 | "kernelspec": { 246 | "display_name": "py_37_env", 247 | "language": "python", 248 | "name": "py_37_env" 249 | }, 250 | "language_info": { 251 | "codemirror_mode": { 252 | "name": "ipython", 253 | "version": 3 254 | }, 255 | "file_extension": ".py", 256 | "mimetype": "text/x-python", 257 | "name": "python", 258 | "nbconvert_exporter": "python", 259 | "pygments_lexer": "ipython3", 260 | "version": "3.7.3" 261 | }, 262 | "nteract": { 263 | "version": "0.12.3" 264 | } 265 | }, 266 | "nbformat": 4, 267 | "nbformat_minor": 4 268 | } 269 | -------------------------------------------------------------------------------- /i2c-addresses.yml: -------------------------------------------------------------------------------- 1 | TLC59116: [1, 1, 0, A3, A2, A1, A0] 2 | MCP23008: [0, 1, 0, 0, A2, A1, A0] 3 | UCS2113-1: [1, 0, 1, 0, 1, 1, 1] 4 | UCS2113-2: [1, 0, 1, 1, 0, 0, 0] 5 | 24AA025E48: [1, 0, 1, 0, 0, A1, A0] 6 | AT24C01D: [1, 0, 1, 0, A2, A1, A0] 7 | AT24C02D: [1, 0, 1, 0, A2, A1, A0] 8 | ATECC508A: [1, 1, 0, 0, 0, 0, 0] 9 | MCP9808: [0, 0, 1, 1, A2, A1, A0] 10 | BMI055_ACCEL: [0, 0, 1, 1, 0, 0, 0] 11 | BMI055_GYRO: [0, 0, 1, 1, 0, 0, 1] 12 | BMI160: [1, 1, 0, 1, 0, 0, 1] 13 | AR0135: [0, 0, 1, SADDR, 0, 0, 0] -------------------------------------------------------------------------------- /resources/SMA6J.lib: -------------------------------------------------------------------------------- 1 | * File : SMA6J.LIB 2 | * Revision : 1.0 3 | * Date : January 2016 4 | * 5 | *************************************************************************************** 6 | * Information included is believed to be accurate and reliable. However, * 7 | * ST Microelectronics assumes no responsibility for the consequences of * 8 | * use of such information nor for any infringement of patents or other * 9 | * rights of third parties which may result from its use. No license is * 10 | * granted by implication or otherwise under any patent patent rights of * 11 | * ST Microelectronics. Specification mentionned in this publication are * 12 | * subject to change without notice. This publication superseedes and * 13 | * replaces all information previously supplied. ST Microelectronics * 14 | * products are not authorized for use as critical components in life * 15 | * support or systems without express written approval of ST * 16 | * Microelectronics. * 17 | * * * 18 | * (c) 1997 ST Microelectronics. All rights reserved. * 19 | * * * 20 | * ST Microelectronics GROUP OF COMPANIES * 21 | * Australia - Brazil - France - Germany - Hong Kong - Italy - Japan * 22 | * Korea - Malaysia - Malta - Morocco - The Netherlands - Singapore * 23 | * Spain - Sweden - Switzerland - Taiwan - United Kingdom - U.S.A. * 24 | * * 25 | *************************************************************************************** 26 | * 27 | ******** PARAMETERS DESCRIPTION ******** 28 | * IRM Stand-off current at VRM 29 | * VBR Breakdown voltage 30 | * IR Reverse current at VBR 31 | * VCL Clamping voltage 32 | * Ipp Surge current 33 | * Cjo junction capacitance at 0V 34 | * IS Saturation current 35 | * N Emission coefficient 36 | * RS Serie resistance 37 | * IKF High injection knee current 38 | ***************************************** 39 | 40 | ***************************************** 41 | *********** UNIDIRECTIONAL TRANSIL *********** 42 | ***************************************** 43 | 44 | .SUBCKT TRANSIL Anode Cathode PARAMS: 45 | + IRM=1u VBRnom=12 VBRmax=13 IR=1m 46 | + VCLmax=20 Ipp=100 Cjof=1n 47 | + ISF=1f NF=1 RSF=1m IKFF=1000 48 | 49 | Drev A_int Cathode TRANSR 50 | Dfwd Anode Cathode TRANSF 51 | Dr A_int Anode DTRANS 52 | 53 | ***** REVERSE BEHAVIOUR ***** 54 | .MODEL TRANSR D( 55 | + IS={IRM/2} RS={(VCLmax-VBRmax)/Ipp} 56 | + BV={VBRnom} IBV={IR} 57 | + IKF=1000 Cjo=1p M=.3333 VJ=.6 58 | + ISR=1n TT=1u ) 59 | 60 | .MODEL DTRANS D( 61 | + IS=1n N=.01 RS=1u IKF=1000 Cjo=1p 62 | + M=.3333 VJ=.6 ISR=1n BV=1000 IBV=1u 63 | + TT=1u ) 64 | 65 | ***** JUNCTION CAPACITANCE BEHAVIOUR Cj(VR) ***** 66 | .MODEL TRANSF D( 67 | + IS={ISF} N={NF} RS={RSF} IKF={IKFF} 68 | + Cjo={Cjof} M=.35 VJ=0.65 ISR=1.000E-21 69 | + BV=1000 IBV=1n TT=1u ) 70 | 71 | 72 | 73 | .ENDS 74 | 75 | ***************************************** 76 | *********** BIDIRECTIONAL TRANSIL ********** 77 | ***************************************** 78 | 79 | ********** Low voltage ************ 80 | .SUBCKT TRANSILBLV Anode1 Anode2 PARAMS: 81 | + IRM=1u VBRnom=12 VBRmax=13 IR=1m 82 | + VCLmax=20 Ipp=100 Cjof=1n 83 | + ISBF=1f NBF=1 84 | + MCB=0.21 VJCB=0.65 85 | 86 | ***** SCHEMATICS DESCRIPTION ***** 87 | Drev1 A_int1 Cathode TRANSR 88 | Dfwd1 Anode1 Cathode TRANSBF 89 | Dr1 A_int1 Anode1 DTRANS 90 | Drev2 A_int2 Cathode TRANSR 91 | Dfwd2 Anode2 Cathode TRANSBF 92 | Dr2 A_int2 Anode2 DTRANS 93 | 94 | ***** REVERSE BEHAVIOUR ***** 95 | .MODEL TRANSR D( 96 | + IS={IRM/2} RS={(VCLmax-VBRmax)/Ipp} 97 | + BV={VBRnom} IBV={IR} 98 | + IKF=1000 Cjo=1p M=.3333 VJ=.6 99 | + ISR=1p TT=1u ) 100 | 101 | .MODEL DTRANS D( 102 | + IS=1n N=.01 RS=1u IKF=1000 Cjo=1p 103 | + M=.3333 VJ=.6 ISR=1p BV=1000 IBV=100u 104 | + TT=1u ) 105 | 106 | ***** JUNCTION CAPACITANCE BEHAVIOUR ***** 107 | .MODEL TRANSBF D( 108 | + IS={ISBF} N={NBF} RS=1u IKF=1000 109 | + Cjo={Cjof} M={MCB} VJ={VJCB} ISR=1p 110 | + BV=1000 IBV=100u TT=1u ) 111 | 112 | .ENDS 113 | 114 | 115 | ********** High voltage ********** 116 | .SUBCKT TRANSILBHV Anode1 Anode2 PARAMS: 117 | + IRM=1u VBRnom=12 VBRmax=13 IR=1m 118 | + VCLmax=20 Ipp=100 Cjof=1n 119 | + ISBF=1f NBF=1 120 | + MCB=0.35 VJCB=0.65 121 | 122 | ***** SCHEMATICS DESCRIPTION ***** 123 | Drev1 A_int1 Cathode TRANSR 124 | Dfwd1 Anode1 Cathode TRANSBF 125 | Dr1 A_int1 Anode1 DTRANS 126 | Drev2 A_int2 Cathode TRANSR 127 | Dfwd2 Anode2 Cathode TRANSBF 128 | Dr2 A_int2 Anode2 DTRANS 129 | 130 | ***** REVERSE BEHAVIOUR ***** 131 | .MODEL TRANSR D( 132 | + IS={IRM/2} RS={(VCLmax-VBRmax)/Ipp} 133 | + BV={VBRnom} IBV={IR} 134 | + IKF=1000 Cjo=1p M=.3333 VJ=.6 135 | + ISR=1p TT=1u ) 136 | 137 | .MODEL DTRANS D( 138 | + IS=1n N=.01 RS=1u IKF=1000 Cjo=1p 139 | + M=.3333 VJ=.6 ISR=1p BV=1000 IBV=100u 140 | + TT=1u ) 141 | 142 | ***** JUNCTION CAPACITANCE BEHAVIOUR ***** 143 | .MODEL TRANSBF D( 144 | + IS={ISBF} N={NBF} RS=1u IKF=1000 145 | + Cjo={Cjof} M={MCB} VJ={VJCB} ISR=1p 146 | + BV=1000 IBV=100u TT=1u ) 147 | 148 | .ENDS 149 | 150 | 151 | 152 | ************************************************************************************************* 153 | * SMA6J family 154 | ************************************************************************************************* 155 | 156 | 157 | .SUBCKT SMA6J5_0A Anode Cathode 158 | X1 Anode Cathode TRANSIL PARAMS: 159 | + IRM=20u VBRnom=6.74 VBRmax=7.07 160 | + IR=10m VCLmax=13.4 Ipp=298 Cjof=3.5n 161 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 162 | .ENDS 163 | 164 | 165 | .SUBCKT SMA6J5_0CA Anode1 Anode2 166 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 167 | + IRM=20u VBRnom=6.74 VBRmax=7.07 168 | + IR=10m VCLmax=13.4 Ipp=298 Cjof=1750p 169 | + ISBF=1n NBF=.01 170 | .ENDS 171 | 172 | 173 | .SUBCKT SMA6J6_0A Anode Cathode 174 | X1 Anode Cathode TRANSIL PARAMS: 175 | + IRM=20u VBRnom=7.05 VBRmax=7.41 176 | + IR=10m VCLmax=13.7 Ipp=290 Cjof=2.85n 177 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 178 | .ENDS 179 | 180 | 181 | .SUBCKT SMA6J6_0CA Anode1 Anode2 182 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 183 | + IRM=20u VBRnom=7.05 VBRmax=7.41 184 | + IR=10m VCLmax=13.7 Ipp=290 Cjof=1500p 185 | + ISBF=1n NBF=.01 186 | .ENDS 187 | 188 | 189 | .SUBCKT SMA6J6_5A Anode Cathode 190 | X1 Anode Cathode TRANSIL PARAMS: 191 | + IRM=20u VBRnom=7.58 VBRmax=7.96 192 | + IR=10m VCLmax=14.5 Ipp=276 Cjof=2.61n 193 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 194 | .ENDS 195 | 196 | 197 | .SUBCKT SMA6J6_5CA Anode1 Anode2 198 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 199 | + IRM=20u VBRnom=7.58 VBRmax=7.96 200 | + IR=10m VCLmax=14.5 Ipp=276 Cjof=1380p 201 | + ISBF=1n NBF=.01 202 | .ENDS 203 | 204 | 205 | .SUBCKT SMA6J8_5A Anode Cathode 206 | X1 Anode Cathode TRANSIL PARAMS: 207 | + IRM=20u VBRnom=9.9 VBRmax=10.4 208 | + IR=1m VCLmax=19.5 Ipp=205 Cjof=1.92n 209 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 210 | .ENDS 211 | 212 | 213 | .SUBCKT SMA6J8_5CA Anode1 Anode2 214 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 215 | + IRM=20u VBRnom=9.9 VBRmax=10.4 216 | + IR=1m VCLmax=19.5 Ipp=205 Cjof=1020p 217 | + ISBF=1n NBF=.01 218 | .ENDS 219 | 220 | 221 | .SUBCKT SMA6J10A Anode Cathode 222 | X1 Anode Cathode TRANSIL PARAMS: 223 | + IRM=0.2u VBRnom=11.7 VBRmax=12.3 224 | + IR=1m VCLmax=21.7 Ipp=184 Cjof=1.6n 225 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 226 | .ENDS 227 | 228 | 229 | .SUBCKT SMA6J10CA Anode1 Anode2 230 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 231 | + IRM=0.2u VBRnom=11.7 VBRmax=12.3 232 | + IR=1m VCLmax=21.7 Ipp=184 Cjof=835p 233 | + ISBF=1n NBF=.01 234 | .ENDS 235 | 236 | 237 | .SUBCKT SMA6J12A Anode Cathode 238 | X1 Anode Cathode TRANSIL PARAMS: 239 | + IRM=0.2u VBRnom=14 VBRmax=14.7 240 | + IR=1m VCLmax=25.3 Ipp=157 Cjof=1.31n 241 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 242 | .ENDS 243 | 244 | 245 | .SUBCKT SMA6J12CA Anode1 Anode2 246 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 247 | + IRM=0.2u VBRnom=14 VBRmax=14.7 248 | + IR=1m VCLmax=25.3 Ipp=157 Cjof=663p 249 | + ISBF=1n NBF=.01 250 | .ENDS 251 | 252 | 253 | .SUBCKT SMA6J13A Anode Cathode 254 | X1 Anode Cathode TRANSIL PARAMS: 255 | + IRM=0.2u VBRnom=15.2 VBRmax=15.9 256 | + IR=1m VCLmax=27.2 Ipp=147 Cjof=1.20n 257 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 258 | .ENDS 259 | 260 | 261 | .SUBCKT SMA6J13CA Anode1 Anode2 262 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 263 | + IRM=0.2u VBRnom=15.2 VBRmax=15.9 264 | + IR=1m VCLmax=27.2 Ipp=147 Cjof=600p 265 | + ISBF=1n NBF=.01 266 | .ENDS 267 | 268 | 269 | .SUBCKT SMA6J15A Anode Cathode 270 | X1 Anode Cathode TRANSIL PARAMS: 271 | + IRM=0.2u VBRnom=17.6 VBRmax=18.5 272 | + IR=1m VCLmax=32.5 Ipp=123 Cjof=1.02n 273 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 274 | .ENDS 275 | 276 | 277 | .SUBCKT SMA6J15CA Anode1 Anode2 278 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 279 | + IRM=0.2u VBRnom=17.6 VBRmax=18.5 280 | + IR=1m VCLmax=35.5 Ipp=123 Cjof=500p 281 | + ISBF=1n NBF=.01 282 | .ENDS 283 | 284 | 285 | .SUBCKT SMA6J18A Anode Cathode 286 | X1 Anode Cathode TRANSIL PARAMS: 287 | + IRM=0.2u VBRnom=21.1 VBRmax=22.1 288 | + IR=1m VCLmax=39.3 Ipp=102 Cjof=840p 289 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 290 | .ENDS 291 | 292 | 293 | .SUBCKT SMA6J18CA Anode1 Anode2 294 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 295 | + IRM=0.2u VBRnom=21.1 VBRmax=22.1 296 | + IR=1m VCLmax=39.3 Ipp=102 Cjof=398p 297 | + ISBF=1n NBF=.01 298 | .ENDS 299 | 300 | 301 | .SUBCKT SMA6J20A Anode Cathode 302 | X1 Anode Cathode TRANSIL PARAMS: 303 | + IRM=0.2u VBRnom=23.4 VBRmax=24.5 304 | + IR=1m VCLmax=42.8 Ipp=93 Cjof=752p 305 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 306 | .ENDS 307 | 308 | 309 | .SUBCKT SMA6J20CA Anode1 Anode2 310 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 311 | + IRM=0.2u VBRnom=23.4 VBRmax=24.5 312 | + IR=1m VCLmax=42.8 Ipp=93 Cjof=350p 313 | + ISBF=1n NBF=.01 314 | .ENDS 315 | 316 | 317 | .SUBCKT SMA6J24A Anode Cathode 318 | X1 Anode Cathode TRANSIL PARAMS: 319 | + IRM=0.2u VBRnom=28.1 VBRmax=29.5 320 | + IR=1m VCLmax=50 Ipp=80 Cjof=622p 321 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 322 | .ENDS 323 | 324 | 325 | .SUBCKT SMA6J24CA Anode1 Anode2 326 | X1 Anode1 Anode2 TRANSILBLV PARAMS: 327 | + IRM=0.2u VBRnom=28.1 VBRmax=29.5 328 | + IR=1m VCLmax=50 Ipp=80 Cjof=281p 329 | + ISBF=1n NBF=.01 330 | .ENDS 331 | 332 | .SUBCKT SMA6J26A Anode Cathode 333 | X1 Anode Cathode TRANSIL PARAMS: 334 | + IRM=0.2u VBRnom=30.4 VBRmax=31.9 335 | + IR=1m VCLmax=53.5 Ipp=75 Cjof=573p 336 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 337 | .ENDS 338 | 339 | 340 | .SUBCKT SMA6J26CA Anode1 Anode2 341 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 342 | + IRM=0.2u VBRnom=30.4 VBRmax=31.9 343 | + IR=1m VCLmax=53.5 Ipp=75 Cjof=288p 344 | + ISBF=1n NBF=.01 345 | .ENDS 346 | 347 | 348 | .SUBCKT SMA6J28A Anode Cathode 349 | X1 Anode Cathode TRANSIL PARAMS: 350 | + IRM=0.2u VBRnom=32.7 VBRmax=34.4 351 | + IR=1m VCLmax=59 Ipp=68 Cjof=532p 352 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 353 | .ENDS 354 | 355 | 356 | .SUBCKT SMA6J28CA Anode1 Anode2 357 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 358 | + IRM=0.2u VBRnom=32.7 VBRmax=34.4 359 | + IR=1m VCLmax=59 Ipp=68 Cjof=268p 360 | + ISBF=1n NBF=.01 361 | .ENDS 362 | 363 | 364 | .SUBCKT SMA6J33A Anode Cathode 365 | X1 Anode Cathode TRANSIL PARAMS: 366 | + IRM=0.2u VBRnom=38.6 VBRmax=40.6 367 | + IR=1m VCLmax=69 Ipp=57 Cjof=452p 368 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 369 | .ENDS 370 | 371 | 372 | .SUBCKT SMA6J33CA Anode1 Anode2 373 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 374 | + IRM=0.2u VBRnom=38.6 VBRmax=40.6 375 | + IR=1m VCLmax=69 Ipp=57 Cjof=223p 376 | + ISBF=1n NBF=.01 377 | .ENDS 378 | 379 | 380 | .SUBCKT SMA6J40A Anode Cathode 381 | X1 Anode Cathode TRANSIL PARAMS: 382 | + IRM=0.2u VBRnom=46.7 VBRmax=49.1 383 | + IR=1m VCLmax=84 Ipp=48 Cjof=376p 384 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 385 | .ENDS 386 | 387 | 388 | .SUBCKT SMA6J40CA Anode1 Anode2 389 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 390 | + IRM=0.2u VBRnom=46.7 VBRmax=49.1 391 | + IR=1m VCLmax=84 Ipp=48 Cjof=183p 392 | + ISBF=1n NBF=.01 393 | .ENDS 394 | 395 | 396 | .SUBCKT SMA6J48A Anode Cathode 397 | X1 Anode Cathode TRANSIL PARAMS: 398 | + IRM=0.2u VBRnom=56.1 VBRmax=58.9 399 | + IR=1m VCLmax=100 Ipp=40 Cjof=317p 400 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 401 | .ENDS 402 | 403 | 404 | .SUBCKT SMA6J48CA Anode1 Anode2 405 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 406 | + IRM=0.2u VBRnom=56.1 VBRmax=58.9 407 | + IR=1m VCLmax=100 Ipp=40 Cjof=153p 408 | + ISBF=1n NBF=.01 409 | .ENDS 410 | 411 | 412 | .SUBCKT SMA6J58A Anode Cathode 413 | X1 Anode Cathode TRANSIL PARAMS: 414 | + IRM=0.2u VBRnom=67.8 VBRmax=71.2 415 | + IR=1m VCLmax=121 Ipp=33 Cjof=268p 416 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 417 | .ENDS 418 | 419 | 420 | .SUBCKT SMA6J58CA Anode1 Anode2 421 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 422 | + IRM=0.2u VBRnom=67.8 VBRmax=71.2 423 | + IR=1m VCLmax=121 Ipp=33 Cjof=135p 424 | + ISBF=1n NBF=.01 425 | .ENDS 426 | 427 | 428 | .SUBCKT SMA6J70A Anode Cathode 429 | X1 Anode Cathode TRANSIL PARAMS: 430 | + IRM=0.2u VBRnom=81.9 VBRmax=86 431 | + IR=1m VCLmax=146 Ipp=27 Cjof=228p 432 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 433 | .ENDS 434 | 435 | 436 | .SUBCKT SMA6J70CA Anode1 Anode2 437 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 438 | + IRM=0.2u VBRnom=81.9 VBRmax=86 439 | + IR=1m VCLmax=146 Ipp=27 Cjof=109p 440 | + ISBF=1n NBF=.01 441 | .ENDS 442 | 443 | 444 | .SUBCKT SMA6J85A Anode Cathode 445 | X1 Anode Cathode TRANSIL PARAMS: 446 | + IRM=0.2u VBRnom=99 VBRmax=104 447 | + IR=1m VCLmax=178 Ipp=22.5 Cjof=194p 448 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 449 | .ENDS 450 | 451 | 452 | .SUBCKT SMA6J85CA Anode1 Anode2 453 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 454 | + IRM=0.2u VBRnom=99 VBRmax=104 455 | + IR=1m VCLmax=178 Ipp=22.5 Cjof=94p 456 | + ISBF=1n NBF=.01 457 | .ENDS 458 | 459 | 460 | .SUBCKT SMA6J100A Anode Cathode 461 | X1 Anode Cathode TRANSIL PARAMS: 462 | + IRM=0.2u VBRnom=117 VBRmax=123 463 | + IR=1m VCLmax=212 Ipp=19 Cjof=171p 464 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 465 | .ENDS 466 | 467 | 468 | .SUBCKT SMA6J100CA Anode1 Anode2 469 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 470 | + IRM=0.2u VBRnom=117 VBRmax=123 471 | + IR=1m VCLmax=212 Ipp=19 Cjof=84p 472 | + ISBF=1n NBF=.01 473 | .ENDS 474 | 475 | 476 | .SUBCKT SMA6J130A Anode Cathode 477 | X1 Anode Cathode TRANSIL PARAMS: 478 | + IRM=0.2u VBRnom=152 VBRmax=159 479 | + IR=1m VCLmax=265 Ipp=15 Cjof=140p 480 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 481 | .ENDS 482 | 483 | 484 | .SUBCKT SMA6J130CA Anode1 Anode2 485 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 486 | + IRM=0.2u VBRnom=152 VBRmax=159 487 | + IR=1m VCLmax=265 Ipp=15 Cjof=71p 488 | + ISBF=1n NBF=.01 489 | .ENDS 490 | 491 | 492 | .SUBCKT SMA6J154A Anode Cathode 493 | X1 Anode Cathode TRANSIL PARAMS: 494 | + IRM=0.2u VBRnom=180 VBRmax=189 495 | + IR=1m VCLmax=317 Ipp=12.6 Cjof=125p 496 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 497 | .ENDS 498 | 499 | 500 | .SUBCKT SMA6J154CA Anode1 Anode2 501 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 502 | + IRM=0.2u VBRnom=180 VBRmax=189 503 | + IR=1m VCLmax=317 Ipp=12.6 Cjof=64.5p 504 | + ISBF=1n NBF=.01 505 | .ENDS 506 | 507 | 508 | .SUBCKT SMA6J170A Anode Cathode 509 | X1 Anode Cathode TRANSIL PARAMS: 510 | + IRM=0.2u VBRnom=199 VBRmax=209 511 | + IR=1m VCLmax=353 Ipp=11.3 Cjof=117p 512 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 513 | .ENDS 514 | 515 | 516 | .SUBCKT SMA6J170CA Anode1 Anode2 517 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 518 | + IRM=0.2u VBRnom=199 VBRmax=209 519 | + IR=1m VCLmax=353 Ipp=11.3 Cjof=61.3p 520 | + ISBF=1n NBF=.01 521 | .ENDS 522 | 523 | 524 | .SUBCKT SMA6J188A Anode Cathode 525 | X1 Anode Cathode TRANSIL PARAMS: 526 | + IRM=0.2u VBRnom=220 VBRmax=231 527 | + IR=1m VCLmax=388 Ipp=10.3 Cjof=110p 528 | + ISF=27.04f NF=1.016 RSF=13.69m IKFF=41.7 529 | .ENDS 530 | 531 | 532 | .SUBCKT SMA6J188CA Anode1 Anode2 533 | X1 Anode1 Anode2 TRANSILBHV PARAMS: 534 | + IRM=0.2u VBRnom=220 VBRmax=231 535 | + IR=1m VCLmax=388 Ipp=10.3 Cjof=55p 536 | + ISBF=1n NBF=.01 537 | .ENDS 538 | 539 | 540 | 541 | 542 | 543 | 544 | -------------------------------------------------------------------------------- /resources/image-fsw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CapableRobot/notebooks/ec143375765e4278bde95eafc23f014957018279/resources/image-fsw.png -------------------------------------------------------------------------------- /resources/video-thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CapableRobot/notebooks/ec143375765e4278bde95eafc23f014957018279/resources/video-thumb.jpg --------------------------------------------------------------------------------