Skip to content

Commit

Permalink
Merge pull request #768 from WildernessLabs/IGnssSensor
Browse files Browse the repository at this point in the history
Update GNSS drivers to use IGnssSensor interface
  • Loading branch information
adrianstevens authored Sep 13, 2023
2 parents e154780 + f9d6eac commit 352101e
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
using System;
using System.Text;
using Meadow.Foundation.Sensors.Location.Gnss;
using Meadow.Foundation.Sensors.Location.Gnss;
using Meadow.Hardware;
using Meadow.Peripherals.Sensors.Location.Gnss;
using System;
using System.Text;

namespace Meadow.Foundation.Sensors.Gnss
{
/// <summary>
/// NMEA Event args - holds an NMEA sentence as a string
/// </summary>
public class NmeaEventArgs
{
/// <summary>
/// The NMEA sentence
/// </summary>
public string NmeaSentence { get; set; } = string.Empty;
}

/// <summary>
/// Represents MT3339 MediaTek high-performance, single-chip, multi-GNSS solution
/// </summary>
public class Mt3339
public class Mt3339 : IGnssSensor
{
readonly ISerialMessagePort serialPort;
NmeaSentenceProcessor? nmeaProcessor;

/// <summary>
/// Supported GNSS result types
/// </summary>
public IGnssResult[] SupportedResultTypes { get; } = new IGnssResult[]
{
new GnssPositionInfo(),
new ActiveSatellites(),
new CourseOverGround()
};

/// <summary>
/// Raised when GNSS data is received
/// </summary>
public event EventHandler<IGnssResult> GnssDataReceived = delegate { };

/// <summary>
/// Raised when GAG data is recieved
/// </summary>
Expand Down Expand Up @@ -92,17 +96,28 @@ protected void Initialize()
}

/// <summary>
/// Start updates
/// Start updating GNSS data
/// </summary>
public void StartUpdating()
{
serialPort.Open();

this.serialPort.Write(Encoding.ASCII.GetBytes(Commands.PMTK_Q_RELEASE));
serialPort.Write(Encoding.ASCII.GetBytes(Commands.PMTK_Q_RELEASE));

this.serialPort.Write(Encoding.ASCII.GetBytes(Commands.PGCMD_ANTENNA));
serialPort.Write(Encoding.ASCII.GetBytes(Commands.PGCMD_ANTENNA));

this.serialPort.Write(Encoding.ASCII.GetBytes(Commands.PMTK_SET_NMEA_OUTPUT_ALLDATA));
serialPort.Write(Encoding.ASCII.GetBytes(Commands.PMTK_SET_NMEA_OUTPUT_ALLDATA));
}

/// <summary>
/// Stop updating GNSS data
/// </summary>
public void StopUpdating()
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
}

/// <summary>
Expand All @@ -113,46 +128,61 @@ protected void InitDecoders()
nmeaProcessor = new NmeaSentenceProcessor();

var mtkDecoder = new MtkDecoder();

nmeaProcessor.RegisterDecoder(mtkDecoder);

var ggaDecoder = new GgaDecoder();

nmeaProcessor.RegisterDecoder(ggaDecoder);
ggaDecoder.PositionReceived += (object sender, GnssPositionInfo location) =>
GgaReceived(this, location);

ggaDecoder.PositionReceived += (object sender, GnssPositionInfo location) =>
{
GgaReceived?.Invoke(this, location);
GnssDataReceived?.Invoke(this, location);
};

var gllDecoder = new GllDecoder();
nmeaProcessor.RegisterDecoder(gllDecoder);
gllDecoder.GeographicLatitudeLongitudeReceived += (object sender, GnssPositionInfo location) => {
GllReceived(this, location);
gllDecoder.GeographicLatitudeLongitudeReceived += (object sender, GnssPositionInfo location) =>
{
GllReceived?.Invoke(this, location);
GnssDataReceived?.Invoke(this, location);
};

var gsaDecoder = new GsaDecoder();
nmeaProcessor.RegisterDecoder(gsaDecoder);
gsaDecoder.ActiveSatellitesReceived += (object sender, ActiveSatellites activeSatellites) =>
GsaReceived(this, activeSatellites);

gsaDecoder.ActiveSatellitesReceived += (object sender, ActiveSatellites activeSatellites) =>
{
GsaReceived?.Invoke(this, activeSatellites);
GnssDataReceived?.Invoke(this, activeSatellites);
};

var rmcDecoder = new RmcDecoder();
nmeaProcessor.RegisterDecoder(rmcDecoder);
rmcDecoder.PositionCourseAndTimeReceived += (object sender, GnssPositionInfo positionCourseAndTime) =>
RmcReceived(this, positionCourseAndTime);
rmcDecoder.PositionCourseAndTimeReceived += (object sender, GnssPositionInfo positionCourseAndTime) =>
{
RmcReceived?.Invoke(this, positionCourseAndTime);
GnssDataReceived?.Invoke(this, positionCourseAndTime);
};

var vtgDecoder = new VtgDecoder();
nmeaProcessor.RegisterDecoder(vtgDecoder);
vtgDecoder.CourseAndVelocityReceived += (object sender, CourseOverGround courseAndVelocity) =>
VtgReceived(this, courseAndVelocity);
{
VtgReceived?.Invoke(this, courseAndVelocity);
GnssDataReceived?.Invoke(this, courseAndVelocity);
};


var gsvDecoder = new GsvDecoder();
nmeaProcessor.RegisterDecoder(gsvDecoder);
gsvDecoder.SatellitesInViewReceived += (object sender, SatellitesInView satellites) =>
GsvReceived(this, satellites);
{
GsvReceived?.Invoke(this, satellites);
GnssDataReceived?.Invoke(this, satellites);
};
}

private void SerialPort_MessageReceived(object sender, SerialMessageData e)
{
string msg = (e.GetMessageString(Encoding.ASCII));
nmeaProcessor?.ProcessNmeaMessage(msg);
nmeaProcessor?.ProcessNmeaMessage(e.GetMessageString(Encoding.ASCII));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,13 @@ private async Task InitializeI2c(II2cBus i2cBus, byte address)

private async Task StartUpdatingI2c()
{
cts = new CancellationTokenSource();

var t = new Task(() =>
{
int len;
while (true)
while (cts.IsCancellationRequested == false)
{
len = i2cComms.ReadRegisterAsUShort(0xFD, ByteOrder.BigEndian);
Expand All @@ -92,5 +94,10 @@ private async Task StartUpdatingI2c()
t.Start();
await t;
}

private void StopUpdatingI2c()
{
cts.Cancel();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,13 @@ private void StartUpdatingSerial()
serialPort.Write(Encoding.ASCII.GetBytes(Commands.PMTK_Q_RELEASE));
serialPort.Write(Encoding.ASCII.GetBytes(Commands.PGCMD_ANTENNA));
}

private void StopUpdatingSerial()
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ private async Task InitializeSpi()

private async Task StartUpdatingSpi()
{
cts = new CancellationTokenSource();

byte[] data = new byte[BUFFER_SIZE];

static bool HasMoreData(byte[] data)
Expand All @@ -109,7 +111,7 @@ static bool HasMoreData(byte[] data)

var t = new Task(() =>
{
while (true)
while (cts.Token.IsCancellationRequested == false) { }
{
spiComms.Read(data);
messageProcessor.Process(data);
Expand All @@ -122,5 +124,10 @@ static bool HasMoreData(byte[] data)
}, TaskCreationOptions.LongRunning);
await t;
}

void StopUpdatingSpi()
{
cts?.Cancel();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,33 @@
using Meadow.Peripherals.Sensors.Location.Gnss;
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.Foundation.Sensors.Gnss
{
/// <summary>
/// Represents a NEO-M8 GNSS module
/// </summary>
public partial class NeoM8
public partial class NeoM8 : IGnssSensor
{
NmeaSentenceProcessor nmeaProcessor;

/// <summary>
/// Raised when GNSS data is received
/// </summary>
public event EventHandler<IGnssResult> GnssDataReceived = delegate { };

/// <summary>
/// Supported GNSS result types
/// </summary>
public IGnssResult[] SupportedResultTypes { get; } = new IGnssResult[]
{
new GnssPositionInfo(),
new ActiveSatellites(),
new CourseOverGround()
};

/// <summary>
/// Raised when GGA position data is received
/// </summary>
Expand Down Expand Up @@ -59,6 +75,8 @@ public partial class NeoM8

SerialMessageProcessor messageProcessor;

CancellationTokenSource cts;

const byte BUFFER_SIZE = 128;
const byte COMMS_SLEEP_MS = 200;

Expand All @@ -67,7 +85,7 @@ public partial class NeoM8
/// </summary>
public async Task Reset()
{
if(ResetPort != null)
if (ResetPort != null)
{
ResetPort.State = false;
await Task.Delay(TimeSpan.FromMilliseconds(10));
Expand All @@ -80,7 +98,7 @@ public async Task Reset()
/// </summary>
public void StartUpdating()
{
switch(communicationMode)
switch (communicationMode)
{
case CommunicationMode.Serial:
StartUpdatingSerial();
Expand All @@ -94,6 +112,25 @@ public void StartUpdating()
}
}

/// <summary>
/// Stop updating
/// </summary>
public void StopUpdating()
{
switch (communicationMode)
{
case CommunicationMode.Serial:
StopUpdatingSerial();
break;
case CommunicationMode.SPI:
StopUpdatingSpi();
break;
case CommunicationMode.I2C:
StopUpdatingI2c();
break;
}
}

void InitDecoders()
{
nmeaProcessor = new NmeaSentenceProcessor();
Expand All @@ -102,42 +139,48 @@ void InitDecoders()
nmeaProcessor.RegisterDecoder(ggaDecoder);
ggaDecoder.PositionReceived += (object sender, GnssPositionInfo location) =>
{
GgaReceived(this, location);
GgaReceived?.Invoke(this, location);
GnssDataReceived?.Invoke(this, location);
};

var gllDecoder = new GllDecoder();
nmeaProcessor.RegisterDecoder(gllDecoder);
gllDecoder.GeographicLatitudeLongitudeReceived += (object sender, GnssPositionInfo location) =>
{
GllReceived(this, location);
GllReceived?.Invoke(this, location);
GnssDataReceived?.Invoke(this, location);
};

var gsaDecoder = new GsaDecoder();
nmeaProcessor.RegisterDecoder(gsaDecoder);
gsaDecoder.ActiveSatellitesReceived += (object sender, ActiveSatellites activeSatellites) =>
{
GsaReceived(this, activeSatellites);
GsaReceived?.Invoke(this, activeSatellites);
GnssDataReceived?.Invoke(this, activeSatellites);
};

var rmcDecoder = new RmcDecoder();
nmeaProcessor.RegisterDecoder(rmcDecoder);
rmcDecoder.PositionCourseAndTimeReceived += (object sender, GnssPositionInfo positionCourseAndTime) =>
{
RmcReceived(this, positionCourseAndTime);
RmcReceived?.Invoke(this, positionCourseAndTime);
GnssDataReceived?.Invoke(this, positionCourseAndTime);
};

var vtgDecoder = new VtgDecoder();
nmeaProcessor.RegisterDecoder(vtgDecoder);
vtgDecoder.CourseAndVelocityReceived += (object sender, CourseOverGround courseAndVelocity) =>
{
VtgReceived(this, courseAndVelocity);
VtgReceived?.Invoke(this, courseAndVelocity);
GnssDataReceived?.Invoke(this, courseAndVelocity);
};

var gsvDecoder = new GsvDecoder();
nmeaProcessor.RegisterDecoder(gsvDecoder);
gsvDecoder.SatellitesInViewReceived += (object sender, SatellitesInView satellites) =>
{
GsvReceived(this, satellites);
GsvReceived?.Invoke(this, satellites);
GnssDataReceived?.Invoke(this, satellites);
};
}

Expand Down

0 comments on commit 352101e

Please sign in to comment.