• [ON7IR] Digital SWR & Power meter with 7-segment display

    From ON7IR via rec.radio.amateur.moderat@21:1/5 to All on Sun Jan 30 09:51:43 2022
    XPost: rec.radio.amateur.moderated

    Ham radio ON7IR

    ///////////////////////////////////////////
    Digital SWR & Power meter with 7-segment display

    Posted: 28 Jan 2022 02:59 AM PST https://on7ir.blogspot.com/2022/01/digital-swr-power-meter-with-7-segment.html





    A few people asked me if the Digital SWR and Power meter sketch can be used without a TFT-display but with an inexpensive 7-segment LED display.
    Ofcourse that is possible :-)
    I have two, three and four digits displays available but I chose to use the
    two digit version. The displays have a common anode per segment. The sketch
    can easily be changed for common kathode displays (use byte hardwareConfig
    = COMMON_KATHODE; instead). Two digits can display up to 99 Watt. There is
    no overflow routine in the sketch. If you choose to use a 3 digit display
    to display 100 or more Watts then in the sketch you have to change byte numDigits = 3; and define an extra pin for the 3th segment with byte digitPins[] = {10, 11, 12}; and add an extra 330 ohm resistor.
    Reading forwarded and reflected power and calculating SWR routines are the
    same as before. I suggest you read part 1 and part 2 of the Digital SWR and powermeter sketch to understand.
    With a pushbutton one can choose to display SWR or Power. Initially the SWR setting is active and the display shows "Sr". After the button is
    pushed 'Pr' is shown on the display meaning that power will be measured.
    Here a 1K resistor was used but a 330 ohm is fine, the segment leds are brighter
    with it (although not representative on the photo).

    Each button press swaps the readout. If the transceiver is transmitting and
    the button is pressed then the actual value of SWR or power is shown. The decimal point is only lit when reading SWR.
    At the moment I do not intend to build the circuit so the pictures and
    video are only from development stage.The breadboard and Arduino Leonardo
    used for modification
    of the sketch in order to use a 7-segment led display.




    The sketch has been tested on an Arduino Leonardo but unlikely will cause problems on a Uno or Nano. A simple averaging routine is used to become a
    less nervous readout. /*
    ** Digital PWR & SWR meter v1.1a by ON7IR **
    ** Version with 7 segment led's **
    ** Published at on7ir.blogspot.com Jan 28th, 2022 **
    ** Copyright (C) 2021 Rudi Imbrechts (ON7IR) **

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <https://www.gnu.org/licenses/>.


    ** This sketch makes use of the SWR bridge from a Daiwa CN-410M analog
    SWR meter
    Forward and reflected values from this SWR bridge are the input for
    the Arduino.
    Output is presented on a 7 segment led display

    ** The sketch uses two libraries.
    - Sevseg library to drive the 7 segment led display, see https://github.com/DeanIsMe/SevSeg
    - multiMap library, see https://github.com/RobTillaart/MultiMap

    ** a two-digit common anode 7-segment led display is connected like
    this :-
    ** (but you can a common kathode type as well when changing
    hardwareConfig)
    **
    ** CA left B C E D <- top row pins (CA = Common Anode)
    ** G H A F CA right <- bottom row pins
    **
    **
    ** AAA
    ** F B
    ** F B
    ** GGG
    ** E C
    ** E C
    ** DDD
    ** °H decimal point

    */

    #include <SevSeg.h>
    #include "MultiMap.h"
    #define button 12 // pushbutton between D12 and GND

    //-----------------------------------------------------------------------------

    const int fwdInPin = A0; // input forward power from SWR bridge const int refInPin = A1; // input reflected power from SWR
    bridge
    unsigned int sensorFWD = 0; // raw forward value
    unsigned int sensorREF = 0; // raw reflected value
    float fwdInVoltage; // calculated forward voltage from
    SWR bridge
    float refInVoltage; // calculated reflected voltage
    from SWR bridge
    float outputValueFWD; // calculated forward power
    float outputValueREF; // calculated reflected power
    float cswr; // used to calculate swr
    float swr; // contains SWR value
    const int swrTreshold = 5; // SWR treshold value. Not interested in
    SWR higher than 5
    const int avg = 10; // averaging number. A higher value slows down the display rate
    bool toggle; // used to swap readout
    bool debounced() { // simple but effective debounce
    intercept
    static uint16_t state = 0;
    state = (state << 1) | digitalRead(button) | 0xfe00;
    return (state == 0xff00);
    }

    SevSeg sevseg;

    void setup() {
    byte numDigits = 2; // two 7 segment displays
    byte digitPins[] = {10, 11}; // select 7 segment display. Put a 330 ohm resistor between each pin and each common
    anode
    byte segmentPins[] = {6, 5, 2, 3, 4, 7, 8, 9};
    bool resistorsOnSegments = false; // depends on how
    display is connected,
    bool updateWithDelaysIn = true; // see segsev
    library documentation
    bool leadingZeros = false; // no leading zeros
    byte hardwareConfig = COMMON_ANODE; // set to COMMON_KATHODE when this type of displays is used
    sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
    sevseg.setBrightness(90);
    pinMode(button, INPUT_PULLUP);
    }

    void showData() { // display the
    value
    if (outputValueFWD == 0) {
    if (toggle) {
    sevseg.setChars("pr"); // set to display
    power
    } else {
    sevseg.setChars("sr"); // set to display swr
    }
    }
    else {
    if (toggle) {
    sevseg.setNumber(outputValueFWD); // show power
    } else {
    sevseg.setNumber(swr * 10, 1); // show swr. Value times
    10 is needed for correct display. Decimal point on digit 1.
    }
    }
    sevseg.refreshDisplay();
    }

    void readSensors() {
    sensorFWD = 0; //
    prepare for averaging sensor values,
    sensorREF = 0; // averaging results in a less nervous display
    for (int i = 0; i < avg; i++) { //
    start averaging
    sensorFWD += analogRead(fwdInPin); // read analog value of forwarded signal
    sensorREF += analogRead(refInPin); // read analog value
    of reflected signal
    }
    sensorFWD /= avg;
    sensorREF /= avg; // averaging done
    sensorFWD = constrain(sensorFWD, 70, 1023); // constrain to prevent a negative output value
    sensorREF = constrain(sensorREF, 0, 1023);
    }

    // Converting forward and reflected power from the SWR bridge.
    // inREF, outREF, inFWD and outFWD values are obtained from measurements
    done on _my_ SWR bridge and transceiver at the same time.
    // They cannot be used with another SWR bridge, you have to measure them yourself and replace them in here.

    void ref2watt() {
    refInVoltage = sensorREF * (5.0 /
    1023.0); //
    convert the reflected input value to milliVolts
    float outREF[] = { 0, 0.2, 0.4, 0.6, 0.8, 1, 1.5, 2, 4, 13, 16, 20, 42,
    92, 110 }; // measured reflected power in Watts
    float inREF[] = { 18, 118, 185, 230, 270, 310, 400, 465, 773, 1488, 1664, 1926, 2700, 3900, 4300 }; // measured voltage in milliVolts
    outputValueREF = multiMap(refInVoltage * 1000, inREF, outREF,
    15); // map these 15 values
    outputValueREF = constrain(outputValueREF, 0,
    outputValueFWD); // reflected power cannot be higher than forwarded power
    }

    void fwd2watt() {
    fwdInVoltage = sensorFWD * (5.0 / 1023.0);
    // same comments as in the void ref2watt() except that these are the
    forward values
    float outFWD[] = { 0, 1, 1.5376, 2.6896, 4, 5.0176, 6.1504, 7.3984,
    8.2944, 9.2416, 15.6816, 24.6016, 33.64, 45.56, 53.29, 64, 72.25, 81,
    92.16, 100, 120 };
    float inFWD[] = { 350, 370, 424, 581, 695, 790, 877, 959, 996, 1107,
    1332, 1697, 2039, 2398, 2601, 2838, 3055, 3287, 3502, 3800, 4000 };
    outputValueFWD = multiMap(fwdInVoltage * 1000, inFWD, outFWD,
    21); // map these 21 values
    }

    void calcSWR() {
    cswr = sqrt((outputValueREF) / (outputValueFWD)); // use formulas
    to calculate SWR
    swr = ((1 + cswr) / (1 - cswr));
    swr = constrain(swr, 1, swrTreshold);
    }

    void loop() {
    if (debounced()) {
    toggle = !toggle; // swap readout
    }
    readSensors(); // get sensor values
    fwd2watt(); // get forward power
    ref2watt(); // get reflected power
    calcSWR(); // get calculated SWR
    showData(); // display variable screen
    data
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)