fix spectrum display for LCD, better display for TFT

This commit is contained in:
Hansi, dl9rdz 2020-11-11 00:12:10 +01:00
parent 052f502d45
commit fa75c20584
4 changed files with 126 additions and 49 deletions

View File

@ -1766,13 +1766,7 @@ void loopSpectrum() {
scanner.scan(); scanner.scan();
scanner.plotResult(); scanner.plotResult();
if (sonde.config.marker != 0) {
itoa((sonde.config.startfreq), buf, 10);
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);
}
if (sonde.config.spectrum > 0) { if (sonde.config.spectrum > 0) {
int remaining = sonde.config.spectrum - (millis() - specTimer) / 1000; int remaining = sonde.config.spectrum - (millis() - specTimer) / 1000;
itoa(remaining, buf, 10); itoa(remaining, buf, 10);

View File

@ -1,4 +1,4 @@
const char *version_name = "rdzTTGOsonde"; const char *version_name = "rdzTTGOsonde";
const char *version_id = "devel20200728"; const char *version_id = "devel20201111";
const int SPIFFS_MAJOR=2; const int SPIFFS_MAJOR=2;
const int SPIFFS_MINOR=4; const int SPIFFS_MINOR=4;

View File

@ -399,7 +399,14 @@ void ILI9225Display::drawString(uint8_t x, uint8_t y, const char *s, int16_t wid
} }
if(width==WIDTH_AUTO || alignright) { if(width==WIDTH_AUTO || alignright) {
tft->getGFXTextExtent(s, x, y + gfxoffsets[findex-3].yofs, &w, &h); tft->getGFXTextExtent(s, x, y + gfxoffsets[findex-3].yofs, &w, &h);
if(width==WIDTH_AUTO) width=w; if(width==WIDTH_AUTO) {
width=w;
if(alignright) {
x -= w;
Serial.print("reducing x by widht, its now ");
Serial.println(x);
}
}
} }
if(findex-3>=ngfx) findex=3; if(findex-3>=ngfx) findex=3;
@ -413,7 +420,7 @@ void ILI9225Display::drawString(uint8_t x, uint8_t y, const char *s, int16_t wid
} }
void ILI9225Display::drawTile(uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr) { void ILI9225Display::drawTile(uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr) {
tft->drawTile(x, 2*y, cnt, tile_ptr); tft->drawTile(x, y, cnt, tile_ptr);
#if 0 #if 0
int i,j; int i,j;
tft->startWrite(); tft->startWrite();

View File

@ -5,76 +5,136 @@
#include "Sonde.h" #include "Sonde.h"
#include "Display.h" #include "Display.h"
#define CHANBW 10
#define PIXSAMPL (50/CHANBW) double STARTF;
#define SMOOTH 3
struct scancfg {
int PLOT_W; // Width of plot, in pixel
int PLOT_H8; // Height of plot, in 8 pixel units
int TICK1; // Pixel per MHz marker
int TICK2; // Pixel per sub-Mhz marker (250k or 200k)
double CHANSTEP; // Scanner frequenz steps
int SMPL_PIX; // Frequency steps per pixel
int NCHAN; // number of channels to scan, PLOT_W * SMPL_PIX
int SMOOTH;
};
struct scancfg scanLCD={ 121, 7, 120/6, 120/6/4, 6000.0/120.0/10.0, 10, 120*10, 2 };
struct scancfg scanTFT={ 210, 16, 210/6, 210/6/5, 6000.0/210.0/10.0, 10, 210*10, 1 };
struct scancfg &scanconfig = scanTFT;
#define CHANBW 12500
//#define PIXSAMPL (50/CHANBW)
//#define STARTF 401000000 //#define STARTF 401000000
#define NCHAN ((int)(6000/CHANBW))
double STARTF = (sonde.config.startfreq * 1000000); // max of 120*5 and 210*3
//int CHANBW = (sonde.config.channelbw); #define MAXN 210*10
//int NCHAN = ((int)(6000/CHANBW)); // max of 120 and 210 (ceil(210/8)*8))
//int PIXSAMPL = (50/CHANBW); #define MAXDISP 216
int scanresult[NCHAN]; int scanresult[MAXN];
int scandisp[NCHAN/PIXSAMPL]; int scandisp[MAXDISP];
double peakf=0;
#define PLOT_N 128
#define TICK1 (128/6)
#define TICK2 (TICK1/4)
//#define PLOT_MIN -250 //#define PLOT_MIN -250
#define PLOT_MIN (sonde.config.noisefloor*2) #define PLOT_MIN (sonde.config.noisefloor*2)
#define PLOT_SCALE(x) (x<PLOT_MIN?0:(x-PLOT_MIN)/2) #define PLOT_SCALE(x) (x<PLOT_MIN?0:(x-PLOT_MIN)/2)
const byte tilepatterns[9]={0,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF}; const byte tilepatterns[9]={0,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF};
void Scanner::fillTiles(uint8_t *row, int value) { void Scanner::fillTiles(uint8_t *row, int value) {
for(int y=0; y<8; y++) { for(int y=0; y<scanconfig.PLOT_H8; y++) {
int nbits = value - 8*(7-y); int nbits = value - 8*(scanconfig.PLOT_H8-1-y);
if(nbits<0) { row[8*y]=0; continue; } if(nbits<0) { row[8*y]=0; continue; }
if(nbits>=8) { row[8*y]=255; continue; } if(nbits>=8) { row[8*y]=255; continue; }
row[8*y] = tilepatterns[nbits]; row[8*y] = tilepatterns[nbits];
} }
} }
/* /* LCD:
* There are 16*8 columns to plot, NPLOT must be lower than that * There are 16*8 columns to plot, NPLOT must be lower than that
* currently, we use 128 * 50kHz channels * currently, we use 128 * 50kHz channels
* There are 8*8 values to plot; MIN is bottom end, * There are 8*8 values to plot; MIN is bottom end,
* TFT:
* There are 210 columns to plot
* Currently we use 210 * (6000/120)kHz channels, i.e. 28.5714kHz
*/ */
uint8_t tiles[16] = { 0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0, 1, 3, 7, 15, 31, 63, 127, 255}; ///// unused???? uint8_t tiles[16] = { 0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0, 1, 3, 7, 15, 31, 63, 127, 255};
void Scanner::plotResult() void Scanner::plotResult()
{ {
uint8_t row[8*8]; int yofs = 0;
for(int i=0; i<PLOT_N; i+=8) { char buf[30];
if(sonde.config.disptype != 0) {
yofs = 2;
if (sonde.config.marker != 0) {
itoa((sonde.config.startfreq), buf, 10);
disp.rdis->drawString(0, 1, buf);
disp.rdis->drawString(95, 1, "MHz");
itoa((sonde.config.startfreq + 6), buf, 10);
disp.rdis->drawString(195, 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");
itoa((sonde.config.startfreq + 6), buf, 10);
disp.rdis->drawString(13, 1, buf);
}
}
uint8_t row[scanconfig.PLOT_H8*8];
for(int i=0; i<scanconfig.PLOT_W; i+=8) {
for(int j=0; j<8; j++) { for(int j=0; j<8; j++) {
fillTiles(row+j, PLOT_SCALE(scandisp[i+j])); fillTiles(row+j, PLOT_SCALE(scandisp[i+j]));
if( ((i+j)%TICK1)==0) { row[j] |= 0x07; } if( (i+j)>=scanconfig.PLOT_W ) { for(int y=0; y<scanconfig.PLOT_H8; y++) row[j+8*y]=0; }
if( ((i+j)%TICK2)==0) { row[j] |= 0x01; } if( ((i+j)%scanconfig.TICK1)==0) { row[j] |= 0x07; }
if( ((i+j)%scanconfig.TICK2)==0) { row[j] |= 0x01; }
} }
for(int y=0; y<8; y++) { for(int y=0; y<scanconfig.PLOT_H8; y++) {
if(sonde.config.marker && y==1) { if(sonde.config.marker && y==1 && sonde.config.disptype==0 ) {
// don't overwrite MHz marker text // don't overwrite MHz marker text
if(i<3*8 || (i>=7*8&&i<10*8) || i>=13*8) continue; if(i<3*8 || (i>=7*8&&i<10*8) || i>=13*8) continue;
} }
disp.rdis->drawTile(i/8, y, 1, row+8*y); disp.rdis->drawTile(i/8, y+yofs, 1, row+8*y);
} }
} }
if(sonde.config.disptype != 0) { // large TFT
sprintf(buf, "Peak: %03.3f MHz", peakf*0.000001);
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);
}
} }
void Scanner::scan() void Scanner::scan()
{ {
if(sonde.config.disptype==0) { // LCD small
scanconfig = scanLCD;
} else {
scanconfig = scanTFT;
}
// Configure // Configure
STARTF = (sonde.config.startfreq * 1000000);
sx1278.writeRegister(REG_PLL_HOP, 0x80); // FastHopOn sx1278.writeRegister(REG_PLL_HOP, 0x80); // FastHopOn
sx1278.setRxBandwidth(CHANBW*1000); sx1278.setRxBandwidth((int)(scanconfig.CHANSTEP*1000));
sx1278.writeRegister(REG_RSSI_CONFIG, SMOOTH&0x07); double bw = sx1278.getRxBandwidth();
Serial.print("RX Bandwith for scan: "); Serial.println(bw);
sx1278.writeRegister(REG_RSSI_CONFIG, scanconfig.SMOOTH&0x07);
sx1278.setFrequency(STARTF); sx1278.setFrequency(STARTF);
Serial.print("Start freq = "); Serial.println(STARTF);
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE); sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
delay(20);
unsigned long start = millis(); unsigned long start = millis();
uint32_t lastfrf=-1; uint32_t lastfrf= STARTF * (1<<19) / SX127X_CRYSTAL_FREQ;
for(int iter=0; iter<2; iter++) { // two interations, to catch all RS41 transmissions float freq;
for(int i=0; i<NCHAN; i++) { int wait = 20 + 1000*(1<<(scanconfig.SMOOTH+1))/4/(0.001*CHANBW);
float freq = STARTF + 1000.0*i*CHANBW; for(int iter=0; iter<3; iter++) { // two interations, to catch all RS41 transmissions
delayMicroseconds(20000);
for(int i=0; i<scanconfig.PLOT_W*scanconfig.SMPL_PIX; i++) {
freq = STARTF + 1000.0*i*scanconfig.CHANSTEP;
//freq = 404000000 + 100*i*scanconfig.CHANSTEP;
uint32_t frf = freq * 1.0 * (1<<19) / SX127X_CRYSTAL_FREQ; uint32_t frf = freq * 1.0 * (1<<19) / SX127X_CRYSTAL_FREQ;
if( (lastfrf>>16)!=(frf>>16) ) { if( (lastfrf>>16)!=(frf>>16) ) {
sx1278.writeRegister(REG_FRF_MSB, (frf&0xff0000)>>16); sx1278.writeRegister(REG_FRF_MSB, (frf&0xff0000)>>16);
@ -84,9 +144,8 @@ void Scanner::scan()
} }
sx1278.writeRegister(REG_FRF_LSB, (frf&0x0000ff)); sx1278.writeRegister(REG_FRF_LSB, (frf&0x0000ff));
lastfrf = frf; lastfrf = frf;
// Wait TS_HOP (20us) + TS_RSSI ( 2^(SMOOTH+1) / 4 / CHANBW us) // Wait TS_HOP (20us) + TS_RSSI ( 2^(scacconfig.SMOOTH+1) / 4 / CHANBW us)
int wait = 20 + 1000*(1<<(SMOOTH+1))/4/CHANBW; delayMicroseconds(wait);
delayMicroseconds(wait+5);
int rssi = -(int)sx1278.readRegister(REG_RSSI_VALUE_FSK); int rssi = -(int)sx1278.readRegister(REG_RSSI_VALUE_FSK);
if(iter==0) { scanresult[i] = rssi; } else { if(iter==0) { scanresult[i] = rssi; } else {
if(rssi>scanresult[i]) scanresult[i]=rssi; if(rssi>scanresult[i]) scanresult[i]=rssi;
@ -94,20 +153,37 @@ void Scanner::scan()
} }
} }
unsigned long duration = millis()-start; unsigned long duration = millis()-start;
Serial.print("wait: ");
Serial.println(wait);
Serial.print("Scan time: "); Serial.print("Scan time: ");
Serial.println(duration); Serial.println(duration);
for(int i=0; i<NCHAN; i+=PIXSAMPL) { Serial.print("Final freq: ");
scandisp[i/PIXSAMPL]=scanresult[i]; Serial.println(freq);
for(int j=1; j<PIXSAMPL; j++) { scandisp[i/PIXSAMPL]+=scanresult[i+j]; } int peakidx=-1;
int peakres=-9999;
for(int i=0; i<scanconfig.PLOT_W; i+=1) {
scandisp[i]=scanresult[i*scanconfig.SMPL_PIX];
for(int j=1; j<scanconfig.SMPL_PIX; j++) {
int r = scanresult[i*scanconfig.SMPL_PIX+j];
scandisp[i]+=r;
if(r>peakres+1) { peakres=r; peakidx=i*scanconfig.SMPL_PIX+j; }
}
//for(int j=1; j<PIXSAMPL; j++) { if(scanresult[i+j]>scandisp[i/PIXSAMPL]) scandisp[i/PIXSAMPL] = scanresult[i+j]; } //for(int j=1; j<PIXSAMPL; j++) { if(scanresult[i+j]>scandisp[i/PIXSAMPL]) scandisp[i/PIXSAMPL] = scanresult[i+j]; }
Serial.print(scanresult[i]); Serial.print(", "); Serial.print(scanresult[i]); Serial.print(", ");
} }
peakidx--;
double newpeakf = STARTF + scanconfig.CHANSTEP*1000.0*peakidx;
if(newpeakf<peakf-20000 || newpeakf>peakf+20000) peakf=newpeakf; // different frequency
else if (newpeakf < peakf) peakf = 0.75*newpeakf + 0.25*peakf; // averaging on frequency, some bias towards lower...
else peakf = 0.25*newpeakf + 0.75*peakf;
Serial.println("\n"); Serial.println("\n");
for(int i=0; i<NCHAN/PIXSAMPL; i++) { for(int i=0; i<scanconfig.PLOT_W; i++) {
scandisp[i]/=PIXSAMPL; scandisp[i]/=scanconfig.SMPL_PIX;
Serial.print(scandisp[i]); Serial.print(", "); Serial.print(scandisp[i]); Serial.print(", ");
} }
Serial.println("\n"); Serial.println("\n");
Serial.print("Peak: ");
Serial.print(peakf);
} }
Scanner scanner = Scanner(); Scanner scanner = Scanner();