From 81ce496e8157f77b4bf20e3f92f989c926d3ac0e Mon Sep 17 00:00:00 2001 From: Pawel Jalocha Date: Tue, 22 Feb 2022 19:35:57 +0000 Subject: [PATCH] Beta code to connect to APRS and pass own and received positions, thus acting as OGN receiver --- main/aprs.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++--------- main/aprs.h | 10 +++++++++ main/gps.cpp | 8 +++++-- main/gps.h | 4 +++- main/proc.cpp | 29 ++++++++++++++++++------ 5 files changed, 92 insertions(+), 21 deletions(-) diff --git a/main/aprs.cpp b/main/aprs.cpp index b00eeba..6272b91 100644 --- a/main/aprs.cpp +++ b/main/aprs.cpp @@ -10,6 +10,7 @@ #include "socket.h" #include "proc.h" +#include "gps.h" #ifdef WITH_APRS @@ -33,7 +34,10 @@ static void AP_Print(void (*Output)(char)) Format_String(Output, Line); } } -Socket APRS_Socket; // socket to talk to APRS server +FIFO, 16> APRSrx_FIFO; +FIFO, 4> APRStx_FIFO; + +static Socket APRS_Socket; // socket to talk to APRS server bool APRS_isConnected(void) { return APRS_Socket.isConnected(); } static const char *APRS_Host = "aprs.glidernet.org"; // server address @@ -157,7 +161,9 @@ void vTaskAPRS(void* pvParameters) for(uint8_t Idx=0; Idx<10; Idx++) // wait to obtain local IP from DHCP { vTaskDelay(1000); if(WIFI_State.isConnected==1) break; - if(WIFI_getLocalIP()) break; } + if(WIFI_getLocalIP()) + { if(WIFI_IP.ip.addr && WIFI_IP.gw.addr) break; } + } #ifdef DEBUG_PRINT xSemaphoreTake(CONS_Mutex, portMAX_DELAY); @@ -186,18 +192,52 @@ void vTaskAPRS(void* pvParameters) // APRS_Socket.setBlocking(0); int Write=APRS_Socket.Send(Line, LoginLen); // send login to the APRS server int LinePtr=0; - for(int Idx=0; Idx<120; Idx++) // wait for some time and watch what the server sends to us - { int Left = MaxLineLen-LinePtr; if(Left<1) break; - int Read=APRS_Socket.Receive(Line+LinePtr, Left-1); + // for(int Idx=0; Idx<120; Idx++) // wait for some time and watch what the server sends to us + for( ; ; ) + { int Left = MaxLineLen-LinePtr; if(Left<128) break; // how much space left for receive data + int Read=APRS_Socket.Receive(Line+LinePtr, Left-1); // read moredatafrom the socket #ifdef DEBUG_PRINT - xSemaphoreTake(CONS_Mutex, portMAX_DELAY); - Format_String(CONS_UART_Write, "APRS: "); - Format_SignDec(CONS_UART_Write, Read); - Format_String(CONS_UART_Write, "\n"); - xSemaphoreGive(CONS_Mutex); + if(Read<0) + { xSemaphoreTake(CONS_Mutex, portMAX_DELAY); + Format_String(CONS_UART_Write, "APRS: "); + Format_SignDec(CONS_UART_Write, Read); + Format_String(CONS_UART_Write, "\n"); + xSemaphoreGive(CONS_Mutex); } #endif if(Read<0) break; // if an error reading from the APRS server - if(Read==0) continue; // no more bytes: keep going + if(Read==0) // no more data on the receive + { bool TimeValid = GPS_DateTime.isTimeValid() && GPS_DateTime.isDateValid(); + uint32_t Time = GPS_DateTime.getUnixTime(); + char *Msg = Line+LinePtr; + while(APRStx_FIFO.Full()) + { OGN_TxPacket *TxPacket=APRStx_FIFO.getRead(); + if(TimeValid) + { uint8_t Len = TxPacket->Packet.WriteAPRS(Msg, Time); Msg[Len++]='\n'; Msg[Len]=0; +#ifdef DEBUG_PRINT + xSemaphoreTake(CONS_Mutex, portMAX_DELAY); + Format_String(CONS_UART_Write, "APRS <- "); + Format_String(CONS_UART_Write, Msg); + xSemaphoreGive(CONS_Mutex); +#endif + int Write = APRS_Socket.Send(Msg, Len); if(Write<0) break; } + APRStx_FIFO.Read(); } + while(APRSrx_FIFO.Full()) + { OGN_RxPacket *RxPacket=APRSrx_FIFO.getRead(); + uint8_t RxErr = RxPacket->RxErr; + if(TimeValid && RxErr<=8) + { uint8_t Len = RxPacket->Packet.WriteAPRS(Msg, Time, "OGNTRK"); + if(RxErr) + { Msg[Len++]=' '; Msg[Len++]='0'+RxErr; Msg[Len++]='e'; } + Msg[Len++]='\n'; Msg[Len]=0; +#ifdef DEBUG_PRINT + xSemaphoreTake(CONS_Mutex, portMAX_DELAY); + Format_String(CONS_UART_Write, "APRS <- "); + Format_String(CONS_UART_Write, Msg); + xSemaphoreGive(CONS_Mutex); +#endif + int Write = APRS_Socket.Send(Msg, Len); if(Write<0) break; } + APRSrx_FIFO.Read(); } + continue; } int LineLen = LinePtr+Read; int MsgPtr = 0; Line[LineLen]=0; diff --git a/main/aprs.h b/main/aprs.h index c8bee01..6a5818f 100644 --- a/main/aprs.h +++ b/main/aprs.h @@ -1,4 +1,12 @@ +#ifndef __APRS_H__ +#define __APRS_H__ + #include "hal.h" +#include "ogn.h" +#include "fifo.h" + +extern FIFO, 16> APRSrx_FIFO; +extern FIFO, 4> APRStx_FIFO; bool WIFI_isConnected(void); bool APRS_isConnected(void); @@ -8,3 +16,5 @@ bool APRS_isConnected(void); #endif void vTaskAPRS(void* pvParameters); +#endif // __APRS_H__ + diff --git a/main/gps.cpp b/main/gps.cpp index ee3522a..c9ed854 100644 --- a/main/gps.cpp +++ b/main/gps.cpp @@ -56,11 +56,14 @@ static TickType_t Burst_Tick; // [msec] System Tick when the data b int32_t GPS_Altitude = 0; // [0.1m] last valid altitude int32_t GPS_Latitude = 0; // [1/60000deg] int32_t GPS_Longitude = 0; // [1/60000deg] - GPS_Time GPS_DateTime = { 0, 0, 0, 0, 0, 0, 0 } ; + GPS_Time GPS_DateTime = { -1, -1, -1, -1, -1, -1, -1 } ; int16_t GPS_GeoidSepar= 0; // [0.1m] uint16_t GPS_LatCosine = 3000; // [1.0/4096] + uint32_t GPS_Random = 0x12345678; // random number from the LSB of the GPS data - uint16_t GPS_SatSNR = 0; // [0.25dB] + + uint16_t GPS_SatSNR = 0; // [0.25dB] average SNR from the GSV sentences + uint8_t GPS_SatCnt = 0; Status GPS_Status; // GPS status flags @@ -171,6 +174,7 @@ static void ProcessGSV(NMEA_RxMsg &GSV) // process GxGSV to extract uint8_t Count=0; uint16_t Sum=0; for(uint8_t Sys=0; Sys<4; Sys++) { Count+=SatSNRcount[Sys]; Sum+=SatSNRsum[Sys]; } + GPS_SatCnt = Count; if(Count) GPS_SatSNR = (4*Sum+Count/2)/Count; else GPS_SatSNR = 0; } diff --git a/main/gps.h b/main/gps.h index 8129a26..0d16a84 100644 --- a/main/gps.h +++ b/main/gps.h @@ -26,7 +26,9 @@ extern uint16_t GPS_LatCosine; // [1.0/(1<<12)] Latitude Cosine for extern uint32_t GPS_TimeSinceLock; // [sec] time since GPS has a valid lock extern uint32_t GPS_Random; // random number produced from the GPS data extern uint16_t GPS_PosPeriod; // [msec] how often (which period) the GPS/MAV is sending the positions -extern uint16_t GPS_SatSNR; // [0.25dB] average SNR for satellites being used for navigation + +extern uint16_t GPS_SatSNR; // [0.25dB] average SNR for satellites being tracked +extern uint8_t GPS_SatCnt; // [0.25dB] number of satellites being tracked typedef union { uint8_t Flags; diff --git a/main/proc.cpp b/main/proc.cpp index a0f8382..dc89e13 100644 --- a/main/proc.cpp +++ b/main/proc.cpp @@ -19,6 +19,9 @@ #ifdef WITH_SDLOG #include "sdlog.h" #endif +#ifdef WITH_APRS +#include "aprs.h" +#endif #ifdef WITH_SOUND #include "sound.h" @@ -87,8 +90,8 @@ static LDPC_Decoder Decoder; // decoder and error corrector for the OGN static int FlashLog(OGN_RxPacket *Packet, uint32_t Time) { OGN_LogPacket *LogPacket = FlashLog_FIFO.getWrite(); if(LogPacket==0) return -1; // allocate new packet in the LOG_FIFO - LogPacket->Packet = Packet->Packet; // copy the packet - LogPacket->Flags=0x80; + LogPacket->Packet = Packet->Packet; // copy the packet + LogPacket->Flags=0x80; // set Rx flag LogPacket->setTime(Time); LogPacket->setCheck(); FlashLog_FIFO.Write(); // finalize the write @@ -97,7 +100,8 @@ static int FlashLog(OGN_RxPacket *Packet, uint32_t Time) static int FlashLog(OGN_TxPacket *Packet, uint32_t Time) { OGN_LogPacket *LogPacket = FlashLog_FIFO.getWrite(); if(LogPacket==0) return -1; LogPacket->Packet = Packet->Packet; - LogPacket->Flags=0x00; + LogPacket->Flags=0x00; // clear Rx flag + // LogPacket->SNR = ; LogPacket->setTime(Time); LogPacket->setCheck(); FlashLog_FIFO.Write(); @@ -383,9 +387,12 @@ static void ProcessRxPacket(OGN_RxPacket *RxPacket, uint8_t RxPacket if(KNOB_Tick>12) Play(Play_Vol_1 | Play_Oct_2 | 7, 3); // if Knob>12 => make a beep for every received packet #endif #endif // WITH_LOOKOUT -#ifdef WITH_LOG bool Signif = PrevRxPacket!=0; if(!Signif) Signif=OGN_isSignif(&(RxPacket->Packet), &(PrevRxPacket->Packet)); +#ifdef WITH_APRS + if(Signif) APRSrx_FIFO.Write(*RxPacket); +#endif +#ifdef WITH_LOG if(Signif) FlashLog(RxPacket, RxTime); // log only significant packets #endif #ifdef WITH_PFLAA @@ -717,12 +724,17 @@ void vTaskPROC(void* pvParameters) // xSemaphoreGive(CONS_Mutex); // } #endif // WITH_FLASHLOG -#ifdef WITH_LOG bool isSignif = OGN_isSignif(&(PosPacket.Packet), &PrevLoggedPacket); if(isSignif) - { FlashLog(&PosPacket, PosTime); - PrevLoggedPacket = PosPacket.Packet; } + { +#ifdef WITH_APRS + APRStx_FIFO.Write(PosPacket); #endif +#ifdef WITH_LOG + FlashLog(&PosPacket, PosTime); +#endif + PrevLoggedPacket = PosPacket.Packet; + } } else // if GPS position is not complete, contains no valid position, etc. { if((SlotTime-PosTime)>=30) { PosPacket.Packet.Position.Time=0x3F; } // if no valid position for more than 30 seconds then set the time as unknown for the transmitted packet OGN_TxPacket *TxPacket = RF_TxFIFO.getWrite(); @@ -777,6 +789,9 @@ void vTaskPROC(void* pvParameters) { doTx=ReadInfo(StatPacket.Packet); } // and overwrite the StatPacket with the Info data if(doTx) { StatTxBackOff=16+(RX_Random%15); +#ifdef WITH_APRS + APRStx_FIFO.Write(StatPacket); +#endif #ifdef WITH_LOG FlashLog(&StatPacket, PosTime); // log the status packet #endif