mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-18 13:02:21 +02:00
fix(esp_modem) Add example that reads GNSS info
This commit is contained in:
committed by
David Cermak
parent
71a2388acb
commit
652314e73d
@ -0,0 +1,9 @@
|
|||||||
|
idf_component_register(SRCS "SIM7070_gnss.cpp"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
PRIV_REQUIRES esp_modem)
|
||||||
|
|
||||||
|
set_target_properties(${COMPONENT_LIB} PROPERTIES
|
||||||
|
CXX_STANDARD 17
|
||||||
|
CXX_STANDARD_REQUIRED ON
|
||||||
|
CXX_EXTENSIONS ON
|
||||||
|
)
|
@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// Created on: 23.08.2022
|
||||||
|
// Author: franz
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
#include <charconv>
|
||||||
|
#include <list>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "cxx_include/esp_modem_dte.hpp"
|
||||||
|
#include "cxx_include/esp_modem_dce.hpp"
|
||||||
|
#include "esp_modem_config.h"
|
||||||
|
#include "cxx_include/esp_modem_api.hpp"
|
||||||
|
#include "cxx_include/command_library.hpp"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "SIM7070_gnss.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
const static char *const TAG = "SIM7070_gnss";
|
||||||
|
|
||||||
|
|
||||||
|
class LocalFactory: public esp_modem::dce_factory::Factory {
|
||||||
|
public:
|
||||||
|
static std::unique_ptr<DCE_gnss> create(const esp_modem::dce_config *config, std::shared_ptr<esp_modem::DTE> dte, esp_netif_t *netif)
|
||||||
|
{
|
||||||
|
return esp_modem::dce_factory::Factory::build_generic_DCE<SIM7070_gnss, DCE_gnss, std::unique_ptr<DCE_gnss>>(config, dte, netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module
|
||||||
|
* @return unique pointer of the resultant DCE
|
||||||
|
*/
|
||||||
|
std::unique_ptr<DCE_gnss> create_SIM7070_GNSS_dce(const esp_modem::dce_config *config,
|
||||||
|
std::shared_ptr<esp_modem::DTE> dte,
|
||||||
|
esp_netif_t *netif)
|
||||||
|
{
|
||||||
|
return LocalFactory::create(config, std::move(dte), netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::CommandableIf *t, gps_t &gps)
|
||||||
|
{
|
||||||
|
|
||||||
|
ESP_LOGV(TAG, "%s", __func__ );
|
||||||
|
std::string_view out;
|
||||||
|
auto ret = esp_modem::dce_commands::generic_get_string(t, "AT+CGNSINF\r", out);
|
||||||
|
if (ret != esp_modem::command_result::OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
constexpr std::string_view pattern = "+CGNSINF: ";
|
||||||
|
if (out.find(pattern) == std::string_view::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Parsing +CGNSINF:
|
||||||
|
* <GNSS run status>,
|
||||||
|
* <Fix status>,
|
||||||
|
* <UTC date & Time>,
|
||||||
|
* <Latitude>,
|
||||||
|
* <Longitude>,
|
||||||
|
* <MSL Altitude>,
|
||||||
|
* <Speed Over Ground>,
|
||||||
|
* <Course Over Ground>,
|
||||||
|
* <Fix Mode>,
|
||||||
|
* <Reserved1>,
|
||||||
|
* <HDOP>,
|
||||||
|
* <PDOP>,
|
||||||
|
* <VDOP>,
|
||||||
|
* <Reserved2>,
|
||||||
|
* <GNSS Satellites in View>,
|
||||||
|
* <Reserved3>,
|
||||||
|
* <HPA>,
|
||||||
|
* <VPA>
|
||||||
|
*/
|
||||||
|
out = out.substr(pattern.size());
|
||||||
|
int pos = 0;
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//GNSS run status
|
||||||
|
int GNSS_run_status;
|
||||||
|
if (std::from_chars(out.data(), out.data() + pos, GNSS_run_status).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
gps.run = (gps_run_t)GNSS_run_status;
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//Fix status
|
||||||
|
{
|
||||||
|
std::string_view fix_status = out.substr(0, pos);
|
||||||
|
if (fix_status.length() > 1) {
|
||||||
|
int Fix_status;
|
||||||
|
if (std::from_chars(out.data(), out.data() + pos, Fix_status).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
gps.fix = (gps_fix_t)Fix_status;
|
||||||
|
} else {
|
||||||
|
gps.fix = GPS_FIX_INVALID;
|
||||||
|
}
|
||||||
|
} //clean up Fix status
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//UTC date & Time
|
||||||
|
{
|
||||||
|
std::string_view UTC_date_and_Time = out.substr(0, pos);
|
||||||
|
if (UTC_date_and_Time.length() > 1) {
|
||||||
|
if (std::from_chars(out.data() + 0, out.data() + 4, gps.date.year).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
if (std::from_chars(out.data() + 4, out.data() + 6, gps.date.month).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
if (std::from_chars(out.data() + 6, out.data() + 8, gps.date.day).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
if (std::from_chars(out.data() + 8, out.data() + 10, gps.tim.hour).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
if (std::from_chars(out.data() + 10, out.data() + 12, gps.tim.minute).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
if (std::from_chars(out.data() + 12, out.data() + 14, gps.tim.second).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
if (std::from_chars(out.data() + 15, out.data() + 18, gps.tim.thousand).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gps.date.year = 0;
|
||||||
|
gps.date.month = 0;
|
||||||
|
gps.date.day = 0;
|
||||||
|
gps.tim.hour = 0;
|
||||||
|
gps.tim.minute = 0;
|
||||||
|
gps.tim.second = 0;
|
||||||
|
gps.tim.thousand = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //clean up UTC date & Time
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//Latitude
|
||||||
|
{
|
||||||
|
std::string_view Latitude = out.substr(0, pos);
|
||||||
|
if (Latitude.length() > 1) {
|
||||||
|
gps.latitude = std::stof(std::string(out.substr(0, pos)));
|
||||||
|
} else {
|
||||||
|
gps.latitude = 0;
|
||||||
|
}
|
||||||
|
} //clean up Latitude
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//Longitude
|
||||||
|
{
|
||||||
|
std::string_view Longitude = out.substr(0, pos);
|
||||||
|
if (Longitude.length() > 1) {
|
||||||
|
gps.longitude = std::stof(std::string(out.substr(0, pos)));
|
||||||
|
} else {
|
||||||
|
gps.longitude = 0;
|
||||||
|
}
|
||||||
|
} //clean up Longitude
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//Altitude
|
||||||
|
{
|
||||||
|
std::string_view Altitude = out.substr(0, pos);
|
||||||
|
if (Altitude.length() > 1) {
|
||||||
|
gps.altitude = std::stof(std::string(out.substr(0, pos)));
|
||||||
|
} else {
|
||||||
|
gps.altitude = 0;
|
||||||
|
}
|
||||||
|
} //clean up Altitude
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//Speed Over Ground Km/hour
|
||||||
|
{
|
||||||
|
std::string_view gps_speed = out.substr(0, pos);
|
||||||
|
if (gps_speed.length() > 1) {
|
||||||
|
gps.speed = std::stof(std::string(gps_speed));
|
||||||
|
} else {
|
||||||
|
gps.speed = 0;
|
||||||
|
}
|
||||||
|
} //clean up gps_speed
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//Course Over Ground degrees
|
||||||
|
{
|
||||||
|
std::string_view gps_cog = out.substr(0, pos);
|
||||||
|
if (gps_cog.length() > 1) {
|
||||||
|
gps.cog = std::stof(std::string(gps_cog));
|
||||||
|
} else {
|
||||||
|
gps.cog = 0;
|
||||||
|
}
|
||||||
|
} //clean up gps_cog
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
// Fix Mode
|
||||||
|
{
|
||||||
|
std::string_view FixModesubstr = out.substr(0, pos);
|
||||||
|
if (FixModesubstr.length() > 1) {
|
||||||
|
int Fix_Mode;
|
||||||
|
if (std::from_chars(out.data(), out.data() + pos, Fix_Mode).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
gps.fix_mode = (gps_fix_mode_t)Fix_Mode;
|
||||||
|
} else {
|
||||||
|
gps.fix_mode = GPS_MODE_INVALID;
|
||||||
|
}
|
||||||
|
} //clean up Fix Mode
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//HDOP
|
||||||
|
{
|
||||||
|
std::string_view HDOP = out.substr(0, pos);
|
||||||
|
if (HDOP.length() > 1) {
|
||||||
|
gps.dop_h = std::stof(std::string(HDOP));
|
||||||
|
} else {
|
||||||
|
gps.dop_h = 0;
|
||||||
|
}
|
||||||
|
} //clean up HDOP
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//PDOP
|
||||||
|
{
|
||||||
|
std::string_view PDOP = out.substr(0, pos);
|
||||||
|
if (PDOP.length() > 1) {
|
||||||
|
gps.dop_p = std::stof(std::string(PDOP));
|
||||||
|
} else {
|
||||||
|
gps.dop_p = 0;
|
||||||
|
}
|
||||||
|
} //clean up PDOP
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//VDOP
|
||||||
|
{
|
||||||
|
std::string_view VDOP = out.substr(0, pos);
|
||||||
|
if (VDOP.length() > 1) {
|
||||||
|
gps.dop_v = std::stof(std::string(VDOP));
|
||||||
|
} else {
|
||||||
|
gps.dop_v = 0;
|
||||||
|
}
|
||||||
|
} //clean up VDOP
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//sats_in_view
|
||||||
|
{
|
||||||
|
std::string_view sats_in_view = out.substr(0, pos);
|
||||||
|
if (sats_in_view.length() > 1) {
|
||||||
|
if (std::from_chars(out.data(), out.data() + pos, gps.sats_in_view).ec == std::errc::invalid_argument) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gps.sats_in_view = 0;
|
||||||
|
}
|
||||||
|
} //clean up sats_in_view
|
||||||
|
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
if ((pos = out.find(',')) == std::string::npos) {
|
||||||
|
return esp_modem::command_result::FAIL;
|
||||||
|
}
|
||||||
|
//HPA
|
||||||
|
{
|
||||||
|
std::string_view HPA = out.substr(0, pos);
|
||||||
|
if (HPA.length() > 1) {
|
||||||
|
gps.hpa = std::stof(std::string(HPA));
|
||||||
|
} else {
|
||||||
|
gps.hpa = 0;
|
||||||
|
}
|
||||||
|
} //clean up HPA
|
||||||
|
out = out.substr(pos + 1);
|
||||||
|
//VPA
|
||||||
|
{
|
||||||
|
std::string_view VPA = out.substr(0, pos);
|
||||||
|
if (VPA.length() > 1) {
|
||||||
|
gps.vpa = std::stof(std::string(VPA));
|
||||||
|
} else {
|
||||||
|
gps.vpa = 0;
|
||||||
|
}
|
||||||
|
} //clean up VPA
|
||||||
|
|
||||||
|
return esp_modem::command_result::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_modem::command_result SIM7070_gnss::get_gnss_information_sim70xx(gps_t &gps)
|
||||||
|
{
|
||||||
|
return get_gnss_information_sim70xx_lib(dte.get(), gps);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_modem::command_result DCE_gnss::get_gnss_information_sim70xx(gps_t &gps)
|
||||||
|
{
|
||||||
|
return device->get_gnss_information_sim70xx(gps);
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// Created on: 23.08.2022
|
||||||
|
// Author: franz
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "cxx_include/esp_modem_dce_factory.hpp"
|
||||||
|
#include "cxx_include/esp_modem_dce_module.hpp"
|
||||||
|
#include "nmea_parser.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Definition of a custom modem which inherits from the GenericModule, uses all its methods
|
||||||
|
* and could override any of them. Here, for demonstration purposes only, we redefine just `get_module_name()`
|
||||||
|
*/
|
||||||
|
class SIM7070_gnss: public esp_modem::SIM7070 {
|
||||||
|
using SIM7070::SIM7070;
|
||||||
|
public:
|
||||||
|
esp_modem::command_result get_gnss_information_sim70xx(gps_t &gps);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DCE_gnss : public esp_modem::DCE_T<SIM7070_gnss> {
|
||||||
|
public:
|
||||||
|
|
||||||
|
using DCE_T<SIM7070_gnss>::DCE_T;
|
||||||
|
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
|
||||||
|
template <typename ...Agrs> \
|
||||||
|
esp_modem::return_type name(Agrs&&... args) \
|
||||||
|
{ \
|
||||||
|
return device->name(std::forward<Agrs>(args)...); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_ALL_COMMAND_APIS(forwards name(...)
|
||||||
|
{
|
||||||
|
device->name(...);
|
||||||
|
} )
|
||||||
|
|
||||||
|
#undef ESP_MODEM_DECLARE_DCE_COMMAND
|
||||||
|
|
||||||
|
esp_modem::command_result get_gnss_information_sim70xx(gps_t &gps);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module
|
||||||
|
* @return unique pointer of the resultant DCE
|
||||||
|
*/
|
||||||
|
std::unique_ptr<DCE_gnss> create_SIM7070_GNSS_dce(const esp_modem::dce_config *config,
|
||||||
|
std::shared_ptr<esp_modem::DTE> dte,
|
||||||
|
esp_netif_t *netif);
|
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Origin: https://github.com/espressif/esp-idf/blob/master/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define GPS_MAX_SATELLITES_IN_USE (12)
|
||||||
|
#define GPS_MAX_SATELLITES_IN_VIEW (16)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPS fix type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
GPS_FIX_INVALID, /*!< Not fixed */
|
||||||
|
GPS_FIX_GPS, /*!< GPS */
|
||||||
|
GPS_FIX_DGPS, /*!< Differential GPS */
|
||||||
|
} gps_fix_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPS run type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
GPS_RUN_INVALID, /*!< Not fixed */
|
||||||
|
GPS_RUN_GPS, /*!< GPS */
|
||||||
|
} gps_run_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPS fix mode
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
GPS_MODE_INVALID, /*!< Not fixed */
|
||||||
|
GPS_MODE_2D, /*!< 2D GPS */
|
||||||
|
GPS_MODE_3D /*!< 3D GPS */
|
||||||
|
} gps_fix_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPS satellite information
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t num; /*!< Satellite number */
|
||||||
|
uint8_t elevation; /*!< Satellite elevation */
|
||||||
|
uint16_t azimuth; /*!< Satellite azimuth */
|
||||||
|
uint8_t snr; /*!< Satellite signal noise ratio */
|
||||||
|
} gps_satellite_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPS time
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t hour; /*!< Hour */
|
||||||
|
uint8_t minute; /*!< Minute */
|
||||||
|
uint8_t second; /*!< Second */
|
||||||
|
uint16_t thousand; /*!< Thousand */
|
||||||
|
} gps_time_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPS date
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t day; /*!< Day (start from 1) */
|
||||||
|
uint8_t month; /*!< Month (start from 1) */
|
||||||
|
uint16_t year; /*!< Year (start from 2000) */
|
||||||
|
} gps_date_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief NMEA Statement
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
STATEMENT_UNKNOWN = 0, /*!< Unknown statement */
|
||||||
|
STATEMENT_GGA, /*!< GGA */
|
||||||
|
STATEMENT_GSA, /*!< GSA */
|
||||||
|
STATEMENT_RMC, /*!< RMC */
|
||||||
|
STATEMENT_GSV, /*!< GSV */
|
||||||
|
STATEMENT_GLL, /*!< GLL */
|
||||||
|
STATEMENT_VTG /*!< VTG */
|
||||||
|
} nmea_statement_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPS object
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct gps_s {
|
||||||
|
float latitude; /*!< Latitude (degrees) */
|
||||||
|
float longitude; /*!< Longitude (degrees) */
|
||||||
|
float altitude; /*!< Altitude (meters) */
|
||||||
|
gps_run_t run; /*!< run status */
|
||||||
|
gps_fix_t fix; /*!< Fix status */
|
||||||
|
uint8_t sats_in_use; /*!< Number of satellites in use */
|
||||||
|
gps_time_t tim; /*!< time in UTC */
|
||||||
|
gps_fix_mode_t fix_mode; /*!< Fix mode */
|
||||||
|
float dop_h; /*!< Horizontal dilution of precision */
|
||||||
|
float dop_p; /*!< Position dilution of precision */
|
||||||
|
float dop_v; /*!< Vertical dilution of precision */
|
||||||
|
uint8_t sats_in_view; /*!< Number of satellites in view */
|
||||||
|
gps_date_t date; /*!< Fix date */
|
||||||
|
float speed; /*!< Ground speed, unit: m/s */
|
||||||
|
float cog; /*!< Course over ground */
|
||||||
|
float hpa; /*!< Horizontal Position Accuracy */
|
||||||
|
float vpa; /*!< Vertical Position Accuracy */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct gps_s gps_t;
|
||||||
|
typedef struct gps_s esp_modem_gps_s_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief NMEA Parser Event ID
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
GPS_UPDATE, /*!< GPS information has been updated */
|
||||||
|
GPS_UNKNOWN /*!< Unknown statements detected */
|
||||||
|
} nmea_event_id_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -22,6 +22,10 @@ menu "Example Configuration"
|
|||||||
bool "SIM7070"
|
bool "SIM7070"
|
||||||
help
|
help
|
||||||
SIM7070 is Multi-Band CAT M and NB IoT module.
|
SIM7070 is Multi-Band CAT M and NB IoT module.
|
||||||
|
config EXAMPLE_MODEM_DEVICE_SIM7070_GNSS
|
||||||
|
bool "SIM7070_GNSS"
|
||||||
|
help
|
||||||
|
SIM7070 is Multi-Band CAT M and NB IoT module with Support for GNSS Location API
|
||||||
config EXAMPLE_MODEM_DEVICE_SIM7600
|
config EXAMPLE_MODEM_DEVICE_SIM7600
|
||||||
bool "SIM7600"
|
bool "SIM7600"
|
||||||
help
|
help
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "esp_vfs_dev.h" // For optional VFS support
|
#include "esp_vfs_dev.h" // For optional VFS support
|
||||||
#include "esp_https_ota.h" // For potential OTA configuration
|
#include "esp_https_ota.h" // For potential OTA configuration
|
||||||
#include "vfs_resource/vfs_create.hpp"
|
#include "vfs_resource/vfs_create.hpp"
|
||||||
|
#include "SIM7070_gnss.hpp"
|
||||||
|
|
||||||
#if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE)
|
#if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE)
|
||||||
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE
|
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE
|
||||||
@ -87,15 +88,17 @@ extern "C" void app_main(void)
|
|||||||
assert(esp_netif);
|
assert(esp_netif);
|
||||||
|
|
||||||
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
|
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
|
||||||
std::unique_ptr<DCE> dce = create_BG96_dce(&dce_config, dte, esp_netif);
|
auto dce = create_BG96_dce(&dce_config, dte, esp_netif);
|
||||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1
|
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1
|
||||||
std::unique_ptr<DCE> dce = create_SIM800_dce(&dce_config, dte, esp_netif);
|
auto dce = create_SIM800_dce(&dce_config, dte, esp_netif);
|
||||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7000 == 1
|
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7000 == 1
|
||||||
std::unique_ptr<DCE> dce = create_SIM7000_dce(&dce_config, dte, esp_netif);
|
auto dce = create_SIM7000_dce(&dce_config, dte, esp_netif);
|
||||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070 == 1
|
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070 == 1
|
||||||
std::unique_ptr<DCE> dce = create_SIM7070_dce(&dce_config, dte, esp_netif);
|
auto dce = create_SIM7070_dce(&dce_config, dte, esp_netif);
|
||||||
|
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS == 1
|
||||||
|
auto dce = create_SIM7070_GNSS_dce(&dce_config, dte, esp_netif);
|
||||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
|
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
|
||||||
std::unique_ptr<DCE> dce = create_SIM7600_dce(&dce_config, dte, esp_netif);
|
auto dce = create_SIM7600_dce(&dce_config, dte, esp_netif);
|
||||||
#else
|
#else
|
||||||
#error "Unsupported device"
|
#error "Unsupported device"
|
||||||
#endif
|
#endif
|
||||||
@ -135,6 +138,12 @@ extern "C" void app_main(void)
|
|||||||
}
|
}
|
||||||
std::cout << "Operator name:" << str << std::endl;
|
std::cout << "Operator name:" << str << std::endl;
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS == 1
|
||||||
|
if (dce->set_gnss_power_mode(1) == esp_modem::command_result::OK) {
|
||||||
|
std::cout << "Modem set_gnss_power_mode: OK" << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Try to connect to the network and publish an mqtt topic */
|
/* Try to connect to the network and publish an mqtt topic */
|
||||||
ESPEventHandlerSync event_handler(loop);
|
ESPEventHandlerSync event_handler(loop);
|
||||||
event_handler.listen_to(ESPEvent(IP_EVENT, ESPEventID(ESP_EVENT_ANY_ID)));
|
event_handler.listen_to(ESPEvent(IP_EVENT, ESPEventID(ESP_EVENT_ANY_ID)));
|
||||||
@ -184,6 +193,43 @@ extern "C" void app_main(void)
|
|||||||
std::cout << "Modem IMSI number:" << str << std::endl;
|
std::cout << "Modem IMSI number:" << str << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS == 1
|
||||||
|
gps_t gps;
|
||||||
|
|
||||||
|
for (int i = 0; i < 200; ++i) {
|
||||||
|
if (dce->get_gnss_information_sim70xx(gps) == esp_modem::command_result::OK) {
|
||||||
|
ESP_LOGI(TAG, "gps.run %i",
|
||||||
|
gps.run);
|
||||||
|
ESP_LOGI(TAG, "gps.fix %i",
|
||||||
|
gps.fix);
|
||||||
|
ESP_LOGI(TAG, "gps.date.year %i gps.date.month %i gps.date.day %i",
|
||||||
|
gps.date.year, gps.date.month, gps.date.day);
|
||||||
|
ESP_LOGI(TAG, "gps.tim.hour %i gps.tim.minute %i gps.tim.second %i gps.tim.thousand %i",
|
||||||
|
gps.tim.hour, gps.tim.minute, gps.tim.second, gps.tim.thousand);
|
||||||
|
ESP_LOGI(TAG, "gps.latitude %f gps.longitude %f ",
|
||||||
|
gps.latitude, gps.longitude );
|
||||||
|
ESP_LOGI(TAG, "gps.altitude %f",
|
||||||
|
gps.altitude);
|
||||||
|
ESP_LOGI(TAG, "gps.speed %f",
|
||||||
|
gps.speed);
|
||||||
|
ESP_LOGI(TAG, "gps.cog %f",
|
||||||
|
gps.cog);
|
||||||
|
ESP_LOGI(TAG, "gps.fix_mode %i",
|
||||||
|
gps.fix_mode);
|
||||||
|
ESP_LOGI(TAG, "gps.dop_h %f gps.dop_p %f gps.dop_v %f ",
|
||||||
|
gps.dop_h, gps.dop_p, gps.dop_v );
|
||||||
|
ESP_LOGI(TAG, "gps.sats_in_view %i",
|
||||||
|
gps.sats_in_view);
|
||||||
|
ESP_LOGI(TAG, "gps.hpa %f gps.vpa %f",
|
||||||
|
gps.hpa, gps.vpa);
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000)); //Wait
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS
|
||||||
|
|
||||||
|
|
||||||
#if CONFIG_EXAMPLE_PERFORM_OTA == 1
|
#if CONFIG_EXAMPLE_PERFORM_OTA == 1
|
||||||
esp_http_client_config_t config = { };
|
esp_http_client_config_t config = { };
|
||||||
config.skip_cert_common_name_check = true;
|
config.skip_cert_common_name_check = true;
|
||||||
|
@ -9,4 +9,4 @@ CONFIG_PARTITION_TABLE_TWO_OTA=y
|
|||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF=y
|
CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF=y
|
||||||
CONFIG_NEWLIB_STDIN_LINE_ENDING_LF=y
|
CONFIG_NEWLIB_STDIN_LINE_ENDING_LF=y
|
||||||
CONFIG_MAIN_TASK_STACK_SIZE=8192
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
||||||
|
27
components/esp_modem/include/cxx_include/command_library.hpp
Normal file
27
components/esp_modem/include/cxx_include/command_library.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
namespace esp_modem::dce_commands {
|
||||||
|
command_result generic_command(CommandableIf *t, const std::string &command,
|
||||||
|
const std::list<std::string_view> &pass_phrase,
|
||||||
|
const std::list<std::string_view> &fail_phrase,
|
||||||
|
uint32_t timeout_ms);
|
||||||
|
|
||||||
|
|
||||||
|
command_result generic_command(CommandableIf *t, const std::string &command,
|
||||||
|
const std::string &pass_phrase,
|
||||||
|
const std::string &fail_phrase, uint32_t timeout_ms);
|
||||||
|
|
||||||
|
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500);
|
||||||
|
|
||||||
|
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500);
|
||||||
|
|
||||||
|
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout = 500);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // esp_modem::dce_commands
|
@ -10,6 +10,8 @@
|
|||||||
#include "cxx_include/esp_modem_dte.hpp"
|
#include "cxx_include/esp_modem_dte.hpp"
|
||||||
#include "cxx_include/esp_modem_dce_module.hpp"
|
#include "cxx_include/esp_modem_dce_module.hpp"
|
||||||
#include "cxx_include/esp_modem_command_library.hpp"
|
#include "cxx_include/esp_modem_command_library.hpp"
|
||||||
|
#include "cxx_include/command_library.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace esp_modem::dce_commands {
|
namespace esp_modem::dce_commands {
|
||||||
|
|
||||||
@ -40,7 +42,7 @@ command_result generic_command(CommandableIf *t, const std::string &command,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline command_result generic_command(CommandableIf *t, const std::string &command,
|
command_result generic_command(CommandableIf *t, const std::string &command,
|
||||||
const std::string &pass_phrase,
|
const std::string &pass_phrase,
|
||||||
const std::string &fail_phrase, uint32_t timeout_ms)
|
const std::string &fail_phrase, uint32_t timeout_ms)
|
||||||
{
|
{
|
||||||
@ -50,7 +52,7 @@ static inline command_result generic_command(CommandableIf *t, const std::string
|
|||||||
return generic_command(t, command, pass, fail, timeout_ms);
|
return generic_command(t, command, pass, fail, timeout_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500)
|
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms)
|
||||||
{
|
{
|
||||||
ESP_LOGV(TAG, "%s", __func__ );
|
ESP_LOGV(TAG, "%s", __func__ );
|
||||||
return t->command(command, [&](uint8_t *data, size_t len) {
|
return t->command(command, [&](uint8_t *data, size_t len) {
|
||||||
@ -77,7 +79,7 @@ static inline command_result generic_get_string(CommandableIf *t, const std::str
|
|||||||
}, timeout_ms);
|
}, timeout_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500)
|
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms)
|
||||||
{
|
{
|
||||||
ESP_LOGV(TAG, "%s", __func__ );
|
ESP_LOGV(TAG, "%s", __func__ );
|
||||||
std::string_view out;
|
std::string_view out;
|
||||||
@ -89,7 +91,7 @@ static inline command_result generic_get_string(CommandableIf *t, const std::str
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout = 500)
|
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout)
|
||||||
{
|
{
|
||||||
ESP_LOGV(TAG, "%s", __func__ );
|
ESP_LOGV(TAG, "%s", __func__ );
|
||||||
return generic_command(t, command, "OK", "ERROR", timeout);
|
return generic_command(t, command, "OK", "ERROR", timeout);
|
||||||
|
Reference in New Issue
Block a user