von meiner Seite ging der Link aber wenn das so ist, werde ich die Ratschläge befolgen.
Wie bekomme ich aber ein Bildschirm Foto in meinem Beitrag hinein.
Über Dropbox hatte ich ja keinen Erfolg. Die Änderungen mache ich dann morgen.
Code:
//*********************************************************************************
//**
//** Project.........: A menu driven Multi Display RF Power and SWR Meter
//** using a Tandem Match Coupler and 2x AD8307.
//**
//** Copyright (c) 2015 Loftur E. Jonasson (tf3lj [at] arrl [dot] net)
//**
//** 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 <http://www.gnu.org/licenses/>.
//**
//** Platform........: Teensy 3.1/3.2 (http://www.pjrc.com)
//**
//** Initial version.: 0.50, 2013-09-29 Loftur Jonasson, TF3LJ / VE2LJX
//** (beta version)
//**
//*********************************************************************************
#include "PSWR_I.h"
volatile adbuffer_t measure;// Two 256 byte circular buffers carrying the sampled adc-inputs
// from the interrupt function to the main loop.
double adc_ref; // ADC reference (Teensy or external AD7991)
int16_t fwd; // AD input - 12 bit value, v-forward
int16_t rev; // AD input - 12 bit value, v-reverse
double f_inst; // Calculated Forward voltage
double r_inst; // Calculated Reverse voltage
#if AD8307_INSTALLED
double ad8307_FdBm; // Measured AD8307 forward voltage in dBm
double ad8307_RdBm; // Measured AD8307 reverse current in dBm
#endif
double fwd_power_mw; // Calculated forward power in mW
double ref_power_mw; // Calculated reflected power in mW
double power_mw; // Calculated power in mW
double power_mw_pk; // Calculated 100ms peak power in mW
double power_mw_pep; // Calculated PEP power in mW (1s, 2.5s or 5s)
double power_mw_lng; // Calculated MAX power in mW, 30 sec or longer window
double power_mw_avg; // Calculated AVG power in mW, 100ms
double power_mw_1savg; // Calculated AVG power in mW, 1 second
double power_db; // Calculated power in dBm
double power_db_pk; // Calculated 100ms peak power in dBm
double power_db_pep; // Calculated PEP power in dBm
double power_db_lng; // Calculated MAX power in dBm, 30 sec or longer window
double swr=1.0; // SWR as an absolute value
double swr_avg=1.0; // SWR average over 10 ms (smoothed value)
uint16_t swr_bar; // logarithmic SWR value for bargraph, 1000 equals SWR of 10:1
uint16_t menu_level = 0; // Used with PSWRmenu. Keep track of which menu we are in
char lcd_buf[82]; // Used to process data to be passed to LCD and USB Serial
uint16_t Menu_exit_timer;// Used for a timed display when returning from Menu
uint8_t mode_display; // Active display
flags flag; // Various op flags
bool Reverse; // BOOL: True if reverse power is greater than forward power
bool X_LedState; // BOOL: Debug LED
//-----------------------------------------------------------------------------------------
// Variables in ram/flash rom (default)
var_t R = {
{
{ // Meter calibration if 2x AD8307
CAL1_NOR_VALUE, // First calibrate point in 10 x dBm
CALFWD1_DEFAULT, // First Calibrate point, Forward direction, Volts * 10000
CALREV1_DEFAULT // First Calibrate point, Reverse direction, Volts * 10000
},
{
CAL2_NOR_VALUE, // Second Calibrate point in 10 x dBm
CALFWD2_DEFAULT, // Second Calibrate point, Forward direction, Volts * 10000
CALREV2_DEFAULT // Second Calibrate point, Reverse direction, Volts * 10000
}
}, // Second Calibrate point, Reverse direction, db*10 + 2 x AD values
// Meter calibration if diode detectors
(uint8_t) METER_CAL*100, // Calibration fudge of diode detector style meter
SWR_ALARM, // Default SWR Alarm trigger, defined in PSWR_A.h
SWR_THRESHOLD, // Default SWR Alarm power threshold defined in PSWR_A.h
0, // USB Continuous reporting off
1, // USB Reporting type, 1=Instantaneous Power (raw format) and SWR to USB
PEP_PERIOD, // PEP envelope sampling time in SAMPLE_TIME increments
0, // Default AVG sampling time, 0 for short, 1 for 1 second
{
SCALE_RANGE1, // User definable Scale Ranges, up to 3 ranges per decade
SCALE_RANGE2, // e.g. ... 6W 12W 24W 60W 120W 240W ...
SCALE_RANGE3 // If all values set as "2", then ... 2W 20W 200W ...
},
SLEEPMSG, // Shown when nothing else to display on LCD
// Configurable by USB Serial input command: $sleepmsg="blabla"
SLEEPTHRESHOLD, // Minimum relevant power to exit Sleep Display (0.001=1uW),
// valid values are 0, 0.001, 0.01, 0.1, 1 and 10
DEFAULT_MODE // Set default Display Mode
};
//-----------------------------------------------------------------------------------------
// Instanciate an Encoder Object
Encoder Enc(EncI, EncQ);
//-----------------------------------------------------------------------------------------
// Timers for various tasks:
Metro pollMetro = Metro(POLL_TIMER);// Power/SWR calc and TFT LCD printout timer
Metro pushMetro = Metro(1); // 1 millisecond timer for Pushbutton management
Metro slowMetro = Metro(100); // 100 millisecond timer for various tasks
//-----------------------------------------------------------------------------------------
// initialize the LCD
LiquidCrystalFast lcd(LCD_RS, LCD_RW, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
//-----------------------------------------------------------------------------------------
// Instanciate a virtual LCD object for easier (flicker free) handling of the LCD
TextLCD VirtLCD; // A 20x4 Virtual Text LCD to LCD
//
//-----------------------------------------------------------------------------------------
// Forward & Reverse Voltage Measure and collect Function ( Interrupt driven )
//-----------------------------------------------------------------------------------------
//
void powerSampler(void)
{
#if INTR_LOOP_THRU_LED // Blink LED every time going through here
digitalWrite(X_Led,X_LedState ^= 1); // Set the LED
#endif
adc_poll_and_feed_circular(); // Read fwd and Rev AD, external or internal and feed circular buffer
#if INTR_LOOP_THRU_LED // Blink LED every time going through here
digitalWrite(X_Led,X_LedState ^= 1); // Reset the LED
#endif
}
//
//-----------------------------------------------------------------------------------------
// Top level task
// runs in an endless loop
//-----------------------------------------------------------------------------------------
//
void loop()
{
static uint8_t multi_button; // State of Multipurpose Enact Switch
// (Multipurpose pushbutton)
static uint8_t old_multi_button; // Last state of Multipurpose Enact Switch
static uint16_t power_timer; // Used to stay out of Screensaver
//-------------------------------------------------------------------------------
// Here we do routines which are to be run through as often as possible
//-------------------------------------------------------------------------------
#if FAST_LOOP_THRU_LED // Blink a LED every time
digitalWrite(X_Led,X_LedState ^= 1); // Blink a led
#endif
pswr_sync_from_interrupt(); // Read and process circular buffers containing adc input,
// calculate forward and reverse power, pep, pk and avg
//-------------------------------------------------------------------
// Green LED if power is detected
if (power_mw > R.idle_disp_thresh) digitalWrite(G_Led, 1);
else digitalWrite(G_Led, 0);
//-------------------------------------------------------------------
// Check USB Serial port for incoming commands
usb_read_serial();
//-------------------------------------------------------------------------------
// Here we do routines which are to be accessed once every POLL_TIMER milliseconds
//-------------------------------------------------------------------------------
// Poll timer.
if (pollMetro.check()) // check if the metro has passed its interval .
{
#if POLL_LOOP_THRU_LED // Blink LED every POLL_TIMER, when going through the main loop
digitalWrite(X_Led,X_LedState ^= 1); // Blink a led
#endif
//-------------------------------------------------------------------
// Prepare various types of power for print to LCD and calculate SWR
calc_SWR_and_power();
//----------------------------------------------
// Power Detected Flag and Timer
// Flag is set whenever power above a minimum
// relevant value is detected (see PSWR_A.h)
#if AD8307_INSTALLED
if ((power_mw > R.idle_disp_thresh) || flag.mode_display)
#else
if ((power_mw > MIN_PWR_FOR_METER) || flag.mode_display)
#endif
{
power_timer = 0;
flag.power_detected = true;
}
else if (power_timer < SLEEPTIME) power_timer++;
else flag.power_detected = false; // Activate screensaver if no power for a while
//-------------------------------------------------------------------
// Menu Exit announcement Timer
if (Menu_exit_timer == 1) VirtLCD.clear(); // Clear announcement before going live again
if (Menu_exit_timer > 0) Menu_exit_timer--;
//-------------------------------------------------------------------
// We are either entering or exiting Config Menu, need to clear up display
// or
// We just changed display modes, start/restart EEPROM save timer for new default display
if (flag.mode_change && !flag.mode_display)
{
flag.mode_change = false;
if (flag.config_mode) // Entering Config Menu
{
VirtLCD.clear();
}
}
//-------------------------------------------------------------------
// Various Menu (rotary encoder) selectable display/function modes
//
if (Menu_exit_timer == 0)
{
if (flag.config_mode) // Pushbutton Configuration Menu
{
ConfigMenu();
}
else if (mode_display == POWER_BARPK) // 100ms Peak Power, Bargraph, PWR, SWR, PEP
{
lcd_display_clean("100ms Peak Power", "Pk: ", power_mw_pk);
}
else if (mode_display == POWER_BARAVG) // 1s Average Power, Bargraph, PWR, SWR, PEP
{
lcd_display_clean("100ms Average Power", "Avg:", power_mw_avg);
}
else if (mode_display == POWER_BARAVG1S) // 1s Average Power, Bargraph, PWR, SWR, PEP
{
lcd_display_clean("1s Average Power", "Av1:", power_mw_1savg);
}
else if (mode_display == POWER_BARINST) // Instantaneous Power, Bargraph, PWR, SWR, PEP
{
lcd_display_clean("Instantaneous Power", " ", power_mw);
}
else if (mode_display == POWER_CLEAN_DBM) // Power Meter in dBm
{
lcd_display_clean_dBm();
}
else if (mode_display == POWER_MIXED) // Fwd, Reflected and SWR
{
lcd_display_mixed();
}
}
//----------------------------------------------
// Send text to Display
VirtLCD.transfer();
}
//-------------------------------------------------------------------------------
// Here we do timing related routines which are to be accessed once every millisecond
//-------------------------------------------------------------------------------
if (pushMetro.check()) // check if the metro has passed its interval
{
//-------------------------------------------------------------------------------
// Encoder and Pushbutton Management
//
multi_button = multipurpose_pushbutton();
if (old_multi_button != multi_button) // A new state of the Multi Purpose Pushbutton
{
if (multi_button == 1) // Short Push detected
{
flag.short_push = true; // Used with Configuraton Menu functions
}
else if ((multi_button == 2) && (flag.config_mode != true)) // Long Push detected
{
flag.config_mode = true; // Ask for Config Menu Mode
flag.mode_change = true; // Indicate that we need to set up for this mode
flag.mode_display = false;
}
}
old_multi_button = multi_button;
//-------------------------------------------------------------------
// Do stuff when not in Config Menu
if (!flag.config_mode)
{
if (flag.short_push) // Short push to clear SWR Alarm
{
flag.short_push = false;
digitalWrite(R_Led,false); // Clear SWR Alarm LED
flag.swr_alarm = false; // Clear SWR Alarm Flag
}
if (Enc.read()/ENC_RESDIVIDE != 0) // Encoder turned to cycle through modes
{
flag.mode_change = true; // Force Mode Intro Display whenever Mode has been changed
flag.mode_display = true;
flag.mode_newdefault = true; // Indicate that patience timer for a potential new
// default mode to be saved into EEPROM is running
// Mode switching travels only one click at a time, ignoring extra clicks
if (Enc.read()/ENC_RESDIVIDE > 0)
{
mode_display++;
if (mode_display > MAX_MODE) mode_display = 1;
Enc.write(0); // Reset data from Encoder
}
else if (Enc.read()/ENC_RESDIVIDE < 0)
{
mode_display--;
if (mode_display == 0) mode_display = MAX_MODE;
Enc.write(0); // Reset data from Encoder
}
}
}
}
//-------------------------------------------------------------------------------
// Here we do timing related routines which are to be accessed once every 1/10th of a second
//-------------------------------------------------------------------------------
if (slowMetro.check()) // check if the metro has passed its interval .
{
#if SLOW_LOOP_THRU_LED // Blink LED every 100ms, when going through the main loop
digitalWrite(X_Led,X_LedState ^= 1); // Blink a led
#endif
usb_cont_report(); // Report Power and SWR to USB, if in Continuous mode
//----------------------------------------------
// Patience timer for storing new Default Mode into EEPROM
if (flag.mode_newdefault)
{
static uint16_t newdefaulttimer;
if (newdefaulttimer++ == 100) // Store current screen as default if stable for 10 seconds
{
flag.mode_newdefault = false;
newdefaulttimer = 0;
if (R.mode_display != mode_display)
R.mode_display = mode_display;
EEPROM_writeAnything(1,R);
}
}
}
}
//
//-----------------------------------------------------------------------------------------
// Setup Ports, timers, start the works and never return, unless reset
// by the watchdog timer
// then - do everything, all over again
//-----------------------------------------------------------------------------------------
//
void setup()
{
uint8_t coldstart;
// Enable LEDs and set to LOW = Off
pinMode(R_Led, OUTPUT); // SWR Alarm
digitalWrite(R_Led, LOW);
pinMode(G_Led, OUTPUT); // Not used for now (previously used for USB traffic indication)
digitalWrite(G_Led, LOW);
pinMode(X_Led, OUTPUT); // Debug LED
digitalWrite(X_Led, LOW);
pinMode(EnactSW, INPUT_PULLUP); // Menu/Enact pushbutton switch
adc_init(); // Init Builtin ADCs
#if WIRE_ENABLED // I2C enabled in PSWR_A.h?
// Start I2C on port SDA0/SCL0 (pins 18/19) - 400 kHz
Wire.begin(I2C_MASTER,0x00,I2C_PINS_18_19,I2C_PULLUP_EXT,I2C_RATE_400);
uint8_t i2c_status = I2C_Init(); // Initialize I2C comms
#endif
coldstart = EEPROM.read(0); // Grab the coldstart byte indicator in EEPROM for
// comparison with the COLDSTART_REFERENCE
//
// Initialize all memories if first upload or if COLDSTART_REF has been modified
// either through PSWR_A.h or through Menu functions
if (coldstart != COLDSTART_REF)
{
EEPROM.write(0,COLDSTART_REF); // COLDSTART_REF in first byte indicates all initialized
EEPROM_writeAnything(1,R); // Write default settings into EEPROM
}
else // EEPROM contains stored data, retrieve the data
{
EEPROM_readAnything(1,R); // Read the stored data
}
Serial.begin(9600); // initialize USB virtual serial serial port
//------------------------------------------
// Initialize a 20x4 LCD
lcd.begin(20, 4);
lcd.noDisplay(); // The excessive initialize sequence below helps some OLED LCDs
lcd.clear();
lcd.leftToRight();
lcd.noAutoscroll();
lcd.noBlink();
lcd.noCursor();
lcd.display();
lcd.home();
lcd.createChar(0,0);
lcd_bargraph_Init(); // Initialize LCD Bargraph
//------------------------------------------
// LCD Print Version and I2C information (6 seconds in total during startup)
lcd.setCursor(0,0);
lcd.print(F(STARTUPDISPLAY1));
lcd.setCursor(0,1);
lcd.print(F(STARTUPDISPLAY2));
delay(300);
lcd.setCursor(20-strlen(STARTUPDISPLAY3),1);
lcd.print(STARTUPDISPLAY3);
delay(200);
lcd.setCursor(20-strlen(STARTUPDISPLAY4),2);
lcd.print(STARTUPDISPLAY4);
delay(2500);
lcd.setCursor(0,3);
lcd.print(F(STARTUPDISPLAY5));
sprintf(lcd_buf,"V%s", VERSION);
lcd.setCursor(20-strlen(lcd_buf),3);
lcd.print(lcd_buf);
delay(2000);
#if WIRE_ENABLED // I2C scan report
lcd.setCursor(0,3);
if (i2c_status==1) lcd.print(F("AD7991-0 detected "));
else if (i2c_status==2) lcd.print(F("AD7991-1 detected "));
else lcd.print(F("Using built-in A/D "));
delay(1000);
#endif
mode_display = R.mode_display; // Active Display Mode
flag.mode_change = true; // Force a Display of Mode Intro when starting up
flag.mode_display = true;
lcd.clear();
VirtLCD.init(); // Prep for going live: init and clear the Virtual LCD
VirtLCD.clear();
Timer1.initialize(SAMPLE_TIMER); // Init the adc sample timer interrupt function
Timer1.attachInterrupt(powerSampler); // Start the works
}