2018-11-25 20:07:34 +00:00
2018-11-25 20:11:22 +00:00
// Tracker for LoRA APRS
2018-11-25 20:07:34 +00:00
//
// TTGO T-Beam includes GPS module + optional DHT22 (not yet DONE)
//
// can be used as tracker only, tracker plus weather reports (temperature and humidity) or weather reports station only
//
// updated from OE1ACM sketch by OE3CJB to enable WX data to be sent via LoRa APRS.
// one package is with position and battery voltage
// the next is with weather data in APRS format
//
// licensed under CC BY-NC-SA
//
2020-08-27 19:41:54 +00:00
// version: V1.3
// last update: 27.08.2020
// change history
// symbol RV added
// compressed packets in tracker mode (base91)
//
2020-01-02 19:13:30 +00:00
// version: V1.2
// last update: 02.01.2020
2019-11-22 13:22:31 +00:00
// change history
2020-01-02 19:13:30 +00:00
// added course change to smart Beaconing
// code cleaned
// change of mode with KEY (without display but with LED only)
// change of symbol with KEY (without display but with LED only)
//
// version V1.1
2019-11-22 13:22:31 +00:00
// added HW Version V1.0 support
// added presetting in the header TTGO...config.h to prevent long initial setup at first boot up
// added "SPACE" to allowed letters for callsign for shorter callsigns - has to be added at the end
// added smart beaconing
//
// version V1.0beta
// first released version//
2018-11-25 20:07:34 +00:00
2020-04-19 15:52:27 +00:00
// #define DEBUG // used for debugging purposes , e.g. turning on special serial or display logging
2018-12-01 11:27:58 +00:00
// Includes
2018-11-25 20:07:34 +00:00
2018-12-01 20:31:34 +00:00
# include <TTGO_T-Beam_LoRa_APRS_config.h> // to config user parameters
2018-12-01 11:27:58 +00:00
# include <Arduino.h>
2018-12-06 06:47:42 +00:00
# include <Preferences.h>
2018-12-01 11:27:58 +00:00
# include <Adafruit_Sensor.h>
# include <SPI.h>
2018-12-01 20:31:34 +00:00
# include <BG_RF95.h> // library from OE1ACM
2018-11-25 20:07:34 +00:00
2018-12-01 11:27:58 +00:00
# include <TinyGPS++.h>
# include <math.h>
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
# include <OneWire.h> // libraries for DS18B20
# include <DallasTemperature.h>
# else
# include <DHTesp.h> // library from https://github.com/beegee-tokyo/DHTesp for DHT22
# endif
2018-12-01 11:27:58 +00:00
# include <driver/adc.h>
# include <Wire.h>
2018-11-25 20:07:34 +00:00
2018-12-01 11:27:58 +00:00
# include <Adafruit_SSD1306.h>
# include <splash.h>
# include <Adafruit_GFX.h>
# include <Adafruit_SPITFT.h>
# include <Adafruit_SPITFT_Macros.h>
# include <gfxfont.h>
2019-11-29 17:44:22 +00:00
# include <axp20x.h>
2019-11-22 13:22:31 +00:00
2020-01-02 19:13:30 +00:00
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//PINs used for HW extensions
// Pin for battery voltage -> bei T-Beam ADC1_CHANNEL_7
// #define ANALOG_PIN_0 35 // connected to battery
// I2C LINES
# define I2C_SDA 21
# define I2C_SCL 22
// DISPLAY address
# define SSD1306_ADDRESS 0x3C
// AXP192 address
2020-02-02 15:58:19 +00:00
// #define AXP192_SLAVE_ADDRESS 0x34 // already defined in axp20x.h
2018-11-25 20:07:34 +00:00
/* for feather32u4
# define RFM95_CS 8
# define RFM95_RST 4
# define RFM95_INT 7
*/
2020-01-02 19:13:30 +00:00
// Variables for DHT22 temperature and humidity sensor
2018-11-25 20:07:34 +00:00
int chk ;
2018-12-01 20:31:34 +00:00
boolean hum_temp = false ;
2018-12-09 21:23:20 +00:00
float hum = 0 ; //Stores humidity value
float temp = 99.99 ; //Stores temperature value
float tempf = 99.99 ; //Stores temperature value
2018-11-25 20:07:34 +00:00
//other global Variables
String Textzeile1 , Textzeile2 ;
2018-12-06 06:47:42 +00:00
int button = 0 ;
int button_ctr = 0 ;
2020-01-02 19:13:30 +00:00
// int version=0; // 0 = V0.7, 1 = V1.0
// bool ssd1306_found = false;
// bool axp192_found = false;
2018-12-06 06:47:42 +00:00
enum Tx_Mode { TRACKER , WX_TRACKER , WX_MOVE , WX_FIXED } ;
// Position from GPS for TRACKER and WX_TRACKER
// Position for WX_ONLY from Headerfile!!!
Tx_Mode tracker_mode ;
2018-11-25 20:07:34 +00:00
// Pins for GPS
2019-11-22 13:22:31 +00:00
# ifdef T_BEAM_V1_0
static const int RXPin = 12 , TXPin = 34 ; // changed BG A3 A2
# else
static const int RXPin = 15 , TXPin = 12 ; // changed BG A3 A2
# endif
2018-11-25 20:07:34 +00:00
static const uint32_t GPSBaud = 9600 ; //GPS
const byte TX_en = 0 ;
const byte RX_en = 0 ; //TX/RX enable 1W modul
2019-11-22 13:22:31 +00:00
// LED for signalling
# ifdef T_BEAM_V1_0
const byte TXLED = 33 ; //pin number for LED on TX Tracker
# else
const byte TXLED = 14 ; //pin number for LED on TX Tracker
# endif
// Button of TTGO T-Beam
# ifdef T_BEAM_V1_0
2020-01-02 19:13:30 +00:00
// const byte BUTTON = 38; //pin number for Button on TTGO T-Beam
# define BUTTON 38 //pin number for Button on TTGO T-Beam
2019-11-22 13:22:31 +00:00
# else
2020-01-02 19:13:30 +00:00
# define BUTTON 39 //pin number for Button on TTGO T-Beam
2019-11-22 13:22:31 +00:00
# endif
2018-11-25 20:07:34 +00:00
// const byte GPSLED = 6; // pin gps & Heartbeat
// const byte GPSLED1 = 9; // pin gps & Heartbeat
// Pins for LoRa module
2019-11-22 13:22:31 +00:00
//#ifdef T_BEAM_V1_0
// const byte lora_PReset = 14; //pin where LoRa device reset line is connected
// const byte lora_PNSS = 18; //pin number where the NSS line for the LoRa device is connected.
//#else
const byte lora_PReset = 23 ; //pin where LoRa device reset line is connected
const byte lora_PNSS = 18 ; //pin number where the NSS line for the LoRa device is connected.
//#endif
2018-11-25 20:07:34 +00:00
// pin 11 MOSI
// pin 12 MISO
// pin 13 SCLK
// #define ModemConfig BG_RF95::Bw125Cr45Sf4096
2020-01-31 13:04:08 +00:00
# define DHTPIN 25 // the DHT22 is connected to PIN25
# define ONE_WIRE_BUS 25 // the DS18B20 is connected to PIN25
2019-11-22 13:22:31 +00:00
// Variables for APRS packaging
String Tcall ; //your Call Sign for normal position reports
String wxTcall ; //your Call Sign for weather reports
String sTable = " / " ; //Primer
String wxTable = " / " ; //Primer
String wxSymbol = " _ " ; //Symbol Code Weather Station
// Tracker setting: use these lines to modify the tracker behaviour
# define TXFREQ 433.775 // Transmit frequency in MHz
# define TXdbmW 18 // Transmit power in dBm
# define TXenablePA 0 // switch internal power amplifier on (1) or off (0)
2018-11-25 20:07:34 +00:00
// Variables and Constants
2018-12-06 06:47:42 +00:00
Preferences prefs ;
2018-11-25 20:07:34 +00:00
String InputString = " " ; //data on buff is copied to this string
String Outputstring = " " ;
String outString = " " ; //The new Output String with GPS Conversion RAW
2018-12-09 21:23:20 +00:00
String LongShown = " " ;
String LatShown = " " ;
2018-12-24 14:29:36 +00:00
String LongFixed = " " ;
String LatFixed = " " ;
String TxSymbol = " " ;
2018-12-06 06:47:42 +00:00
boolean wx ;
2018-11-25 20:07:34 +00:00
//byte arrays
byte lora_TXBUFF [ 128 ] ; //buffer for packet to send
2020-02-02 20:40:08 +00:00
byte lora_RXBUFF [ 128 ] ; //buffer for packet to send
2018-11-25 20:07:34 +00:00
//byte Variables
byte lora_TXStart ; //start of packet data in TXbuff
byte lora_TXEnd ; //end of packet data in TXbuff
byte lora_FTXOK ; //flag, set to 1 if TX OK
byte lora_TXPacketType ; //type number of packet to send
byte lora_TXDestination ; //destination address of packet to send
byte lora_TXSource ; //source address of packet received
byte lora_FDeviceError ; //flag, set to 1 if RFM98 device error
byte lora_TXPacketL ; //length of packet to send, includes source, destination and packet type.
unsigned long lastTX = 0L ;
2018-12-01 11:27:58 +00:00
float BattVolts ;
2018-11-25 20:07:34 +00:00
2019-11-22 13:22:31 +00:00
// variables for smart beaconing
2020-01-02 19:13:30 +00:00
float average_speed [ 5 ] = { 0 , 0 , 0 , 0 , 0 } , average_speed_final = 0 , max_speed = 30 , min_speed = 0 ;
float old_course = 0 , new_course = 0 ;
2020-01-05 17:12:52 +00:00
int point_avg_speed = 0 , point_avg_course = 0 ;
2019-11-22 13:22:31 +00:00
ulong min_time_to_nextTX = 60000L ; // minimum time period between TX = 60000ms = 60secs = 1min
ulong nextTX = 60000L ; // preset time period between TX = 60000ms = 60secs = 1min
2020-05-03 20:40:45 +00:00
# define ANGLE 60 // angle to send packet at smart beaconing
2020-04-19 15:52:27 +00:00
# define ANGLE_AVGS 3 // angle averaging - x times
float average_course [ ANGLE_AVGS ] ;
float avg_c_y , avg_c_x ;
# ifdef DEBUG
// debug Variables
String TxRoot = " 0 " ;
float millis_angle [ ANGLE_AVGS ] ;
# endif
2019-11-22 13:22:31 +00:00
2020-08-30 10:42:15 +00:00
# define TX_BASE91 // if BASE91 is set, packets will be sent compressed (in TRACKER-mode only)
2018-12-01 11:27:58 +00:00
static const adc_atten_t atten = ADC_ATTEN_DB_6 ;
static const adc_unit_t unit = ADC_UNIT_1 ;
2018-11-25 20:07:34 +00:00
static void smartDelay ( unsigned long ) ;
void recalcGPS ( void ) ;
void sendpacket ( void ) ;
void loraSend ( byte , byte , byte , byte , byte , long , byte , float ) ;
void batt_read ( void ) ;
2018-12-06 06:47:42 +00:00
void writedisplaytext ( String , String , String , String , String , String , int ) ;
2018-12-09 21:23:20 +00:00
void setup_data ( void ) ;
2018-11-25 20:07:34 +00:00
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
OneWire oneWire ( ONE_WIRE_BUS ) ;
DallasTemperature sensors ( & oneWire ) ;
# else
DHTesp dht ; // Initialize DHT sensor for normal 16mhz Arduino
# endif
2018-11-25 20:07:34 +00:00
// SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device
HardwareSerial ss ( 1 ) ; // TTGO has HW serial
TinyGPSPlus gps ; // The TinyGPS++ object
2019-11-22 13:22:31 +00:00
# ifdef T_BEAM_V1_0
AXP20X_Class axp ;
# endif
2018-11-25 20:07:34 +00:00
// checkRX
uint8_t buf [ BG_RF95_MAX_MESSAGE_LEN ] ;
uint8_t len = sizeof ( buf ) ;
// Singleton instance of the radio driver
BG_RF95 rf95 ( 18 , 26 ) ; // TTGO T-Beam has NSS @ Pin 18 and Interrupt IO @ Pin26
// initialize OLED display
# define OLED_RESET 4 // not used
Adafruit_SSD1306 display ( 128 , 64 , & Wire , OLED_RESET ) ;
2020-01-02 19:13:30 +00:00
// +---------------------------------------------------------------------+//
// + SETUP --------------------------------------------------------------+//
// +---------------------------------------------------------------------+//
2018-11-25 20:07:34 +00:00
void setup ( )
{
2020-04-19 15:52:27 +00:00
for ( int i = 0 ; i < ANGLE_AVGS ; i + + ) { average_course [ i ] = 0 ; } // set average_course to "0"
2018-12-06 06:47:42 +00:00
prefs . begin ( " nvs " , false ) ;
tracker_mode = ( Tx_Mode ) prefs . getChar ( " tracker_mode " , 0 ) ;
prefs . end ( ) ;
//tracker_mode = current_mode;
/////////////////
// hier muss aus dem RAM der Modus gelesen werden!
/////////////////
if ( tracker_mode = = WX_TRACKER ) {
wx = true ;
} else {
wx = false ;
}
2018-11-25 20:07:34 +00:00
2020-04-19 15:52:27 +00:00
tracker_mode = TRACKER ;
2018-11-25 20:07:34 +00:00
pinMode ( TXLED , OUTPUT ) ;
2018-12-06 06:47:42 +00:00
pinMode ( BUTTON , INPUT ) ;
2018-12-01 20:10:13 +00:00
digitalWrite ( TXLED , LOW ) ; // turn blue LED off
2018-11-25 20:07:34 +00:00
Serial . begin ( 115200 ) ;
2019-11-22 13:22:31 +00:00
2020-01-02 19:13:30 +00:00
Wire . begin ( I2C_SDA , I2C_SCL ) ;
2019-11-22 13:22:31 +00:00
# ifdef T_BEAM_V1_0 // initialize power controller - new on HW V1.0
if ( ! axp . begin ( Wire , AXP192_SLAVE_ADDRESS ) ) {
2020-01-02 19:13:30 +00:00
Serial . println ( " LoRa-APRS / Init / AXP192 Begin PASS " ) ;
2019-11-22 13:22:31 +00:00
} else {
2020-01-02 19:13:30 +00:00
Serial . println ( " LoRa-APRS / Init / AXP192 Begin FAIL " ) ;
2019-11-22 13:22:31 +00:00
}
axp . setPowerOutPut ( AXP192_LDO2 , AXP202_ON ) ;
2020-01-30 15:15:56 +00:00
if ( tracker_mode ! = WX_FIXED ) {
axp . setPowerOutPut ( AXP192_LDO3 , AXP202_ON ) ; // switch on GPS in all modes except WX_FIXED
} else {
axp . setPowerOutPut ( AXP192_LDO3 , AXP202_OFF ) ; // switch off GPS in WX_FIXED mode
}
2019-11-22 13:22:31 +00:00
axp . setPowerOutPut ( AXP192_DCDC2 , AXP202_ON ) ;
axp . setPowerOutPut ( AXP192_EXTEN , AXP202_ON ) ;
axp . setPowerOutPut ( AXP192_DCDC1 , AXP202_ON ) ;
axp . setDCDC1Voltage ( 3300 ) ;
# endif
2020-01-02 19:13:30 +00:00
if ( ! display . begin ( SSD1306_SWITCHCAPVCC , SSD1306_ADDRESS ) ) {
2018-11-25 20:07:34 +00:00
for ( ; ; ) ; // Don't proceed, loop forever
}
2020-01-02 19:13:30 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " Display OK! " , " " , " PRESS 3sec for config " , 1000 ) ;
Serial . println ( " LoRa-APRS / Init / Display OK! / PRESS 3sec for config " ) ;
2018-12-06 06:47:42 +00:00
2020-01-02 19:13:30 +00:00
# ifndef DONT_USE_FLASH_MEMORY
2018-12-09 21:23:20 +00:00
//////////////////////////// Setup CALLSIGN
prefs . begin ( " nvs " , false ) ;
2019-11-22 13:22:31 +00:00
Tcall = prefs . getString ( " Tcall " , CALLSIGN ) ;
wxTcall = prefs . getString ( " wxTcall " , WX_CALLSIGN ) ;
LongFixed = prefs . getString ( " LongFixed " , LONGITUDE_PRESET ) ;
LatFixed = prefs . getString ( " LatFixed " , LATIDUDE_PRESET ) ;
TxSymbol = prefs . getString ( " TxSymbol " , APRS_SYMBOL ) ;
2018-12-09 21:23:20 +00:00
prefs . end ( ) ;
2020-01-02 19:13:30 +00:00
# else
Tcall = CALLSIGN ;
wxTcall = WX_CALLSIGN ;
LongFixed = LONGITUDE_PRESET ;
LatFixed = LATIDUDE_PRESET ;
TxSymbol = APRS_SYMBOL ;
# endif
Serial . println ( " LoRa-APRS / Call= " + Tcall + " / WX-Call= " + wxTcall + " / TxSymbol= " + TxSymbol ) ;
2018-12-09 21:23:20 +00:00
int start_button_pressed = millis ( ) ;
2020-01-02 19:13:30 +00:00
# ifndef DONT_USE_FLASH_MEMORY
2018-12-09 21:23:20 +00:00
while ( ( digitalRead ( BUTTON ) = = LOW ) & & ( millis ( ) < start_button_pressed + 3000 ) ) {
}
2020-01-02 19:13:30 +00:00
2019-11-22 13:22:31 +00:00
if ( ( digitalRead ( BUTTON ) = = LOW ) | | ( Tcall = = " OE1XYZ-0 " ) ) { // into setup when no real data entered in TTGO...config.h
2020-01-02 19:13:30 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " " , " Entering Setup! " , " " , " " , 2000 ) ;
2018-12-09 21:23:20 +00:00
setup_data ( ) ;
}
2020-01-02 19:13:30 +00:00
# endif
2018-12-09 21:23:20 +00:00
2018-12-06 06:47:42 +00:00
switch ( tracker_mode ) {
case TRACKER :
2018-12-06 07:26:17 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " Mode " , " TRACKER " , " " , 1000 ) ;
2020-01-02 19:13:30 +00:00
Serial . println ( " LoRa-APRS / Init / Mode / TRACKER " ) ;
blinker ( 1 ) ;
break ;
case WX_TRACKER :
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " Mode " , " WX&TRACKER " , " " , 1000 ) ;
Serial . println ( " LoRa-APRS / Init / Mode / WX & TRACKER " ) ;
blinker ( 2 ) ;
2018-12-06 06:47:42 +00:00
break ;
case WX_MOVE :
2018-12-06 07:26:17 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " Mode " , " WX_MOVE " , " " , 1000 ) ;
2020-01-02 19:13:30 +00:00
Serial . println ( " LoRa-APRS / Init / Mode / WX only - moving " ) ;
blinker ( 3 ) ;
2018-12-06 06:47:42 +00:00
break ;
case WX_FIXED :
2018-12-06 07:26:17 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " Mode " , " WX_FIXED " , " (no GPS used) " , 1000 ) ;
2020-01-02 19:13:30 +00:00
Serial . println ( " LoRa-APRS / Init / Mode / WX only - fixed Pos (no GPS used) " ) ;
blinker ( 4 ) ;
2018-12-06 06:47:42 +00:00
break ;
default :
2018-12-06 07:26:17 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " Mode " , " UNKNOWN " , " STOPPED " , 1000 ) ;
2020-01-02 19:13:30 +00:00
Serial . println ( " LoRa-APRS / Init / Mode / UNKNOWN STOPPED!!!! " ) ;
while ( true ) {
blinker ( 1 ) ;
}
2018-12-06 06:47:42 +00:00
break ;
}
if ( ! rf95 . init ( ) ) {
2018-11-25 20:07:34 +00:00
2018-12-09 21:23:20 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " RF95 FAILED! " , " :-( " , " " , 250 ) ;
2020-01-02 19:13:30 +00:00
Serial . println ( " LoRa-APRS / Init / RF95 FAILED! " ) ;
2018-11-25 20:07:34 +00:00
for ( ; ; ) ; // Don't proceed, loop forever
}
2019-11-22 13:22:31 +00:00
if ( max_time_to_nextTX < nextTX ) { max_time_to_nextTX = nextTX ; }
2020-01-02 19:13:30 +00:00
// digitalWrite(TXLED, HIGH);
2018-12-09 21:23:20 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " RF95 OK! " , " " , " " , 250 ) ;
2020-01-02 19:13:30 +00:00
// digitalWrite(TXLED, LOW);
Serial . println ( " LoRa-APRS / Init / RF95 OK! " ) ;
2018-11-25 20:07:34 +00:00
2018-12-06 06:47:42 +00:00
if ( tracker_mode ! = WX_FIXED ) {
2019-11-22 13:22:31 +00:00
ss . begin ( GPSBaud , SERIAL_8N1 , TXPin , RXPin ) ; //Startup HW serial for GPS
2020-01-02 19:13:30 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " GPS Serial OK! " , " " , " " , 250 ) ;
Serial . println ( " LoRa-APRS / Init / GPS Serial OK! " ) ;
writedisplaytext ( " " + Tcall , " " , " Init: " , " Waiting for GPS " , " " , " " , 250 ) ;
Serial . println ( " LoRa-APRS / Init / Waiting for GPS " ) ;
while ( millis ( ) < 5000 & & gps . charsProcessed ( ) < 10 ) { }
if ( millis ( ) > 5000 & & gps . charsProcessed ( ) < 10 ) {
writedisplaytext ( " " + Tcall , " " , " Init: " , " ERROR! " , " No GPS data! " , " Please restart TTGO " , 0 ) ;
Serial . println ( " LoRa-APRS / Init / GPS ERROR - no GPS data - please RESTART TTGO " ) ;
while ( true ) { blinker ( 1 ) ; }
}
writedisplaytext ( " " + Tcall , " " , " Init: " , " Data from GPS OK! " , " " , " " , 250 ) ;
Serial . println ( " LoRa-APRS / Init / Data from GPS OK! " ) ;
2020-01-30 15:15:56 +00:00
} else {
writedisplaytext ( " " + Tcall , " " , " Init: " , " GPS switched OFF! " , " " , " " , 250 ) ;
Serial . println ( " LoRa-APRS / Init / GPS switched OFF! " ) ;
2018-12-06 06:47:42 +00:00
}
2018-11-25 20:07:34 +00:00
2020-01-02 19:13:30 +00:00
# ifdef T_BEAM_V1_0
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " ADC OK! " , " BAT: " + String ( axp . getBattVoltage ( ) / 1000 , 1 ) , " " , 250 ) ;
Serial . print ( " LoRa-APRS / Init / ADC OK! / BAT: " ) ;
Serial . println ( String ( axp . getBattVoltage ( ) / 1000 , 1 ) ) ;
# else
adc1_config_width ( ADC_WIDTH_BIT_12 ) ;
adc1_config_channel_atten ( ADC1_CHANNEL_7 , ADC_ATTEN_DB_6 ) ;
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " ADC OK! " , " BAT: " + String ( analogRead ( 35 ) * 7.221 / 4096 , 1 ) , " " , 250 ) ;
Serial . print ( " LoRa-APRS / Init / ADC OK! / BAT: " ) ;
Serial . println ( String ( analogRead ( 35 ) * 7.221 / 4096 , 1 ) ) ;
# endif
2018-11-25 20:07:34 +00:00
rf95 . setFrequency ( 433.775 ) ;
rf95 . setModemConfig ( BG_RF95 : : Bw125Cr45Sf4096 ) ; // hard coded because of double definition
rf95 . setTxPower ( 5 ) ;
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
sensors . begin ( ) ;
# else
dht . setup ( DHTPIN , dht . AUTO_DETECT ) ; // initialize DHT22
# endif
2018-12-01 20:10:13 +00:00
delay ( 250 ) ;
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
sensors . requestTemperatures ( ) ; // Send the command to get temperature readings
temp = sensors . getTempCByIndex ( 0 ) ; // get temp from 1st (!) sensor only
# else
temp = dht . getTemperature ( ) ;
hum = dht . getHumidity ( ) ;
# endif
2018-12-09 21:23:20 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " DHT OK! " , " TEMP: " + String ( temp , 1 ) , " HUM: " + String ( hum , 1 ) , 250 ) ;
2020-01-02 19:13:30 +00:00
Serial . print ( " LoRa-APRS / Init / DHT OK! Temp= " ) ;
2018-12-01 20:31:34 +00:00
Serial . print ( String ( temp ) ) ;
Serial . print ( " Hum= " ) ;
Serial . println ( String ( hum ) ) ;
2020-01-02 19:13:30 +00:00
writedisplaytext ( " LoRa-APRS " , " " , " Init: " , " FINISHED OK! " , " =:-) " , " " , 250 ) ;
Serial . println ( " LoRa-APRS / Init / FINISHED OK! / =:-) " ) ;
2018-12-06 06:47:42 +00:00
writedisplaytext ( " " , " " , " " , " " , " " , " " , 0 ) ;
2018-11-25 20:07:34 +00:00
}
2020-01-02 19:13:30 +00:00
// +---------------------------------------------------------------------+//
// + MAINLOOP -----------------------------------------------------------+//
// +---------------------------------------------------------------------+//
void loop ( ) {
if ( digitalRead ( BUTTON ) = = LOW ) {
+ + button_ctr ;
2020-02-02 20:40:08 +00:00
if ( button_ctr > = 5 ) {
2020-01-02 19:13:30 +00:00
switch ( tracker_mode ) {
case TRACKER :
tracker_mode = WX_TRACKER ;
writedisplaytext ( " LoRa-APRS " , " " , " New Mode " , " WX-TRACKER " , " " , " " , 500 ) ;
Serial . println ( " LoRa-APRS / New Mode / WX-TRACKER " ) ;
blinker ( 2 ) ;
break ;
case WX_TRACKER :
tracker_mode = WX_MOVE ;
writedisplaytext ( " LoRa-APRS " , " " , " New Mode " , " WX-MOVING " , " " , " " , 500 ) ;
Serial . println ( " LoRa-APRS / New Mode / WX-MOVING " ) ;
blinker ( 3 ) ;
break ;
case WX_MOVE :
tracker_mode = WX_FIXED ;
writedisplaytext ( " LoRa-APRS " , " " , " New Mode " , " WX-FIXED " , " " , " " , 500 ) ;
Serial . println ( " LoRa-APRS / New Mode / WX-FIXED " ) ;
2020-01-30 15:15:56 +00:00
# ifdef T_BEAM_V1_0
axp . setPowerOutPut ( AXP192_LDO3 , AXP202_OFF ) ; // switch OFF GPS at mode WX_FIXED
# endif
2020-01-02 19:13:30 +00:00
blinker ( 4 ) ;
break ;
case WX_FIXED :
default :
tracker_mode = TRACKER ;
writedisplaytext ( " LoRa-APRS " , " " , " New Mode " , " TRACKER " , " " , " " , 500 ) ;
Serial . println ( " LoRa-APRS / New Mode / TRACKER " ) ;
2020-01-30 15:15:56 +00:00
# ifdef T_BEAM_V1_0
axp . setPowerOutPut ( AXP192_LDO3 , AXP202_ON ) ; // switch on GPS in all modes except WX_FIXED
# endif
2020-01-02 19:13:30 +00:00
blinker ( 1 ) ;
break ;
}
prefs . begin ( " nvs " , false ) ;
prefs . putChar ( " tracker_mode " , ( char ) tracker_mode ) ;
prefs . end ( ) ;
button_ctr = 0 ;
2020-01-30 15:15:56 +00:00
// ESP.restart();
2020-01-02 19:13:30 +00:00
}
} else {
button_ctr = 0 ;
}
2020-02-02 20:40:08 +00:00
if ( hum_temp ) {
2020-01-02 19:13:30 +00:00
hum_temp = false ;
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
sensors . requestTemperatures ( ) ; // Send the command to get temperature readings
temp = sensors . getTempCByIndex ( 0 ) ; // get temp from 1st (!) sensor only
# else
temp = dht . getTemperature ( ) ;
# endif
2020-01-02 19:13:30 +00:00
} else {
hum_temp = true ;
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
hum = 0 ;
# else
hum = dht . getHumidity ( ) ;
# endif
2020-01-02 19:13:30 +00:00
}
2018-11-25 20:07:34 +00:00
2020-01-30 15:15:56 +00:00
if ( tracker_mode ! = WX_FIXED ) {
while ( ss . available ( ) > 0 ) {
gps . encode ( ss . read ( ) ) ;
}
2020-01-02 19:13:30 +00:00
}
2018-11-25 20:07:34 +00:00
2020-01-02 19:13:30 +00:00
if ( rf95 . waitAvailableTimeout ( 100 ) ) {
2020-02-19 10:30:00 +00:00
# ifdef SHOW_RX_PACKET // only show RX packets when activitated in config
2020-02-02 20:40:08 +00:00
if ( rf95 . recvAPRS ( lora_RXBUFF , & len ) ) {
Serial . print ( " ((RX)): " ) ;
InputString = " " ;
for ( int i = 0 ; i < len ; i + + ) {
InputString + = ( char ) lora_RXBUFF [ i ] ;
}
Serial . println ( InputString ) ;
2020-02-02 20:46:54 +00:00
blinker ( 3 ) ;
2020-02-19 10:30:00 +00:00
writedisplaytext ( " ((RX)) " , " " , InputString , " " , " " , " " , SHOW_RX_TIME ) ;
2018-12-06 06:47:42 +00:00
}
2020-02-19 10:30:00 +00:00
# endif
2018-12-06 06:47:42 +00:00
}
2018-12-01 20:10:13 +00:00
2020-01-02 19:13:30 +00:00
if ( tracker_mode ! = WX_FIXED ) {
LatShown = String ( gps . location . lat ( ) , 5 ) ;
LongShown = String ( gps . location . lng ( ) , 5 ) ;
2019-11-29 17:44:22 +00:00
2020-01-02 19:13:30 +00:00
average_speed [ point_avg_speed ] = gps . speed . kmph ( ) ; // calculate smart beaconing
+ + point_avg_speed ;
if ( point_avg_speed > 4 ) { point_avg_speed = 0 ; }
average_speed_final = ( average_speed [ 0 ] + average_speed [ 1 ] + average_speed [ 2 ] + average_speed [ 3 ] + average_speed [ 4 ] ) / 5 ;
nextTX = ( max_time_to_nextTX - min_time_to_nextTX ) / ( max_speed - min_speed ) * ( max_speed - average_speed_final ) + min_time_to_nextTX ;
2020-04-19 15:52:27 +00:00
# ifdef DEBUG
TxRoot = " S " ;
# endif
2018-11-25 20:07:34 +00:00
2020-01-02 19:13:30 +00:00
if ( nextTX < min_time_to_nextTX ) { nextTX = min_time_to_nextTX ; }
if ( nextTX > max_time_to_nextTX ) { nextTX = max_time_to_nextTX ; }
2020-01-30 15:15:56 +00:00
average_course [ point_avg_course ] = gps . course . deg ( ) ; // calculate smart beaconing course
2020-04-19 15:52:27 +00:00
# ifdef DEBUG
millis_angle [ point_avg_course ] = millis ( ) ;
# endif
2020-01-30 15:15:56 +00:00
+ + point_avg_course ;
2020-04-19 15:52:27 +00:00
if ( point_avg_course > ( ANGLE_AVGS - 1 ) ) {
2020-01-30 15:15:56 +00:00
point_avg_course = 0 ;
2020-04-19 15:52:27 +00:00
avg_c_y = 0 ;
avg_c_x = 0 ;
for ( int i = 0 ; i < ANGLE_AVGS ; i + + ) {
avg_c_y + = sin ( average_course [ i ] / 180 * 3.1415 ) ;
avg_c_x + = cos ( average_course [ i ] / 180 * 3.1415 ) ;
}
new_course = atan2f ( avg_c_y , avg_c_x ) * 180 / 3.1415 ;
if ( new_course < 0 ) { new_course = 360 + new_course ; }
if ( ( old_course < ANGLE ) & & ( new_course > ( 360 - ANGLE ) ) ) {
if ( abs ( new_course - old_course - 360 ) > = ANGLE ) {
2020-02-02 12:45:19 +00:00
nextTX = 0 ;
2020-04-19 15:52:27 +00:00
// lastTX = min_time_to_nextTX
# ifdef DEBUG
TxRoot = " W1 " ;
for ( int i = 0 ; i < 2 ; i + + )
{
// TxRoot += " c:" + String(average_course[i]) + " t:" + String(millis_angle[i]);
TxRoot + = " " + String ( millis_angle [ i ] , 2 ) ;
}
TxRoot = TxRoot + " new: " + String ( new_course ) + " old: " + String ( old_course ) ;
# endif
2020-02-02 12:45:19 +00:00
}
} else {
2020-04-19 15:52:27 +00:00
if ( ( old_course > ( 360 - ANGLE ) ) & & ( new_course < ANGLE ) ) {
if ( abs ( new_course - old_course + 360 ) > = ANGLE ) {
2020-02-02 12:45:19 +00:00
nextTX = 0 ;
2020-04-19 15:52:27 +00:00
# ifdef DEBUG
TxRoot = " W2 " ;
for ( int i = 0 ; i < 2 ; i + + )
{
// TxRoot += " c:" + String(average_course[i]) + " t:" + String(millis_angle[i]);
TxRoot + = " " + String ( millis_angle [ i ] , 2 ) ;
}
TxRoot = TxRoot + " new: " + String ( new_course ) + " old: " + String ( old_course ) ;
# endif
2020-02-02 12:45:19 +00:00
}
} else {
2020-04-19 15:52:27 +00:00
if ( abs ( new_course - old_course ) > = ANGLE ) {
2020-02-02 12:45:19 +00:00
nextTX = 0 ;
2020-04-19 15:52:27 +00:00
# ifdef DEBUG
TxRoot = " W3 " ;
for ( int i = 0 ; i < 2 ; i + + )
{
// TxRoot += " c:" + String(average_course[i]) + " t:" + String(millis_angle[i]);
TxRoot + = " " + String ( millis_angle [ i ] , 2 ) ;
}
TxRoot = TxRoot + " new: " + String ( new_course ) + " old: " + String ( old_course ) ;
# endif
2020-02-02 12:45:19 +00:00
}
}
2020-01-30 15:15:56 +00:00
}
old_course = new_course ;
}
2020-01-02 19:13:30 +00:00
} else {
LatShown = LatFixed ;
LongShown = LongFixed ;
2020-01-16 20:01:13 +00:00
nextTX = max_time_to_nextTX ;
2018-11-25 20:07:34 +00:00
}
2019-11-22 13:22:31 +00:00
2020-01-02 19:13:30 +00:00
batt_read ( ) ;
2019-11-22 13:22:31 +00:00
2020-01-02 19:13:30 +00:00
if ( button_ctr = = 2 ) {
nextTX = 0 ;
2020-04-19 15:52:27 +00:00
# ifdef DEBUG
TxRoot = " B " ;
# endif
2020-01-02 19:13:30 +00:00
}
2019-11-22 13:22:31 +00:00
2020-01-02 19:13:30 +00:00
if ( ( millis ( ) < max_time_to_nextTX ) & & ( lastTX = = 0 ) ) {
nextTX = 0 ;
2020-04-19 15:52:27 +00:00
# ifdef DEBUG
TxRoot = " 1 " ;
# endif
2020-01-02 19:13:30 +00:00
}
2018-11-25 20:07:34 +00:00
2020-01-02 19:13:30 +00:00
if ( ( lastTX + nextTX ) < = millis ( ) ) {
if ( tracker_mode ! = WX_FIXED ) {
// if (gps.location.isValid()) {
if ( gps . location . age ( ) < 2000 ) {
digitalWrite ( TXLED , HIGH ) ;
if ( hum_temp ) {
writedisplaytext ( " ((TX)) " , " " , " LAT: " + LatShown , " LON: " + LongShown , " SPD: " + String ( gps . speed . kmph ( ) , 1 ) + " CRS: " + String ( gps . course . deg ( ) , 1 ) , " BAT: " + String ( BattVolts , 1 ) + " HUM: " + String ( hum , 1 ) , 0 ) ;
} else {
writedisplaytext ( " ((TX)) " , " " , " LAT: " + LatShown , " LON: " + LongShown , " SPD: " + String ( gps . speed . kmph ( ) , 1 ) + " CRS: " + String ( gps . course . deg ( ) , 1 ) , " SAT: " + String ( gps . satellites . value ( ) ) + " TEMP: " + String ( temp , 1 ) , 0 ) ;
}
sendpacket ( ) ;
Serial . print ( " ((TX)) / LAT: " ) ;
Serial . print ( LatShown ) ;
Serial . print ( " / LON: " ) ;
Serial . print ( LongShown ) ;
Serial . print ( " / SPD: " ) ;
Serial . print ( String ( gps . speed . kmph ( ) , 1 ) ) ;
Serial . print ( " / CRS: " ) ;
Serial . print ( String ( gps . course . deg ( ) , 1 ) ) ;
Serial . print ( " / SAT: " ) ;
Serial . print ( String ( gps . satellites . value ( ) ) ) ;
Serial . print ( " / BAT: " ) ;
Serial . print ( String ( BattVolts , 1 ) ) ;
Serial . print ( " / TEMP: " ) ;
Serial . print ( String ( temp , 1 ) ) ;
Serial . print ( " / HUM: " ) ;
Serial . println ( String ( hum , 1 ) ) ;
digitalWrite ( TXLED , LOW ) ;
2018-12-06 06:47:42 +00:00
} else {
2020-01-02 19:13:30 +00:00
if ( hum_temp ) {
writedisplaytext ( " " + Tcall , " (TX) at valid GPS " , " LAT: not valid " , " LON: not valid " , " SPD: --- CRS: --- " , " BAT: " + String ( BattVolts , 1 ) + " HUM: " + String ( hum , 1 ) , 0 ) ;
} else {
writedisplaytext ( " " + Tcall , " (TX) at valid GPS " , " LAT: not valid " , " LON: not valid " , " SPD: --- CRS: --- " , " SAT: " + String ( gps . satellites . value ( ) ) + " TEMP: " + String ( temp , 1 ) , 0 ) ;
}
Serial . print ( " (TX) at valid GPS / LAT: not valid / Lon: not valid / SPD: --- / CRS: --- " ) ;
Serial . print ( " / SAT: " ) ;
Serial . print ( String ( gps . satellites . value ( ) ) ) ;
Serial . print ( " / BAT: " ) ;
Serial . print ( String ( BattVolts , 1 ) ) ;
Serial . print ( " / TEMP: " ) ;
Serial . print ( String ( temp , 1 ) ) ;
Serial . print ( " / HUM: " ) ;
Serial . println ( String ( hum , 1 ) ) ;
2018-12-06 06:47:42 +00:00
}
2020-01-02 19:13:30 +00:00
} else { // ab hier Code für WX_FIXED
2018-12-06 06:47:42 +00:00
digitalWrite ( TXLED , HIGH ) ;
if ( hum_temp ) {
2020-01-02 19:13:30 +00:00
writedisplaytext ( " ((TX)) " , " " , " LAT: " + LatShown , " LON: " + LongShown , " No GPS used " , " BAT: " + String ( BattVolts , 1 ) + " HUM: " + String ( hum , 1 ) , 0 ) ;
2018-12-06 06:47:42 +00:00
} else {
2020-01-02 19:13:30 +00:00
writedisplaytext ( " ((TX)) " , " " , " LAT: " + LatShown , " LON: " + LongShown , " No GPS used " , " SAT: --- TEMP: " + String ( temp , 1 ) , 0 ) ;
2018-12-06 06:47:42 +00:00
}
2020-01-02 19:13:30 +00:00
Serial . print ( " ((TX)) / LAT: " ) ;
Serial . print ( LatShown ) ;
Serial . print ( " / LON: " ) ;
Serial . print ( LongShown ) ;
Serial . print ( " / No GPS used / SAT: --- / BAT: " ) ;
Serial . print ( String ( BattVolts , 1 ) ) ;
Serial . print ( " / TEMP: " ) ;
Serial . print ( String ( temp , 1 ) ) ;
Serial . print ( " / HUM: " ) ;
Serial . println ( String ( hum , 1 ) ) ;
2018-12-06 06:47:42 +00:00
sendpacket ( ) ;
Serial . println ( " State: Packet sent! " ) ;
digitalWrite ( TXLED , LOW ) ;
}
} else {
2020-01-02 19:13:30 +00:00
if ( tracker_mode ! = WX_FIXED ) {
if ( gps . location . age ( ) < 2000 ) {
if ( hum_temp ) {
writedisplaytext ( " " + Tcall , " Time to TX: " + String ( ( ( lastTX + nextTX ) - millis ( ) ) / 1000 ) + " sec " , " LAT: " + LatShown , " LON: " + LongShown , " SPD: " + String ( gps . speed . kmph ( ) , 1 ) + " CRS: " + String ( gps . course . deg ( ) , 1 ) , " BAT: " + String ( BattVolts , 1 ) + " HUM: " + String ( hum , 1 ) , 0 ) ;
} else {
writedisplaytext ( " " + Tcall , " Time to TX: " + String ( ( ( lastTX + nextTX ) - millis ( ) ) / 1000 ) + " sec " , " LAT: " + LatShown , " LON: " + LongShown , " SPD: " + String ( gps . speed . kmph ( ) , 1 ) + " CRS: " + String ( gps . course . deg ( ) , 1 ) , " SAT: " + String ( gps . satellites . value ( ) ) + " TEMP: " + String ( temp , 1 ) , 0 ) ;
}
} else {
if ( hum_temp ) {
writedisplaytext ( " " + Tcall , " Time to TX: " + String ( ( ( lastTX + nextTX ) - millis ( ) ) / 1000 ) + " sec " , " LAT: not valid " , " LON: not valid " , " SPD: --- CRS: --- " , " BAT: " + String ( BattVolts , 1 ) + " HUM: " + String ( hum , 1 ) , 0 ) ;
} else {
writedisplaytext ( " " + Tcall , " Time to TX: " + String ( ( ( lastTX + nextTX ) - millis ( ) ) / 1000 ) + " sec " , " LAT: not valid " , " LON: not valid " , " SPD: --- CRS: --- " , " SAT: " + String ( gps . satellites . value ( ) ) + " TEMP: " + String ( temp , 1 ) , 0 ) ;
}
}
} else { // ab hier WX_FIXED code
if ( hum_temp ) {
2020-01-30 15:15:56 +00:00
writedisplaytext ( " " + wxTcall , " Time to TX: " + String ( ( ( lastTX + nextTX ) - millis ( ) ) / 1000 ) + " sec " , " LAT: " + LatShown , " LON: " + LongShown , " SPD: --- CRS: --- " , " BAT: " + String ( BattVolts , 1 ) + " HUM: " + String ( hum , 1 ) , 0 ) ;
2020-01-02 19:13:30 +00:00
} else {
2020-01-30 15:15:56 +00:00
writedisplaytext ( " " + wxTcall , " Time to TX: " + String ( ( ( lastTX + nextTX ) - millis ( ) ) / 1000 ) + " sec " , " LAT: " + LatShown , " LON: " + LongShown , " SPD: --- CRS: --- " , " SAT: --- TEMP: " + String ( temp , 1 ) , 0 ) ;
2020-01-02 19:13:30 +00:00
}
2018-11-25 20:07:34 +00:00
}
2018-12-06 06:47:42 +00:00
}
2020-01-02 19:13:30 +00:00
smartDelay ( 900 ) ;
2018-11-25 20:07:34 +00:00
}
/////////////////////////////////////////////////////////////////////////////////////////
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay ( unsigned long ms )
{
unsigned long start = millis ( ) ;
do
{
2018-12-06 06:47:42 +00:00
if ( tracker_mode ! = WX_FIXED ) {
2018-11-25 20:07:34 +00:00
while ( ss . available ( ) )
gps . encode ( ss . read ( ) ) ;
2018-12-06 06:47:42 +00:00
}
2018-11-25 20:07:34 +00:00
} while ( millis ( ) - start < ms ) ;
}
2020-08-27 19:41:54 +00:00
char * ax25_base91enc ( char * s , uint8_t n , uint32_t v )
{
/* Creates a Base-91 representation of the value in v in the string */
/* pointed to by s, n-characters long. String length should be n+1. */
for ( s + = n , * s = ' \0 ' ; n ; n - - )
{
* ( - - s ) = v % 91 + 33 ;
v / = 91 ;
}
return ( s ) ;
}
2018-11-25 20:07:34 +00:00
/////////////////////////////////////////////////////////////////////////////////////////
2019-11-22 13:22:31 +00:00
//@APA Recalc GPS Position == generate APRS string
2018-11-25 20:07:34 +00:00
void recalcGPS ( ) {
String Ns , Ew , helper ;
2020-08-27 19:41:54 +00:00
char helper_base91 [ ] = { " 0000 \0 " } ;
2020-02-02 15:58:19 +00:00
float Tlat = 48.2012 , Tlon = 15.6361 ;
2019-10-24 19:54:33 +00:00
int i , Talt , lenalt ;
2020-08-27 19:41:54 +00:00
uint32_t aprs_lat , aprs_lon ;
2020-02-02 15:58:19 +00:00
float Lat = 0.0 ;
float Lon = 0.0 ;
float Tspeed = 0 , Tcourse = 0 ;
2019-10-24 19:54:33 +00:00
String Speedx , Coursex , Altx ;
2018-11-25 20:07:34 +00:00
2018-12-06 06:47:42 +00:00
if ( tracker_mode ! = WX_FIXED ) {
2018-11-25 20:07:34 +00:00
Tlat = gps . location . lat ( ) ;
Tlon = gps . location . lng ( ) ;
2019-10-24 19:54:33 +00:00
Talt = gps . altitude . meters ( ) * 3.28 ;
Altx = Talt ;
lenalt = Altx . length ( ) ;
Altx = " " ;
for ( i = 0 ; i < ( 6 - lenalt ) ; i + + ) {
Altx + = " 0 " ;
}
Altx + = Talt ;
Tcourse = gps . course . deg ( ) ;
Tspeed = gps . speed . knots ( ) ;
2018-11-25 20:07:34 +00:00
if ( Tlat < 0 ) { Ns = " S " ; } else { Ns = " N " ; }
if ( Tlon < 0 ) { Ew = " W " ; } else { Ew = " E " ; }
if ( Tlat < 0 ) { Tlat = - Tlat ; }
unsigned int Deg_Lat = Tlat ;
Lat = 100 * ( Deg_Lat ) + ( Tlat - Deg_Lat ) * 60 ;
if ( Tlon < 0 ) { Tlon = - Tlon ; }
unsigned int Deg_Lon = Tlon ;
Lon = 100 * ( Deg_Lon ) + ( Tlon - Deg_Lon ) * 60 ;
2020-08-30 10:42:15 +00:00
aprs_lat = 900000000 - Tlat * 10000000 ;
aprs_lat = aprs_lat / 26 - aprs_lat / 2710 + aprs_lat / 15384615 ;
aprs_lon = 900000000 + Tlon * 10000000 / 2 ;
aprs_lon = aprs_lon / 26 - aprs_lon / 2710 + aprs_lon / 15384615 ;
2018-12-06 06:47:42 +00:00
}
2018-11-25 20:07:34 +00:00
2018-12-06 06:47:42 +00:00
outString = " " ;
switch ( tracker_mode ) {
case WX_FIXED :
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
sensors . requestTemperatures ( ) ; // Send the command to get temperature readings
tempf = sensors . getTempFByIndex ( 0 ) ; // get temp from 1st (!) sensor only
hum = 0 ;
# else
hum = dht . getHumidity ( ) ;
tempf = dht . getTemperature ( ) * 9 / 5 + 32 ;
# endif
2019-11-22 13:22:31 +00:00
for ( i = 0 ; i < wxTcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( wxTcall . charAt ( i ) ! = ' ' ) {
outString + = wxTcall . charAt ( i ) ;
}
}
// outString = wxTcall;
2018-12-06 06:47:42 +00:00
outString + = " >APRS:! " ;
2018-12-24 14:29:36 +00:00
outString + = LatFixed ;
2018-12-06 06:47:42 +00:00
outString + = wxTable ;
2018-12-24 14:29:36 +00:00
outString + = LongFixed ;
2018-12-06 06:47:42 +00:00
outString + = wxSymbol ;
2020-08-30 10:42:15 +00:00
2018-12-06 06:47:42 +00:00
outString + = " .../...g...t " ;
2018-12-09 21:23:20 +00:00
if ( tempf < 0 ) { // negative Werte erstellen
2018-12-06 06:47:42 +00:00
outString + = " - " ;
2018-12-09 21:23:20 +00:00
if ( tempf > - 10 ) { outString + = " 0 " ; }
tempf = abs ( tempf ) ;
2018-12-06 06:47:42 +00:00
} else { // positive Werte erstellen
2018-12-09 21:23:20 +00:00
if ( tempf < 100 ) { outString + = " 0 " ; }
if ( tempf < 10 ) { outString + = " 0 " ; }
2018-12-06 06:47:42 +00:00
}
2018-12-09 21:23:20 +00:00
helper = String ( tempf , 0 ) ;
2018-12-06 06:47:42 +00:00
helper . trim ( ) ;
outString + = helper ;
outString + = " r...p...P...h " ;
if ( hum < 10 ) { outString + = " 0 " ; }
helper = String ( hum , 0 ) ;
helper . trim ( ) ;
outString + = helper ;
outString + = " b......DHT22 " ;
2020-08-30 10:42:15 +00:00
outString + = MY_COMMENT ;
2018-12-06 06:47:42 +00:00
break ;
case WX_TRACKER :
if ( wx ) {
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
sensors . requestTemperatures ( ) ; // Send the command to get temperature readings
tempf = sensors . getTempFByIndex ( 0 ) ; // get temp from 1st (!) sensor only
hum = 0 ;
# else
hum = dht . getHumidity ( ) ;
tempf = dht . getTemperature ( ) * 9 / 5 + 32 ;
# endif
2020-08-30 10:42:15 +00:00
# ifndef TX_BASE91
for ( i = 0 ; i < wxTcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( wxTcall . charAt ( i ) ! = ' ' ) {
outString + = wxTcall . charAt ( i ) ;
}
2019-11-22 13:22:31 +00:00
}
2020-08-30 10:42:15 +00:00
// outString = (wxTcall);
outString + = " >APRS:! " ;
if ( Tlat < 10 ) { outString + = " 0 " ; }
outString + = String ( Lat , 2 ) ;
outString + = Ns ;
outString + = wxTable ;
if ( Tlon < 100 ) { outString + = " 0 " ; }
if ( Tlon < 10 ) { outString + = " 0 " ; }
outString + = String ( Lon , 2 ) ;
outString + = Ew ;
outString + = wxSymbol ;
# else
for ( i = 0 ; i < Tcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( Tcall . charAt ( i ) ! = ' ' ) {
outString + = Tcall . charAt ( i ) ;
}
}
// outString = (Tcall);
outString + = " >APRS:!/ " ;
ax25_base91enc ( helper_base91 , 4 , aprs_lat ) ;
for ( i = 0 ; i < 4 ; i + + ) {
outString + = helper_base91 [ i ] ;
}
ax25_base91enc ( helper_base91 , 4 , aprs_lon ) ;
for ( i = 0 ; i < 4 ; i + + ) {
outString + = helper_base91 [ i ] ;
}
outString + = wxSymbol ;
ax25_base91enc ( helper_base91 , 1 , ( uint32_t ) Tcourse / 4 ) ;
outString + = helper_base91 [ 0 ] ;
ax25_base91enc ( helper_base91 , 1 , ( uint32_t ) ( log1p ( Tspeed ) / 0.07696 ) ) ;
outString + = helper_base91 [ 0 ] ;
outString + = " \x48 " ;
# endif
2018-12-06 06:47:42 +00:00
outString + = " .../...g...t " ;
2018-12-09 21:23:20 +00:00
if ( tempf < 0 ) { // negative Werte erstellen
2018-12-06 06:47:42 +00:00
outString + = " - " ;
2018-12-09 21:23:20 +00:00
if ( tempf > - 10 ) { outString + = " 0 " ; }
tempf = abs ( tempf ) ;
2018-12-06 06:47:42 +00:00
} else { // positive Werte erstellen
2018-12-09 21:23:20 +00:00
if ( tempf < 100 ) { outString + = " 0 " ; }
if ( tempf < 10 ) { outString + = " 0 " ; }
2018-12-06 06:47:42 +00:00
}
2018-12-09 21:23:20 +00:00
helper = String ( tempf , 0 ) ;
2018-12-06 06:47:42 +00:00
helper . trim ( ) ;
outString + = helper ;
outString + = " r...p...P...h " ;
if ( hum < 10 ) { outString + = " 0 " ; }
helper = String ( hum , 0 ) ;
helper . trim ( ) ;
outString + = helper ;
outString + = " b......DHT22 " ;
2020-08-30 10:42:15 +00:00
outString + = MY_COMMENT ;
2018-12-06 06:47:42 +00:00
wx = ! wx ;
} else {
2020-08-30 10:42:15 +00:00
# ifndef TX_BASE91
for ( i = 0 ; i < Tcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( Tcall . charAt ( i ) ! = ' ' ) {
outString + = Tcall . charAt ( i ) ;
}
2019-11-22 13:22:31 +00:00
}
2020-08-30 10:42:15 +00:00
// outString = (Tcall);
outString + = " >APRS:! " ;
if ( Tlat < 10 ) { outString + = " 0 " ; }
outString + = String ( Lat , 2 ) ;
outString + = Ns ;
outString + = sTable ;
if ( Tlon < 100 ) { outString + = " 0 " ; }
if ( Tlon < 10 ) { outString + = " 0 " ; }
outString + = String ( Lon , 2 ) ;
outString + = Ew ;
outString + = TxSymbol ;
# else
for ( i = 0 ; i < Tcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( Tcall . charAt ( i ) ! = ' ' ) {
outString + = Tcall . charAt ( i ) ;
}
}
// outString = (Tcall);
outString + = " >APRS:!/ " ;
ax25_base91enc ( helper_base91 , 4 , aprs_lat ) ;
for ( i = 0 ; i < 4 ; i + + ) {
outString + = helper_base91 [ i ] ;
}
ax25_base91enc ( helper_base91 , 4 , aprs_lon ) ;
for ( i = 0 ; i < 4 ; i + + ) {
outString + = helper_base91 [ i ] ;
}
outString + = TxSymbol ;
ax25_base91enc ( helper_base91 , 1 , ( uint32_t ) Tcourse / 4 ) ;
outString + = helper_base91 [ 0 ] ;
ax25_base91enc ( helper_base91 , 1 , ( uint32_t ) ( log1p ( Tspeed ) / 0.07696 ) ) ;
outString + = helper_base91 [ 0 ] ;
outString + = " \x48 " ;
# endif
# ifdef HW_COMMENT
outString + = " /A= " ;
outString + = Altx ;
outString + = " Batt= " ;
outString + = String ( BattVolts , 2 ) ;
outString + = ( " V " ) ;
# endif
outString + = MY_COMMENT ;
2018-12-06 06:47:42 +00:00
wx = ! wx ;
}
break ;
case WX_MOVE :
2020-01-31 13:04:08 +00:00
# ifdef DS18B20
sensors . requestTemperatures ( ) ; // Send the command to get temperature readings
tempf = sensors . getTempFByIndex ( 0 ) ; // get temp from 1st (!) sensor only
hum = 0 ;
# else
hum = dht . getHumidity ( ) ;
tempf = dht . getTemperature ( ) * 9 / 5 + 32 ;
# endif
2020-08-30 10:42:15 +00:00
# ifndef TX_BASE91
for ( i = 0 ; i < wxTcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( wxTcall . charAt ( i ) ! = ' ' ) {
outString + = wxTcall . charAt ( i ) ;
}
2019-11-22 13:22:31 +00:00
}
2020-08-30 10:42:15 +00:00
// outString = (wxTcall);
outString + = " >APRS:! " ;
if ( Tlat < 10 ) { outString + = " 0 " ; }
outString + = String ( Lat , 2 ) ;
outString + = Ns ;
outString + = wxTable ;
if ( Tlon < 100 ) { outString + = " 0 " ; }
if ( Tlon < 10 ) { outString + = " 0 " ; }
outString + = String ( Lon , 2 ) ;
outString + = Ew ;
outString + = wxSymbol ;
# else
for ( i = 0 ; i < Tcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( Tcall . charAt ( i ) ! = ' ' ) {
outString + = Tcall . charAt ( i ) ;
}
}
// outString = (Tcall);
outString + = " >APRS:!/ " ;
ax25_base91enc ( helper_base91 , 4 , aprs_lat ) ;
for ( i = 0 ; i < 4 ; i + + ) {
outString + = helper_base91 [ i ] ;
}
ax25_base91enc ( helper_base91 , 4 , aprs_lon ) ;
for ( i = 0 ; i < 4 ; i + + ) {
outString + = helper_base91 [ i ] ;
}
outString + = wxSymbol ;
ax25_base91enc ( helper_base91 , 1 , ( uint32_t ) Tcourse / 4 ) ;
outString + = helper_base91 [ 0 ] ;
ax25_base91enc ( helper_base91 , 1 , ( uint32_t ) ( log1p ( Tspeed ) / 0.07696 ) ) ;
outString + = helper_base91 [ 0 ] ;
outString + = " \x48 " ;
# endif
2018-11-25 20:07:34 +00:00
outString + = " .../...g...t " ;
2018-12-09 21:23:20 +00:00
if ( tempf < 0 ) { // negative Werte erstellen
2018-11-25 20:07:34 +00:00
outString + = " - " ;
2018-12-09 21:23:20 +00:00
if ( tempf > - 10 ) { outString + = " 0 " ; }
tempf = abs ( tempf ) ;
2018-11-25 20:07:34 +00:00
} else { // positive Werte erstellen
2018-12-09 21:23:20 +00:00
if ( tempf < 100 ) { outString + = " 0 " ; }
if ( tempf < 10 ) { outString + = " 0 " ; }
2018-11-25 20:07:34 +00:00
}
2018-12-09 21:23:20 +00:00
helper = String ( tempf , 0 ) ;
2018-11-25 20:07:34 +00:00
helper . trim ( ) ;
outString + = helper ;
outString + = " r...p...P...h " ;
if ( hum < 10 ) { outString + = " 0 " ; }
helper = String ( hum , 0 ) ;
helper . trim ( ) ;
outString + = helper ;
outString + = " b......DHT22 " ;
2020-08-30 10:42:15 +00:00
outString + = MY_COMMENT ;
2018-12-06 06:47:42 +00:00
break ;
case TRACKER :
default :
2020-08-27 19:41:54 +00:00
# ifndef TX_BASE91
for ( i = 0 ; i < Tcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( Tcall . charAt ( i ) ! = ' ' ) {
outString + = Tcall . charAt ( i ) ;
}
2019-11-22 13:22:31 +00:00
}
2020-08-27 19:41:54 +00:00
// outString = (Tcall);
outString + = " >APRS:! " ;
if ( Tlat < 10 ) { outString + = " 0 " ; }
outString + = String ( Lat , 2 ) ;
outString + = Ns ;
outString + = sTable ;
if ( Tlon < 100 ) { outString + = " 0 " ; }
if ( Tlon < 10 ) { outString + = " 0 " ; }
outString + = String ( Lon , 2 ) ;
outString + = Ew ;
outString + = TxSymbol ;
if ( Tcourse < 100 ) { outString + = " 0 " ; }
if ( Tcourse < 10 ) { outString + = " 0 " ; }
Coursex = String ( Tcourse , 0 ) ;
Coursex . replace ( " " , " " ) ;
outString + = Coursex ;
outString + = " / " ;
if ( Tspeed < 100 ) { outString + = " 0 " ; }
if ( Tspeed < 10 ) { outString + = " 0 " ; }
Speedx = String ( Tspeed , 0 ) ;
Speedx . replace ( " " , " " ) ;
outString + = Speedx ;
2020-08-30 10:42:15 +00:00
# ifdef HW_COMMENT
outString + = " /A= " ;
outString + = Altx ;
outString + = " Batt= " ;
outString + = String ( BattVolts , 2 ) ;
outString + = ( " V " ) ;
# endif
outString + = MY_COMMENT ;
2020-08-27 19:41:54 +00:00
# ifdef DEBUG
outString + = ( " Debug: " ) ;
outString + = TxRoot ;
# endif
# else
for ( i = 0 ; i < Tcall . length ( ) ; + + i ) { // remove unneeded "spaces" from callsign field
if ( Tcall . charAt ( i ) ! = ' ' ) {
outString + = Tcall . charAt ( i ) ;
}
}
// outString = (Tcall);
outString + = " >APRS:!/ " ;
ax25_base91enc ( helper_base91 , 4 , aprs_lat ) ;
for ( i = 0 ; i < 4 ; i + + ) {
outString + = helper_base91 [ i ] ;
}
ax25_base91enc ( helper_base91 , 4 , aprs_lon ) ;
for ( i = 0 ; i < 4 ; i + + ) {
outString + = helper_base91 [ i ] ;
}
outString + = TxSymbol ;
ax25_base91enc ( helper_base91 , 1 , ( uint32_t ) Tcourse / 4 ) ;
outString + = helper_base91 [ 0 ] ;
ax25_base91enc ( helper_base91 , 1 , ( uint32_t ) ( log1p ( Tspeed ) / 0.07696 ) ) ;
outString + = helper_base91 [ 0 ] ;
outString + = " \x48 " ;
2020-08-30 10:42:15 +00:00
# ifdef HW_COMMENT
outString + = " /A= " ;
outString + = Altx ;
outString + = " Batt= " ;
outString + = String ( BattVolts , 2 ) ;
outString + = ( " V " ) ;
# endif
outString + = MY_COMMENT ;
2020-08-27 19:41:54 +00:00
# endif
2019-10-24 19:54:33 +00:00
Serial . print ( " outString= " ) ;
// Speedx = String(Tspeed,0);
// Speedx.replace(" ","");
Serial . println ( outString ) ;
// Serial.println("=");
2020-08-27 19:41:54 +00:00
break ;
2018-11-25 20:07:34 +00:00
}
}
/////////////////////////////////////////////////////////////////////////////////////////
void sendpacket ( )
{
batt_read ( ) ;
Outputstring = " " ;
2018-12-06 06:47:42 +00:00
switch ( tracker_mode ) {
case WX_FIXED :
2018-11-25 20:07:34 +00:00
recalcGPS ( ) ; //
Outputstring = outString ;
2018-12-06 06:47:42 +00:00
loraSend ( lora_TXStart , lora_TXEnd , 60 , 255 , 1 , 10 , TXdbmW , TXFREQ ) ; //send the packet, data is in TXbuff from lora_TXStart to lora_TXEnd
break ;
case TRACKER :
case WX_TRACKER :
case WX_MOVE :
default :
if ( gps . location . isValid ( ) | | gps . location . isUpdated ( ) ) {
recalcGPS ( ) ; //
Outputstring = outString ;
loraSend ( lora_TXStart , lora_TXEnd , 60 , 255 , 1 , 10 , TXdbmW , TXFREQ ) ; //send the packet, data is in TXbuff from lora_TXStart to lora_TXEnd
} else {
Outputstring = ( Tcall ) ;
Outputstring + = " No GPS-Fix " ;
Outputstring + = " Batt= " ;
Outputstring + = String ( BattVolts , 2 ) ;
Outputstring + = ( " V " ) ;
loraSend ( lora_TXStart , lora_TXEnd , 60 , 255 , 1 , 10 , 5 , TXFREQ ) ; //send the packet, data is in TXbuff from lora_TXStart to lora_TXEnd
}
break ;
2018-11-25 20:07:34 +00:00
}
}
///////////////////////////////////////////////////////////////////////////////////////
void loraSend ( byte lora_LTXStart , byte lora_LTXEnd , byte lora_LTXPacketType , byte lora_LTXDestination , byte lora_LTXSource , long lora_LTXTimeout , byte lora_LTXPower , float lora_FREQ )
{
byte i ;
byte ltemp ;
2018-12-06 06:47:42 +00:00
if ( rf95 . waitAvailableTimeout ( 100 ) ) {
if ( rf95 . recvAPRS ( buf , & len ) ) {
}
2018-11-25 20:07:34 +00:00
}
2018-12-06 06:47:42 +00:00
// time of last TX
lastTX = millis ( ) ;
2018-11-25 20:07:34 +00:00
2018-12-06 06:47:42 +00:00
ltemp = Outputstring . length ( ) ;
for ( i = 0 ; i < = ltemp ; i + + )
{
lora_TXBUFF [ i ] = Outputstring . charAt ( i ) ;
}
2018-11-25 20:07:34 +00:00
2018-12-06 06:47:42 +00:00
i - - ;
lora_TXEnd = i ;
lora_TXBUFF [ i ] = ' \0 ' ;
2018-11-25 20:07:34 +00:00
// digitalWrite(PLED1, HIGH); //LED on during packet
rf95 . setModemConfig ( BG_RF95 : : Bw125Cr45Sf4096 ) ;
rf95 . setFrequency ( lora_FREQ ) ;
rf95 . setTxPower ( lora_LTXPower ) ;
rf95 . sendAPRS ( lora_TXBUFF , Outputstring . length ( ) ) ;
rf95 . waitPacketSent ( ) ;
}
///////////////////////////////////////////////////////////////////////////////////////
void batt_read ( )
{
2018-12-01 11:27:58 +00:00
float BattRead = analogRead ( 35 ) * 7.221 ;
2019-11-29 17:44:22 +00:00
# ifdef T_BEAM_V1_0
BattVolts = axp . getBattVoltage ( ) / 1000 ;
# else
2018-12-01 11:27:58 +00:00
BattVolts = ( BattRead / 4096 ) ;
2019-11-29 17:44:22 +00:00
# endif
2018-11-25 20:07:34 +00:00
}
///////////////////////////////////////////////////////////////////////////////////////
2018-12-09 21:23:20 +00:00
void writedisplaytext ( String HeaderTxt , String Line1 , String Line2 , String Line3 , String Line4 , String Line5 , int warten ) {
2018-11-25 20:07:34 +00:00
display . clearDisplay ( ) ;
display . setTextColor ( WHITE ) ;
display . setTextSize ( 2 ) ;
display . setCursor ( 0 , 0 ) ;
2018-12-06 06:47:42 +00:00
display . println ( HeaderTxt ) ;
2018-11-25 20:07:34 +00:00
display . setTextSize ( 1 ) ;
2018-12-01 11:27:58 +00:00
display . setCursor ( 0 , 16 ) ;
2018-11-25 20:07:34 +00:00
display . println ( Line1 ) ;
2018-12-01 11:27:58 +00:00
display . setCursor ( 0 , 26 ) ;
2018-11-25 20:07:34 +00:00
display . println ( Line2 ) ;
2018-12-01 11:27:58 +00:00
display . setCursor ( 0 , 36 ) ;
2018-11-25 20:07:34 +00:00
display . println ( Line3 ) ;
2018-12-01 11:27:58 +00:00
display . setCursor ( 0 , 46 ) ;
display . println ( Line4 ) ;
display . setCursor ( 0 , 56 ) ;
display . println ( Line5 ) ;
2018-11-25 20:07:34 +00:00
display . display ( ) ;
smartDelay ( warten ) ;
}
2018-12-09 21:23:20 +00:00
///////////////////////////////////////////////////////////////////////////////////////
void setup_data ( void ) {
2019-11-22 13:22:31 +00:00
char werte_call [ 37 ] = { ' ' , ' A ' , ' B ' , ' C ' , ' D ' , ' E ' , ' F ' , ' G ' , ' H ' , ' I ' , ' J ' , ' K ' , ' L ' , ' M ' , ' N ' , ' O ' , ' P ' , ' Q ' , ' R ' , ' S ' , ' T ' , ' U ' , ' V ' , ' W ' , ' X ' , ' Y ' , ' Z ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' , ' 0 ' } ;
2018-12-24 14:29:36 +00:00
String werte_SSID [ 16 ] = { " 0 " , " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " , " 9 " , " 10 " , " 11 " , " 12 " , " 13 " , " 14 " , " 15 " } ;
char werte_latlon [ 14 ] = { ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' , ' N ' , ' S ' , ' E ' , ' W ' } ;
2020-07-29 11:30:40 +00:00
String werte_TxSymbol_text [ 6 ] = { " WX Station " , " Car " , " Person " , " Bicycle " , " Motorcycle " , " RV " } ;
String werte_TxSymbol_symbol [ 6 ] = { " _ " , " > " , " [ " , " b " , " < " , " R " } ;
String werte_weiter_symbol [ 2 ] = { " yes " , " no " } ;
2018-12-24 14:29:36 +00:00
int8_t pos_in_string ;
2019-11-22 13:22:31 +00:00
int8_t pos_ssid ;
2018-12-09 21:23:20 +00:00
bool key_pressed = false ;
2020-02-02 15:58:19 +00:00
int waiter ;
2018-12-09 21:23:20 +00:00
int initial_waiter = 2000 ;
char aktueller_letter ;
int8_t pos_letter ;
String pfeile = " ^ " ;
2019-11-22 13:22:31 +00:00
int8_t initial_ssid ;
2018-12-09 21:23:20 +00:00
2020-01-02 19:13:30 +00:00
// set Tx Symbol - gleich zu Beginn, falls man nur das Symbol ändern möchte
pos_ssid = 0 ;
2018-12-09 21:23:20 +00:00
while ( true ) {
2020-01-02 19:13:30 +00:00
TxSymbol = werte_TxSymbol_symbol [ pos_ssid ] ;
blinker ( pos_ssid + 1 ) ;
writedisplaytext ( " SETUP " , " Symbol " , werte_TxSymbol_text [ pos_ssid ] , " " , " PRESS KEY to select " , " " , 0 ) ;
2018-12-09 21:23:20 +00:00
waiter = millis ( ) ;
while ( millis ( ) < ( waiter + 1000 + initial_waiter ) ) {
if ( digitalRead ( BUTTON ) = = LOW ) {
key_pressed = true ;
}
}
initial_waiter = 0 ;
if ( key_pressed = = true ) {
key_pressed = false ;
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " Symbol " , werte_TxSymbol_text [ pos_ssid ] , " " , " programmed " , " " , 2000 ) ;
2018-12-09 21:23:20 +00:00
break ;
}
+ + pos_ssid ;
2020-07-29 11:30:40 +00:00
if ( pos_ssid > = 6 ) { pos_ssid = 0 ; }
2018-12-09 21:23:20 +00:00
}
2020-01-02 19:13:30 +00:00
// smartDelay(500);
2018-12-09 21:23:20 +00:00
2020-01-02 19:13:30 +00:00
// fragen, ob es weiter gehen soll
pos_ssid = 0 ;
2018-12-09 21:23:20 +00:00
key_pressed = false ;
initial_waiter = 2000 ;
while ( true ) {
2020-01-02 19:13:30 +00:00
// TxSymbol = werte_TxSymbol_symbol[pos_ssid];
blinker ( 2 - pos_ssid ) ;
writedisplaytext ( " SETUP " , " stop it? " , " " + werte_weiter_symbol [ pos_ssid ] , " " , " PRESS KEY to select " , " " , 0 ) ;
2018-12-09 21:23:20 +00:00
waiter = millis ( ) ;
while ( millis ( ) < ( waiter + 1000 + initial_waiter ) ) {
if ( digitalRead ( BUTTON ) = = LOW ) {
key_pressed = true ;
}
}
initial_waiter = 0 ;
if ( key_pressed = = true ) {
key_pressed = false ;
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " stop it? " , " " + werte_weiter_symbol [ pos_ssid ] , " " , " selected " , " " , 2000 ) ;
2018-12-09 21:23:20 +00:00
break ;
}
+ + pos_ssid ;
2020-01-02 19:13:30 +00:00
if ( pos_ssid > = 2 ) { pos_ssid = 0 ; }
2018-12-24 14:29:36 +00:00
}
2020-01-02 19:13:30 +00:00
if ( pos_ssid ! = 0 ) {
// set callsign - one for both reports
pos_in_string = 0 ;
2018-12-24 14:29:36 +00:00
key_pressed = false ;
2020-01-02 19:13:30 +00:00
initial_waiter = 2000 ;
while ( pos_in_string < 6 ) {
key_pressed = false ;
aktueller_letter = ( char ) Tcall . charAt ( pos_in_string ) ; // ist Buchstabe holen
for ( pos_letter = 0 ; pos_letter < 37 ; pos_letter + + ) {
if ( aktueller_letter = = werte_call [ pos_letter ] ) {
break ;
}
2018-12-24 14:29:36 +00:00
}
2020-01-02 19:13:30 +00:00
while ( true ) {
Tcall . setCharAt ( pos_in_string , aktueller_letter ) ;
writedisplaytext ( " SETUP " , " Call " , " " + Tcall , " " + pfeile , " PRESS KEY to select " , " " , 0 ) ;
waiter = millis ( ) ;
while ( millis ( ) < ( waiter + 1000 + initial_waiter ) ) {
if ( digitalRead ( BUTTON ) = = LOW ) {
key_pressed = true ;
}
}
initial_waiter = 0 ;
if ( key_pressed = = true ) {
key_pressed = false ;
break ;
}
// nächster Buchstabe
+ + pos_letter ;
if ( pos_letter > = 37 ) { pos_letter = 0 ; }
aktueller_letter = werte_call [ pos_letter ] ;
}
initial_waiter = 2000 ;
pfeile = " " + pfeile ;
+ + pos_in_string ;
2018-12-24 14:29:36 +00:00
}
2020-01-02 19:13:30 +00:00
// set normal SSID
initial_ssid = ( int8_t ) ( Tcall . substring ( 7 , 9 ) ) . toInt ( ) ;
pos_ssid = initial_ssid ;
pfeile = " ^ " ;
key_pressed = false ;
initial_waiter = 2000 ;
2018-12-24 14:29:36 +00:00
while ( true ) {
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " normal SSID " , " " + Tcall , pfeile , " PRESS KEY to select " , " " , 0 ) ;
2018-12-24 14:29:36 +00:00
waiter = millis ( ) ;
while ( millis ( ) < ( waiter + 1000 + initial_waiter ) ) {
if ( digitalRead ( BUTTON ) = = LOW ) {
key_pressed = true ;
}
}
initial_waiter = 0 ;
if ( key_pressed = = true ) {
key_pressed = false ;
break ;
}
2020-01-02 19:13:30 +00:00
+ + pos_ssid ;
if ( pos_ssid > = 16 ) { pos_ssid = 0 ; }
Tcall = Tcall . substring ( 0 , 6 ) + " - " + werte_SSID [ pos_ssid ] ;
2018-12-24 14:29:36 +00:00
}
2018-12-09 21:23:20 +00:00
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " Call " , " " + Tcall , " " , " programmed " , " " , 2000 ) ;
// set WX SSID
initial_ssid = ( int8_t ) ( wxTcall . substring ( 7 , 9 ) ) . toInt ( ) ;
pos_ssid = initial_ssid ;
2018-12-24 14:29:36 +00:00
key_pressed = false ;
2020-01-02 19:13:30 +00:00
initial_waiter = 2000 ;
2018-12-24 14:29:36 +00:00
while ( true ) {
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " WX SSID " , " " + wxTcall , pfeile , " PRESS KEY to select " , " " , 0 ) ;
2018-12-24 14:29:36 +00:00
waiter = millis ( ) ;
while ( millis ( ) < ( waiter + 1000 + initial_waiter ) ) {
if ( digitalRead ( BUTTON ) = = LOW ) {
key_pressed = true ;
}
}
initial_waiter = 0 ;
if ( key_pressed = = true ) {
key_pressed = false ;
break ;
}
2020-01-02 19:13:30 +00:00
+ + pos_ssid ;
if ( pos_ssid > = 16 ) { pos_ssid = 0 ; }
wxTcall = wxTcall . substring ( 0 , 6 ) + " - " + werte_SSID [ pos_ssid ] ;
2018-12-24 14:29:36 +00:00
}
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " WX-Call " , " " + wxTcall , " " , " programmed " , " " , 2000 ) ;
// set LONGITUDE
pfeile = " ^ " ;
pos_in_string = 0 ;
key_pressed = false ;
2018-12-24 14:29:36 +00:00
initial_waiter = 2000 ;
2020-01-02 19:13:30 +00:00
while ( pos_in_string < 9 ) {
key_pressed = false ;
aktueller_letter = ( char ) LongFixed . charAt ( pos_in_string ) ; // ist Buchstabe holen
for ( pos_letter = 0 ; pos_letter < 14 ; pos_letter + + ) {
if ( aktueller_letter = = werte_latlon [ pos_letter ] ) {
break ;
}
}
while ( true ) {
LongFixed . setCharAt ( pos_in_string , aktueller_letter ) ;
writedisplaytext ( " SETUP " , " Longitude " , " " + LongFixed , " " + pfeile , " for fixed POS " , " PRESS KEY to select " , 0 ) ;
waiter = millis ( ) ;
while ( millis ( ) < ( waiter + 1000 + initial_waiter ) ) {
if ( digitalRead ( BUTTON ) = = LOW ) {
key_pressed = true ;
}
}
initial_waiter = 0 ;
if ( key_pressed = = true ) {
key_pressed = false ;
break ;
}
// nächster Buchstabe
+ + pos_letter ;
if ( pos_letter > = 14 ) { pos_letter = 0 ; }
aktueller_letter = werte_latlon [ pos_letter ] ;
}
initial_waiter = 2000 ;
2018-12-24 14:29:36 +00:00
pfeile = " " + pfeile ;
2020-01-02 19:13:30 +00:00
+ + pos_in_string ;
if ( pos_in_string = = 5 ) {
+ + pos_in_string ;
pfeile = " " + pfeile ;
2018-12-24 14:29:36 +00:00
}
}
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " Longitude " , " " + LongFixed , " " , " for fixed POS " , " programmed " , 2000 ) ;
// set LATITUDE
pfeile = " ^ " ;
pos_in_string = 0 ;
key_pressed = false ;
initial_waiter = 2000 ;
while ( pos_in_string < 8 ) {
2018-12-24 14:29:36 +00:00
key_pressed = false ;
2020-01-02 19:13:30 +00:00
aktueller_letter = ( char ) LatFixed . charAt ( pos_in_string ) ; // ist Buchstabe holen
for ( pos_letter = 0 ; pos_letter < 14 ; pos_letter + + ) {
if ( aktueller_letter = = werte_latlon [ pos_letter ] ) {
break ;
}
}
while ( true ) {
LatFixed . setCharAt ( pos_in_string , aktueller_letter ) ;
writedisplaytext ( " SETUP " , " Latitude " , " " + LatFixed , " " + pfeile , " for fixed POS " , " PRESS KEY to select " , 0 ) ;
waiter = millis ( ) ;
while ( millis ( ) < ( waiter + 1000 + initial_waiter ) ) {
if ( digitalRead ( BUTTON ) = = LOW ) {
key_pressed = true ;
}
}
initial_waiter = 0 ;
if ( key_pressed = = true ) {
key_pressed = false ;
break ;
}
// nächster Buchstabe
+ + pos_letter ;
if ( pos_letter > = 14 ) { pos_letter = 0 ; }
aktueller_letter = werte_latlon [ pos_letter ] ;
}
initial_waiter = 2000 ;
pfeile = " " + pfeile ;
+ + pos_in_string ;
if ( pos_in_string = = 4 ) {
+ + pos_in_string ;
pfeile = " " + pfeile ;
}
2018-12-24 14:29:36 +00:00
}
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " Latitude " , " " + LatFixed , " " , " for fixed POS " , " programmed " , 2000 ) ;
2018-12-24 14:29:36 +00:00
2020-01-02 19:13:30 +00:00
}
2018-12-24 14:29:36 +00:00
// write all values to NVRAM
2018-12-09 21:23:20 +00:00
prefs . begin ( " nvs " , false ) ;
prefs . putString ( " Tcall " , Tcall ) ;
prefs . putString ( " wxTcall " , wxTcall ) ;
2018-12-24 14:29:36 +00:00
prefs . putString ( " LatFixed " , LatFixed ) ;
prefs . putString ( " LongFixed " , LongFixed ) ;
prefs . putString ( " TxSymbol " , TxSymbol ) ;
2018-12-09 21:23:20 +00:00
prefs . end ( ) ;
2020-01-02 19:13:30 +00:00
writedisplaytext ( " SETUP " , " ALL DONE " , " " , " stored in NVS " , " " , " " , 2000 ) ;
}
void blinker ( int counter ) {
for ( int i = 0 ; i < ( counter - 1 ) ; i + + ) {
digitalWrite ( TXLED , HIGH ) ; // turn blue LED ON
smartDelay ( 150 ) ;
digitalWrite ( TXLED , LOW ) ; // turn blue LED OFF
smartDelay ( 100 ) ;
}
digitalWrite ( TXLED , HIGH ) ; // turn blue LED ON
smartDelay ( 150 ) ;
digitalWrite ( TXLED , LOW ) ; // turn blue LED OFF
2018-12-09 21:23:20 +00:00
}