/* detector1: Calculate the input WiFi power from the measured voltage, by linear interpolation, for the RF detector CPDETLS-4000 with 20 dB attenuator. When using no attenuator simply substract 20 to the dBm and divide the mW by hundred, or comment that line in main with ld_p += 20.0;. When using a 40 dB attenuator simply add 20 to the dBm and multiply the mW by hundred. The data sheet of the detector says nothing about the temperture dependence and accuracy. The accuracy of the estimated power in mW is about 10 %. Input: The measured voltage [mV] Output: The calculated input power [mW, dBm] Version 2013-10-03 * ---------------------------------------------------------------------------- * "THE BEERWARE LICENSE" (Revision 44): * Dr. Rolf Freitag (rolf dot freitag at email dot de) wrote this file. * As long as you retain this notice you can do whatever * the GPL (GNU Public License version 3) allows with this stuff. * If you think this stuff is worth it, you can send me money via * paypal, and get a contribution receipt if you wish, or if we met some day * you can buy me a beer in return. * ---------------------------------------------------------------------------- */ #include #include #include // 2.45 GHz, 2 GHz WiFi band #define FREQUENCY 2.45 //#define DEBUG /* Array of the dBm and frequency points: 2 and 3 GHz, -10 ... 10 dBm from the data sheet, and interpolatet values for 2.45 GHz (WiFi), without attenuator. first index: 0 for 2 GHz, 1 interpolatet, 2 for 3 GHz second: -10 dBm, -8 dBm, ... 10 dBm Value: Voltage [mV] */ long double ald_2ghzband[3][11] = { {1.809, 5.682, 17.811, 43.310, 88.722, 148.010, 235.005, 349.170, 477.430, 659.485, 887.470}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {4.037, 12.702, 34.399, 70.238, 126.286, 200.485, 299.975, 427.445, 594.675, 802.725, 1063.620} }; // Array of the dBm values (in the datasheet) const int ci_dbms[11] = { -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10 }; // interpolate the detector table for the wifi frequency, linear interpolation void interpolate1 (void) { int i = 0; for (i = 0; i < 11; i++) { ald_2ghzband[1][i] = ald_2ghzband[0][i] + (ald_2ghzband[2][i] - ald_2ghzband[0][i]) * (FREQUENCY - 2.0); } return; } // interpolate1 // calculate the power [dBm] by linear interpolation and inversion, x(y) from y(x) long double calc_power (const long double ld_y) { int i = 0; if (ld_y < ald_2ghzband[1][0]) // lower than minimum: return the half value with warning { printf ("Warning: The Input value is too low, < 10 dBm! The calculated value is only guessed!\n"); return (((long double) ci_dbms[0]) -3); } if (ld_y > ald_2ghzband[1][10]) // greater than maximum: return double value with warning { printf("Warning: The Input value is too high, > 30 dBm! The calculated value is only guessed and the detector is not in the safe operating area!\n"); return (((long double)ci_dbms[10]) +3); } if (ld_y == ald_2ghzband[1][0]) // minimum return ((long double)ci_dbms[0]); if (ld_y == ald_2ghzband[1][10]) // maximum return ((long double)ci_dbms[10]); // go to the closest point which is higher than the input value, ald_2ghzband[1][i] for (i = 1; i < 11; i++) { if (ald_2ghzband[1][i] > ld_y) break; } #ifdef DEBUG printf("%s: i=%d, Offset: %d dBm, delta1: %Lf (%d -%d), delta2: %Lf\n", __FUNCTION__, i, ci_dbms[i - 1], ((long double)ci_dbms[i] - (long double)ci_dbms[i - 1]), ci_dbms[i], ci_dbms[i-1], (ld_y -ald_2ghzband[1][i -1]) / (ald_2ghzband[1][i] -ald_2ghzband[1][i -1])); #endif // interpolate, linear interpolation in dBm, between ci_dbms[i - 1] and ci_dbms[i] return ((long double)ci_dbms[i - 1] + (ld_y -ald_2ghzband[1][i -1]) * ((long double)ci_dbms[i] - (long double)ci_dbms[i - 1]) / (ald_2ghzband[1][i] -ald_2ghzband[1][i -1])); } // calc_power int main (int argc, char *argv[]) { long double ld_y = 0, ld_p = 0, ld_pmw = 0; char **endptr = NULL; #ifdef DEBUG int i=0; #endif interpolate1 (); // calculate the 2.45 GHz detector values if (argc < 2) { printf ("Missing input value [mV], exiting\n"); return (-1); } endptr = &(argv[1]) + 10; // end pointer for limitation ld_y = strtold (argv[1], endptr); // mV, input (from the DMM) and limitation #ifdef DEBUG // print the interpolatet values for (i = 0; i < 11; i++) { printf ("interpolatet: %.2Lf\n", ald_2ghzband[1][i]); } for (i = 0; i < 11; i++) { printf ("ci_dbms: %d\n", ci_dbms[i]); } #endif ld_p = calc_power (ld_y); // power in dBm ld_p += 20.0; // add 20 when using the 20 dBm attenuator ld_pmw = powl (10.0, ld_p / 10.0); // power in mW //ld_pmw = expl(ld_p*logl(10.0)/10.0); // mW printf ("At %.2Lf Millivolt the Power is %.1Lf mW = %.1Lf dBm (with a 20 dB attenuator).\n", ld_y, ld_pmw, ld_p); return (0); } // main