1---
2app_version: 0.1.0
3precision: 3
4form_title: Receiver Dynamic Range (MDS, IP3, SFDR)
5form_description: How does your receiver actually perform between "too weak to hear" and "so strong it creates its own interference"? Enter noise figure, bandwidth and third-order intercept — get MDS, predicted IM3 products and spurious-free dynamic range.
6form_inputs: Noise figure (dB)|nf_db, Bandwidth (Hz)|bw_hz, Output IP3 (dBm)|oip3_dbm, Fundamental output level (dBm)|pout_dbm
7form_outputs: MDS (dBm)|mds_dbm, Predicted IM3 level (dBm)|pim3_dbm, IM3 below fundamental (dBc)|imd_dbc, SFDR (dB)|sfdr_db
8---
9# Receiver Dynamic Range (MDS, IP3, SFDR)
10// "How weak a signal can I hear, and how strong a nearby signal will start
11// generating fake ones?"
12
13# Minimum discernible signal
14// −174 dBm/Hz is the thermal noise floor at the standard reference
15// temperature (290 K, kT in dBm/Hz) — everything else adds to it.
16nf_db = 6 // dB, receiver noise figure
17bw_hz = 2400 // Hz, e.g. an SSB filter
18
19mds_dbm = -174 + nf_db + 10 * log10(bw_hz)
20"MDS (dBm)": mds_dbm
21
22# Third-order intermodulation
23// Two strong nearby signals mix in any non-linearity and throw third-order
24// products right on top of weaker wanted signals. OIP3 is the (virtual)
25// output level where the extrapolated fundamental and IM3 lines would meet;
26// IM3 rises 3 dB for every 1 dB the fundamental rises.
27oip3_dbm = 20 // dBm, typical for a decent mixer/front end
28pout_dbm = -10 // dBm, fundamental output level of each tone
29
30pim3_dbm = 3 * pout_dbm - 2 * oip3_dbm
31imd_dbc = pout_dbm - pim3_dbm
32
33"Predicted IM3 product level (dBm)": pim3_dbm
34"IM3 below fundamental (dBc)": imd_dbc
35
36# Spurious-free dynamic range
37// The input range between "just above the noise floor" and "IM3 products
38// start poking out of the noise floor" — set the IM3 line equal to MDS and
39// solve for the gap.
40sfdr_db = (2 / 3) * (oip3_dbm - mds_dbm)
41"Spurious-free dynamic range (dB)": sfdr_db
42