Skip to content

Commit 652314e

Browse files
fix(esp_modem) Add example that reads GNSS info
1 parent 71a2388 commit 652314e

File tree

9 files changed

+634
-12
lines changed

9 files changed

+634
-12
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
idf_component_register(SRCS "SIM7070_gnss.cpp"
2+
INCLUDE_DIRS "."
3+
PRIV_REQUIRES esp_modem)
4+
5+
set_target_properties(${COMPONENT_LIB} PROPERTIES
6+
CXX_STANDARD 17
7+
CXX_STANDARD_REQUIRED ON
8+
CXX_EXTENSIONS ON
9+
)
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
//
7+
// Created on: 23.08.2022
8+
// Author: franz
9+
10+
11+
#include <cstdio>
12+
#include <cstring>
13+
#include <map>
14+
#include <string_view>
15+
#include <vector>
16+
#include <charconv>
17+
#include <list>
18+
#include "sdkconfig.h"
19+
#include "esp_event.h"
20+
#include "cxx_include/esp_modem_dte.hpp"
21+
#include "cxx_include/esp_modem_dce.hpp"
22+
#include "esp_modem_config.h"
23+
#include "cxx_include/esp_modem_api.hpp"
24+
#include "cxx_include/command_library.hpp"
25+
#include "esp_log.h"
26+
#include "SIM7070_gnss.hpp"
27+
28+
29+
const static char *const TAG = "SIM7070_gnss";
30+
31+
32+
class LocalFactory: public esp_modem::dce_factory::Factory {
33+
public:
34+
static std::unique_ptr<DCE_gnss> create(const esp_modem::dce_config *config, std::shared_ptr<esp_modem::DTE> dte, esp_netif_t *netif)
35+
{
36+
return esp_modem::dce_factory::Factory::build_generic_DCE<SIM7070_gnss, DCE_gnss, std::unique_ptr<DCE_gnss>>(config, dte, netif);
37+
}
38+
39+
};
40+
/**
41+
* @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module
42+
* @return unique pointer of the resultant DCE
43+
*/
44+
std::unique_ptr<DCE_gnss> create_SIM7070_GNSS_dce(const esp_modem::dce_config *config,
45+
std::shared_ptr<esp_modem::DTE> dte,
46+
esp_netif_t *netif)
47+
{
48+
return LocalFactory::create(config, std::move(dte), netif);
49+
}
50+
51+
esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::CommandableIf *t, gps_t &gps)
52+
{
53+
54+
ESP_LOGV(TAG, "%s", __func__ );
55+
std::string_view out;
56+
auto ret = esp_modem::dce_commands::generic_get_string(t, "AT+CGNSINF\r", out);
57+
if (ret != esp_modem::command_result::OK) {
58+
return ret;
59+
}
60+
61+
62+
63+
constexpr std::string_view pattern = "+CGNSINF: ";
64+
if (out.find(pattern) == std::string_view::npos) {
65+
return esp_modem::command_result::FAIL;
66+
}
67+
/**
68+
* Parsing +CGNSINF:
69+
* <GNSS run status>,
70+
* <Fix status>,
71+
* <UTC date & Time>,
72+
* <Latitude>,
73+
* <Longitude>,
74+
* <MSL Altitude>,
75+
* <Speed Over Ground>,
76+
* <Course Over Ground>,
77+
* <Fix Mode>,
78+
* <Reserved1>,
79+
* <HDOP>,
80+
* <PDOP>,
81+
* <VDOP>,
82+
* <Reserved2>,
83+
* <GNSS Satellites in View>,
84+
* <Reserved3>,
85+
* <HPA>,
86+
* <VPA>
87+
*/
88+
out = out.substr(pattern.size());
89+
int pos = 0;
90+
if ((pos = out.find(',')) == std::string::npos) {
91+
return esp_modem::command_result::FAIL;
92+
}
93+
//GNSS run status
94+
int GNSS_run_status;
95+
if (std::from_chars(out.data(), out.data() + pos, GNSS_run_status).ec == std::errc::invalid_argument) {
96+
return esp_modem::command_result::FAIL;
97+
}
98+
gps.run = (gps_run_t)GNSS_run_status;
99+
out = out.substr(pos + 1);
100+
if ((pos = out.find(',')) == std::string::npos) {
101+
return esp_modem::command_result::FAIL;
102+
}
103+
//Fix status
104+
{
105+
std::string_view fix_status = out.substr(0, pos);
106+
if (fix_status.length() > 1) {
107+
int Fix_status;
108+
if (std::from_chars(out.data(), out.data() + pos, Fix_status).ec == std::errc::invalid_argument) {
109+
return esp_modem::command_result::FAIL;
110+
}
111+
gps.fix = (gps_fix_t)Fix_status;
112+
} else {
113+
gps.fix = GPS_FIX_INVALID;
114+
}
115+
} //clean up Fix status
116+
out = out.substr(pos + 1);
117+
if ((pos = out.find(',')) == std::string::npos) {
118+
return esp_modem::command_result::FAIL;
119+
}
120+
//UTC date & Time
121+
{
122+
std::string_view UTC_date_and_Time = out.substr(0, pos);
123+
if (UTC_date_and_Time.length() > 1) {
124+
if (std::from_chars(out.data() + 0, out.data() + 4, gps.date.year).ec == std::errc::invalid_argument) {
125+
return esp_modem::command_result::FAIL;
126+
}
127+
if (std::from_chars(out.data() + 4, out.data() + 6, gps.date.month).ec == std::errc::invalid_argument) {
128+
return esp_modem::command_result::FAIL;
129+
}
130+
if (std::from_chars(out.data() + 6, out.data() + 8, gps.date.day).ec == std::errc::invalid_argument) {
131+
return esp_modem::command_result::FAIL;
132+
}
133+
if (std::from_chars(out.data() + 8, out.data() + 10, gps.tim.hour).ec == std::errc::invalid_argument) {
134+
return esp_modem::command_result::FAIL;
135+
}
136+
if (std::from_chars(out.data() + 10, out.data() + 12, gps.tim.minute).ec == std::errc::invalid_argument) {
137+
return esp_modem::command_result::FAIL;
138+
}
139+
if (std::from_chars(out.data() + 12, out.data() + 14, gps.tim.second).ec == std::errc::invalid_argument) {
140+
return esp_modem::command_result::FAIL;
141+
}
142+
if (std::from_chars(out.data() + 15, out.data() + 18, gps.tim.thousand).ec == std::errc::invalid_argument) {
143+
return esp_modem::command_result::FAIL;
144+
}
145+
} else {
146+
gps.date.year = 0;
147+
gps.date.month = 0;
148+
gps.date.day = 0;
149+
gps.tim.hour = 0;
150+
gps.tim.minute = 0;
151+
gps.tim.second = 0;
152+
gps.tim.thousand = 0;
153+
}
154+
155+
} //clean up UTC date & Time
156+
out = out.substr(pos + 1);
157+
if ((pos = out.find(',')) == std::string::npos) {
158+
return esp_modem::command_result::FAIL;
159+
}
160+
//Latitude
161+
{
162+
std::string_view Latitude = out.substr(0, pos);
163+
if (Latitude.length() > 1) {
164+
gps.latitude = std::stof(std::string(out.substr(0, pos)));
165+
} else {
166+
gps.latitude = 0;
167+
}
168+
} //clean up Latitude
169+
out = out.substr(pos + 1);
170+
if ((pos = out.find(',')) == std::string::npos) {
171+
return esp_modem::command_result::FAIL;
172+
}
173+
//Longitude
174+
{
175+
std::string_view Longitude = out.substr(0, pos);
176+
if (Longitude.length() > 1) {
177+
gps.longitude = std::stof(std::string(out.substr(0, pos)));
178+
} else {
179+
gps.longitude = 0;
180+
}
181+
} //clean up Longitude
182+
out = out.substr(pos + 1);
183+
if ((pos = out.find(',')) == std::string::npos) {
184+
return esp_modem::command_result::FAIL;
185+
}
186+
//Altitude
187+
{
188+
std::string_view Altitude = out.substr(0, pos);
189+
if (Altitude.length() > 1) {
190+
gps.altitude = std::stof(std::string(out.substr(0, pos)));
191+
} else {
192+
gps.altitude = 0;
193+
}
194+
} //clean up Altitude
195+
out = out.substr(pos + 1);
196+
if ((pos = out.find(',')) == std::string::npos) {
197+
return esp_modem::command_result::FAIL;
198+
}
199+
//Speed Over Ground Km/hour
200+
{
201+
std::string_view gps_speed = out.substr(0, pos);
202+
if (gps_speed.length() > 1) {
203+
gps.speed = std::stof(std::string(gps_speed));
204+
} else {
205+
gps.speed = 0;
206+
}
207+
} //clean up gps_speed
208+
out = out.substr(pos + 1);
209+
if ((pos = out.find(',')) == std::string::npos) {
210+
return esp_modem::command_result::FAIL;
211+
}
212+
//Course Over Ground degrees
213+
{
214+
std::string_view gps_cog = out.substr(0, pos);
215+
if (gps_cog.length() > 1) {
216+
gps.cog = std::stof(std::string(gps_cog));
217+
} else {
218+
gps.cog = 0;
219+
}
220+
} //clean up gps_cog
221+
out = out.substr(pos + 1);
222+
if ((pos = out.find(',')) == std::string::npos) {
223+
return esp_modem::command_result::FAIL;
224+
}
225+
// Fix Mode
226+
{
227+
std::string_view FixModesubstr = out.substr(0, pos);
228+
if (FixModesubstr.length() > 1) {
229+
int Fix_Mode;
230+
if (std::from_chars(out.data(), out.data() + pos, Fix_Mode).ec == std::errc::invalid_argument) {
231+
return esp_modem::command_result::FAIL;
232+
}
233+
gps.fix_mode = (gps_fix_mode_t)Fix_Mode;
234+
} else {
235+
gps.fix_mode = GPS_MODE_INVALID;
236+
}
237+
} //clean up Fix Mode
238+
out = out.substr(pos + 1);
239+
if ((pos = out.find(',')) == std::string::npos) {
240+
return esp_modem::command_result::FAIL;
241+
}
242+
out = out.substr(pos + 1);
243+
if ((pos = out.find(',')) == std::string::npos) {
244+
return esp_modem::command_result::FAIL;
245+
}
246+
//HDOP
247+
{
248+
std::string_view HDOP = out.substr(0, pos);
249+
if (HDOP.length() > 1) {
250+
gps.dop_h = std::stof(std::string(HDOP));
251+
} else {
252+
gps.dop_h = 0;
253+
}
254+
} //clean up HDOP
255+
out = out.substr(pos + 1);
256+
if ((pos = out.find(',')) == std::string::npos) {
257+
return esp_modem::command_result::FAIL;
258+
}
259+
//PDOP
260+
{
261+
std::string_view PDOP = out.substr(0, pos);
262+
if (PDOP.length() > 1) {
263+
gps.dop_p = std::stof(std::string(PDOP));
264+
} else {
265+
gps.dop_p = 0;
266+
}
267+
} //clean up PDOP
268+
out = out.substr(pos + 1);
269+
if ((pos = out.find(',')) == std::string::npos) {
270+
return esp_modem::command_result::FAIL;
271+
}
272+
//VDOP
273+
{
274+
std::string_view VDOP = out.substr(0, pos);
275+
if (VDOP.length() > 1) {
276+
gps.dop_v = std::stof(std::string(VDOP));
277+
} else {
278+
gps.dop_v = 0;
279+
}
280+
} //clean up VDOP
281+
out = out.substr(pos + 1);
282+
if ((pos = out.find(',')) == std::string::npos) {
283+
return esp_modem::command_result::FAIL;
284+
}
285+
out = out.substr(pos + 1);
286+
if ((pos = out.find(',')) == std::string::npos) {
287+
return esp_modem::command_result::FAIL;
288+
}
289+
//sats_in_view
290+
{
291+
std::string_view sats_in_view = out.substr(0, pos);
292+
if (sats_in_view.length() > 1) {
293+
if (std::from_chars(out.data(), out.data() + pos, gps.sats_in_view).ec == std::errc::invalid_argument) {
294+
return esp_modem::command_result::FAIL;
295+
}
296+
} else {
297+
gps.sats_in_view = 0;
298+
}
299+
} //clean up sats_in_view
300+
301+
out = out.substr(pos + 1);
302+
if ((pos = out.find(',')) == std::string::npos) {
303+
return esp_modem::command_result::FAIL;
304+
}
305+
out = out.substr(pos + 1);
306+
if ((pos = out.find(',')) == std::string::npos) {
307+
return esp_modem::command_result::FAIL;
308+
}
309+
//HPA
310+
{
311+
std::string_view HPA = out.substr(0, pos);
312+
if (HPA.length() > 1) {
313+
gps.hpa = std::stof(std::string(HPA));
314+
} else {
315+
gps.hpa = 0;
316+
}
317+
} //clean up HPA
318+
out = out.substr(pos + 1);
319+
//VPA
320+
{
321+
std::string_view VPA = out.substr(0, pos);
322+
if (VPA.length() > 1) {
323+
gps.vpa = std::stof(std::string(VPA));
324+
} else {
325+
gps.vpa = 0;
326+
}
327+
} //clean up VPA
328+
329+
return esp_modem::command_result::OK;
330+
}
331+
332+
esp_modem::command_result SIM7070_gnss::get_gnss_information_sim70xx(gps_t &gps)
333+
{
334+
return get_gnss_information_sim70xx_lib(dte.get(), gps);
335+
}
336+
337+
esp_modem::command_result DCE_gnss::get_gnss_information_sim70xx(gps_t &gps)
338+
{
339+
return device->get_gnss_information_sim70xx(gps);
340+
}

0 commit comments

Comments
 (0)