display removed

This commit is contained in:
oh3bsg 2023-02-13 18:27:07 +02:00
parent 07859d7f70
commit c44988ef6e
17 changed files with 390 additions and 180 deletions

View File

@ -16,7 +16,8 @@
#include "src/SX1278FSK.h"
#include "src/Sonde.h"
#include "src/Display.h"
//#include "src/Display.h"
#include "src\headless.h"
#include "src/Scanner.h"
#include "src/geteph.h"
#include "src/rs92gps.h"
@ -82,6 +83,8 @@ const char *dfmSubtypeStrSH[16] = { NULL, NULL, NULL, NULL, NULL, NULL,
#define APRS_MOBILE_STATION_UPDATE_TIME (20*1000)
unsigned long time_last_aprs_update = 0;
#define EARTH_RADIUS (6371000.0F)
#if FEATURE_SONDEHUB
#define SONDEHUB_STATION_UPDATE_TIME (60*60*1000) // 60 min
#define SONDEHUB_MOBILE_STATION_UPDATE_TIME (30*1000) // 30 sec
@ -102,7 +105,6 @@ enum { SH_LOC_OFF, SH_LOC_FIXED, SH_LOC_CHASE, SH_LOC_AUTO };
#define MIN_LOC_AUTO_DIST 200 /* meter */
#define SH_LOC_AUTO_IS_CHASE ( gpsPos.valid && ( (isnan(sonde.config.rxlat) || isnan(sonde.config.rxlon) ) || \
calcLatLonDist( gpsPos.lat, gpsPos.lon, sonde.config.rxlat, sonde.config.rxlon ) > MIN_LOC_AUTO_DIST ) )
extern float calcLatLonDist(float lat1, float lon1, float lat2, float lon2);
// KISS over TCP for communicating with APRSdroid
WiFiServer tncserver(14580);
@ -147,6 +149,15 @@ void WiFiEvent(WiFiEvent_t event);
char buffer[85];
MicroNMEA nmea(buffer, sizeof(buffer));
//float calcLatLonDist(float lat1, float lon1, float lat2, float lon2);
float calcLatLonDist(float lat1, float lon1, float lat2, float lon2) {
float x = radians(lon1-lon2) * cos( radians((lat1+lat2)/2) );
float y = radians(lat2-lat1);
float d = sqrt(x*x+y*y)*EARTH_RADIUS;
return d;
}
// Read line from file, independent of line termination (LF or CR LF)
String readLine(Stream &stream) {
String s = stream.readStringUntil('\n');
@ -715,10 +726,10 @@ const char *createConfigForm() {
strcat(ptr, "<div id=\"cfgtab\"></div>");
strcat(ptr, "<script src=\"cfg.js\"></script>");
strcat(ptr, "<script>\n");
sprintf(ptr + strlen(ptr), "var scr=\"Using /screens%d.txt", Display::getScreenIndex(sonde.config.screenfile));
for (int i = 0; i < disp.nLayouts; i++) {
sprintf(ptr + strlen(ptr), "<br>%d=%s", i, disp.layouts[i].label);
}
//sprintf(ptr + strlen(ptr), "var scr=\"Using /screens%d.txt", Display::getScreenIndex(sonde.config.screenfile));
//for (int i = 0; i < disp.nLayouts; i++) {
// sprintf(ptr + strlen(ptr), "<br>%d=%s", i, disp.layouts[i].label);
//}
strcat(ptr, "\";\n");
strcat(ptr, "var cf=new Map();\n");
for (int i = 0; i < N_CONFIG; i++) {
@ -1909,8 +1920,8 @@ void setup()
for (int i = 0; i < 10; i++) { // try multiple times
Wire.begin(21, 22);
// Make sure the whole thing powers up!?!?!?!?!?
U8X8 *u8x8 = new U8X8_SSD1306_128X64_NONAME_HW_I2C(0, 22, 21);
u8x8->initDisplay();
//U8X8 *u8x8 = new U8X8_SSD1306_128X64_NONAME_HW_I2C(0, 22, 21);
//u8x8->initDisplay();
delay(500);
scanI2Cdevice();
@ -1924,36 +1935,36 @@ void setup()
// Display backlight on M5 Core2
axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);
axp.setDCDC3Voltage(3300);
// SetBusPowerMode(0):
// #define AXP192_GPIO0_CTL (0x90)
// #define AXP192_GPIO0_VOL (0x91)
// #define AXP202_LDO234_DC23_CTL (0x12)
// SetBusPowerMode(0):
// #define AXP192_GPIO0_CTL (0x90)
// #define AXP192_GPIO0_VOL (0x91)
// #define AXP202_LDO234_DC23_CTL (0x12)
// The axp class lacks a functino to set GPIO0 VDO to 3.3V (as is done by original M5Stack software)
// so do this manually (default value 2.8V did not have the expected effect :))
// data = Read8bit(0x91);
// write1Byte(0x91, (data & 0X0F) | 0XF0);
uint8_t reg;
Wire.beginTransmission((uint8_t)AXP192_SLAVE_ADDRESS);
Wire.write(AXP192_GPIO0_VOL);
Wire.endTransmission();
Wire.requestFrom(AXP192_SLAVE_ADDRESS, 1);
reg = Wire.read();
reg = (reg&0x0F) | 0xF0;
Wire.beginTransmission((uint8_t)AXP192_SLAVE_ADDRESS);
Wire.write(AXP192_GPIO0_VOL);
Wire.write(reg);
Wire.endTransmission();
// data = Read8bit(0x90);
// Write1Byte(0x90, (data & 0XF8) | 0X02)
axp.setGPIOMode(AXP_GPIO_0, AXP_IO_LDO_MODE); // disable AXP supply from VBUS
pmu_irq = 2; // IRQ pin is not connected on Core2
// data = Read8bit(0x12); //read reg 0x12
// Write1Byte(0x12, data | 0x40); // enable 3,3V => 5V booster
// this is done below anyway: axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
// The axp class lacks a functino to set GPIO0 VDO to 3.3V (as is done by original M5Stack software)
// so do this manually (default value 2.8V did not have the expected effect :))
// data = Read8bit(0x91);
// write1Byte(0x91, (data & 0X0F) | 0XF0);
uint8_t reg;
Wire.beginTransmission((uint8_t)AXP192_SLAVE_ADDRESS);
Wire.write(AXP192_GPIO0_VOL);
Wire.endTransmission();
Wire.requestFrom(AXP192_SLAVE_ADDRESS, 1);
reg = Wire.read();
reg = (reg&0x0F) | 0xF0;
Wire.beginTransmission((uint8_t)AXP192_SLAVE_ADDRESS);
Wire.write(AXP192_GPIO0_VOL);
Wire.write(reg);
Wire.endTransmission();
// data = Read8bit(0x90);
// Write1Byte(0x90, (data & 0XF8) | 0X02)
axp.setGPIOMode(AXP_GPIO_0, AXP_IO_LDO_MODE); // disable AXP supply from VBUS
pmu_irq = 2; // IRQ pin is not connected on Core2
// data = Read8bit(0x12); //read reg 0x12
// Write1Byte(0x12, data | 0x40); // enable 3,3V => 5V booster
// this is done below anyway: axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.adc1Enable(AXP202_ACIN_VOL_ADC1, 1);
axp.adc1Enable(AXP202_ACIN_CUR_ADC1, 1);
axp.adc1Enable(AXP202_ACIN_VOL_ADC1, 1);
axp.adc1Enable(AXP202_ACIN_CUR_ADC1, 1);
} else {
// GPS on T-Beam, buzzer on M5 Core2
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
@ -2022,58 +2033,58 @@ void setup()
}
initTouch();
disp.init();
//disp.init();
delay(100);
Serial.println("Showing welcome display");
disp.rdis->welcome();
//disp.rdis->welcome();
delay(3000);
Serial.println("Clearing display");
sonde.clearDisplay();
//sonde.clearDisplay();
setupWifiList();
Serial.printf("before disp.initFromFile... layouts is %p\n", disp.layouts);
//Serial.printf("before disp.initFromFile... layouts is %p\n", disp.layouts);
disp.initFromFile(sonde.config.screenfile);
Serial.printf("disp.initFromFile... layouts is %p", disp.layouts);
//disp.initFromFile(sonde.config.screenfile);
//Serial.printf("disp.initFromFile... layouts is %p", disp.layouts);
// == show initial values from config.txt ========================= //
if (sonde.config.debug == 1) {
disp.rdis->setFont(FONT_SMALL);
disp.rdis->drawString(0, 0, "Config:");
//disp.rdis->setFont(FONT_SMALL);
//disp.rdis->drawString(0, 0, "Config:");
delay(500);
itoa(sonde.config.oled_sda, buf, 10);
disp.rdis->drawString(0, 1, " SDA:");
disp.rdis->drawString(6, 1, buf);
//disp.rdis->drawString(0, 1, " SDA:");
//disp.rdis->drawString(6, 1, buf);
delay(500);
itoa(sonde.config.oled_scl, buf, 10);
disp.rdis->drawString(0, 2, " SCL:");
disp.rdis->drawString(6, 2, buf);
//disp.rdis->drawString(0, 2, " SCL:");
//disp.rdis->drawString(6, 2, buf);
delay(500);
itoa(sonde.config.oled_rst, buf, 10);
disp.rdis->drawString(0, 3, " RST:");
disp.rdis->drawString(6, 3, buf);
//disp.rdis->drawString(0, 3, " RST:");
//disp.rdis->drawString(6, 3, buf);
delay(1000);
itoa(sonde.config.led_pout, buf, 10);
disp.rdis->drawString(0, 4, " LED:");
disp.rdis->drawString(6, 4, buf);
//disp.rdis->drawString(0, 4, " LED:");
//disp.rdis->drawString(6, 4, buf);
delay(500);
itoa(sonde.config.spectrum, buf, 10);
disp.rdis->drawString(0, 5, " SPEC:");
disp.rdis->drawString(6, 5, buf);
//disp.rdis->drawString(0, 5, " SPEC:");
//disp.rdis->drawString(6, 5, buf);
delay(500);
itoa(sonde.config.maxsonde, buf, 10);
disp.rdis->drawString(0, 6, " MAX:");
disp.rdis->drawString(6, 6, buf);
//disp.rdis->drawString(0, 6, " MAX:");
//disp.rdis->drawString(6, 6, buf);
delay(5000);
sonde.clearDisplay();
//sonde.clearDisplay();
}
// == show initial values from config.txt ========================= //
@ -2163,12 +2174,12 @@ void enterMode(int mode) {
mainState = (MainState)mode;
if (mainState == ST_SPECTRUM) {
Serial.println("Entering ST_SPECTRUM mode");
sonde.clearDisplay();
disp.rdis->setFont(FONT_SMALL);
//sonde.clearDisplay();
//disp.rdis->setFont(FONT_SMALL);
specTimer = millis();
//scanner.init();
} else if (mainState == ST_WIFISCAN) {
sonde.clearDisplay();
//sonde.clearDisplay();
}
if (mode == ST_DECODER) {
// trigger activation of background task
@ -2176,8 +2187,8 @@ void enterMode(int mode) {
rxtask.activate = ACT_SONDE(sonde.currentSonde);
//
Serial.println("clearing and updating display");
sonde.clearDisplay();
sonde.updateDisplay();
//sonde.clearDisplay();
//sonde.updateDisplay();
}
printf("enterMode ok\n");
}
@ -2483,12 +2494,12 @@ void loopDecoder() {
}
Serial.print("MAIN: updateDisplay started\n");
if (forceReloadScreenConfig) {
disp.initFromFile(sonde.config.screenfile);
sonde.clearDisplay();
//disp.initFromFile(sonde.config.screenfile);
//sonde.clearDisplay();
forceReloadScreenConfig = false;
}
int t = millis();
sonde.updateDisplay();
//sonde.updateDisplay();
Serial.printf("MAIN: updateDisplay done (after %d ms)\n", (int)(millis() - t));
}
@ -2498,10 +2509,10 @@ void setCurrentDisplay(int value) {
}
void loopSpectrum() {
int marker = 0;
//int marker = 0;
char buf[10];
uint8_t dispw, disph, dispxs, dispys;
disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
//uint8_t dispw, disph, dispxs, dispys;
//disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
switch (getKeyPress()) {
case KP_SHORT: /* move selection of peak, TODO */
@ -2534,21 +2545,21 @@ void loopSpectrum() {
int remaining = sonde.config.spectrum - (millis() - specTimer) / 1000;
Serial.printf("config.spectrum:%d specTimer:%ld millis:%ld remaining:%d\n", sonde.config.spectrum, specTimer, millis(), remaining);
if (sonde.config.marker != 0) {
marker = 1;
//marker = 1;
}
snprintf(buf, 10, "%d Sec.", remaining);
disp.rdis->drawString(0, dispys <= 1 ? (1 + marker) : (dispys + 1)*marker, buf);
//disp.rdis->drawString(0, dispys <= 1 ? (1 + marker) : (dispys + 1)*marker, buf);
if (remaining <= 0) {
setCurrentDisplay(0);
//setCurrentDisplay(0);
enterMode(ST_DECODER);
}
}
}
void startSpectrumDisplay() {
sonde.clearDisplay();
disp.rdis->setFont(FONT_SMALL);
disp.rdis->drawString(0, 0, "Spectrum Scan...");
//sonde.clearDisplay();
//disp.rdis->setFont(FONT_SMALL);
//disp.rdis->drawString(0, 0, "Spectrum Scan...");
delay(500);
enterMode(ST_SPECTRUM);
}
@ -2782,7 +2793,7 @@ void loopWifiBackground() {
// update IP in display
String localIPstr = WiFi.localIP().toString();
sonde.setIP(localIPstr.c_str(), false);
sonde.updateDisplayIP();
//sonde.updateDisplayIP();
enableNetwork(true);
}
if (wifi_cto > 20) { // failed, restart scanning
@ -2792,7 +2803,7 @@ void loopWifiBackground() {
} else if (wifi_state == WIFI_CONNECTED) {
if (!WiFi.isConnected()) {
sonde.setIP("", false);
sonde.updateDisplayIP();
//sonde.updateDisplayIP();
wifi_state = WIFI_DISABLED; // restart scan
enableNetwork(false);
@ -2813,7 +2824,7 @@ void startAP() {
IPAddress myIP = WiFi.softAPIP();
String myIPstr = myIP.toString();
sonde.setIP(myIPstr.c_str(), true);
sonde.updateDisplayIP();
//sonde.updateDisplayIP();
// enableNetwork(true); done later in WifiLoop.
}
@ -2831,22 +2842,22 @@ void initialMode() {
}
void loopTouchCalib() {
uint8_t dispw, disph, dispxs, dispys;
disp.rdis->clear();
disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
//uint8_t dispw, disph, dispxs, dispys;
//disp.rdis->clear();
//disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
char num[10];
while (1) {
int t1 = touchRead(button1.pin & 0x7f);
//int t1 = touchRead(button1.pin & 0x7f);
int t2 = touchRead(button2.pin & 0x7f);
disp.rdis->setFont(FONT_LARGE);
disp.rdis->drawString(0, 0, "Touch calib.");
disp.rdis->drawString(0, 3 * dispys, "Touch1: ");
snprintf(num, 10, "%d ", t1);
disp.rdis->drawString(8 * dispxs, 3 * dispys, num);
disp.rdis->drawString(0, 6 * dispys, "Touch2: ");
//disp.rdis->setFont(FONT_LARGE);
//disp.rdis->drawString(0, 0, "Touch calib.");
//disp.rdis->drawString(0, 3 * dispys, "Touch1: ");
//snprintf(num, 10, "%d ", t1);
//disp.rdis->drawString(8 * dispxs, 3 * dispys, num);
//disp.rdis->drawString(0, 6 * dispys, "Touch2: ");
snprintf(num, 10, "%d ", t2);
disp.rdis->drawString(8 * dispxs, 6 * dispys, num);
//disp.rdis->drawString(8 * dispxs, 6 * dispys, num);
delay(300);
}
}
@ -2858,7 +2869,7 @@ void loopTouchCalib() {
// 3: traditional sync. WifiScan. Tries to connect to a network, in case of failure activates AP.
// Mode 3 shows more debug information on serial port and display.
#define MAXWIFIDELAY 40
static const char* _scan[2] = {"/", "\\"};
//static const char* _scan[2] = {"/", "\\"};
void loopWifiScan() {
if (sonde.config.wifi == 0) { // no Wifi
wifi_state = WIFI_DISABLED;
@ -2877,12 +2888,12 @@ void loopWifiScan() {
return;
}
// wifi==3 => original mode with non-async wifi setup
disp.rdis->setFont(FONT_SMALL);
disp.rdis->drawString(0, 0, "WiFi Scan...");
uint8_t dispw, disph, dispxs, dispys;
disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
//disp.rdis->setFont(FONT_SMALL);
//disp.rdis->drawString(0, 0, "WiFi Scan...");
//uint8_t dispw, disph, dispxs, dispys;
//disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
int line = 0;
//int line = 0;
int cnt = 0;
WiFi.disconnect(true);
@ -2891,8 +2902,8 @@ void loopWifiScan() {
int n = WiFi.scanNetworks();
for (int i = 0; i < n; i++) {
String ssid = WiFi.SSID(i);
disp.rdis->drawString(0, dispys * (1 + line), ssid.c_str());
line = (line + 1) % (disph / dispys);
//disp.rdis->drawString(0, dispys * (1 + line), ssid.c_str());
//line = (line + 1) % (disph / dispys);
String mac = WiFi.BSSIDstr(i);
String encryptionTypeDescription = translateEncryptionType(WiFi.encryptionType(i));
Serial.printf("Network %s: RSSI %d, MAC %s, enc: %s\n", ssid.c_str(), WiFi.RSSI(i), mac.c_str(), encryptionTypeDescription.c_str());
@ -2902,18 +2913,18 @@ void loopWifiScan() {
Serial.printf("Match found at scan entry %d, config network %d\n", i, index);
}
}
int lastl = (disph / dispys - 2) * dispys;
//int lastl = (disph / dispys - 2) * dispys;
if (index >= 0) { // some network was found
Serial.print("Connecting to: "); Serial.print(fetchWifiSSID(index));
Serial.print(" with password "); Serial.println(fetchWifiPw(index));
disp.rdis->drawString(0, lastl, "Conn:");
disp.rdis->drawString(6 * dispxs, lastl, fetchWifiSSID(index));
//disp.rdis->drawString(0, lastl, "Conn:");
//disp.rdis->drawString(6 * dispxs, lastl, fetchWifiSSID(index));
WiFi.begin(fetchWifiSSID(index), fetchWifiPw(index));
while (WiFi.status() != WL_CONNECTED && cnt < MAXWIFIDELAY) {
delay(500);
Serial.print(".");
disp.rdis->drawString(15 * dispxs, lastl + dispys, _scan[cnt & 1]);
//disp.rdis->drawString(15 * dispxs, lastl + dispys, _scan[cnt & 1]);
cnt++;
}
}
@ -2924,8 +2935,8 @@ void loopWifiScan() {
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
disp.rdis->drawString(0, lastl, "AP: ");
disp.rdis->drawString(6 * dispxs, lastl + 1, networks[0].id.c_str());
//disp.rdis->drawString(0, lastl, "AP: ");
//disp.rdis->drawString(6 * dispxs, lastl + 1, networks[0].id.c_str());
delay(3000);
} else {
Serial.println("");
@ -2934,7 +2945,7 @@ void loopWifiScan() {
String localIPstr = WiFi.localIP().toString();
Serial.println(localIPstr);
sonde.setIP(localIPstr.c_str(), false);
sonde.updateDisplayIP();
//sonde.updateDisplayIP();
wifi_state = WIFI_CONNECTED;
bool hasRS92 = false;
for (int i = 0; i < MAXSONDE; i++) {
@ -2963,20 +2974,22 @@ String getHeaderValue(String header, String headerName) {
void execOTA() {
int contentLength = 0;
bool isValidContentType = false;
sonde.clearDisplay();
uint8_t dispxs, dispys;
//sonde.clearDisplay();
//uint8_t dispxs,
//uint8_t dispys;
if ( ISOLED(sonde.config) ) {
disp.rdis->setFont(FONT_SMALL);
dispxs = dispys = 1;
//disp.rdis->setFont(FONT_SMALL);
//dispxs =
//dispys = 1;
char uh[17];
strncpy(uh, updateHost, 17);
uh[16] = 0;
disp.rdis->drawString(0, 0, uh);
//disp.rdis->drawString(0, 0, uh);
} else {
disp.rdis->setFont(5);
dispxs = 18;
dispys = 20;
disp.rdis->drawString(0, 0, updateHost);
//disp.rdis->setFont(5);
//dispxs = 18;
//dispys = 20;
//disp.rdis->drawString(0, 0, updateHost);
}
Serial.print("Connecting to: "); Serial.println(updateHost);
@ -2988,7 +3001,7 @@ void execOTA() {
// First, update file system
Serial.println("Fetching fs update");
disp.rdis->drawString(0, 1 * dispys, "Fetching fs...");
//disp.rdis->drawString(0, 1 * dispys, "Fetching fs...");
client.printf("GET %supdate.fs.bin HTTP/1.1\r\n"
"Host: %s\r\n"
"Cache-Control: no-cache\r\n"
@ -3018,7 +3031,7 @@ void execOTA() {
memset(fnstr, ' ', 16);
strncpy(fnstr, fn, 16);
fnstr[16] = 0;
disp.rdis->drawString(0, 2 * dispys, fnstr);
//disp.rdis->drawString(0, 2 * dispys, fnstr);
File f = SPIFFS.open(fn, FILE_WRITE);
// read sz bytes........
while (len > 0) {
@ -3043,7 +3056,7 @@ void execOTA() {
// Connection succeeded, fecthing the bin
Serial.printf("Fetching bin: %supdate.ino.bin\n", updatePrefix);
disp.rdis->drawString(0, 3 * dispys, "Fetching update");
//disp.rdis->drawString(0, 3 * dispys, "Fetching update");
// Get the contents of the bin file
client.printf("GET %supdate.ino.bin HTTP/1.1\r\n"
@ -3064,9 +3077,9 @@ void execOTA() {
// Check what is the contentLength and if content type is `application/octet-stream`
Serial.println("contentLength : " + String(contentLength) + ", isValidContentType : " + String(isValidContentType));
disp.rdis->drawString(0, 4 * dispys, "Len: ");
//disp.rdis->drawString(0, 4 * dispys, "Len: ");
String cls = String(contentLength);
disp.rdis->drawString(5 * dispxs, 4 * dispys, cls.c_str());
//disp.rdis->drawString(5 * dispxs, 4 * dispys, cls.c_str());
// check contentLength and content type
if (contentLength && isValidContentType) {
@ -3075,7 +3088,7 @@ void execOTA() {
// If yes, begin
if (canBegin) {
disp.rdis->drawString(0, 5 * dispys, "Starting update");
//disp.rdis->drawString(0, 5 * dispys, "Starting update");
Serial.println("Begin OTA. This may take 2 - 5 mins to complete. Things might be quite for a while.. Patience!");
// No activity would appear on the Serial monitor
// So be patient. This may take 2 - 5mins to complete
@ -3093,7 +3106,7 @@ void execOTA() {
Serial.println("OTA done!");
if (Update.isFinished()) {
Serial.println("Update successfully completed. Rebooting.");
disp.rdis->drawString(0, 7 * dispys, "Rebooting....");
//disp.rdis->drawString(0, 7 * dispys, "Rebooting....");
delay(1000);
ESP.restart();
} else {
@ -3218,10 +3231,10 @@ void loop() {
#endif
loopWifiBackground();
if (currentDisplay != lastDisplay && (mainState == ST_DECODER)) {
disp.setLayout(currentDisplay);
sonde.clearDisplay();
sonde.updateDisplay();
lastDisplay = currentDisplay;
//disp.setLayout(currentDisplay);
//sonde.clearDisplay();
//sonde.updateDisplay();
//lastDisplay = currentDisplay;
}
#if FEATURE_MQTT

View File

@ -16,6 +16,7 @@
<a href="#" onclick="selTab(event,'Data')" class="tablinks">Data</a>
<a href="#" onclick="document.location.href='livemap.html'" class="tablinks">LiveMap</a>
<a href="#" onclick="selTab(event,'Map')" class="tablinks">Map</a>
<a href="#" onclick="selTab(event,'Spectrum')" class="tablinks">Spectrum</a>
<a href="#" onclick="selTab(event,'Config')" class="tablinks">Config</a>
<a href="#" onclick="selTab(event,'Control')" class="tablinks">Control</a>
<a href="#" onclick="selTab(event,'About')" class="tablinks">About</a>
@ -41,6 +42,10 @@
<iframe class="tci" src="" ></iframe>
</div>
<div id="Spectrum" class="tabcontent" data-src="spectrum.html">
<iframe class="tci" src="" ></iframe>
</div>
<div id="Config" class="tabcontent" data-src="config.html">
<iframe class="tci" src="" ></iframe>
</div>

View File

@ -1,4 +1,4 @@
RDZsonde
RDZsonde
DinoGast
Schokolade
NETGEAR12
vanillagrasshopper651

View File

@ -1,17 +1,7 @@
# Frequency in Mhz (format nnn.nnn)
# Type (4=RS41, 6=DFM normal, DFM-06, 9=DFM inverted, DFM-09)
#
402.300 4 + Greifswald
402.500 4 - Schleswig
402.700 4 + HH-Sasel
403.000 4 - DeBilt
404.100 4 + Norderney
404.300 4 - Schleswig_2
404.500 4 - Meppen
404.700 4 - Greifswald_2
405.100 4 - Lindenberg
405.700 4 + Bergen
405.900 4 + Bergen_2
405.100 4 + Meppen_2
405.300 4 - Essen
403.000 4 + Jokioinen
405.300 4 + Sundsvall
404.000 4 + Tallinn
# end

129
RX_FSK/data/spectrum.html Normal file
View File

@ -0,0 +1,129 @@
<!DOCTYPE html>
<html>
<head>
<title>rdzTTGOSonde Spectrum by OH3BSG</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<link rel="icon" href="data:,">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="wrapper"><div class="header">
<h2>rdzTTGOSonde Spectrum</h2>
<div class="topnav" id="myTopnav">
<a href="#" onclick="selTab(event,'QRG')" class="tablinks" id="defaultTab">QRG</a>
<a href="#" onclick="selTab(event,'WiFi')" class="tablinks">WiFi</a>
<a href="#" onclick="selTab(event,'Data')" class="tablinks">Data</a>
<a href="#" onclick="document.location.href='livemap.html'" class="tablinks">LiveMap</a>
<a href="#" onclick="selTab(event,'Map')" class="tablinks">Map</a>
<a href="#" onclick="selTab(event,'Spectrum')" class="tablinks">Spectrum</a>
<a href="#" onclick="selTab(event,'Config')" class="tablinks">Config</a>
<a href="#" onclick="selTab(event,'Control')" class="tablinks">Control</a>
<a href="#" onclick="selTab(event,'About')" class="tablinks">About</a>
<a href="javascript:void(0);" class="icon" onclick="myFunction()">
<span class="hamburger"></span>
</a>
</div>
</div>
<div id="QRG" class="tabcontent" data-src="qrg.html">
<iframe class="tci" src="" ></iframe>
</div>
<div id="WiFi" class="tabcontent" data-src="wifi.html">
<iframe class="tci" src="" ></iframe>
</div>
<div id="Data" class="tabcontent" data-src="status.html">
<iframe class="tci" src="" ></iframe>
</div>
<div id="Map" class="tabcontent" data-src="map.html">
<iframe class="tci" src="" ></iframe>
</div>
<div id="Spectrum" class="tabcontent" data-src="spectrum.html">
<iframe class="tci" src="" ></iframe>
</div>
<div id="Config" class="tabcontent" data-src="config.html">
<iframe class="tci" src="" ></iframe>
</div>
<div id="Control" class="tabcontent" data-src="control.html">
<iframe class="tci" src="" ></iframe>
</div>
<div id="About" class="tabcontent">
<div class="tci">
%VERSION_NAME%<br>
Copyright &copy; 2019-2021 by Hansi Reiser, DL9RDZ<br>
(version %VERSION_ID%)<br><br>
<a href="/upd.html">Check for update (requires TTGO internet connection via WiFi)</a><br><br>
with contributions by Vigor and Xavier (M20 support),
<a href="https://github.com/LukePrior">Luke Prior</a> and <a href="https://github.com/oh3bsg">OH3BSG</a> (SondeHub support),
<a href="https://www.dl2mf.de/" target="_blank">Meinhard Guenther, DL2MF</a>,
<a href="https://github.com/bazjo">Johannes</a>, <a href="http://www.p1337.synology.me/dokuwiki/doku.php?id=public:wettersonden">Robert Stefanowicz</a>,
<a href="https://github.com/puspis">Josema</a>, and probably some more people I forgot to mention here.
<br>
<br>
Autodetect info: %AUTODETECT_INFO%<br>
<br>
RS92 RINEX eph state: %EPHSTATE%<br>
<br>
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 2 of
the License, or (at your option) any later version.<br>
See <a href="https://www.gnu.org/licenses/gpl-2.0.txt">https://www.gnu.org/licenses/gpl-2.0.txt</a>
for details.
</div>
</div>
</div>
<script>
function selTab(evt, id) {
var i, tabcontent, tablinks;
tabcontent=document.getElementsByClassName("tabcontent");
for(i=0; i<tabcontent.length; i++) {
tabcontent[i].style.display = "none";
var link = tabcontent[i].dataset.src;
if(link) {
var iframe = tabcontent[i].getElementsByTagName("iframe")[0];
iframe.setAttribute("src", "");
}
}
tablinks=document.getElementsByClassName("tablinks");
for(i=0; i<tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
var act = document.getElementById(id);
act.style.display = "flex";
evt.currentTarget.className += " active";
var link = act.dataset.src;
if(link) {
var iframe = act.getElementsByTagName("iframe")[0];
iframe.setAttribute("src", link);
}
var x = document.getElementById("myTopnav");
x.className = "topnav";
}
/* Toggle between adding and removing the "responsive" class to topnav when the user clicks on the icon */
function myFunction() {
var x = document.getElementById("myTopnav");
if (x.className === "topnav") {
x.className += " responsive";
} else {
x.className = "topnav";
}
}
document.getElementById("defaultTab").click();
</script>
</body>
</html>

View File

@ -1,3 +1,4 @@
#if 0
#include "../features.h"
#include <U8x8lib.h>
#include <U8g2lib.h>
@ -1780,3 +1781,4 @@ void Display::updateDisplay() {
}
Display disp = Display();
#endif // 0

View File

@ -1,3 +1,4 @@
#if 0
#ifndef Display_h
#define Display_h
@ -199,4 +200,5 @@ public:
extern Display disp;
#endif
#endif
#endif // 0

View File

@ -1,10 +1,10 @@
#include "Scanner.h"
#include <U8x8lib.h>
//#include <U8x8lib.h>
#include "SX1278FSK.h"
#include "Sonde.h"
#include "Display.h"
//#include "Display.h"
double STARTF;
@ -80,19 +80,19 @@ void Scanner::plotResult()
yofs = 2;
if (sonde.config.marker != 0) {
itoa((sonde.config.startfreq), buf, 10);
disp.rdis->drawString(0, 1, buf);
disp.rdis->drawString(scanconfig.PLOT_W/2-10, 1, "MHz");
//disp.rdis->drawString(0, 1, buf);
//disp.rdis->drawString(scanconfig.PLOT_W/2-10, 1, "MHz");
itoa((sonde.config.startfreq + 6), buf, 10);
disp.rdis->drawString(scanconfig.PLOT_W-15, 1, buf);
//disp.rdis->drawString(scanconfig.PLOT_W-15, 1, buf);
}
}
else {
if (sonde.config.marker != 0) {
itoa((sonde.config.startfreq), buf, 10);
disp.rdis->drawString(0, 1, buf);
disp.rdis->drawString(7, 1, "MHz");
//disp.rdis->drawString(0, 1, buf);
//disp.rdis->drawString(7, 1, "MHz");
itoa((sonde.config.startfreq + 6), buf, 10);
disp.rdis->drawString(13, 1, buf);
//disp.rdis->drawString(13, 1, buf);
}
}
uint8_t row[scanconfig.PLOT_H8*8];
@ -108,15 +108,15 @@ void Scanner::plotResult()
// don't overwrite MHz marker text
if(i<3*8 || (i>=7*8&&i<10*8) || i>=13*8) continue;
}
disp.rdis->drawTile(i/8, y+yofs, 1, row+8*y);
//disp.rdis->drawTile(i/8, y+yofs, 1, row+8*y);
}
}
if(ISTFT) { // large TFT
sprintf(buf, "Peak: %03.3f MHz", peakf*0.000001);
disp.rdis->drawString(0, (yofs+scanconfig.PLOT_H8+1)*8, buf);
//disp.rdis->drawString(0, (yofs+scanconfig.PLOT_H8+1)*8, buf);
} else {
sprintf(buf, "Peak: %03.3fMHz", peakf*0.000001);
disp.rdis->drawString(0, 7, buf);
//disp.rdis->drawString(0, 7, buf);
}
}

View File

@ -7,6 +7,7 @@
#include "ShFreqImport.h"
#include "Sonde.h"
//#include "headless.h"
static int ppos;
static int quotes;
@ -25,7 +26,6 @@ static int valuepos;
static int importState;
static float homelat, homelon;
// Map SondeHub type string to Stype. -1 for not supported types.
int ShFreqImport::stringToStype(const char *type) {
if(type[2]=='4') return STYPE_RS41;

View File

@ -1,5 +1,5 @@
#include <U8x8lib.h>
#include <U8g2lib.h>
//#include <U8x8lib.h>
//#include <U8g2lib.h>
#include "Sonde.h"
#include "RS41.h"
@ -8,7 +8,7 @@
#include "M10M20.h"
#include "MP3H.h"
#include "SX1278FSK.h"
#include "Display.h"
//#include "Display.h"
#include <Wire.h>
uint8_t debug = 255-8-16;
@ -106,7 +106,7 @@ void Sonde::defaultConfig() {
config.button2_axp = 0;
config.norx_timeout = 20;
config.screenfile = 1;
config.tft_spifreq = SPI_DEFAULT_FREQ;
//config.tft_spifreq = SPI_DEFAULT_FREQ;
if(initlevels[16]==0) {
config.oled_sda = 4;
config.oled_scl = 15;
@ -507,11 +507,12 @@ void Sonde::receive() {
int event = getKeyPressEvent();
if (!event) event = timeoutEvent(si);
int action = (event==EVT_NONE) ? ACT_NONE : disp.layout->actions[event];
//int action = (event==EVT_NONE) ? ACT_NONE : disp.layout->actions[event];
//if(action!=ACT_NONE) { Serial.printf("event %x: action is %x\n", event, action); }
// If action is to move to a different sonde index, we do update things here, set activate
// to force the sx1278 task to call sonde.setup(), and pass information about sonde to
// main loop (display update...)
#if 0
if(action == ACT_DISPLAY_SCANNER || action == ACT_NEXTSONDE || action==ACT_PREVSONDE || (action>64&&action<128) ) {
// handled here...
if(action==ACT_DISPLAY_SCANNER) {
@ -529,8 +530,9 @@ void Sonde::receive() {
rxtask.activate = ACT_SONDE(rxtask.currentSonde);
}
}
Serial.printf("Sonde:receive(): result %d (%s), event %02x => action %02x\n", res, (res<=3)?RXstr[res]:"?", event, action);
res = (action<<8) | (res&0xff);
#endif // 0
//Serial.printf("Sonde:receive(): result %d (%s), event %02x => action %02x\n", res, (res<=3)?RXstr[res]:"?", event, action);
//res = (action<<8) | (res&0xff);
// let waitRXcomplete resume...
rxtask.receiveResult = res;
}
@ -548,7 +550,7 @@ rxloop:
if( rxtask.receiveResult == RX_UPDATERSSI ) {
rxtask.receiveResult = 0xFFFF;
Serial.printf("RSSI update: %d/2\n", sonde.si()->rssi);
disp.updateDisplayRSSI();
//disp.updateDisplayRSSI();
goto rxloop;
}
@ -594,6 +596,7 @@ uint8_t Sonde::timeoutEvent(SondeInfo *si) {
now, si->rxStart, disp.layout->timeouts[1],
now, si->norxStart, disp.layout->timeouts[2], si->lastState);
#endif
#if 0
if(disp.layout->timeouts[0]>=0 && now - si->viewStart >= disp.layout->timeouts[0]) {
Serial.println("Sonde::timeoutEvent: View");
return EVT_VIEWTO;
@ -606,6 +609,7 @@ uint8_t Sonde::timeoutEvent(SondeInfo *si) {
Serial.println("Sonde::timeoutEvent: NORX");
return EVT_NORXTO;
}
#endif // 0
return 0;
}
@ -631,7 +635,7 @@ uint8_t Sonde::updateState(uint8_t event) {
} else if(event==ACT_DISPLAY_NEXT) {
int i;
for(i=0; config.display[i]!=-1; i++) {
if(config.display[i] == disp.layoutIdx) break;
//if(config.display[i] == disp.layoutIdx) break;
}
if(config.display[i]==-1 || config.display[i+1]==-1) {
//unknown index, or end of list => loop to start
@ -641,13 +645,13 @@ uint8_t Sonde::updateState(uint8_t event) {
}
}
if(n>=0 && n<ACT_MAXDISPLAY) {
if(n>=disp.nLayouts) {
Serial.println("WARNNG: next layout out of range");
n = config.display[1];
}
//if(n>=disp.nLayouts) {
// Serial.println("WARNNG: next layout out of range");
// n = config.display[1];
//}
Serial.printf("Setting display mode %d\n", n);
disp.setLayout(n);
sonde.clearDisplay();
//disp.setLayout(n);
//sonde.clearDisplay();
return 0xFF;
}
@ -679,6 +683,7 @@ void Sonde::clearAllData(SondeInfo *si) {
si->d.temperature = si->d.tempRHSensor = si->d.relativeHumidity = si->d.pressure = si->d.batteryVoltage = NAN;
}
#if 0
void Sonde::updateDisplayPos() {
disp.updateDisplayPos();
}
@ -715,7 +720,7 @@ void Sonde::updateDisplay()
void Sonde::clearDisplay() {
disp.rdis->clear();
}
#endif // 0
SondeType Sonde::realType(SondeInfo *si) {
if(TYPE_IS_METEO(si->type) && si->d.subtype>0 ) { return si->d.subtype==1 ? STYPE_M10:STYPE_M20; }
else return si->type;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
// original source: https://github.com/Nkawu/TFT22_ILI9225
#if 0
#include "TFT22_ILI9225.h"
@ -1416,4 +1416,4 @@ void TFT22_ILI9225::getGFXTextExtent(STRING str, int16_t x, int16_t y, int16_t *
}
if(*w>0) (*w)--;
}
#endif // 0

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
// original source: https://github.com/Nkawu/TFT22_ILI9225
#if 0
#ifndef TFT22_ILI9225_h
#define TFT22_ILI9225_h
@ -469,3 +469,4 @@ class TFT22_ILI9225 {
};
#endif
#endif // 0

View File

@ -5,7 +5,7 @@
#include <rom/miniz.h>
#include <inttypes.h>
#include <WiFi.h>
#include "Display.h"
//#include "Display.h"
#include "Sonde.h"
extern WiFiClient client;
@ -89,16 +89,16 @@ void geteph() {
if(!buf) { Serial.println("Invalid FTP host config"); return; }
*buf = 0;
buf++;
uint8_t dispw, disph, dispxs, dispys;
disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
disp.rdis->clear();
disp.rdis->setFont(FONT_SMALL);
disp.rdis->drawString(0, 0, host);
//uint8_t dispw, disph, dispxs, dispys;
//disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
//disp.rdis->clear();
//disp.rdis->setFont(FONT_SMALL);
//disp.rdis->drawString(0, 0, host);
// fetch rinex from server
char *ptr = buf + strlen(buf);
snprintf(ptr, 128, "%04d/%03d/brdc%03d0.%02dn.gz", year, day, day, year-2000);
Serial.println("running geteph\n");
disp.rdis->drawString(0, 1*dispys, ptr+9);
//disp.rdis->drawString(0, 1*dispys, ptr+9);
if(!client.connect(host, 21)) {
Serial.printf("FTP connection to %s failed\n", host);
@ -156,9 +156,9 @@ void geteph() {
fh.close();
snprintf(buf, 16, "Fetched %d B ",len);
buf[16]=0;
disp.rdis->drawString(0,2*dispys,buf);
//disp.rdis->drawString(0,2*dispys,buf);
disp.rdis->drawString(0,4*dispys,"Decompressing...");
//disp.rdis->drawString(0,4*dispys,"Decompressing...");
// decompression
tinfl_decompressor *decomp = (tinfl_decompressor *)malloc(sizeof(tinfl_decompressor));
tinfl_init(decomp);
@ -226,7 +226,7 @@ void geteph() {
status.close();
snprintf(buf, 16, "Done: %d B ",total);
buf[16]=0;
disp.rdis->drawString(0,5*dispys,buf);
//disp.rdis->drawString(0,5*dispys,buf);
ephstate = EPH_GOOD;
delay(1000);

View File

@ -6,6 +6,7 @@
// To use a font in your Arduino sketch, #include the corresponding .h
// file and pass address of GFXfont struct to setFont().
#if 0
#ifndef _GFFFONT_H_
#define _GFFFONT_H_
@ -24,3 +25,4 @@ typedef struct { // Data stored for FONT AS A WHOLE:
} GFXfont;
#endif // _GFFFONT_H_
#endif // 0

20
RX_FSK/src/headless.c Normal file
View File

@ -0,0 +1,20 @@
#include <Arduino.h>
#include <math.h>
#include "headless.h"
//#define EARTH_RADIUS (6371000.0F)
#ifndef PI
#define PI (3.1415926535897932384626433832795)
#endif
// defined by Arduino.h #define radians(x) ( (x)*180.0F/PI )
struct GpsPos gpsPos;
/*
float calcLatLonDist(float lat1, float lon1, float lat2, float lon2) {
float x = radians(lon1-lon2) * cos( radians((lat1+lat2)/2) );
float y = radians(lat2-lat1);
float d = sqrt(x*x+y*y)*EARTH_RADIUS;
return d;
}
*/

19
RX_FSK/src/headless.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef HEADLESS_H
#define HEADLESS_H
struct GpsPos {
double lat;
double lon;
int alt;
int course;
float speed;
int sat;
int accuracy;
int hdop;
int valid;
};
extern struct GpsPos gpsPos;
//float calcLatLonDist(float lat1, float lon1, float lat2, float lon2);
#endif // HEADLESS_H

View File

@ -45,3 +45,25 @@ lib_ignore = Time
;
extra_scripts = post:scripts/makefontpartition.py
;board_build.partitions = partition-fonts.csv
[env:ttgo-lora32-headless]
platform = https://github.com/platformio/platform-espressif32.git
board = ttgo-lora32-v1
framework = arduino
monitor_speed = 115200
lib_deps =
${extra.lib_deps_builtin}
${extra.lib_deps_external}
paulstoffregen/Time@^1.6.0
lib_ignore = Time
; Add / remove the following two lines for separate fonts partition in flash
; after changes:
; - pio run --target=upload (uploads partition table)
; - pio run --target=uploadfs (uploads file system matching the new partition table)
; if enable also do:
; - pio run --target=uploadfonts (uploads fonts.bin created during the first pio run)
; Then everything should be "back to normal"
;
extra_scripts = post:scripts/makefontpartition.py
;board_build.partitions = partition-fonts.csv