ihsm-self-contained-hw/Data_Link_Calculations.ipynb
2024-07-04 19:51:12 +02:00

351 lines
36 KiB
Text

{
"cells": [
{
"cell_type": "code",
"execution_count": 37,
"id": "d7de813d-2e9e-4a41-9ef3-d76f6179953f",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import math\n",
"import colour\n",
"import scipy.constants as const\n",
"import scipy\n",
"from matplotlib import pyplot as plt\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"id": "15d9a3a8-5ef6-4940-a775-0d3312f57620",
"metadata": {},
"source": [
"# Optical data link transimpedance amplifier calculations\n",
"\n",
"This notebook calculates the parameters of the TIA we use in the optical data link receivers. Note that we use two sets of parameters because the uplink and downlink parts of the link are asymmetrical. The uplink (stator to rotor) uses a yellow LED and a phototransistor intended for use as an ambient light sensor. The downlink (rotor to stator) uses a standard IR LED and IR photodiode.\n",
"\n",
"The optical calculations here are worst-case calculations, and the real values are likely to be much better. Here, we use a simple model where LED and photodiode are in an infinite vacuum. In the real thing, the two are going to be inside of a small chamber that has high-albedo walls, so a lot of the light that would miss the photodiode in our model here is going to hit it in practice.\n",
"\n",
"## Common parameters\n",
"\n",
"## Uplink (stator to rotor) parameter set\n",
"\n",
"* LED: Osram LY Q396 0603 yellow LED [Datasheet](https://look.ams-osram.com/m/7f3b49fc98442cfa/original/LY-Q396.pdf)\n",
"* Receiver: Everlight ALS-PT19-315C/L177 Ambient Light Sensor (phototransistor output) [Datasheet](https://en.everlight.com/wp-content/plugins/ItemRelationship/product_files/pdf/ALS-PT19-315C-L177-TR8_V8.pdf)\n",
"\n",
"## Downlink (rotor to stator) parameter set\n",
"\n",
"* LED: ~~Everlight IR26-21C/L110 1206 package 20° IR LED\n",
"[Datasheet](https://www.tme.eu/Document/b8c892bb4ce9fb47542a9a75d00e22cf/IR26-21C-L110-TR8.PDF)~~\n",
" Vishay VSMY2940GX01 2.3x2.3mm lensed IR LED [Datasheet](https://www.vishay.com/docs/84583/vsmy2940rgx01.pdf)\n",
"* Receiver: ~~Everlight PD15-21B 1206 package IR **Photodiode**\n",
"[Datasheet](https://datasheet.octopart.com/PD15-21B-TR8-Everlight-datasheet-157602352.pdf)~~\n",
" Vishay VBP104FAS 6.4x3.9mm IR photodiode with bandpass, [Datasheet](https://www.vishay.com/docs/81169/vbp104fa.pdf)\n",
"* This datasheet is rather poor, so here's a better one for a comparable part: [Vishay VEMD6110X01 Datasheet](https://www.vishay.com/docs/84179/vemd6110x01.pdf)\n"
]
},
{
"cell_type": "code",
"execution_count": 118,
"id": "9894dd0d-c0ad-4574-b15f-264a06f5df89",
"metadata": {},
"outputs": [],
"source": [
"par = {\n",
" 'common': {\n",
" 'distance': 10e-3, # Distance from LED to PD/PT in mm\n",
" },\n",
" 'uplink': {\n",
" 'led_Ie': 145.0e-3/100*20, # Radiant intensity in mW / sr at I_F = 20 mA\n",
" 'led_theta': 20, # View angle in degrees\n",
" 'led_current': 20e-3, # LED current in mA\n",
" 'pd_eff': 32e-6, # Photodiode efficiency ^= short-circuit current at some low reverse voltage at 1 mW/cm^2\n",
" 'pd_Ir0': 30e-9, # Photodiode worst-case reverse dark current in A\n",
" },\n",
" 'downlink': {\n",
" 'als_IPH3': 520e-6, # ALS Photocurrent at 1000 lux from CIE standard illuminant-A\n",
" 'led_IV_typ': 60e-3, # typical luminous intensity in Cd\n",
" 'als_spectral_response':\n",
" {\"x\":[299.372,340.167,377.824,426.778,470.711,528.452,569.874,607.531,618.828,627.615,635.146,638.912,652.72,664.017,667.782,685.356,697.908,726.778,749.372,843.515,894.351],\"y\":[3.659,5.488,9.451,22.866,40.244,63.11,81.402,94.512,96.646,99.695,96.341,79.878,60.366,40.244,32.317,19.512,12.805,9.756,7.927,8.232,7.317]},\n",
" 'led_spectral_response':\n",
" {\"x\":[373.584,439.648,489.746,537.5,554.199,563.281,569.434,574.414,579.688,588.184,590.82,592.578,595.215,597.559,598.145,601.953,606.934,610.742,618.652,630.078,793.555,796.631],\"y\":[0.005,0.005,0.004,0.002,0.008,0.031,0.067,0.125,0.274,0.806,0.993,0.994,0.776,0.475,0.318,0.185,0.077,0.034,0.01,0.004,0.001,0.004]},\n",
" },\n",
"}\n",
"\n",
"for sk in par:\n",
" if sk != 'common':\n",
" for k in par['common']:\n",
" if k not in par[sk]:\n",
" par[sk][k] = par['common'][k]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "f85bd870-4a6e-4bfd-842a-3ad02261d583",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Photodiode irradiance: 0.023 mW/cm^2\n",
"Photodiode current: 0.747 µA\n",
"Photodiode SNR: 27.92910861784319 dB\n"
]
}
],
"source": [
"def calculate_pd_current():\n",
" p = par['uplink'] # Downlink has a phototransistor, not a photodiode\n",
" # cf. https://en.wikipedia.org/wiki/Solid_angle#Pyramid for solid angle conversion\n",
" a = b = 1e-2 # 1 cm square side lengths in m\n",
" d = p['distance']\n",
" # [sr/cm^2]\n",
" angle_norm = 4*math.atan(a*b / (2*d*math.sqrt(4*(d**2) + a**2 + b**2))) # Solid angle of a 1cm^2 square at the target distance\n",
" # irradiance in mW / cm^2 units\n",
" # [mw/sr] * [mA/mA = 1] * [sr / cm^2] = [mw/cm^2]\n",
" irradiance_pd = p['led_Ie'] * p['led_current']/20e-3 * angle_norm\n",
" # [A/(mW/cm^2)] * [mw/cm^2] = [A]\n",
" current_pd = p['pd_eff'] * irradiance_pd # current in A\n",
" print(f'Photodiode irradiance: {irradiance_pd:.3f} mW/cm^2')\n",
" print(f'Photodiode current: {current_pd*1e6:.3f} µA')\n",
" print(f'Photodiode SNR: {20*math.log10(current_pd/p['pd_Ir0'])} dB')\n",
"calculate_pd_current()"
]
},
{
"cell_type": "code",
"execution_count": 125,
"id": "9046032e-30d6-42c7-a8ee-f6f5497e2c39",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Phototransistor current I = 0.231 mA\n"
]
}
],
"source": [
"def calculate_pt_current():\n",
" obs = colour.colorimetry.SDS_LEFS_PHOTOPIC['CIE 1924 Photopic Standard Observer']\n",
" spec = par['downlink']['als_spectral_response']\n",
" dis_pt = colour.SpectralDistribution(spec['y'], spec['x']).normalise().interpolate(obs.shape)\n",
" spec = par['downlink']['led_spectral_response']\n",
" dis_led = colour.SpectralDistribution(spec['y'], spec['x']).normalise().interpolate(obs.shape)\n",
" eff = colour.luminous_efficiency(dis_led, dis_pt)\n",
" \n",
" a = b = 1e-2 # [m]\n",
" d = par['downlink']['distance'] # target distance [m]\n",
" # [sr/cm^2]\n",
" angle_norm = 4*math.atan(a*b / (2*d*math.sqrt(4*(d**2) + a**2 + b**2))) # Solid angle of a 1cm^2 square at the target distance\n",
" \n",
" # [lm/m^2] = [Cd = lm/sr] * [sr/cm^2] * 100 * 100\n",
" irr_act = par['downlink']['led_IV_typ'] * angle_norm * 100 * 100\n",
" \n",
" # Reference irradiance = 1000 [lx = lm/m^2]\n",
" irr_ref = 1000\n",
" \n",
" I = par['downlink']['als_IPH3'] * eff * irr_act/irr_ref\n",
" print(f'Phototransistor current I = {I*1e3:.3f} mA')\n",
"calculate_pt_current()"
]
},
{
"cell_type": "code",
"execution_count": 105,
"id": "38563b8c-5660-4c9f-a795-2effaf277253",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.44303728982398322"
]
},
"execution_count": 105,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spec = par['downlink']['als_spectral_response']\n",
"x = np.linspace(350, 850, 1000)\n",
"y = scipy.interpolate.interp1d(spec['x'], spec['y'])(x) / 100\n",
"#plt.plot(x, y)\n",
"\n",
"#area_under_curve = scipy.integrate.cumulative_trapezoid(y, x)[-1]\n",
"#normalized_density_per_nm = y / area_under_curve\n",
"#plt.twinx().plot(x, normalized_density_per_nm)\n",
"#dx = (850 - 350) / 1000\n",
"#sum(normalized_density_per_nm * normalized_density_per_nm / dx)\n",
"# lx = lm/m^2\n",
"# 1000 lm / m^2\n"
]
},
{
"cell_type": "code",
"execution_count": 85,
"id": "e5f00dba-3a1f-4acd-8da2-9ee47740c799",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.0016979522350344949"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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ihtuuAEHDhxodowQAs8//zwiIyPh4+ODyy+/HPv27Wt2TH19PR555BGEhITAz88P1113HY4fP+7I34pLSUtLg0KhwMyZM63P8TzbT35+Pu6880507doVvr6+GDRoEDIyMqxf57nuOJPJhGeffRbx8fHw8fFBjx49MG/ePFgsFusxPM/ts379ekycOBGRkZFQKBRYsWJFs6/b67yWl5fjrrvugk6ng06nw1133YWKioqOhRce6osvvhBeXl7igw8+EJmZmWLGjBnCz89P5OTkyI7mEq699lrx8ccfi71794qdO3eK8ePHi5iYGFFVVWU95pVXXhEBAQHi66+/Fnv27BGTJ08WERERwmAwWI+ZNm2aiIqKEunp6WL79u3iiiuuEAMHDhQmk0nGb8upbd26VcTFxYkBAwaIGTNmWJ/nebaPsrIyERsbK+655x6xZcsWcfToUfHzzz+LQ4cOWY/hue64l156SXTt2lWsWrVKHD16VHz55ZfC399fLFiwwHoMz3P7rF69WsyZM0d8/fXXAoD45ptvmn3dXud1zJgxIikpSWzatEls2rRJJCUliQkTJnQou8eWkaFDh4pp06Y1ey4hIUE8/fTTkhK5tuLiYgFArFu3TgghhMViEeHh4eKVV16xHlNXVyd0Op149913hRBCVFRUCC8vL/HFF19Yj8nPzxdKpVKsWbPGsb8BJ1dZWSl69+4t0tPTxWWXXWYtIzzP9vPUU0+JSy655Jxf57m2j/Hjx4v77ruv2XOTJk0Sd955pxCC59lezi4j9jqvmZmZAoD4448/rMds3rxZABBZWVntzuuRl2mMRiMyMjKQmpra7PnU1FRs2rRJUirXptfrAQDBwcEAgKNHj6KwsLDZOdZqtbjsssus5zgjIwMNDQ3NjomMjERSUhL/O5zlb3/7G8aPH4+rr7662fM8z/azcuVKDBkyBDfffDNCQ0MxePBgfPDBB9av81zbxyWXXIJffvkF2dnZAIBdu3Zh48aNGDduHACe585ir/O6efNm6HQ6DBs2zHrM8OHDodPpOnTuXeJGefZWUlICs9mMsLCwZs+HhYWhsLBQUirXJYTArFmzcMkllyApKQkArOextXOck5NjPUaj0aBLly4tjuF/h9O++OILbN++HX/++WeLr/E828+RI0ewaNEizJo1C8888wy2bt2K6dOnQ6vVYsqUKTzXdvLUU09Br9cjISEBKpUKZrMZL7/8Mm677TYA/DPdWex1XgsLCxEaGtri+4eGhnbo3HtkGWmiUCia/bsQosVzdGEPP/wwdu/ejY0bN7b4WnvOMf87nJaXl4cZM2bgp59+gre39zmP43nuOIvFgiFDhmD+/PkAgMGDB2Pfvn1YtGgRpkyZYj2O57pjli1bhs8++wyff/45+vfvj507d2LmzJmIjIzE3XffbT2O57lz2OO8tnZ8R8+9R16mCQkJgUqlatHiiouLW7RGOr9HHnkEK1euxNq1a9G9e3fr8+Hh4QBw3nMcHh4Oo9GI8vLycx7j6TIyMlBcXIyUlBSo1Wqo1WqsW7cOb7/9NtRqtfU88Tx3XEREBPr169fsucTEROTm5gLgn2l7eeKJJ/D000/j1ltvRXJyMu666y48+uijSEtLA8Dz3FnsdV7Dw8NRVFTU4vufPHmyQ+feI8uIRqNBSkoK0tPTmz2fnp6OkSNHSkrlWoQQePjhh7F8+XL8+uuviI+Pb/b1+Ph4hIeHNzvHRqMR69ats57jlJQUeHl5NTumoKAAe/fu5X+HU6666irs2bMHO3futD6GDBmCO+64Azt37kSPHj14nu1k1KhRLZanZ2dnIzY2FgD/TNtLTU0NlMrmHz0qlcq6tJfnuXPY67yOGDECer0eW7dutR6zZcsW6PX6jp37dk99dXFNS3s/+ugjkZmZKWbOnCn8/PzEsWPHZEdzCQ8++KDQ6XTit99+EwUFBdZHTU2N9ZhXXnlF6HQ6sXz5crFnzx5x2223tbqMrHv37uLnn38W27dvF1deeaXHL8+7kDNX0wjB82wvW7duFWq1Wrz88svi4MGDYsmSJcLX11d89tln1mN4rjvu7rvvFlFRUdalvcuXLxchISHiySeftB7D89w+lZWVYseOHWLHjh0CgHjzzTfFjh07rFtW2Ou8jhkzRgwYMEBs3rxZbN68WSQnJ3Npb0f8+9//FrGxsUKj0YiLLrrIuiyVLgxAq4+PP/7YeozFYhHPPfecCA8PF1qtVlx66aViz549zb5PbW2tePjhh0VwcLDw8fEREyZMELm5uQ7+3biWs8sIz7P9fPfddyIpKUlotVqRkJAg3n///WZf57nuOIPBIGbMmCFiYmKEt7e36NGjh5gzZ46or6+3HsPz3D5r165t9efy3XffLYSw33ktLS0Vd9xxhwgICBABAQHijjvuEOXl5R3KrhBCiPaPqxARERF1jEfOGSEiIiLnwTJCREREUrGMEBERkVQsI0RERCQVywgRERFJxTJCREREUrGMEBERkVQsI0RERCQVywgRERFJxTJCREREUrGMEBERkVQsI0RERCTV/wPrDh1gxWqgxwAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ill = colour.sd_CIE_standard_illuminant_A()\n",
"y_ill = scipy.interpolate.interp1d(ill.wavelengths, ill.values, bounds_error=False, fill_value=0.0)(x)\n",
"\n",
"plt.plot(y)\n",
"\n",
"sum(y * y) / sum(y) / sum(y)"
]
},
{
"cell_type": "code",
"execution_count": 51,
"id": "5f2f8eb4-40db-41cd-bf33-38e9968f3783",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.6451612903225806"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1000 / 155 / 100 / 100 * 1e3"
]
},
{
"cell_type": "code",
"execution_count": 59,
"id": "f3ae1150-8040-462a-bae2-9e82313a2800",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.8"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"8 / 100 / 100 * 1e3"
]
},
{
"cell_type": "code",
"execution_count": 123,
"id": "5f75eb80-fcc0-4106-8987-6b41d70470d2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Irradiance of CIE standard illuminant at 1000 lx is 0.642 mW/cm^2\n",
"Normalized phototransistor response is 1.049 mA @ 1mW/cm^2\n"
]
}
],
"source": [
"def calculate_pt_current():\n",
" p = par['downlink'] # Downlink has a phototransistor, not a photodiode\n",
" # cf. https://en.wikipedia.org/wiki/Solid_angle#Pyramid for solid angle conversion\n",
" a = b = 1e-2 # 1 cm square side lengths in m\n",
" d = p['distance']\n",
" # [sr/cm^2]\n",
" angle_norm = 4*math.atan(a*b / (2*d*math.sqrt(4*(d**2) + a**2 + b**2))) # Solid angle of a 1cm^2 square at the target distance\n",
"\n",
" # Black body power per area (Stefan-Boltzmann Law)\n",
" # ================================================\n",
" \n",
" # Black body temperature of CIE standard illuminant A\n",
" T = 2856 # K\n",
" \n",
" # Note: The emissivity of a black body is 1.0\n",
" # [W/m^2] = [1] * [W m^-2 K^-4] * [K^4]\n",
" power_per_area = 1.0 * const.sigma * T**4\n",
"\n",
" # [lm/w]\n",
" eff_lm_per_watt = colour.luminous_efficacy(colour.sd_CIE_standard_illuminant_A())\n",
" # [w/m^2] = [lx = lm/m^2] / [lm/w]\n",
" # intensity at test point = 1000 lx\n",
" irr_watt_per_m2 = 1000 / eff_lm_per_watt\n",
" irr_mw_per_cm2 = irr_watt_per_m2 * 1e3 / 100 / 100\n",
" print(f'Irradiance of CIE standard illuminant at 1000 lx is {irr_mw_per_cm2:.3f} mW/cm^2')\n",
" \n",
" obs = colour.colorimetry.SDS_LEFS_PHOTOPIC['CIE 1924 Photopic Standard Observer']\n",
" dis = colour.SpectralDistribution(spec['y'], spec['x']).normalise().interpolate(obs.shape)\n",
" eff_pt = colour.luminous_efficiency(dis) # phototransistor efficiency w.r.t. standard observer\n",
" \n",
" # response in [A / [mw/cm^2]]\n",
" normalized_response = par['downlink']['als_IPH3'] / (irr_mw_per_cm2 * eff_pt)\n",
" print(f'Normalized phototransistor response is {normalized_response*1e3:.3f} mA @ 1mW/cm^2')\n",
"\n",
"calculate_pt_current()"
]
},
{
"cell_type": "markdown",
"id": "4268d9e8-ed49-4ab2-98b6-e6d54ba70215",
"metadata": {},
"source": [
"\n",
"https://en.wikipedia.org/wiki/Transimpedance_amplifier"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "userpkgs",
"language": "python",
"name": "userpkgs"
},
"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.12.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}