[code]/*Field Strength Meter program
A0: analog data input from AD8307 log amp buffered by OPA344
D2: Latch Relay output to switch Low mode e.g. no attenator
D3: Latch Relay output to switch High mode e.g. use 20dB pai attenator
D4: Low / High toggle switch input
I2C(SDA, SCL): fro LCD and high resolution ADC (16bits)
LCD library: I2CLiquidCrystal
EEPROM:address 0 is offset data lower byte
address 1 is offset data higher byte
if get W command from serial line, then write offset data to address 0 and 1
This sketch has 3 type of sketch#define NORMAL
normal operation, it does not use caribraion data in EEPROM.
This type sketch is normal use for Field Strength meter shield.
#define CALIBRATIONThis type sketch is used for writing the caribration data to EEPROM.
#define USE_CARIBRATION
normal operation with caribration data from EEPROM
programed by S. Iwasaki
reference site:// http://pol8139.tumblr.com/post/86687323586/ardunio-voltmeter
CARIBRATION sketch usage:
1) Add 0dBm output from SSG.
2) then check serial line display data
3) if data is stable, then send W charactre4) program checks W command, if W command received, then write offset data to EEPROM address
0 and 1offset data is b, it is dBm value
History:
2015/10/21

Ver.1.1 Change delay time 1Sec to 0.1Sec

2014/11/24 07:32 Ver.1.0*/

// select sketch type#define NORMAL// #define CALIBRATION// #define USE_CARIBRATION// toggle debug message to serial port// #define DEBUG#ifdef NORMAL#undef CALIBRATION#undef USE_CARIBRATION#endif// include the library code:#include <I2CLiquidCrystal.h>#include <Wire.h>#include <EEPROM.h>// define Pins
#define relayLow 2#define relayHigh 3#define S1 4// define delay value#define delay_time 20 // set pulse width for latching relay, unit is mSec// function prototype
void SenseChange(int); // On and Off the attenator depend by S1 switch, and display H or L markon LCD
void PrintSense(int); // display the sensitivity on LCD display by H or L// declear register
int S1_status; // hold S1 switch status#ifdef CALIBRATION// EEPROM address and value
int address; // EEPROM address
byte offsetL; // Low byte

byte offsetH; // High byte
#endif#ifdef USE_CARIBRATION// EEPROM address and value
int address; // EEPROM address
byte offsetL; // Low byte
byte offsetH; // High byte
int offset; // offset value from EEPROM#endif#ifdef CALIBRATION// serial in byte
byte inByte;#endif// initialize the library// uncomment next line if you are using a LCD from Straberry Linux using Sitronix ST7032
I2CLiquidCrystal lcd(40, (bool)true);//|+--- set true if the power suply is 5V, false if it is 3.3V//+-------- contrast (0-63)//I2CLiquidCrystal lcd(30, (bool)false);//|+--- set true if the power suply is 5V, false if it is 3.3V//+-------- contrast (0-63)

void setup() {// set up the LCD's number of columns and rows:lcd.begin(8, 2);// set up latching relay
pinMode(relayLow, OUTPUT);
digitalWrite(relayLow, LOW); // port initialize
pinMode(relayHigh, OUTPUT);
digitalWrite(relayHigh, LOW); // port initialize
pinMode(S1, INPUT);
S1_status = digitalRead(S1); // read S1 status
SenseChange(S1_status); // Change sensitivity by S1 value, L is normal H is using 20dB attenator// set up serial line
Serial.begin(9600);
Serial.println("¥nField Strength meter¥n");#ifdef USE_CARIBRATION
address = 0;
offsetL = EEPROM.read(address);
address++;
offsetH = EEPROM.read(address);
offset = int(offsetH << 8) + int(offsetL);
Serial.print("offset: ");Serial.println(offset, DEC);
Serial.print("¥n¥n");#endif}void loop() {int v; // analog read value
int f; // analog volts value converted from analog read value
int i; // integer number part of analog volts value
int d; // after the decimal point value of analog volts value
int d1; // 1digit
int d2; // 2digit
int d3; // 3digit
int b; // dBm value calculated from analog volts value
int b1; // 1digit
int b2; // 2digit
int b3; // 3digit
int bm; // absolute b// initialize senseitivity
lcd.clear(); // LCD clear
S1_status = digitalRead(S1); // read S1 status
SenseChange(S1_status); // Change sensitivity by S1 value, L is normal H is using 20dB attenator
PrintSense(S1_status); // display sensitivity character on LCD// convert analog value to volt value
v = analogRead(A0); // read analog value from A0 pin

f = (long)v * 5000 / 1024; // move decimal point, multiplied by 1000 and 5 volts then divided by1024 (10bits)
i = f / 1000;// get integer number

d = f - i * 1000; // get the number after decimal point
d1 = d / 100;d2 = (d - d1 * 100 ) / 10;// get 1st number// get 2nd number

d3 = (d - d1 * 100 - d2 * 10 ); // get 3rd number#ifdef DEBUG
Serial.print("ADC: ");Serial.print(v, DEC);
Serial.print(" ");Serial.print("Int: ");Serial.print(i, DEC);
Serial.print(" ");Serial.print("Dec: 0.");
Serial.println(d, DEC);#endif// convert volt value to dBm * 10 value, b value is between -800 to 1192b = (long)f * 10 / 25 - 800; // convert from volt to dBm value and multiplied by 10#ifdef USE_CARIBRATION
if ( offset < 0 ) {b = b + abs(offset);} else {b = b - offset;}
Serial.print("calibrated dBm * 10 value: ");Serial.println(b, DEC);
Serial.print("¥n¥n");#endifif (S1_status) { // using attenator, display range is between -60 dBm to 37dBm
b = b + 200; // added attenator valueif ( b < -99 ) { // print -xx.xdBm
bm = abs(b);lcd.print('-');

b1 = bm / 100;b2 = (bm - b1 * 100 ) / 10;// get 1st number// get 2nd number

b3 = (bm - b1 * 100 - b2 * 10 ); // get 3rd number
lcd.print(b1);lcd.print(b2);lcd.print('.');
lcd.print(b3);lcd.print("dBm");}else if ( b < -9 ) { // print -x.xdBm
bm = abs(b);lcd.print('-'); // print minus sign
b1 = bm / 10;
b2 = (bm - b1 * 10);
lcd.print(b1);lcd.print('.');
lcd.print(b2);lcd.print("dBm");}else if ( b < 0 ) { // print -0.xdBm
b1 = abs(b);lcd.print("-0.");lcd.print(b1);lcd.print("dBm");}else if ( b < 10 ) { // print 0.xdBm
lcd.print(" 0."); // print space and leading zero
lcd.print(b);lcd.print("dBm");}else if ( b < 100 ) { // print x.xdBm
b1 = b / 10;
b2 = (b - b1 * 10);
lcd.print(' '); // print space
lcd.print(b1);lcd.print('.');
lcd.print(b2);lcd.print("dBm");}else if ( b < 370 ) { // print xx.xdBm
lcd.print(' '); // print spaceb1 = b / 100;b2 = (b - b1 * 100 ) / 10;// get 1st number// get 2nd number

b3 = (b - b1 * 100 - b2 * 10 ); // get 3rd number
lcd.print(b1);lcd.print(b2);lcd.print('.');
lcd.print(b3);lcd.print("dBm");}else {
lcd.print("R. Over");}// serial output
Serial.print("S1 is H: ");Serial.print("Volt: ");Serial.print(f, DEC);
Serial.print(" dBm * 10: ");Serial.print(b, DEC);#ifdef DEBUG
Serial.print(" bm: ");Serial.print(bm, DEC);
Serial.print(" b1: ");Serial.print(b1, DEC);
Serial.print(" b2: ");Serial.println(b2, DEC);#endifSerial.print("¥n");lcd.setCursor(0, 1);
if ( b < -400 ) {}else if ( b < -300 ) {lcd.write(0xFC);}
else if ( b < -200 ) {lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < -100 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < 0 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < 100 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < 200 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < 300 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}

else {
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}}
else { // normal range, display range is between -80 dBm to 17dBm
if ( b < -99 ) { // print -xx.xdBmbm = abs(b);lcd.print('-');
b1 = bm / 100;b2 = (bm - b1 * 100 ) / 10;// get 1st number// get 2nd number

b3 = (bm - b1 * 100 - b2 * 10 ); // get 3rd number
lcd.print(b1);lcd.print(b2);lcd.print('.');
lcd.print(b3);lcd.print("dBm");}else if ( b < -9 ) { // print -x.xdBm
bm = abs(b);lcd.print('-'); // print minus sign
b1 = bm / 10;
b2 = (bm - b1 * 10);
lcd.print(b1);lcd.print('.');
lcd.print(b2);lcd.print("dBm");}else if ( b < 0 ) { // print -0.xdBm
b1 = abs(b);lcd.print("-0.");lcd.print(b1);lcd.print("dBm");}else if ( b < 10 ) { // print 0.xdbm
lcd.print(" 0."); // print space and leading zero
lcd.print(b);lcd.print("dBm");}else if ( b < 100 ) { // print x.xdbm
b1 = b / 10;
b2 = (b - b1 * 10);
lcd.print(' '); // print space
lcd.print(b1);lcd.print('.');
lcd.print(b2);lcd.print("dBm");}else if ( b < 170 ) {lcd.print(' '); // print spaceb1 = b / 100;b2 = (b - b1 * 100 ) / 10;// get 1st number// get 2nd number

b3 = (b - b1 * 100 - b2 * 10 ); // get 3rd number
lcd.print(b1);lcd.print(b2);lcd.print('.');
lcd.print(b3);lcd.print("dBm");}else {
lcd.print("R. Over");}// serial output
Serial.print("S1 is L: ");Serial.print("Volt: ");Serial.print(f, DEC);
Serial.print(" dBm * 10: ");Serial.print(b, DEC);#ifdef DEBUG
Serial.print(" bm: ");Serial.print(bm, DEC);
Serial.print(" b1: ");Serial.print(b1, DEC);
Serial.print(" b2: ");Serial.println(b2, DEC);#endifSerial.print("¥n");lcd.setCursor(0, 1);
if ( b < -600 ) {}else if ( b < -500 ) {lcd.write(0xFC);}
else if ( b < -400 ) {lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < -300 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < -200 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < -100 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < 0 ) {lcd.write(0xFC);

lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else if ( b < 100 ) {lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}
else {
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);
lcd.write(0xFC);}}#ifdef CALIBRATION// check W command to write offset data
if (Serial.available() > 0) { // is there serial data?
inByte = Serial.read();if (inByte == 'W') { // check W commandaddress = 0; // address initialize
offsetL = lowByte(b); // get lower byte
offsetH = highByte(b); // get higher byte
EEPROM.write(address, offsetL);
address++;
EEPROM.write(address, offsetH);#ifdef DEBUG
Serial.print("b: ");Serial.print(b, DEC);
Serial.print(" offsetL: ");Serial.print(offsetL, HEX);
Serial.print(" offsetH: ");Serial.println(offsetH, HEX);#endifaddress = 0;
offsetL = EEPROM.read(address);
address++;
offsetH = EEPROM.read(address);
int offset = int(offsetH << 8) + int(offsetL);
Serial.print("offset: ");Serial.println(offset, DEC);
Serial.print("¥n¥n");}}#endif// delay(1000); // wait 1 sec
delay(100); // wait 0.1 sec}// Change sensibity by S1 value, L is normal H is using 20dB attenatorvoid SenseChange(int S1_value) {if (S1_value) { // S1 is H
digitalWrite(relayHigh, HIGH);
delay(delay_time);
digitalWrite(relayHigh, LOW);}
else { // S1 is L
digitalWrite(relayLow, HIGH);
delay(delay_time);
digitalWrite(relayLow, LOW);}}

// print sensibity character L or H
void PrintSense(int S1_value) {if (S1_value) { // S1 is H
lcd.print('H');}else { // S1 is L
lcd.print('L');}}[/code]