Public Access
M2 step 3: GNSS Service, with standby and the clock from a Fix
The GNSS Service reads the receiver (UART 15/13, 115200, 1 KB buffer) from its 50 ms tick and feeds the NMEA parser. With a Fix it sets the clock (GNSS is the most trusted TimeSource) and refreshes it every 10 min. Settings gets GNSS On/Off and the coordinate format (Q64). Off puts the receiver in standby with $PCAS12,65535, renewed hourly; On wakes it with a hot start, $PCAS10,0. Both measured on the device: the output stops within a second, and a command wakes it within a second. Commands: gnss status (Fix, satellites per constellation, bytes and sentences), gnss nmea on|off, gnss send <sentence>, gnss restart. The probe is gone; never drive GPIO 15 (the receiver's output): the first probe's swapped-pin attempt silenced it until a power cycle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <Print.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "event_bus.h"
|
||||
#include "nmea_parser.h"
|
||||
#include "service.h"
|
||||
#include "services/clock_service.h"
|
||||
#include "settings.h"
|
||||
|
||||
namespace roro {
|
||||
|
||||
// The GNSS receiver on the Cap LoRa-1262 (see CONTEXT.md and docs/milestones/M2.md): reads its
|
||||
// NMEA from the main loop's tick (about 450 bytes/s, so a 1 KB UART buffer covers any stall),
|
||||
// holds the current Fix, and sets the clock from it. Settings → GNSS switches it on and off.
|
||||
class GnssService : public Service {
|
||||
public:
|
||||
static constexpr int kRxPin = 15, kTxPin = 13; // measured: M2 step 1
|
||||
static constexpr uint32_t kBaud = 115200;
|
||||
static constexpr uint32_t kSilentAfterMs = 3000; // no sentence for this long: receiver silent
|
||||
static constexpr uint32_t kClockEveryMs = 600000; // refresh the clock from the Fix this often
|
||||
// Off (Q58, measured): "$PCAS12,<s>" puts the receiver in standby for that long, and any
|
||||
// command wakes it. Standby is renewed while off, in case the duration is clamped.
|
||||
static constexpr uint32_t kStandbyRenewMs = 3600000;
|
||||
|
||||
GnssService(const Settings& settings, ClockService& clock, EventBus& bus);
|
||||
const char* name() const override { return "gnss"; }
|
||||
uint32_t tickIntervalMs() const override { return 50; }
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void tick(uint32_t nowMs) override;
|
||||
|
||||
bool on() const { return active_; }
|
||||
bool receiving(uint32_t nowMs) const { return active_ && lastLineMs_ && nowMs - lastLineMs_ < kSilentAfterMs; }
|
||||
const gnss::GnssState& state() const { return parser_.state(); }
|
||||
|
||||
// Debug aids (Q68): raw sentences to the console, a status report, and sending a command
|
||||
// ("PCAS10,0" becomes "$PCAS10,0*1C\r\n").
|
||||
void setEcho(bool echo) { echo_ = echo; }
|
||||
void printStatus(Print& out, uint32_t nowMs) const;
|
||||
bool send(const std::string& body);
|
||||
void restart(uint32_t nowMs) {
|
||||
close();
|
||||
open(nowMs);
|
||||
}
|
||||
|
||||
private:
|
||||
void open(uint32_t nowMs); // the UART; the receiver's state follows the setting in tick()
|
||||
void close();
|
||||
void wake(uint32_t nowMs);
|
||||
void standby(uint32_t nowMs);
|
||||
|
||||
const Settings& settings_;
|
||||
ClockService& clock_;
|
||||
EventBus& bus_;
|
||||
gnss::NmeaParser parser_;
|
||||
bool open_ = false, active_ = false, echo_ = false;
|
||||
uint32_t bytes_ = 0, standbyMs_ = 0;
|
||||
uint32_t openedMs_ = 0, lastLineMs_ = 0, firstFixMs_ = 0, clockSetMs_ = 0;
|
||||
gnss::FixType lastFix_ = gnss::FixType::None;
|
||||
};
|
||||
|
||||
} // namespace roro
|
||||
Reference in New Issue
Block a user