L section matching network

       Notebook for designing an L-section matching network.

       Sat Mar 21 15:50:57 CET 2020

       Francesco Urbani https://urbanij.github.io/


About

This notebooks serves as an implementation of the analytic calculation of an L-section lumped parameters matching network.

TL;DR

See calculation: https://urbanij.github.io/projects/matching_networks/calc.html
See usage demo: https://urbanij.github.io/projects/matching_networks/demo.html


This notebook is part of the syRF project.

https://urbanij.github.io/syRF/#Lumped-parameters


Resources:

Tools:

Shunt-series

shunt_series

$$ Z_2 = R_2 + jX_2 = jX_{ser} + \frac{1}{\frac{1}{jX_{shu}} + \frac{1}{R_1 + jX_1}} $$$$ \begin{cases} R_2 = \Re(Z_2)\\ X_2 = \Im(Z_2) \end{cases} $$$$ \begin{cases} X_{shu}(R_1,X_1,R_2,X_2) = \frac{R_1X_2 + R_2X_1 - R_1 \left( X_2 \mp \sqrt{\frac{R_2}{R_1} \left( R_1^2 - R_1R_2 + X_1^2\right)} \right)}{R_1 - R_2} \\ X_{ser}(R_1,X_1,R_2,X_2) = X_2 \mp \sqrt{\frac{R_2}{R_1} \left( R_1^2 - R_1R_2 + X_1^2\right)} \end{cases} $$

if $$ R_1\left(R_1-R_2\right) + X_1^2 \geq 0 $$

Series-shunt

series_shunt

$$ Z_2 = R_2 + jX_2 = \frac{1}{\frac{1}{jX_{shu}} + \frac{1}{R_1+jX_1+jX_{ser}}} $$$$ \begin{cases} R_2 = \Re(Z_2)\\ X_2 = \Im(Z_2) \end{cases} $$$$ \begin{cases} X_{shu}(R_1,X_1,R_2,X_2) = \frac{R_1X_2 \pm \sqrt{R_1R_2 \left(R_2^2-R_1R_2+X_2^2\right)} }{R_1-R_2} \\ X_{ser}(R_1,X_1,R_2,X_2) = -\frac{R_2X_1 \mp \sqrt{R_1R_2\left(R_2^2-R_1R_2+X_2^2\right)}}{R_2} \end{cases} $$

if $$ R_2\left(R_2-R_1\right) + X_2^2 \geq 0 $$

In [1]:
import sys
print("Python version")
print (sys.version)
Python version
3.8.1 (v3.8.1:1b293b6006, Dec 18 2019, 14:08:53) 
[Clang 6.0 (clang-600.0.57)]
In [2]:
# import required libraries

import quantiphy
import numpy as np
In [3]:
print(quantiphy.__version__)
print(np.__version__)
2.10.0
1.18.1
In [ ]:
 
In [4]:
PI = np.pi
In [ ]:
 
In [6]:
class ReactiveComponent:
    """
    Reactive component class
    
    =====
    Args:
        reactance
        
    
    =====
    Examples:
    
        >>> ReactiveComponent(1000, f=1e6)
        Inductor:
            X = 1 kΩ ⇔ B = -1 mS
            L = 159.15 uH (@ 1 MHz)

        >>> ReactiveComponent(0, f=12e6)
        wire:
            X = 0 Ω ⇔ B = -inf

    --------------------------------
    Z = R + jX (impedance = resistance + j*reactance) 
    Y = G + jB (admittance = conductance + j*susceptance)
    
    """
    def __init__(self, reactance, f=None):
        self._frequency = f
        self._reactance = quantiphy.Quantity(str(reactance) + 'Ω')
        self._component_type = "L" if reactance > 0 else "C" if reactance < 0 else "wire"
        
        if f != None: 
            assert f > 0

            self._frequency = quantiphy.Quantity(str(f) + 'Hz')
        
            if self._component_type == "L":
                inductor_val = (self._reactance/(2*PI*self._frequency)).real
                self._component_value = quantiphy.Quantity(str(inductor_val) + 'H')
            elif self._component_type == "C":
                capacitor_val = (-1/(2*PI*self._frequency*self._reactance)).real
                self._component_value = quantiphy.Quantity(str(capacitor_val) + 'F')
            else:
                self._component_value = 0
        else:
            self._component_value = None

    def __eq__(self, other):
        return  self._frequency == other._frequency and \
                self._reactance == other._reactance

    def get_freq(self):
        "Return frequency"
        return self._frequency
    
    def get_susceptance(self):
        "Return equivalent susceptance value"
        if self._reactance != 0:
            return quantiphy.Quantity(str(-1/self._reactance) + 'S')
        else:
            return -np.inf
    
    def __repr__(self, a=3):
        rv = "Inductor" if self._component_type == "L" else "Capacitor" if self._component_type == "C" else "wire"
        rv += ":\n\t"
        rv += f"X = {self._reactance} ⇔ B = {self.get_susceptance() }"
        rv += f"\n\t\033[1m{self._component_type}\033[0;0m = \033[1m{self._component_value}\033[0;0m  (@ {self._frequency})" if self._frequency != None and self._component_type!='wire' else ""
        return rv
In [7]:
print(ReactiveComponent(14, f=13e6))
print(ReactiveComponent(-21, f=31e8))
print(ReactiveComponent(0, f=12e6))
Inductor:
	X = 14 Ω ⇔ B = -71.429 mS
	L = 171.4 nH  (@ 13 MHz)
Capacitor:
	X = -21 Ω ⇔ B = 47.619 mS
	C = 2.4448 pF  (@ 3.1 GHz)
wire:
	X = 0 Ω ⇔ B = -inf
In [8]:
class Solution:
    def __init__(self, config_type, shunt_elem: ReactiveComponent, series_elem: ReactiveComponent):
        
        assert shunt_elem.get_freq() == series_elem.get_freq()
        
        self._config_type = config_type
        self._shunt_elem = shunt_elem
        self._series_elem = series_elem

    def __eq__(self, other):
        return  self._config_type == other._config_type and \
                self._shunt_elem  == other._shunt_elem  and \
                self._series_elem == other._series_elem
    
    def __repr__(self):
        if self._config_type == "shunt-series":
            return f"{self._config_type}\n\tShunt {self._shunt_elem}\n\tSeries {self._series_elem}\n"
        else:
            return f"{self._config_type}\n\tSeries {self._series_elem}\n\tShunt {self._shunt_elem}\n"
In [9]:
# example
Solution("shunt-series", ReactiveComponent(20, 200e5), ReactiveComponent(-24.2, 200e5))
Out[9]:
shunt-series
	Shunt Inductor:
	X = 20 Ω ⇔ B = -50 mS
	L = 159.15 nH  (@ 20 MHz)
	Series Capacitor:
	X = -24.2 Ω ⇔ B = 41.322 mS
	C = 328.83 pF  (@ 20 MHz)
In [10]:
class L_section_matching:
    """
    L section matching network
    
    ============
    args:
        input_impedance:
            the impedance you want to have.
            
        output_impedance:
            the impedance you want to transform the input impedance to.
    
    returns:
        a list of solutions (2 to 4 different results depending on 
        the point on the Smith Chart you start from)
        
    
    Examples:
            >>> mn1 = L_section_matching(input_impedance=102+8j, output_impedance=10, frequency=100e6)
            >>> mn1.match()
            >>> mn1
        
            From (102+8j) Ω to 10 Ω

            #solutions: 2

            shunt-series
                Shunt Inductor:
                X = 34.612 Ω ⇔ B = -28.891 mS
                L = 55.087 nH  (@ 100 MHz)
                Series Capacitor:
                X = -30.435 Ω ⇔ B = 32.857 mS
                C = 52.294 pF  (@ 100 MHz)
            shunt-series
                Shunt Capacitor:
                X = -32.873 Ω ⇔ B = 30.42 mS
                C = 48.415 pF  (@ 100 MHz)
                Series Inductor:
                X = 30.435 Ω ⇔ B = -32.857 mS
                L = 48.438 nH  (@ 100 MHz)
    """
    def __init__(self, input_impedance, output_impedance, frequency=None):
        
        assert input_impedance.real >= 0 and output_impedance.real >= 0
        
        self._Z1 = input_impedance
        self._Z2 = output_impedance
        self._normalized_impedance = input_impedance/output_impedance
        
        self._frequency = frequency
        self._solutions = []
        
        self._input_reactance = ReactiveComponent(input_impedance.imag, frequency)
        
    def match(self):
        R1 = self._Z1.real
        X1 = self._Z1.imag
        R2 = self._Z2.real
        X2 = self._Z2.imag

        if R1*(R1 - R2) + X1**2 >= 0:
            """
            shunt - series configuration (down coversion)
            
                                          jXser
                                       +--------+
                      +-----------+----+        +----+
                      |           |    +--------+
                      |           |
                     +++         +++                                                   1
            Z1 =     | |         | | jXshu             Z2 = R2 + jX2 = jXser + -----------------
            R1 + jX1 | |         | |                                             1        1
                     +++         +++                                           ----- + --------
                      |           |                                            jXshu   R1 + jX1
                      |           |
                      +-----------+------------------+
            
            """

            Xshu_1 = (R1*X2 + R2*X1 - R1*(X2 - ((R2*(R1**2 - R2*R1 + X1**2))/R1)**(1/2)))/(R1 - R2)
            Xser_1 = X2 - ((R2*(R1**2 - R2*R1 + X1**2))/R1)**(1/2)

            Xshu_2 = (R1*X2 + R2*X1 - R1*(X2 + ((R2*(R1**2 - R2*R1 + X1**2))/R1)**(1/2)))/(R1 - R2)
            Xser_2 = X2 + ((R2*(R1**2 - R2*R1 + X1**2))/R1)**(1/2)
            
            sol1 = Solution(
                    config_type="shunt-series", 
                    shunt_elem=ReactiveComponent(Xshu_1, f=self._frequency),
                    series_elem=ReactiveComponent(Xser_1, f=self._frequency)
                )
            
            sol2 = Solution(
                    config_type="shunt-series", 
                    shunt_elem=ReactiveComponent(Xshu_2, f=self._frequency),
                    series_elem=ReactiveComponent(Xser_2, f=self._frequency)
                )

            self._solutions.append(sol1)
            if sol2 != sol1: # do not duplicate solutions
                self._solutions.append(sol2)
     

        if R2*(R2 - R1) + X2**2 >= 0:
            """ series - shunt configuration (up conversion)
            
                                jXser
                              +--------+
                      +-------+        +-----+--------------+
                      |       +--------+     |
                      |                      |
                     +++                    +++                                          1
            Z1 =     | |                    | | jXshu       Z2 = R2 + jX2 = -------------------------
            R1 + jX1 | |                    | |                                1            1
                     +++                    +++                              ----  + ----------------
                      |                      |                               jXshu   R1 + jX1 + jXser
                      |                      |
                      +----------------------+---------------+


            """

            Xshu_1 = (R1*X2 + (R1*R2*(R2**2 - R1*R2 + X2**2))**(1/2))/(R1 - R2)
            Xser_1 = -(R2*X1 - (R1*R2*(R2**2 - R1*R2 + X2**2))**(1/2))/R2

            Xshu_2 = (R1*X2 - (R1*R2*(R2**2 - R1*R2 + X2**2))**(1/2))/(R1 - R2)
            Xser_2 = -(R2*X1 + (R1*R2*(R2**2 - R1*R2 + X2**2))**(1/2))/R2
            
            sol1 = Solution(
                    config_type="series-shunt", 
                    shunt_elem=ReactiveComponent(Xshu_1, f=self._frequency),
                    series_elem=ReactiveComponent(Xser_1, f=self._frequency)
                )
            
            sol2 = Solution(
                    config_type="series-shunt",
                    shunt_elem=ReactiveComponent(Xshu_2, f=self._frequency),
                    series_elem=ReactiveComponent(Xser_2, f=self._frequency)
                )
            
            self._solutions.append(sol1)
            if sol2 != sol1: # do not duplicate solutions
                self._solutions.append(sol2)

    def get_solutions(self):
        rv = ""
        for sol in self._solutions:
            rv += f"{sol._shunt_elem._component_type}={sol._shunt_elem._component_value}, "
            rv += f"{sol._series_elem._component_type}={sol._series_elem._component_value}, "
        return rv
        
        
    def get_input_reactance(self):
        return self._input_reactance
    
    def plot(self):
        pass
        delta_f = 2000
        freq = np.linspace(self._frequency-delta_f/2, self._frequency+delta_f/2, 2000)
        for solution in self._solutions:
            print(solution)
            if solution._config_type=="shunt-series":
                if solution._shunt_elem._component_type == "L":
                    if solution._series_elem._component_type == "C":
                        Z2 = 1/(2*PI*freq*solution._series_elem._component_value.real) 
                        
        plt.plot(freq, Z2)
        
    def __repr__(self):
        rv  = f"From {self._Z1} Ω to {self._Z2} Ω\n\n"
        #rv += f"normalized output = {self._Z1}Ω/{self._Z2}Ω = {self._normalized_impedance}\n\n"
        rv += f"#solutions: {len(self._solutions)}\n\n"
        for solution in self._solutions:
            rv += f"{solution}"
        return rv
In [ ]:
 
In [11]:
mn1 = L_section_matching(input_impedance=102+8j, output_impedance=10, frequency=100e6)
mn1.match()
mn1
Out[11]:
From (102+8j) Ω to 10 Ω

#solutions: 2

shunt-series
	Shunt Inductor:
	X = 34.612 Ω ⇔ B = -28.891 mS
	L = 55.087 nH  (@ 100 MHz)
	Series Capacitor:
	X = -30.435 Ω ⇔ B = 32.857 mS
	C = 52.294 pF  (@ 100 MHz)
shunt-series
	Shunt Capacitor:
	X = -32.873 Ω ⇔ B = 30.42 mS
	C = 48.415 pF  (@ 100 MHz)
	Series Inductor:
	X = 30.435 Ω ⇔ B = -32.857 mS
	L = 48.438 nH  (@ 100 MHz)
In [12]:
mn2 = L_section_matching(input_impedance=90+32j, output_impedance=100, frequency=100e6)
mn2.match()
mn2
Out[12]:
From (90+32j) Ω to 100 Ω

#solutions: 4

shunt-series
	Shunt Capacitor:
	X = -425.64 Ω ⇔ B = 2.3494 mS
	C = 3.7392 pF  (@ 100 MHz)
	Series Capacitor:
	X = -11.738 Ω ⇔ B = 85.194 mS
	C = 135.59 pF  (@ 100 MHz)
shunt-series
	Shunt Capacitor:
	X = -214.36 Ω ⇔ B = 4.6651 mS
	C = 7.4247 pF  (@ 100 MHz)
	Series Inductor:
	X = 11.738 Ω ⇔ B = -85.194 mS
	L = 18.681 nH  (@ 100 MHz)
series-shunt
	Series Capacitor:
	X = -2 Ω ⇔ B = 500 mS
	C = 795.77 pF  (@ 100 MHz)
	Shunt Capacitor:
	X = -300 Ω ⇔ B = 3.3333 mS
	C = 5.3052 pF  (@ 100 MHz)
series-shunt
	Series Capacitor:
	X = -62 Ω ⇔ B = 16.129 mS
	C = 25.67 pF  (@ 100 MHz)
	Shunt Inductor:
	X = 300 Ω ⇔ B = -3.3333 mS
	L = 477.46 nH  (@ 100 MHz)
In [ ]:

In [ ]:
 
In [13]:
mn = L_section_matching(input_impedance=150, output_impedance=100, frequency=100e6)
mn.match()

assert mn.get_solutions() == 'L=337.62 nH, C=22.508 pF, C=7.5026 pF, L=112.54 nH, '

mn
# 150 Ω to 100 Ω ok
Out[13]:
From 150 Ω to 100 Ω

#solutions: 2

shunt-series
	Shunt Inductor:
	X = 212.13 Ω ⇔ B = -4.714 mS
	L = 337.62 nH  (@ 100 MHz)
	Series Capacitor:
	X = -70.711 Ω ⇔ B = 14.142 mS
	C = 22.508 pF  (@ 100 MHz)
shunt-series
	Shunt Capacitor:
	X = -212.13 Ω ⇔ B = 4.714 mS
	C = 7.5026 pF  (@ 100 MHz)
	Series Inductor:
	X = 70.711 Ω ⇔ B = -14.142 mS
	L = 112.54 nH  (@ 100 MHz)
In [14]:
mn = L_section_matching(input_impedance=12, output_impedance=430, frequency=1220e6)
mn.match()

assert mn.get_solutions() == 'C=1.7906 pF, L=9.2393 nH, L=9.5045 nH, C=1.842 pF, '

mn
# 12 to 430 ok
Out[14]:
From 12 Ω to 430 Ω

#solutions: 2

series-shunt
	Series Inductor:
	X = 70.824 Ω ⇔ B = -14.12 mS
	L = 9.2393 nH  (@ 1.22 GHz)
	Shunt Capacitor:
	X = -72.857 Ω ⇔ B = 13.726 mS
	C = 1.7906 pF  (@ 1.22 GHz)
series-shunt
	Series Capacitor:
	X = -70.824 Ω ⇔ B = 14.12 mS
	C = 1.842 pF  (@ 1.22 GHz)
	Shunt Inductor:
	X = 72.857 Ω ⇔ B = -13.726 mS
	L = 9.5045 nH  (@ 1.22 GHz)
In [15]:
mn = L_section_matching(input_impedance=322+39j, output_impedance=10, frequency=100e6)
mn.match()

assert mn.get_solutions() == 'L=94.43 nH, C=28.28 pF, C=28.004 pF, L=89.57 nH, '

mn
# ok   322+39j => 10 
Out[15]:
From (322+39j) Ω to 10 Ω

#solutions: 2

shunt-series
	Shunt Inductor:
	X = 59.332 Ω ⇔ B = -16.854 mS
	L = 94.43 nH  (@ 100 MHz)
	Series Capacitor:
	X = -56.278 Ω ⇔ B = 17.769 mS
	C = 28.28 pF  (@ 100 MHz)
shunt-series
	Shunt Capacitor:
	X = -56.832 Ω ⇔ B = 17.596 mS
	C = 28.004 pF  (@ 100 MHz)
	Series Inductor:
	X = 56.278 Ω ⇔ B = -17.769 mS
	L = 89.57 nH  (@ 100 MHz)
In [16]:
mn = L_section_matching(input_impedance=32+39j, output_impedance=10-123j, frequency=300e6)
mn.match()
mn
# nope ? http://leleivre.com/rf_lcmatch.html
Out[16]:
From (32+39j) Ω to (10-123j) Ω

#solutions: 4

shunt-series
	Shunt Inductor:
	X = 56.082 Ω ⇔ B = -17.831 mS
	L = 29.752 nH  (@ 300 MHz)
	Series Capacitor:
	X = -149.37 Ω ⇔ B = 6.6948 mS
	C = 3.5517 pF  (@ 300 MHz)
shunt-series
	Shunt Capacitor:
	X = -20.627 Ω ⇔ B = 48.479 mS
	C = 25.719 pF  (@ 300 MHz)
	Series Capacitor:
	X = -96.631 Ω ⇔ B = 10.349 mS
	C = 5.4901 pF  (@ 300 MHz)
series-shunt
	Series Inductor:
	X = 179.42 Ω ⇔ B = -5.5734 mS
	L = 95.187 nH  (@ 300 MHz)
	Shunt Capacitor:
	X = -79.626 Ω ⇔ B = 12.559 mS
	C = 6.6626 pF  (@ 300 MHz)
series-shunt
	Series Capacitor:
	X = -257.42 Ω ⇔ B = 3.8847 mS
	C = 2.0609 pF  (@ 300 MHz)
	Shunt Capacitor:
	X = -278.19 Ω ⇔ B = 3.5946 mS
	C = 1.907 pF  (@ 300 MHz)
In [17]:
mn = L_section_matching(input_impedance=90+30j, output_impedance=100, frequency=100e6)
mn.match()
assert mn.get_solutions() == 'C=5.3052 pF, wire=0, C=5.3052 pF, wire=0, L=477.46 nH, C=26.526 pF, '
mn
Out[17]:
From (90+30j) Ω to 100 Ω

#solutions: 3

shunt-series
	Shunt Capacitor:
	X = -300 Ω ⇔ B = 3.3333 mS
	C = 5.3052 pF  (@ 100 MHz)
	Series wire:
	X = 0 Ω ⇔ B = -inf
series-shunt
	Series wire:
	X = -0 Ω ⇔ B = -inf
	Shunt Capacitor:
	X = -300 Ω ⇔ B = 3.3333 mS
	C = 5.3052 pF  (@ 100 MHz)
series-shunt
	Series Capacitor:
	X = -60 Ω ⇔ B = 16.667 mS
	C = 26.526 pF  (@ 100 MHz)
	Shunt Inductor:
	X = 300 Ω ⇔ B = -3.3333 mS
	L = 477.46 nH  (@ 100 MHz)
In [18]:
mn = L_section_matching(input_impedance=90+312j, output_impedance=100, frequency=100e6)
mn.match()
mn
Out[18]:
From (90+312j) Ω to 100 Ω

#solutions: 4

shunt-series
	Shunt Capacitor:
	X = -6.0662 kΩ ⇔ B = 164.85 uS
	C = 262.36 fF  (@ 100 MHz)
	Series Capacitor:
	X = -327.35 Ω ⇔ B = 3.0548 mS
	C = 4.8619 pF  (@ 100 MHz)
shunt-series
	Shunt Capacitor:
	X = -173.82 Ω ⇔ B = 5.753 mS
	C = 9.1562 pF  (@ 100 MHz)
	Series Inductor:
	X = 327.35 Ω ⇔ B = -3.0548 mS
	L = 521 nH  (@ 100 MHz)
series-shunt
	Series Capacitor:
	X = -282 Ω ⇔ B = 3.5461 mS
	C = 5.6438 pF  (@ 100 MHz)
	Shunt Capacitor:
	X = -300 Ω ⇔ B = 3.3333 mS
	C = 5.3052 pF  (@ 100 MHz)
series-shunt
	Series Capacitor:
	X = -342 Ω ⇔ B = 2.924 mS
	C = 4.6537 pF  (@ 100 MHz)
	Shunt Inductor:
	X = 300 Ω ⇔ B = -3.3333 mS
	L = 477.46 nH  (@ 100 MHz)
In [19]:
input_imp = 200             # Ω

output_imp = (0.15-1.5j)    # mS
output_imp *= 1e-3          # S
output_imp = 1/output_imp   # Ω

f = 200e6                   # Hz

mn = L_section_matching(input_impedance=input_imp, output_impedance=output_imp, frequency=f)
mn.match()
mn
Out[19]:
From 200 Ω to (66.006600660066+660.06600660066j) Ω

#solutions: 4

shunt-series
	Shunt Inductor:
	X = 140.37 Ω ⇔ B = -7.1239 mS
	L = 111.7 nH  (@ 200 MHz)
	Series Inductor:
	X = 566.02 Ω ⇔ B = -1.7667 mS
	L = 450.43 nH  (@ 200 MHz)
shunt-series
	Shunt Capacitor:
	X = -140.37 Ω ⇔ B = 7.1239 mS
	C = 5.669 pF  (@ 200 MHz)
	Series Inductor:
	X = 754.11 Ω ⇔ B = -1.3261 mS
	L = 600.1 nH  (@ 200 MHz)
series-shunt
	Series Inductor:
	X = 1.1372 kΩ ⇔ B = -879.32 uS
	L = 904.99 nH  (@ 200 MHz)
	Shunt Inductor:
	X = 1.5454 kΩ ⇔ B = -647.06 uS
	L = 1.2298 uH  (@ 200 MHz)
series-shunt
	Series Capacitor:
	X = -1.1372 kΩ ⇔ B = 879.32 uS
	C = 699.74 fF  (@ 200 MHz)
	Shunt Inductor:
	X = 425 Ω ⇔ B = -2.3529 mS
	L = 338.2 nH  (@ 200 MHz)
In [ ]:
 
In [ ]:
 
In [ ]:
 

The following has nothing to do with the calculation, I just needed to turn back the output into plain text by removing the bold part.

In [21]:
import re
def plain_text(text):
    # 7-bit C1 ANSI sequences
    ansi_escape = re.compile(r'''
        \x1B  # ESC
        (?:   # 7-bit C1 Fe (except CSI)
            [@-Z\\-_]
        |     # or [ for CSI, followed by a control sequence
            \[
            [0-?]*  # Parameter bytes
            [ -/]*  # Intermediate bytes
            [@-~]   # Final byte
        )
        ''', re.VERBOSE)
    result = ansi_escape.sub('', text)
    return result


# testing how to remove the bold ascii styling from
string_with_nonASCII = 'Capacitor:\n\tX = -21 Ω ⇔ B = 47.619 mS\n\t\x1b[1mC\x1b[0;0m = \x1b[1m2.4448 pF\x1b[0;0m  (@ 3.1 GHz)'

print(string_with_nonASCII)
print(plain_text(string_with_nonASCII))
Capacitor:
	X = -21 Ω ⇔ B = 47.619 mS
	C = 2.4448 pF  (@ 3.1 GHz)
Capacitor:
	X = -21 Ω ⇔ B = 47.619 mS
	C = 2.4448 pF  (@ 3.1 GHz)
In [ ]:
 
In [ ]:
 
In [ ]: