343 lines
8.7 KiB
C++
343 lines
8.7 KiB
C++
#ifndef __Sensor_h__
|
|
#define __Sensor_h__
|
|
|
|
#include <ADC.h>
|
|
#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 <typename T, int N>
|
|
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<int, uBitxSensorsAvgSamples> sMeter;
|
|
TrailingAverage<float, uBitxSensorsAvgSamples> fwdPwr;
|
|
TrailingAverage<float, uBitxSensorsAvgSamples> revPwr;
|
|
TrailingAverage<float, uBitxSensorsAvgSamples> vswr;
|
|
TrailingAverage<float, uBitxSensorsAvgSamples> supply;
|
|
};
|
|
|
|
extern UBitxSensors Sensors;
|
|
|
|
#endif
|