kopia lustrzana https://github.com/dl9rdz/rdz_ttgo_sonde
commit
4fcf26e8ea
|
@ -48,9 +48,12 @@ boolean connected = false;
|
|||
WiFiUDP udp;
|
||||
WiFiClient client;
|
||||
|
||||
// KISS over TCP für communicating with APRSdroid
|
||||
// KISS over TCP for communicating with APRSdroid
|
||||
WiFiServer tncserver(14580);
|
||||
WiFiClient tncclient;
|
||||
// JSON over TCP for communicating with my kotlin andoird test stuff
|
||||
WiFiServer rdzserver(14570);
|
||||
WiFiClient rdzclient;
|
||||
|
||||
unsigned long lastMqttUptime = 0;
|
||||
boolean mqttEnabled;
|
||||
|
@ -1123,8 +1126,6 @@ MicroNMEA nmea(buffer, sizeof(buffer));
|
|||
|
||||
|
||||
|
||||
int lastCourse = 0;
|
||||
|
||||
/// Arrg. MicroNMEA changes type definition... so lets auto-infer type
|
||||
template<typename T>
|
||||
//void unkHandler(const MicroNMEA& nmea) {
|
||||
|
@ -1134,11 +1135,14 @@ void unkHandler(T nmea) {
|
|||
while (*s && *s != ',') s++;
|
||||
if (*s == ',') s++; else return;
|
||||
if (*s == ',') return; /// no new course data
|
||||
lastCourse = nmea.parseFloat(s, 0, NULL);
|
||||
int lastCourse = nmea.parseFloat(s, 0, NULL);
|
||||
Serial.printf("Course update: %d\n", lastCourse);
|
||||
}
|
||||
}
|
||||
//#define DEBUG_GPS 1
|
||||
|
||||
#define DEBUG_GPS 1
|
||||
static bool gpsCourseOld;
|
||||
static int lastCourse;
|
||||
void gpsTask(void *parameter) {
|
||||
nmea.setUnknownSentenceHandler(unkHandler);
|
||||
|
||||
|
@ -1147,16 +1151,27 @@ void gpsTask(void *parameter) {
|
|||
char c = Serial2.read();
|
||||
//Serial.print(c);
|
||||
if (nmea.process(c)) {
|
||||
gpsPos.valid = nmea.isValid();
|
||||
if(gpsPos.valid) {
|
||||
gpsPos.lon = nmea.getLongitude()*0.000001;
|
||||
gpsPos.lat = nmea.getLatitude()*0.000001;
|
||||
long alt = 0;
|
||||
nmea.getAltitude(alt);
|
||||
gpsPos.alt=(int)(alt/1000);
|
||||
gpsPos.course = (int)(nmea.getCourse()/1000);
|
||||
gpsCourseOld = false;
|
||||
if(gpsPos.course==0) {
|
||||
// either north or not new
|
||||
if(lastCourse!=0) // use old value...
|
||||
{
|
||||
gpsCourseOld = true;
|
||||
gpsPos.course = lastCourse;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_GPS
|
||||
Serial.print(nmea.getSentence());
|
||||
long lat = nmea.getLatitude();
|
||||
long lon = nmea.getLongitude();
|
||||
long alt = -1;
|
||||
bool b = nmea.getAltitude(alt);
|
||||
bool valid = nmea.isValid();
|
||||
int course = nmea.getCourse() / 1000;
|
||||
uint8_t hdop = nmea.getHDOP();
|
||||
Serial.printf(" =>: valid: %d N %ld E %ld alt %ld (%d) course:%d dop:%d\n", valid ? 1 : 0, lat, lon, alt, b, c, hdop);
|
||||
Serial.printf(" =>: valid: %d N %f E %f alt %d course:%d dop:%d\n", gpsPos.valid ? 1 : 0, gpsPos.lat, gpsPos.lon, gpsPos.alt, gpsPos.course, hdop);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1760,6 +1775,48 @@ static const char *action2text(uint8_t action) {
|
|||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
#define RDZ_DATA_LEN 128
|
||||
|
||||
void parseGpsJson(char *data) {
|
||||
char *key = NULL;
|
||||
char *value = NULL;
|
||||
// very simple json parser: look for ", then key, then ", then :, then number, then , or } or \0
|
||||
for(int i=0; i<RDZ_DATA_LEN; i++) {
|
||||
if(key==NULL) {
|
||||
if(data[i]!='"') continue;
|
||||
key=data+i+1;
|
||||
i+=2;
|
||||
continue;
|
||||
}
|
||||
if(value==NULL) {
|
||||
if(data[i]!=':') continue;
|
||||
value = data+i+1;
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
if(data[i]==',' || data[i]=='}' || data[i]==0) {
|
||||
// get value
|
||||
double val = strtod(value,NULL);
|
||||
// get data
|
||||
if(strncmp(key,"lat",3)==0) { gpsPos.lat = val; }
|
||||
else if(strncmp(key,"lon",3)==0) { gpsPos.lon = val; }
|
||||
else if(strncmp(key,"alt",3)==0) { gpsPos.alt = (int)val; }
|
||||
else if(strncmp(key,"course",6)==0) { gpsPos.course = (int)val; }
|
||||
gpsPos.valid = true;
|
||||
|
||||
// next item:
|
||||
if(data[i]!=',') break;
|
||||
key = NULL;
|
||||
value = NULL;
|
||||
}
|
||||
}
|
||||
Serial.printf("Parse result: lat=%f, lon=%f, alt=%d, valid=%d\n", gpsPos.lat, gpsPos.lon, gpsPos.alt, gpsPos.valid);
|
||||
}
|
||||
|
||||
static char rdzData[RDZ_DATA_LEN];
|
||||
static int rdzDataPos = 0;
|
||||
|
||||
void loopDecoder() {
|
||||
// sonde knows the current type and frequency, and delegates to the right decoder
|
||||
uint16_t res = sonde.waitRXcomplete();
|
||||
|
@ -1801,8 +1858,31 @@ void loopDecoder() {
|
|||
}
|
||||
Serial.println("");
|
||||
}
|
||||
if (!rdzclient.connected()) {
|
||||
rdzclient = rdzserver.available();
|
||||
if(rdzclient.connected()) {
|
||||
Serial.println("RDZ JSON socket: new connection");
|
||||
}
|
||||
}
|
||||
if(rdzclient.available()) {
|
||||
Serial.print("RDZ JSON socket: received ");
|
||||
while(rdzclient.available()) {
|
||||
char c = (char)rdzclient.read();
|
||||
Serial.print(c);
|
||||
if(c=='\n'||c=='}'||rdzDataPos>=RDZ_DATA_LEN) {
|
||||
// parse GPS position from phone
|
||||
rdzData[rdzDataPos] = c;
|
||||
if(rdzDataPos>2) parseGpsJson(rdzData);
|
||||
rdzDataPos = 0;
|
||||
}
|
||||
else {
|
||||
rdzData[rdzDataPos++] = c;
|
||||
}
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
// wifi (axudp) or bluetooth (bttnc) active => send packet
|
||||
if ((res & 0xff) == 0 && (connected || tncclient.connected() )) {
|
||||
if ((res & 0xff) == 0 && (connected || tncclient.connected() || rdzclient.connected() )) {
|
||||
//Send a packet with position information
|
||||
// first check if ID and position lat+lonis ok
|
||||
SondeInfo *s = &sonde.sondeList[rxtask.receiveSonde];
|
||||
|
@ -1825,6 +1905,65 @@ void loopDecoder() {
|
|||
Serial.print("sending: "); Serial.println(raw);
|
||||
tncclient.write(raw, rawlen);
|
||||
}
|
||||
if (rdzclient.connected()) {
|
||||
Serial.println("Sending position via TCP as rdzJSON");
|
||||
char raw[1024];
|
||||
int len = snprintf(raw, 1024, "{"
|
||||
"\"active\": %d,"
|
||||
"\"freq\": %.2f,"
|
||||
"\"id\": \"%s\","
|
||||
"\"ser\": \"%s\","
|
||||
"\"validId\": %d,"
|
||||
"\"launchsite\": \"%s\","
|
||||
"\"lat\": %.5f,"
|
||||
"\"lon\": %.5f,"
|
||||
"\"alt\": %.1f,"
|
||||
"\"vs\": %.1f,"
|
||||
"\"hs\": %.1f,"
|
||||
"\"dir\": %.1f,"
|
||||
"\"sats\": %d,"
|
||||
"\"validPos\": %d,"
|
||||
"\"time\": %d,"
|
||||
"\"sec\": %d,"
|
||||
"\"frame\": %d,"
|
||||
"\"validTime\": %d,"
|
||||
"\"rssi\": %d,"
|
||||
"\"afc\": %d,"
|
||||
"\"rxStat\": \"%s\","
|
||||
"\"launchKT\": %d,"
|
||||
"\"burstKT\": %d,"
|
||||
"\"countKT\": %d,"
|
||||
"\"crefKT\": %d"
|
||||
"}\n",
|
||||
(int)s->active,
|
||||
s->freq,
|
||||
s->id,
|
||||
s->ser,
|
||||
(int)s->validID,
|
||||
s->launchsite,
|
||||
s->lat,
|
||||
s->lon,
|
||||
s->alt,
|
||||
s->vs,
|
||||
s->hs,
|
||||
s->dir,
|
||||
s->sats,
|
||||
s->validPos,
|
||||
s->time,
|
||||
s->sec,
|
||||
s->frame,
|
||||
(int)s->validTime,
|
||||
s->rssi,
|
||||
s->afc,
|
||||
s->rxStat,
|
||||
s->launchKT,
|
||||
s->burstKT,
|
||||
s->countKT,
|
||||
s->crefKT
|
||||
);
|
||||
|
||||
rdzclient.write(raw, len>1024?1024:len);
|
||||
}
|
||||
}
|
||||
|
||||
// send to MQTT if enabled
|
||||
|
@ -1926,8 +2065,11 @@ void enableNetwork(bool enable) {
|
|||
SetupAsyncServer();
|
||||
udp.begin(WiFi.localIP(), LOCALUDPPORT);
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService("kisstnc", "tcp", 14580);
|
||||
MDNS.addService("jsonrdz", "tcp", 14570);
|
||||
if (sonde.config.kisstnc.active) {
|
||||
tncserver.begin();
|
||||
rdzserver.begin();
|
||||
}
|
||||
|
||||
if (sonde.config.mqtt.active && strlen(sonde.config.mqtt.host) > 0) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const char *version_name = "rdzTTGOsonde";
|
||||
const char *version_id = "devel20201230b";
|
||||
const char *version_id = "devel20210124";
|
||||
const int SPIFFS_MAJOR=2;
|
||||
const int SPIFFS_MINOR=8;
|
||||
|
|
|
@ -19,12 +19,11 @@ extern const char *version_id;
|
|||
|
||||
extern Sonde sonde;
|
||||
|
||||
extern MicroNMEA nmea;
|
||||
|
||||
extern AXP20X_Class axp;
|
||||
extern bool axp192_found;
|
||||
extern SemaphoreHandle_t axpSemaphore;
|
||||
|
||||
struct GpsPos gpsPos;
|
||||
|
||||
SPIClass spiDisp(HSPI);
|
||||
|
||||
|
@ -1233,6 +1232,7 @@ void Display::drawKilltimer(DispEntry *de) {
|
|||
extern int lastCourse; // from RX_FSK.ino
|
||||
void Display::calcGPS() {
|
||||
// base data
|
||||
#if 0
|
||||
#if FAKEGPS
|
||||
gpsValid = true;
|
||||
gpsLat = 48.9;
|
||||
|
@ -1257,12 +1257,13 @@ static int tmpc=0;
|
|||
gpsCourse = lastCourse;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
// distance
|
||||
if( gpsValid && (sonde.si()->validPos&0x03)==0x03 && (layout->usegps&GPSUSE_DIST)) {
|
||||
float lat1 = nmea.getLatitude()*0.000001;
|
||||
if( gpsPos.valid && (sonde.si()->validPos&0x03)==0x03 && (layout->usegps&GPSUSE_DIST)) {
|
||||
float lat1 = gpsPos.lat;
|
||||
float lat2 = sonde.si()->lat;
|
||||
float x = radians(nmea.getLongitude()*0.000001-sonde.si()->lon) * cos( radians((lat1+lat2)/2) );
|
||||
float x = radians(gpsPos.lon-sonde.si()->lon) * cos( radians((lat1+lat2)/2) );
|
||||
float y = radians(lat2-lat1);
|
||||
float d = sqrt(x*x+y*y)*EARTH_RADIUS;
|
||||
gpsDist = (int)d;
|
||||
|
@ -1270,17 +1271,17 @@ static int tmpc=0;
|
|||
gpsDist = -1;
|
||||
}
|
||||
// bearing
|
||||
if( gpsValid && (sonde.si()->validPos&0x03)==0x03 && (layout->usegps&GPSUSE_BEARING)) {
|
||||
float lat1 = radians(gpsLat);
|
||||
if( gpsPos.valid && (sonde.si()->validPos&0x03)==0x03 && (layout->usegps&GPSUSE_BEARING)) {
|
||||
float lat1 = radians(gpsPos.lat);
|
||||
float lat2 = radians(sonde.si()->lat);
|
||||
float lon1 = radians(gpsLon);
|
||||
float lon1 = radians(gpsPos.lon);
|
||||
float lon2 = radians(sonde.si()->lon);
|
||||
float y = sin(lon2-lon1)*cos(lat2);
|
||||
float x = cos(lat1)*sin(lat2) - sin(lat1)*cos(lat2)*cos(lon2-lon1);
|
||||
float dir = atan2(y, x)/PI*180;
|
||||
if(dir<0) dir+=360;
|
||||
gpsDir = (int)dir;
|
||||
gpsBear = gpsDir - gpsCourse;
|
||||
gpsBear = gpsDir - gpsPos.course;
|
||||
if(gpsBear < 0) gpsBear += 360;
|
||||
if(gpsBear >= 360) gpsBear -= 360;
|
||||
} else {
|
||||
|
@ -1288,39 +1289,39 @@ static int tmpc=0;
|
|||
gpsBear = -1;
|
||||
}
|
||||
|
||||
DebugPrintf(DEBUG_DISPLAY, "GPS data: valid%d GPS at %f,%f (alt=%d,cog=%d); sonde at dist=%d, dir=%d rel.bear=%d\n",gpsValid?1:0,
|
||||
gpsLat, gpsLon, gpsAlt, gpsCourse, gpsDist, gpsDir, gpsBear);
|
||||
DebugPrintf(DEBUG_DISPLAY, "GPS data: valid%d GPS at %f,%f (alt=%d,cog=%d); sonde at dist=%d, dir=%d rel.bear=%d\n",gpsPos.valid?1:0,
|
||||
gpsPos.lat, gpsPos.lon, gpsPos.alt, gpsPos.course, gpsDist, gpsDir, gpsBear);
|
||||
}
|
||||
|
||||
void Display::drawGPS(DispEntry *de) {
|
||||
if(sonde.config.gps_rxd<0) return;
|
||||
// TODO: FIXME: ??? if(sonde.config.gps_rxd<0) return;
|
||||
rdis->setFont(de->fmt);
|
||||
switch(de->extra[0]) {
|
||||
case 'V':
|
||||
{
|
||||
// show if GPS location is valid
|
||||
uint8_t *tile = disp.gpsValid?gps_tile:nogps_tile;
|
||||
uint8_t *tile = gpsPos.valid?gps_tile:nogps_tile;
|
||||
rdis->drawTile(de->x, de->y, 1, tile);
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
// GPS long
|
||||
snprintf(buf, 16, "%2.5f", disp.gpsLon);
|
||||
snprintf(buf, 16, "%2.5f", gpsPos.lon);
|
||||
drawString(de,buf);
|
||||
break;
|
||||
case 'A':
|
||||
// GPS lat
|
||||
snprintf(buf, 16, "%2.5f", disp.gpsLat);
|
||||
snprintf(buf, 16, "%2.5f", gpsPos.lat);
|
||||
drawString(de,buf);
|
||||
break;
|
||||
case 'H':
|
||||
// GPS alt
|
||||
snprintf(buf, 16, "%4dm", disp.gpsAlt);
|
||||
snprintf(buf, 16, "%4dm", gpsPos.alt);
|
||||
drawString(de,buf);
|
||||
break;
|
||||
case 'C':
|
||||
// GPS Course over ground
|
||||
snprintf(buf, 4, "%3d", disp.gpsCourse);
|
||||
snprintf(buf, 4, "%3d", gpsPos.course);
|
||||
drawString(de, buf);
|
||||
break;
|
||||
case 'D':
|
||||
|
@ -1330,7 +1331,7 @@ void Display::drawGPS(DispEntry *de) {
|
|||
if( (sonde.si()->validPos&0x03)!=0x03 ) {
|
||||
snprintf(buf, 16, "no pos ");
|
||||
if(de->extra && *de->extra=='5') buf[5]=0;
|
||||
} else if(!disp.gpsValid) {
|
||||
} else if(!gpsPos.valid) {
|
||||
snprintf(buf, 16, "no gps ");
|
||||
if(de->extra && *de->extra=='5') buf[5]=0;
|
||||
} else {
|
||||
|
@ -1350,7 +1351,7 @@ void Display::drawGPS(DispEntry *de) {
|
|||
break;
|
||||
case 'I':
|
||||
// dIrection
|
||||
if( (!disp.gpsValid) || ((sonde.si()->validPos&0x03)!=0x03 ) ) {
|
||||
if( (!gpsPos.valid) || ((sonde.si()->validPos&0x03)!=0x03 ) ) {
|
||||
drawString(de, "---");
|
||||
break;
|
||||
}
|
||||
|
@ -1362,7 +1363,7 @@ void Display::drawGPS(DispEntry *de) {
|
|||
break;
|
||||
case 'B':
|
||||
// relative bearing
|
||||
if( (!disp.gpsValid) || ((sonde.si()->validPos&0x03)!=0x03 ) ) {
|
||||
if( (!gpsPos.valid) || ((sonde.si()->validPos&0x03)!=0x03 ) ) {
|
||||
drawString(de, "---");
|
||||
break;
|
||||
}
|
||||
|
@ -1392,15 +1393,15 @@ void Display::drawGPS(DispEntry *de) {
|
|||
bool rxgood = (sonde.si()->rxStat[0]==0);
|
||||
int angN, angA, angB; // angle of north, array, bullet
|
||||
int validA, validB; // 0: no, 1: yes, -1: old
|
||||
if(circinfo->arr=='C') { angA=disp.gpsCourse; validA=disp.gpsCourseOld?-1:1; }
|
||||
if(circinfo->arr=='C') { angA=gpsPos.course; validA=disp.gpsCourseOld?-1:1; }
|
||||
else { angA=disp.gpsDir; validA=sonde.si()->validPos?(rxgood?1:-1):0; }
|
||||
if(circinfo->bul=='C') { angB=disp.gpsCourse; validB=disp.gpsCourseOld?-1:1; }
|
||||
if(circinfo->bul=='C') { angB=gpsPos.course; validB=disp.gpsCourseOld?-1:1; }
|
||||
else { angB=disp.gpsDir; validB=sonde.si()->validPos?(rxgood?1:-1):0; }
|
||||
if(circinfo->top=='N') {
|
||||
angN = 0;
|
||||
} else {
|
||||
//if (circinfo->top=='C') {
|
||||
angN = 360-disp.gpsCourse;
|
||||
angN = 360-gpsPos.course;
|
||||
angA += angN; if(angA>=360) angA-=360;
|
||||
angB += angN; if(angB>=360) angB-=360;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,15 @@
|
|||
#include <U8x8lib.h>
|
||||
#include <SPIFFS.h>
|
||||
|
||||
struct GpsPos {
|
||||
double lat;
|
||||
double lon;
|
||||
int alt;
|
||||
int course;
|
||||
int valid;
|
||||
};
|
||||
extern struct GpsPos gpsPos;
|
||||
|
||||
#define WIDTH_AUTO 9999
|
||||
struct DispEntry {
|
||||
int16_t y;
|
||||
|
@ -123,11 +132,8 @@ private:
|
|||
static void circ(uint16_t *bm, int16_t w, int16_t x0, int16_t y0, int16_t r, uint16_t fg, boolean fill, uint16_t bg);
|
||||
static int countEntries(File f);
|
||||
void calcGPS();
|
||||
boolean gpsValid;
|
||||
float gpsLat, gpsLon;
|
||||
int gpsAlt;
|
||||
int gpsDist; // -1: invalid
|
||||
int gpsCourse, gpsDir, gpsBear; // 0..360; -1: invalid
|
||||
int gpsDir, gpsBear; // 0..360; -1: invalid
|
||||
boolean gpsCourseOld;
|
||||
static const int LINEBUFLEN{ 255 };
|
||||
static char lineBuf[LINEBUFLEN];
|
||||
|
|
|
@ -19,16 +19,18 @@ const char *evstring[]={"NONE", "KEY1S", "KEY1D", "KEY1M", "KEY1L", "KEY2S", "KE
|
|||
|
||||
const char *RXstr[]={"RX_OK", "RX_TIMEOUT", "RX_ERROR", "RX_UNKNOWN"};
|
||||
|
||||
int fingerprintValue[]={ 17, 31, 64, 4, 55, 48, 23, 128+23, -1 };
|
||||
int fingerprintValue[]={ 17, 31, 64, 4, 55, 48, 23, 128+23, 119, 128+119, -1 };
|
||||
const char *fingerprintText[]={
|
||||
"TTGO T-Beam (new version 1.0), I2C not working after powerup, assuming 0.9\" OLED@21,22",
|
||||
"TTGO LORA32 v2.1_1.6 (0.9\" OLED@21,22)",
|
||||
"TTGO LORA v1.0 (0.9\" OLED@4,15)",
|
||||
"Heltec v1/v2 (0.9\"OLED@4,15)",
|
||||
"TTGO T-Beam (old version), 0.9\" OLED@21,22",
|
||||
"TTGO T-Beam (old version), SPI TFT@4,21,22",
|
||||
"TTGO T-Beam (new version 1.0), 0.9\" OLED@21,22",
|
||||
"TTGO T-Beam (new version 1.0), SPI TFT@4,13,14",
|
||||
"TTGO T-Beam (V0.7), 0.9\" OLED@21,22",
|
||||
"TTGO T-Beam (V0.7), SPI TFT@4,21,22",
|
||||
"TTGO T-Beam (V1.0), 0.9\" OLED@21,22",
|
||||
"TTGO T-Beam (V1.0), SPI TFT@4,13,14",
|
||||
"TTGO T-Beam (V1.1), 0.9\" OLED@21,22",
|
||||
"TTGO T-Beam (V1.1), SPI TFT@4,13,14",
|
||||
};
|
||||
|
||||
/* global variables from RX_FSK.ino */
|
||||
|
@ -97,8 +99,15 @@ void Sonde::defaultConfig() {
|
|||
config.oled_sda = 21;
|
||||
config.oled_scl = 22;
|
||||
if(initlevels[17]==0) { // T-Beam
|
||||
if(initlevels[12]==0) { // T-Beam v1.0
|
||||
int tbeam=7;
|
||||
if(initlevels[12]==0) {
|
||||
tbeam = 10;
|
||||
Serial.println("Autoconfig: looks like T-Beam 1.0 board");
|
||||
} else if ( initlevels[4]==1 && initlevels[12]==1 ) {
|
||||
tbeam = 11;
|
||||
Serial.println("Autoconfig: looks like T-Beam 1.1 board");
|
||||
}
|
||||
if(tbeam == 10 || tbeam == 11) { // T-Beam v1.0 or T-Beam v1.1
|
||||
config.button_pin = 38;
|
||||
config.button2_pin = 15 + 128; //T4 + 128; // T4 = GPIO13
|
||||
// Maybe in future use as default only PWR as button2?
|
||||
|
|
|
@ -30,6 +30,15 @@ TTGO T-Beam 1.0 with OLED display => fingerprint 0010111 => 23
|
|||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:4 1:4 2:0 3:4 4:0 5:4 6:0 7:4 8:0 9:4 10:4 11:4 12:0 13:0 14:4 15:4 16:4 17:0 18:0 19:0 20:0 21:4 22:4 23:4 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
|
||||
|
||||
TTGO T-Team 1.0 with IL9225 TFT => fingerprint 23
|
||||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:1 1:1 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
|
||||
|
||||
vs 0010111
|
||||
T-Beam 1.1 seems to be different: 1110111
|
||||
GPIO4 = 1 (additional pullup) => +64
|
||||
GPIO12 = 1 (maybe additional pullup) => +32
|
||||
|
||||
1
|
||||
|
||||
Fingerprint GPIOs: 4, 12, 16, 17, 21, 22, 23,
|
||||
|
|
Ładowanie…
Reference in New Issue