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}