Please also recommend the brand / type resistor for the attenuator. Is SMD type resistor good?

- Home
- Design & Build
- Parts
- Series Type Stepped Attenuators

You are using an out of date browser. It may not display this or other websites correctly.

You should upgrade or use an alternative browser.

You should upgrade or use an alternative browser.

- Thread starter bigpandahk
- Start date

Please also recommend the brand / type resistor for the attenuator. Is SMD type resistor good?

Code:

```
1: 10500.00 ohms -2.05 dB
2: 8200.00 ohms -4.07 dB
3: 6490.00 ohms -6.09 dB
4: 5100.00 ohms -8.09 dB
5: 4020.00 ohms -10.07 dB
6: 3160.00 ohms -12.02 dB
7: 2610.00 ohms -14.05 dB
8: 2050.00 ohms -16.06 dB
9: 1620.00 ohms -18.06 dB
10: 1300.00 ohms -20.09 dB
11: 1000.00 ohms -22.05 dB
12: 820.00 ohms -24.07 dB
13: 649.00 ohms -26.09 dB
14: 510.00 ohms -28.09 dB
15: 402.00 ohms -30.07 dB
16: 316.00 ohms -32.02 dB
17: 261.00 ohms -34.05 dB
18: 205.00 ohms -36.06 dB
19: 162.00 ohms -38.06 dB
20: 130.00 ohms -40.09 dB
21: 100.00 ohms -42.05 dB
22: 82.00 ohms -44.07 dB
23: 64.90 ohms -46.09 dB
24: 51.00 ohms -48.09 dB
25: 40.20 ohms -50.07 dB
26: 31.60 ohms -52.02 dB
27: 26.10 ohms -54.05 dB
28: 20.50 ohms -56.06 dB
29: 16.20 ohms -58.06 dB
30: 13.00 ohms -60.09 dB
31: 10.00 ohms -62.05 dB
32: 39.00 ohms to ground
total 49960.5 ohms
```

Code:

```
from math import log10
E48 = [
1.00, 1.05, 1.10, 1.15, 1.21, 1.27, 1.33, 1.40,
1.47, 1.54, 1.62, 1.69, 1.78, 1.87, 1.96, 2.05,
2.15, 2.26, 2.37, 2.49, 2.61, 2.74, 2.87, 3.01,
3.16, 3.32, 3.48, 3.65, 3.83, 4.02, 4.22, 4.42,
4.64, 4.87, 5.11, 5.36, 5.62, 5.90, 6.19, 6.49,
6.81, 7.15, 7.50, 7.87, 8.25, 8.66, 9.09, 9.53
]
E24 = [
1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0,
2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.3,
4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1
]
E12 = E24 [0:24:2]
def choose_best (value):
best = None
for p in range (6):
for ent in E48:
resistor = ent * pow(10, p)
if best is None or abs(value-best) > abs(value-resistor):
best = resistor
for ent in E24:
resistor = ent * pow(10, p)
if best is None or abs(value-best) > abs(value-resistor):
best = resistor
return best
TOTAL_RESISTANCE = 50000
STEP = 2.0
STEP_COUNT = 32
def dB_2_ratio(dB):
return pow(10.0, dB/20.0)
def calculate_steps(count, step, resistance):
total = 0.0
remaining_resistance = resistance
target_resistance = resistance
for i in range(1, count):
target_resistance = remaining_resistance / dB_2_ratio (step)
ideal_resistor = remaining_resistance - target_resistance
actual_resistor = choose_best (ideal_resistor)
total += actual_resistor
remaining_resistance -= actual_resistor
atten = 20.0 * log10 (remaining_resistance / resistance)
print ("%s: %6.2f ohms %5.2f dB" % (i, actual_resistor, atten))
print ("%s: %6.2f ohms to ground" % (count, choose_best (remaining_resistance)))
print ("total %6.1f ohms" % total)
calculate_steps (STEP_COUNT, STEP, TOTAL_RESISTANCE)
```

A 100k pot is likely to be "loaded" in most systems unless a high-Z buffer is right after it.

For UN-loaded: re-write your dB as voltages. 0 -2 -4 -6 -8... becomes 0 0.794 0.631 0.501 0.398...

Say 100k. Then from -2dB tap to ground must be 100k*0.794 or 79.4k, and the 0 to -2 resistor must be 100k-79.4k or 20.6k. Go on from there.

Some cheats and checks. -6(.02)dB is half. So you know the sum of resistors above -6 must be 50k, and the sum below -6 must be 50k. Likewise -20 is 1/10 so top is 90k and bottom is 10k; -40dB is 1/100 so top must be 99k and bottom is 1k.

Code:

```
1: 5900.00 ohms 0.00 dB loaded by 47000, 0.00 dB unloaded
2: 6490.00 ohms -2.00 dB loaded by 47000, -1.09 dB unloaded
3: 6490.00 ohms -4.03 dB loaded by 47000, -2.46 dB unloaded
4: 6190.00 ohms -6.04 dB loaded by 47000, -4.10 dB unloaded
5: 5360.00 ohms -8.07 dB loaded by 47000, -6.01 dB unloaded
6: 4420.00 ohms -10.07 dB loaded by 47000, -8.09 dB unloaded
7: 3480.00 ohms -12.07 dB loaded by 47000, -10.29 dB unloaded
8: 2700.00 ohms -14.06 dB loaded by 47000, -12.52 dB unloaded
9: 2050.00 ohms -16.05 dB loaded by 47000, -14.76 dB unloaded
10: 1600.00 ohms -18.02 dB loaded by 47000, -16.96 dB unloaded
11: 1210.00 ohms -20.04 dB loaded by 47000, -19.17 dB unloaded
12: 953.00 ohms -22.02 dB loaded by 47000, -21.32 dB unloaded
13: 715.00 ohms -24.05 dB loaded by 47000, -23.49 dB unloaded
14: 562.00 ohms -26.02 dB loaded by 47000, -25.57 dB unloaded
15: 442.00 ohms -28.01 dB loaded by 47000, -27.64 dB unloaded
16: 348.00 ohms -30.00 dB loaded by 47000, -29.72 dB unloaded
17: 270.00 ohms -32.02 dB loaded by 47000, -31.79 dB unloaded
18: 215.00 ohms -34.01 dB loaded by 47000, -33.82 dB unloaded
19: 169.00 ohms -36.02 dB loaded by 47000, -35.87 dB unloaded
20: 133.00 ohms -38.03 dB loaded by 47000, -37.92 dB unloaded
21: 105.00 ohms -40.04 dB loaded by 47000, -39.95 dB unloaded
22: 82.50 ohms -42.04 dB loaded by 47000, -41.97 dB unloaded
23: 64.90 ohms -44.03 dB loaded by 47000, -43.97 dB unloaded
24: 51.10 ohms -46.01 dB loaded by 47000, -45.96 dB unloaded
25: 42.20 ohms -47.96 dB loaded by 47000, -47.92 dB unloaded
26: 33.00 ohms -49.99 dB loaded by 47000, -49.96 dB unloaded
27: 26.10 ohms -52.00 dB loaded by 47000, -51.97 dB unloaded
28: 20.50 ohms -54.00 dB loaded by 47000, -53.98 dB unloaded
29: 16.20 ohms -55.98 dB loaded by 47000, -55.96 dB unloaded
30: 13.00 ohms -57.94 dB loaded by 47000, -57.93 dB unloaded
31: 10.50 ohms -59.92 dB loaded by 47000, -59.91 dB unloaded
32: 40.20 ohms -61.94 dB loaded by 47000, -61.93 dB unloaded
total 50202.2 ohms
```

Code:

```
from math import log10, sqrt
E48 = [
1.00, 1.05, 1.10, 1.15, 1.21, 1.27, 1.33, 1.40,
1.47, 1.54, 1.62, 1.69, 1.78, 1.87, 1.96, 2.05,
2.15, 2.26, 2.37, 2.49, 2.61, 2.74, 2.87, 3.01,
3.16, 3.32, 3.48, 3.65, 3.83, 4.02, 4.22, 4.42,
4.64, 4.87, 5.11, 5.36, 5.62, 5.90, 6.19, 6.49,
6.81, 7.15, 7.50, 7.87, 8.25, 8.66, 9.09, 9.53
]
E24 = [
1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0,
2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.3,
4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1
]
E12 = E24 [0:24:2]
def choose_best (value, res_values):
best = None
for p in range (6):
for ent in res_values:
resistor = ent * pow(10, p)
if best is None or abs(value-best) > abs(value-resistor):
best = resistor
return best
def dB_2_ratio(dB):
return pow(10.0, dB/20.0)
def ratio_2_dB(num, denom):
return 20.0 * log10 (num / denom)
def calc_loaded_resistances (total, load, ratio):
# Split a total resistance for a given voltage ratio when loaded by load - quadratic solving
a = -ratio
b = ratio * total - load
c = ratio * total * load
temp = b*b - 4*a*c
lower = (-b - sqrt(temp)) / (2*a)
upper = total - lower
return upper, lower
def parallel (r1, r2):
# utility fn for combining impedances
return r1 * r2 / (r1 + r2)
def calculate_steps(count, step, resistance, res_values, load = 47000.0):
# first calculate ideal resistances in chain
target_ratio = 1.0
ideal_resistors = []
last_upper = 0.0
for i in range(1, count):
target_ratio /= dB_2_ratio (step)
upper, lower = calc_loaded_resistances (resistance, load, target_ratio)
ideal_resistors.append (upper - last_upper)
last_upper = upper
# fit closest available values
actual_resistors = []
for i in range (1, count):
actual_resistors.append (choose_best (ideal_resistors[i-1], res_values))
actual_resistors.append (choose_best (lower, res_values))
# calculate actual attenuation factors, loaded or unloaded
total = 0.0
remaining_resistance = sum (actual_resistors)
i = 1
for act in actual_resistors:
atten = ratio_2_dB (parallel (remaining_resistance, load), total + parallel (remaining_resistance, load))
unload_atten = ratio_2_dB (remaining_resistance, remaining_resistance + total)
print ("%s: %6.2f ohms %5.2f dB loaded by %i, %5.2f dB unloaded" % (i, act, atten, load, unload_atten))
total += act
remaining_resistance -= act
i += 1
print ("total %6.1f ohms" % total)
calculate_steps (32, 2, 50000, E48+E24)
# calculate_steps (32, 2, 50000, E24)
```

Why? What makes it so good?Wow I use the same Shallco but mine is motorized with only 32 steps. I believe is the best switch money can buy.

Genuinely interested

The Shallcross/Shallco (and another brand, Daven, also IRC) were PROFESSIONAL attenuators invented in the 1930s for talking-movie and broadcast applications, where reliability was more important than the cost. Find pictures online. Solid contacts with selected metal plating, real springs, solid wafers.

http://www.technicalaudio.com/pdf/Daven/Daven_attenuator_switch_lab_Catalog.pdf

@Mark Tillotson

Mark, your code is excellent and very easy to change the parameters. Thanks a lot.

I found the loaded case is a little trickier as a quadratic has to be solved, but you should do your mental pressups regularly, algebra, coding, whatever.

Motorised!! Can mine be modified?

I don't know, it's 23 steps (I'm sorry my mistake), I bought mine here: BentAudio.com :: TAP

- Home
- Design & Build
- Parts
- Series Type Stepped Attenuators