Posted on 16 Comments

Arduino Code for 0-500MHz, 1nW to 100W RF Power Meter

Here is the code for the Arduino in-line power meter that will feature in my Data Modes column in the August PW.
Copy and paste the code below into your Arduino IDE:
 --------------------------------------------------------------------------------------------------------------------------
 /*
 This sketch uses the Adafruit i2c/SPI LCD backpack
 and shares some code from Adafruit
 ( http://www.ladyada.net/products/i2cspilcdbackpack/index.html )
Sketch produced by Mike Richards (G4WNC) for publication in the August issue
 of Practical Wireless magazine in the UK
 www.g4wnc.com
The LCD Backpack connections:
 * 5V to Arduino 5V pin
 * GND to Arduino GND pin
 * CLK to Analog #5
 * DAT to Analog #4
* The AD8307 voltage output connects to the Arduino A0 pin
*/
// include the library code:
 #include "Wire.h"
 #include "LiquidCrystal.h"
// Initialise the variables
 int value = 0; // Used to store the raw reading from the ADC
 float vout = 0.000; // Holds the true value of the ADC output voltage
 float powerdB = 0.00; // Calculated power in dBm
 float pWatts = 0.00; // Calculated power in watts
 float slope = 40; // Slope of the AD8307 log output (Default = 40)
 float intercept = 44.0; // 0V intercept point (Default = 44)
 float refVolts = 2.5; // Measured value of the 2.5V external reference
// Connect to the LCD via i2c, default address #0 (A0-A2 not jumpered)
 LiquidCrystal lcd(0);
void setup() {
 // Start by setting-up the pin configurations
 analogReference(EXTERNAL); // Set the Arduino to use an external reference for the ADC
 pinMode(4, OUTPUT); // Digital pin 4 is used to supply power to the voltage reference
 digitalWrite(4, HIGH); // Make sure pin 4 is high
 pinMode(A0, INPUT); // Enable the first (A0) input to the ADC
 // set up the LCD's number of rows and columns:
 lcd.begin(20, 4); // Set 4 lines of 20 characters
 // Print a message to the LCD.
 lcd.setCursor(0,0); // set the cursor to the top left, line 0 column 0
 lcd.print("Arduino Power Meter"); // Message on the top line of the display
 lcd.setBacklight(HIGH); // Turn the backlight on to make the display visible
 //Now print the measurement labels
 lcd.setCursor(0,1); // move the cursor to the first position on the 2nd line
 lcd.print("AD8307 Volts: "); // print the label
 lcd.setCursor(0, 2); // Move the cursor to the start of the 3rd line
 lcd.print("Power (dBm): "); // Print the label
 lcd.setCursor(0, 3); // Position the cursor
 lcd.print("Power (Watts):"); // Print the label
 }
void loop() {
value = analogRead(0); //read the ADC and store the result in value
 vout = (value*refVolts)/1023; // Convert the ADC result to volts in vout
 powerdB = (slope*vout)-intercept; // convert the voltage to dBm in 50 ohms
 pWatts = pow(10.0,(powerdB -30)/10.0); // convert dBm to watts
 lcd.setCursor(13, 1); //Move the cursor to the 13th position
 lcd.print(vout,3); // Display the AD8307 voltage
 lcd.setCursor(13, 2); // Position the cursor
 lcd.print(" "); // Print spaces to clear the last result
 lcd.setCursor(13, 2); // Position the cursor
 lcd.print(powerdB,1);// Display the power in dBm
 lcd.setCursor(15,3); // Position the cursor
 lcd.print(" "); // Print spaces to clear the last result
 lcd.setCursor(15,3); //Position the cursor
 lcd.print(pWatts,1);// Display the power in watts
 }

16 thoughts on “Arduino Code for 0-500MHz, 1nW to 100W RF Power Meter

  1. A word of warning when copying this code – the Arduino software doesn’t like the ” marks when they are copied, you need to replace all of them by physically typing the ” into the program.

    1. Hi Lee – Thanks for spotting that problem. I’ve had a look at the problems and the web formatting on my post was using 66 and 99 style inverted commas. I’ve now changed the page formatting so it’s safe to copy and paste direct from the web.

      Thanks again, Mike G4WNC

      1. Thanks for that. It took me a while to figure out what was going wrong!

        A very informative article BTW, thank you. I look forward to reading you again very soon.

        73 de M0LGL

  2. You need the new LiquidCrystal Library from Adafruit, and the:
    #include “Wire.h”
    #include “LiquidCrystal.h”
    needs changing to
    #include
    #include

    73 de M0LGL

  3. ‘ #include ‘
    ‘ #include ‘

    1. Arrrrrgh – it won’t let me put the code in – remove the ” and rep[lace with

      1. Greater than and less than signs – sorry but every time It wouldn’t let me post the actual symbols

  4. In can measure Frequency in kHz to MHz ???? Insted db

  5. Formula for power in watts should be :

    pWatts = pow(10.0,(powerdB )/10.0) * 1000.0;

  6. Hi Mike, great program thanks!
    I have an attenuator -50db to measure 0-100W at the input of the AD8307 RF Power Detector from SV1AFN.

    The output is 20mV/dB, 50mV/dB and 100mV/dB

    Where do I have to enter the value (-50dB and xxmV/dB) in the program or what do I have to change?

    Can someone help me please?

    1. Hi Andreas,

      You only need to chage one line to account for your 50dB RF tap.
      In the ‘Initialise the variables’ section, change the float intercept to 34
      You will then need to use the 25mV output from the SV1AFN AD8307 module.
      For increased accuracy, it’s worth measuring the slope and the intercept point of the AD8307.
      Providing you have access to a decent multimeter and a signal generator/attenuator, this is very easy to do. The measurement is well described in the AD8307 data sheet.
      Regards,

      Mike – G4WNC

  7. Hello
    I find the article and project very useful for my station
    I built a 3Kw dummy load and this power Meter would be a great upgrade .
    How to change the maximum display power to 3Kw Please?
    I use a 60 db attenuator
    Would appreciate help
    Many thanks

    73
    Yoram
    4X1YS

    1. Hi Yoram,
      In the Arduino sketch, I compensate for the loss in the RF tap by altering the intercept point used for the power calculation. The intercept point is the power input required by the AD8307 to give a theoretical 0V output. This figure is calculated from the power vs voltage slope of the AD8307. However, useful results can be had by using the nomonal intercept point of -88dBm. For a 40dB power tap from the transmitter, that figure needs to change to -44dBm but for your 60dB tap/attenuator the intercept will be -24dBm.
      To adapt the code for your system, do the following:
      Find the “// initialise the variables” section of the sketch
      Find the line that begins: float intercept =
      Change that line to read: float intercept = 24.0;

      That’s it!

      Regards,

      Mike – G4WNC

      1. Hi Mike

        Thanks for the quick response
        Indeed changing the parameter did the job
        simply incredible !
        This is a nice upgrade to my dummy load .
        When I finish the job I will be happy to send pictures of the final product .

        Thank you so much Mike !!

        73
        Yoram
        4X1YS

  8. Hi Mick
    I am looking for your article regarding understanding the AD8307 component

    ( http://techham.altervista.org/Arduino-Ham/A%20Look%20at%20the%20Arduino.pdf )

    And unfortunately the link does not work….
    Is there a link to the article Please ?

    Thanks again
    73
    Yoram
    4X1YS

    1. Hi Yoram,

      I sold the original article to Practical Wireless magazine so they own the copyright. I suspect the link you were given was an illegal copy, hence its removal.
      The AD8307 module I used was the one in the link below by Makis SV1AFN. Makis makes a range of useful RF modules. If you follow the link he has the AD8307 data sheet as well as notes on its performance. That should give you all you need.

      AD8307 Module

      Regards,

      Mike – G4WNC

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.