Re: QRP SWR meter recommendation? #ubitx

Jack, W8TEE


You can get a marginal speed improvement by moving the data definitions out of the loops. For example:

#define ELEMENTS(x)  (sizeof(x) / sizeof(x[0]))  // Gets rid of "magic numbers" in the code
float scaledReadin;
for (int pin = 0; pin < ELEMENTS(_analogValue); pin++) {
   if (_analogActive[pin]) {
     scaledReading = analogScalingFactor * (float)analogRead(pin);
     _analogValue[pin] += (scaledReading - _analogValue[pin]) * _analogFilterValue[pin];
The macro ELEMENTS() allows you to determine the number of elements in an array automatically a compile time, thus eliminating the need to hard-code array sizes into the body of the program. That way, you can simply change the definition of the array in one place in the code, recompile, and the new size is automatically changed everywhere in the code. The really nice thing about the macro is that it's completely typeless...that it, it will work with any aggregate data type.

Moving the definition of a variable before and outside the loop saves the compiler the instructions necessary to adjust the stack pointer on each pass through the loop in the "in-scope, out-of-scope" aspect of a data definition within the loop. Quite honestly, on 8 iterations of the loop it will not likely be noticeable. Still, in other programs where SRAM is pretty tight, it could mean the difference between running and a stack crash.

Jack, W8TEE

On Tuesday, August 21, 2018, 1:02:39 AM EDT, Tom, wb6b <wb6b@...> wrote:

Here are some code snippets from a project I did. It calculates SWR from the voltages read from analog pins A6 and A7.

It does a number of other things, so here are the basic pieces of code for SWR extracted out into small snippets.

This first code segments captures selected analog pin voltages and applies an exponential smoothing filter to them.

for (int pin = 0; pin < 8; pin++) {
    if (_analogActive[pin]) {
      float scaledReading = analogScalingFactor * (float)analogRead(pin);
      _analogValue[pin] +=
        (scaledReading - _analogValue[pin]) * _analogFilterValue[pin];

This next slice of code captures the max voltage and applies a slow decay to the max value.

  // Capture the peak analog values with a slow decay time.
  // The decay time is a starting point. May want to adjust it to taste.
  float decayValue = 0.001;

  for (int pin = 0; pin < 8; pin++) {
    if (_analogActive[pin]) {
      float analogValue = _analogValue[pin];

      _analogValueMax[pin] = max(_analogValueMax[pin], analogValue);
      _analogValueMax[pin] += (analogValue - _analogValueMax[pin]) * decayValue;

    } else {
      _analogValueMax[pin] = 0.0;

And here the SWR is calculated from the Max values.

    // "SWR"

    float vf = _analogValueMax[6];
    float vr = _analogValueMax[7];
    float vd = (vf - vr);
    vd = max(vd, 0.002);  // Limit max SWR reading before divide by zero
    // Calculate SWR from directional coupler voltages.
    result = String((vf + vr) / vd);

You can see the full code here:

Tom, wb6b

Join to automatically receive all group messages.