#ifndef __Sensor_h__ #define __Sensor_h__ #include #include "Debug.h" #include "HamFuncs.h" /**********************************************************************/ #ifndef UBITX_SENSORS_S_METER_PIN #define UBITX_SENSORS_S_METER_PIN 27 #endif #ifndef UBITX_SENSORS_FWD_PWR_PIN #define UBITX_SENSORS_FWD_PWR_PIN 20 #endif #ifndef UBITX_SENSORS_REV_PWR_PIN #define UBITX_SENSORS_REV_PWR_PIN 28 #endif #ifndef UBITX_SENSORS_SUPPLY_PIN #define UBITX_SENSORS_SUPPLY_PIN 21 #endif #ifndef UBITX_SENSORS_AVG_SAMPLES #define UBITX_SENSORS_AVG_SAMPLES 16 #endif #ifndef UBITX_SENSORS_S_METER_R1 #define UBITX_SENSORS_S_METER_R1 22000.0 #endif #ifndef UBITX_SENSORS_S_METER_R2 #define UBITX_SENSORS_S_METER_R2 33000.0 #endif #ifndef UBITX_SENSORS_FWD_PWR_R1 #define UBITX_SENSORS_FWD_PWR_R1 22000.0 #endif #ifndef UBITX_SENSORS_FWD_PWR_R2 #define UBITX_SENSORS_FWD_PWR_R2 33000.0 #endif #ifndef UBITX_SENSORS_REV_PWR_R1 #define UBITX_SENSORS_REV_PWR_R1 22000.0 #endif #ifndef UBITX_SENSORS_REV_PWR_R2 #define UBITX_SENSORS_REV_PWR_R2 33000.0 #endif #ifndef UBITX_SENSORS_SUPPLY_R1 #define UBITX_SENSORS_SUPPLY_R1 56000.0 #endif #ifndef UBITX_SENSORS_SUPPLY_R2 #define UBITX_SENSORS_SUPPLY_R2 10000.0 #endif #ifndef UBITX_SENSORS_S_METER_LVL0 #define UBITX_SENSORS_S_METER_LVL0 2 #endif #ifndef UBITX_SENSORS_S_METER_LVL1 #define UBITX_SENSORS_S_METER_LVL1 4 #endif #ifndef UBITX_SENSORS_S_METER_LVL2 #define UBITX_SENSORS_S_METER_LVL2 8 #endif #ifndef UBITX_SENSORS_S_METER_LVL3 #define UBITX_SENSORS_S_METER_LVL3 16 #endif #ifndef UBITX_SENSORS_S_METER_LVL4 #define UBITX_SENSORS_S_METER_LVL4 32 #endif #ifndef UBITX_SENSORS_S_METER_LVL5 #define UBITX_SENSORS_S_METER_LVL5 64 #endif #ifndef UBITX_SENSORS_S_METER_LVL6 #define UBITX_SENSORS_S_METER_LVL6 128 #endif #ifndef UBITX_SENSORS_S_METER_LVL7 #define UBITX_SENSORS_S_METER_LVL7 256 #endif #ifndef UBITX_SENSORS_S_METER_LVL8 #define UBITX_SENSORS_S_METER_LVL8 512 #endif /**********************************************************************/ const int uBitxSensorsSMeterPin = UBITX_SENSORS_S_METER_PIN; const int uBitxSensorsFwdPwrPin = UBITX_SENSORS_FWD_PWR_PIN; const int uBitxSensorsRevPwrPin = UBITX_SENSORS_REV_PWR_PIN; const int uBitxSensorsSupplyPin = UBITX_SENSORS_SUPPLY_PIN; const int uBitxSensorsAvgSamples = UBITX_SENSORS_AVG_SAMPLES; const float uBitxSensorsSMeterR1 = UBITX_SENSORS_S_METER_R1; const float uBitxSensorsSMeterR2 = UBITX_SENSORS_S_METER_R2; const float uBitxSensorsFwdPwrR1 = UBITX_SENSORS_FWD_PWR_R1; const float uBitxSensorsFwdPwrR2 = UBITX_SENSORS_FWD_PWR_R2; const float uBitxSensorsRevPwrR1 = UBITX_SENSORS_REV_PWR_R1; const float uBitxSensorsRevPwrR2 = UBITX_SENSORS_REV_PWR_R2; const float uBitxSensorsSupplyR1 = UBITX_SENSORS_SUPPLY_R1; const float uBitxSensorsSupplyR2 = UBITX_SENSORS_SUPPLY_R2; const int uBitxSensorsSMeterValues[] = { UBITX_SENSORS_S_METER_LVL0, UBITX_SENSORS_S_METER_LVL1, UBITX_SENSORS_S_METER_LVL2, UBITX_SENSORS_S_METER_LVL3, UBITX_SENSORS_S_METER_LVL4, UBITX_SENSORS_S_METER_LVL5, UBITX_SENSORS_S_METER_LVL6, UBITX_SENSORS_S_METER_LVL7, UBITX_SENSORS_S_METER_LVL8 }; const int uBitxSensorsSMeterLevels = sizeof(uBitxSensorsSMeterValues) / sizeof(uBitxSensorsSMeterValues[0]); extern ADC adc; /**********************************************************************/ /*! * @brief Class that maintains a "trailing average" of the last X * samples provided. It is a template that can be instantiated * with both the (numeric) data type that is being stored and * averaged, as well as the number of samples to maintain the * trailing average across. */ template class TrailingAverage { public: /*! * @brief Create a new TrailingAverage object. Data type averaged, * and number of elements to average, are determined when the * template is instantiated. */ TrailingAverage(): average(T(0)), current(0), divisor(T(N)) { for (int i = 0; i < N; i++) { data[i] = T(0); } } /*! * @brief Add a new element to the average. The current last (Nth) * element is removed, and the new element is added. * @param val * The new element/value to incorporate into the average. */ inline void add(T val) { int last = (current - 1) % N; average -= data[last]; current = (current + 1) % N; average += data[current] / divisor; } /*! * @brief Read the current value of the average. * @return The current average. */ inline T read() { return average; } private: T data[N]; T average; int current; T divisor; }; /**********************************************************************/ /*! * @brief Class that handles the various sensors in the uBitx: * S-Meter, forward/reverse power and SWR, and supply voltage. */ class UBitxSensors { public: /*! * @brief Create a new UBitxSensors object. It uses the default * S-Meter, Forward Power, Reverse Power, and Supply Voltage * ADC pins. */ UBitxSensors(): sMeterPin(uBitxSensorsSMeterPin), fwdPwrPin(uBitxSensorsFwdPwrPin), revPwrPin(uBitxSensorsRevPwrPin), supplyPin(uBitxSensorsSupplyPin) { pinMode(sMeterPin, INPUT); // analog pinMode(fwdPwrPin, INPUT); // analog pinMode(revPwrPin, INPUT); // analog pinMode(supplyPin, INPUT); // analog } /*! * @brief Update the value of the S-Meter by reading the associated * ADC pin. */ inline void updateSMeter() { int value = adc.analogRead(sMeterPin); sMeter.add(value); } /*! * @brief Update the value of the Forward and Reverse Power * measurements by reading the associated ADC pin. */ void updatePower() { ADC::Sync_result value = adc.analogSyncRead(fwdPwrPin, revPwrPin); float fwdV = HF::adcIn(value.result_adc0); float revV = HF::adcIn(value.result_adc1); fwdV = HF::divIn(fwdV, uBitxSensorsFwdPwrR1, uBitxSensorsFwdPwrR2); fwdV = HF::bridgeFwd(fwdV); revV = HF::divIn(revV, uBitxSensorsRevPwrR1, uBitxSensorsRevPwrR2); revV = HF::bridgeFwd(revV); fwdPwr.add(HF::P(fwdV)); revPwr.add(HF::P(revV)); vswr.add(HF::VSWR(fwdV, revV)); } /*! * @brief Update the value of the Supply Voltage measurement by * reading the associated ADC pin. */ inline void updateSupply() { float value = HF::adcIn(adc.analogRead(supplyPin)); value = HF::divIn(value, uBitxSensorsSupplyR1, uBitxSensorsSupplyR2); supply.add(value); } /*! * @brief Return the unscaled value of the S-Meter reading. * @return Unscaled S-Meter reading. */ inline int sMeterUnscaled() { return sMeter.read(); } /*! * @brief Return the scaled value of the S-Meter reading. This * is the value that is used to directly control the S-Meter * display on the Nextion LCD. * @return Scaled S-Meter reading. */ int sMeterScaled() { float sig = sMeter.read(); // small number of elements; just doing a linear search for (int i = uBitxSensorsSMeterLevels; i > 0; i--) { if (sig > uBitxSensorsSMeterValues[i - 1]) { return i; } } return 0; } /*! * @brief Return the current Forward Power measurement. * @return Forward Power measurement. */ inline float Pfwd() { return fwdPwr.read(); } /*! * @brief Return the current Reverse Power measurement. * @return Reverse Power measurement. */ inline float Prev() { return revPwr.read(); } /*! * @brief Return the current Voltage Standing Wave Ration (VSWR). * @return Current VSWR calculation. */ inline float VSWR() { return vswr.read(); } /*! * @brief Return the current Voltage Standing Wave Ration (VSWR), * scaled for the Nextion display protocol. * @return Current VSWR calculation (scaled). */ float scaledVSWR() { int val = int(vswr.read()); if (val < 0) { return 0; } else if (val > uBitxSensorsSMeterLevels) { return uBitxSensorsSMeterLevels; } else { return val; } } /*! * @brief Return the current Supply Voltage measurement. * @return Current Supply Voltage. */ inline float supplyVoltage() { return supply.read(); } private: // Pins int sMeterPin; int fwdPwrPin; int revPwrPin; int supplyPin; // Buffers for averages TrailingAverage sMeter; TrailingAverage fwdPwr; TrailingAverage revPwr; TrailingAverage vswr; TrailingAverage supply; }; extern UBitxSensors Sensors; #endif