diff --git a/x7_x9lite/GPSx9L.lua b/x7_x9lite/GPSx9L.lua
index d9eb503..5a918ea 100644
--- a/x7_x9lite/GPSx9L.lua
+++ b/x7_x9lite/GPSx9L.lua
@@ -29,10 +29,9 @@ Setup a "screen (DIsplay 13/13)" and select GPS.lua
################################################################################]]
-log_filename = "/LOGS/GPSpositions.txt"
-
local gpsLAT = 0
local gpsLON = 0
+local gpsHdg = 0
local gpsLAT_H = 0
local gpsLON_H = 0
local gpsPrevLAT = 0
@@ -42,11 +41,12 @@ local gpsALT = 0
local gpsSpeed = 0
local gpssatId = 0
local gpsspeedId = 0
+local gpsHdgId = 0
local gpsaltId = 0
local gpsFIX = 0
local gpsDtH = 0
local gpsTotalDist = 0
-local log_write_wait_time = 10
+local log_write_wait_time = 100
local old_time_write = 0
local update = true
local reset = false
@@ -59,6 +59,19 @@ local coordinates_current = 0
local old_time_write2 = 0
local wait = 100
+-- GPX save
+local armed
+local chArmedId
+local waypoints_recorded = 0
+local gpx_path = ""
+local log_file = nil
+
+-- Pop up save GPX
+local popup_active = false
+local selec = 1 -- 0 = Yes, 1 = No
+local result = "No"
+local mid = LCD_W / 2 -- Center alignment for LCD display
+
local function rnd(v,d)
if d then
return math.floor((v*10^d)+0.5)/(10^d)
@@ -80,35 +93,91 @@ local function SecondsToClock(seconds)
end
end
+local function write_gps_file_header()
+ local dt = getDateTime()
+ local timestamp = string.format(
+ "%d-%02d-%02dT%02d:%02d:%02d",
+ tonumber(dt.year), tonumber(dt.mon ), tonumber(dt.day),
+ tonumber(dt.hour), tonumber(dt.min ), tonumber(dt.sec))
+
+ io.write(log_file, "\n")
+ io.write(log_file, "\n")
+ io.write(log_file, string.format("\n", timestamp))
+ io.write(log_file, string.format("Flight Log\n", timestamp))
+end
+
+local function write_gps_file_footer()
+ io.write(log_file, "\n")
+end
+
+-- Draw popup for savig GPX
+local function drawPopup()
+ -- Popup
+ lcd.drawFilledRectangle(25, 15, mid+10, 40, ERASE)
+ lcd.drawRectangle(25, 15, mid+10, 40, FORCE)
+ lcd.drawText(mid - 30, 20, "¿Save GPX?", 0)
+ lcd.drawText(mid - 25, 38, "Yes", selec == 0 and INVERS or 0)
+ lcd.drawText(mid + 5, 38, "No", selec == 1 and INVERS or 0)
+end
+
+local function stopLog()
+ if waypoints_recorded < 6 then -- no point in storing empty (or very small) logs
+ io.close(log_file)
+ del(gpx_path)
+ result = "Exit"
+ else
+ write_gps_file_footer()
+ io.close(log_file)
+ result = "Done"
+ end
+
+ log_file = nil
+ gpx_path = ""
+ waypoints_recorded = 0
+end
local function write_log()
now = getTime()
- if old_time_write + log_write_wait_time < now then
+
+ -- Generate GPX file
+ armed = getValue(chArmedId) > 0
- ctr = ctr + 1
- time_power_on = SecondsToClock(getGlobalTimer()["session"])
-
- --write logfile
- file = io.open(log_filename, "a")
- io.write(file, coordinates_current ..",".. time_power_on ..", ".. gpsSATS..", ".. gpsALT ..", ".. gpsSpeed, "\r\n")
- io.close(file)
-
- if ctr >= 99 then
- ctr = 0
- --clear log
- file = io.open(log_filename, "w")
- io.write(file, "Number,LAT,LON,radio_time,satellites,GPSalt,GPSspeed", "\r\n")
- io.close(file)
+ if log_file == nil and armed and selec == 0 then
+ result="?"
+ local dt = getDateTime()
+ local timestamp = string.format(
+ "%d-%02d-%02d_%02d_%02d_%02d",
+ tonumber(dt.year), tonumber(dt.mon), tonumber(dt.day),
+ tonumber(dt.hour), tonumber(dt.min), tonumber(dt.sec))
+
+ gpx_path = string.format("/LOGS/gps_log_%s.gpx", timestamp)
+ log_file = io.open(gpx_path, "a")
+ waypoints_recorded = 0
+
+ write_gps_file_header()
+ end
+
+ if not armed and log_file ~= nil and selec == 0 then
+ stopLog()
+ end
- --reopen log for appending data
- file = io.open(log_filename, "a")
- end
+ if armed and selec == 0 and old_time_write + log_write_wait_time < now then
+ local dt = getDateTime()
+ local timestamp = string.format(
+ "%d-%02d-%02dT%02d:%02d:%02d",
+ tonumber(dt.year), tonumber(dt.mon), tonumber(dt.day),
+ tonumber(dt.hour), tonumber(dt.min), tonumber(dt.sec))
+
+ io.write(log_file, string.format(
+ "%f%f%f\n",
+ gpsLAT, gpsLON, gpsALT, gpsSATS, gpsHdg, timestamp))
+
+ waypoints_recorded = waypoints_recorded + 1
old_time_write = now
end
end
-
local function getTelemetryId(name)
field = getFieldInfo(name)
if field then
@@ -136,6 +205,8 @@ local function init()
gpsId = getTelemetryId("GPS")
--number of satellites crossfire
gpssatId = getTelemetryId("Sats")
+ -- Magnetic Orientation
+ gpsHdgId = getTelemetryId("Hdg")
--get IDs GPS Speed and GPS altitude
gpsspeedId = getTelemetryId("GSpd") --GPS ground speed m/s
@@ -146,15 +217,17 @@ local function init()
--if Stats can't be read, try to read Tmp2 (number of satellites SBUS/FRSKY)
if (gpssatId == -1) then gpssatId = getTelemetryId("Tmp2") end
+ chArmedId = getFieldInfo('ch5').id
end
local function background()
--####################################################################
- --get Latitude, Longitude, Speed and Altitude
+ --get Latitude, Longitude, Speed, Hdg and Altitude
--####################################################################
gpsLatLon = getValue(gpsId)
-
+ gpsHdg = getValue(gpsHdgId)
+
if (type(gpsLatLon) == "table") then
gpsLAT = rnd(gpsLatLon["lat"],6)
gpsLON = rnd(gpsLatLon["lon"],6)
@@ -196,9 +269,9 @@ local function background()
--status message "guess"
-- 2D Mode - A 2D (two dimensional) position fix that includes only horizontal coordinates. It requires a minimum of three visible satellites.)
-- 3D Mode - A 3D (three dimensional) position fix that includes horizontal coordinates plus altitude. It requires a minimum of four visible satellites.
- if (tonumber(gpsSATS) < 2) then gpsFIX = "no GPS fix" end
- if (tonumber(gpsSATS) >= 3) and (tonumber(gpsSATS) <= 4) then gpsFIX = "GPS 2D fix" end
- if (tonumber(gpsSATS) >= 5) then gpsFIX = "GPS 3D fix" end
+ if (tonumber(gpsSATS) < 2) then gpsFIX = "no fix" end
+ if (tonumber(gpsSATS) >= 3) and (tonumber(gpsSATS) <= 4) then gpsFIX = "2D fix" end
+ if (tonumber(gpsSATS) >= 5) then gpsFIX = "3D fix" end
--####################################################################
@@ -206,7 +279,7 @@ local function background()
--####################################################################
if (tonumber(gpsSATS) >= 5) then
- if (gpsLAT ~= gpsPrevLAT) and (gpsLON ~= gpsPrevLON) then
+ if (gpsLAT ~= gpsPrevLAT) or (gpsLON ~= gpsPrevLON) then
if (gpsLAT_H ~= 0) and (gpsLON_H ~= 0) then
@@ -215,7 +288,7 @@ local function background()
gpsDtH = string.format("%.2f",gpsDtH)
--total distance traveled
- if (gpsPrevLAT ~= 0) and (gpsPrevLON ~= 0) and (gpsLAT ~= 0) and (gpsLON ~= 0)then
+ if (gpsPrevLAT ~= 0) and (gpsPrevLON ~= 0) and (gpsLAT ~= 0) and (gpsLON ~= 0)then
--print("GPS_Debug_Prev", gpsPrevLAT,gpsPrevLON)
--print("GPS_Debug_curr", gpsLAT,gpsLON)
@@ -230,10 +303,12 @@ local function background()
gpsPrevLAT = gpsLAT
gpsPrevLON = gpsLON
-
- write_log()
end
- end
+ end
+
+ if (tonumber(gpsSATS) >= 3) then
+ write_log()
+ end
end
@@ -277,7 +352,13 @@ local function run(event)
--update screen data
if update == true then
- lcd.drawText(32,1,gpsFIX ,SMLSIZE + INVERS)
+ lcd.drawText(32,1,gpsFIX ,SMLSIZE + INVERS)
+ lcd.drawText(25+(8*5),1,"Save GPX: " ,SMLSIZE + INVERS)
+ if waypoints_recorded > 0 then
+ lcd.drawText(27+(6*5)+(10*5),1,waypoints_recorded ,SMLSIZE + INVERS)
+ else
+ lcd.drawText(27+(6*5)+(10*5),1,result ,SMLSIZE + INVERS)
+ end
lcd.drawText(22,14, gpsSATS, SMLSIZE)
lcd.drawText(60,10, gpsDtH, SMLSIZE)
lcd.drawText(73,20, "km" , SMLSIZE)
@@ -297,7 +378,13 @@ local function run(event)
--blink if telemetry stops
elseif update == false then
- lcd.drawText(32,1,"no GPS data available" ,SMLSIZE + INVERS)
+ lcd.drawText(32,1,"no GPS" ,SMLSIZE + INVERS)
+ lcd.drawText(25+(8*5),1,"Save GPX: " ,SMLSIZE + INVERS)
+ if waypoints_recorded > 0 then
+ lcd.drawText(27+(6*5)+(10*5),1,waypoints_recorded ,SMLSIZE + INVERS)
+ else
+ lcd.drawText(27+(6*5)+(10*5),1,result ,SMLSIZE + INVERS)
+ end
lcd.drawText(22,14, gpsSATS, SMLSIZE + INVERS + BLINK )
lcd.drawText(60,10, gpsDtH , SMLSIZE + INVERS + BLINK)
lcd.drawText(73,20, "km" , SMLSIZE)
@@ -310,6 +397,32 @@ local function run(event)
lcd.drawText(20,56, coordinates_current, SMLSIZE + INVERS + BLINK)
end
+ if not popup_active then
+ if event == EVT_ENTER_BREAK then
+ popup_active = true
+ result="?"
+ end
+ else
+ drawPopup()
+ -- Popup events
+ if event == EVT_PLUS_BREAK or event == EVT_ROT_RIGHT then
+ selec = 1
+ elseif event == EVT_MINUS_BREAK or event == EVT_ROT_LEFT then
+ selec = 0
+ elseif event == EVT_ENTER_BREAK then
+ if selec == 0 then
+ result = "Yes"
+ else
+ result = "No"
+ if waypoints_recorded > 0 then
+ stopLog()
+ end
+ end
+ popup_active = false
+ elseif event == EVT_EXIT_BREAK then
+ popup_active = false
+ end
+ end
end
return {init=init, run=run, background=background}