Monday 10 April 2017

BASIC Tech Group - MyNews 36 - Updated RF METER with OLED display

I have updated the code for my RF Meter to use an OLED display. This is to make it possible to mount the system in a small instrument case...

Screen Shot 2017 04 10 at 10 20 08

Code

// RF_METER_OLED
// V1.5 9-4-17 update to U8g2lib
// RF Meter with OLED display
// inputs
// VIN A3
// AREF 3v3

#include "U8g2lib.h"

// Analog input pin, ref (measured) mV
// AREF can vary between Arduino, measure the 3.3V line and put AREF value here.
// scale for 80dB range to fill bar 0-1023
#define DCIN A3
#define AREF 3300.0
#define BARSCALE (100 / 80)

// intercept (dBm), slope (mw/dB), input impedance, attenuator (dB).
// input attenuator is 4k7/51R
#define INTERCEPT -84.0
#define SLOPE 25.0
#define IMP 50.0
#define ATTN 40.0

// bar length
u8g2_uint_t bL;

double vR, dB, wA; // display values
uint8_t vD, dD, wD; // decimal places
double mW, mV, dBm, Vrms; // calculations

// oled object, OELDADDR 0x3C
//U8GLIB_SH1106_128X64 oled(U8G_I2C_OPT_NONE);
U8G2_SH1106_128X64_NONAME_1_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE, SCL, SDA);

//======SETUP
void setup() {
// oled init, sets I2C addr to 0x3C
oled.begin();

// 3.3V connected to AREF
analogReference(EXTERNAL);
}

//======LOOP
void loop() {
int Ain; // int = signed 16 bit


// calculations for mV input, dBm, mW and Volts, AREF in mV
Ain = analogRead(DCIN); // returns an int 0-1023
mV = (double)(Ain * AREF / 1023); // AREF in mV, calculate & convert to double
dBm = (mV / SLOPE) + INTERCEPT + ATTN; // in doubles
mW = pow(10.0, (dBm / 10.0)); // in double, out double, 0dBm = 1mW
Vrms = sqrt((mW / 1000.0) * IMP); // in double, out double,

bL = (dBm + 40); // -40 to +40dBm

// setup display values
// Volts

dispUpdate(); // display bar, Vrms, dBm and Pwr
}

//=====PICTURE LOOP, layout display positions and contant
// global variables, bH, bL, vR, dB, wA
void dispUpdate() {
oled.firstPage();
do {
dispBar(15, 5, 10, bL);
//--VOLTS--
if (Vrms < 1.0) { // millivolts
vR = Vrms * 1000.0;
vD = 0;
dispMsg(75, 20, "mV");
}
else { // volts
vR = Vrms;
vD = 1;
dispMsg(75, 20, "V");
}
dispNum(30, 20, vR, vD);

//--DBM--
dB = dBm; //dBm
dD = 0;
dispNum(30, 35, dB, dD);
dispMsg(75, 35, "dBm");

//--PWR--
if (mW > 1000) { // watts
wA = mW / 1000;;
wD = 1;
dispMsg(75, 50, "W");
}
else { // milliwatts
wA = mW;
wD = 2;
dispMsg(75, 50, "mW");
}
dispNum(30, 50, wA, wD);

 


} while (oled.nextPage());
}

//=======OLED DISPLAYS
// display bar at x, y, h)eight, l)ength (0-128 pixels)
void dispBar(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t h, u8g2_uint_t l) {
u8g2_uint_t n;

oled.drawFrame(x, y, 100, 11);
for ( n = 0; n < l; n++) {
oled.drawLine(x + n, y, x + n, y + h);
}
}


// display message at at x), y), *m)essage
void dispMsg(u8g2_uint_t x, u8g2_uint_t y, char *m) {
// sets font, cursor position and displays message
oled.setFont(u8g2_font_8x13B_tf); // font
oled.setFontPosTop();
oled.setCursor(x, y);
oled.print(m);
}

// display number at x), y), n)umber (double), d)ecimal places
void dispNum(u8g2_uint_t x, u8g2_uint_t y, double n, uint8_t d) {
// sets font, cursor position and displays number
oled.setFont(u8g2_font_8x13B_tf); // font
oled.setFontPosTop();
oled.setCursor(x, y);
oled.print(n, d);
}

No comments: