Skip to content
Snippets Groups Projects
Commit ceb63a00 authored by philip.schell's avatar philip.schell
Browse files

Update Lora

parent 757dd0c2
No related branches found
No related tags found
No related merge requests found
using System;
using System.Collections.Generic;
using Fraunhofer.Fit.Iot.Lora.Interfaces;
namespace Fraunhofer.Fit.Iot.Lora.Devices {
public class GpsInfo : AConnector {
public GpsInfo(String str) {
String[] infos = str.Split(',');
if (Double.TryParse(infos[0], out Double breitengrad)) {
this.Latitude = breitengrad;
}
if (Double.TryParse(infos[1], out Double laengengrad)) {
this.Longitude = laengengrad;
}
String d = "01.01.2000 " + infos[2][0] + infos[2][1] + ":" + infos[2][2] + infos[2][3] + ":" + infos[2][4] + infos[2][5];
if (DateTime.TryParse(d, out DateTime dv)) {
this.Time = dv.TimeOfDay;
}
if (Double.TryParse(infos[3], out Double hdop)) {
this.Hdop = hdop;
}
this.Fix = !(Math.Abs(this.Latitude) < 0.000001 && Math.Abs(this.Longitude) < 0.000001); //Check for 0 lat and long
}
public GpsInfo(Single lat, Single lon, Byte hour, Byte minute, Byte second, Single hdop, Boolean fix) {
this.Latitude = lat;
this.Longitude = lon;
String d = "01.01.2000 " + hour.ToString() + ":" + minute.ToString() + ":" + second.ToString();
if (DateTime.TryParse(d, out DateTime dv)) {
this.Time = dv.TimeOfDay;
}
this.Hdop = hdop;
this.Fix = fix;
}
public Double Latitude { get; private set; }
public Double Longitude { get; private set; }
public TimeSpan Time { get; private set; }
public Double Hdop { get; private set; }
public Boolean Fix { get; private set; }
public override String ToString() {
return "Lat: " + this.Latitude + " Lon: " + this.Longitude + "\nTime: " + this.Time + " HDOP: " + this.Hdop + " Fix: " + this.Fix;
}
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using Fraunhofer.Fit.Iot.Lora.Events;
using Fraunhofer.Fit.Iot.Lora.Interfaces;
namespace Fraunhofer.Fit.Iot.Lora.Devices {
public class LoraClient : AConnector {
public delegate void DataUpdate(Object sender, DeviceUpdateEvent e);
public event DataUpdate Update;
public Byte PacketRssi { get; private set; }
public Byte Rssi { get; private set; }
public Double Snr { get; private set; }
public DateTime Receivedtime { get; private set; }
public String Name { get; private set; }
public ReadOnlyDictionary<String, WlanNetwork> Wifi { get; private set; }
public GpsInfo Gps { get; private set; }
public Int32 BatteryLevel { get; private set; }
public LoraClient(LoraClientEvent e) {
this.PacketRssi = e.Packetrssi;
this.Rssi = e.Rssi;
this.Snr = e.Snr;
this.Receivedtime = e.UpdateTime;
}
public LoraClient(LoraClientEvent e, String data) : this(e) {
this.Parse(data);
}
public LoraClient(LoraClientEvent e, Byte[] data) : this(e) {
this.Parse(data);
}
private void Parse(Byte[] data) {
if (data.Length == 28) {
this.Name = GetName(data);
Single lat = BitConverter.ToSingle(this.From5to4(data, 9), 0);
Single lon = BitConverter.ToSingle(this.From5to4(data, 14), 0);
Byte hour = data[19];
Byte minute = data[20];
Byte second = data[21];
Single hdop = BitConverter.ToSingle(this.From5to4(data, 22), 0);
this.BatteryLevel = data[27];
Boolean fix = (lat != 0 && lon != 0);
this.Gps = new GpsInfo(lat, lon, hour, minute, second, hdop, fix);
this.Wifi = new ReadOnlyDictionary<String, WlanNetwork>(new Dictionary<String, WlanNetwork>());
this.Update?.Invoke(this, new DeviceUpdateEvent(this, DateTime.Now, this));
}
}
private Byte[] From5to4(Byte[] data, Int32 start) {
if(data.Length < start + 6) {
return new Byte[] { 0, 0, 0, 0 };
}
UInt64 t = 0;
t = data[start + 4];
t += ((UInt64)data[start + 3] << 7);
t += ((UInt64)data[start + 2] << 14);
t += ((UInt64)data[start + 1] << 21);
t += ((UInt64)data[start + 0] << 28);
return BitConverter.GetBytes(t);
}
private void Parse(String text) {
String[] texts = text.Split(new String[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
this.Name = GetName(text);
Dictionary<String, WlanNetwork> wifis = new Dictionary<String, WlanNetwork>();
for(Int16 i=1;i<texts.Length-1;i++) {
WlanNetwork w = new WlanNetwork(texts[i]);
if(w.Success) {
String id = w.MacAddr;
wifis.Add(id, w);
}
}
this.Wifi = new ReadOnlyDictionary<String, WlanNetwork>(wifis);
String[] infos = texts[texts.Length - 1].Split(',');
if (infos.Length >= 5 && Int32.TryParse(infos[4], out Int32 batteryLevel)) {
this.BatteryLevel = batteryLevel;
}
this.Gps = new GpsInfo(texts[texts.Length - 1]);
this.Update?.Invoke(this, new DeviceUpdateEvent(this, DateTime.Now, this));
}
public override String ToString() {
String ret = this.Name + "\n" + "Packet: PRssi: "+this.PacketRssi+" Rssi: "+this.Rssi+" SNR: "+this.Snr+" Time: "+this.Receivedtime.ToString() + " Battery: " + this.BatteryLevel+"\n";
ret += "WLAN:\n";
foreach (KeyValuePair<String, WlanNetwork> item in this.Wifi) {
ret += item.ToString() + "\n";
}
ret += "GPS:\n" + this.Gps.ToString();
return ret;
}
private void SetUpdate(LoraClientEvent e) {
this.PacketRssi = e.Packetrssi;
this.Rssi = e.Rssi;
this.Snr = e.Snr;
this.Receivedtime = e.UpdateTime;
}
public void SetUpdate(LoraClientEvent e, String data) {
this.SetUpdate(e);
this.Parse(data);
}
public void SetUpdate(LoraClientEvent e, Byte[] data) {
this.SetUpdate(e);
this.Parse(data);
}
public static Boolean CheckPacket(String message)
{
String[] m;
if (message.Contains("\r\n")) {
m = message.Split(new String[] { "\r\n" }, StringSplitOptions.None);
} else if (message.Contains("\n")) {
m = message.Split(new String[] { "\n" }, StringSplitOptions.None);
} else {
return false;
}
if (m.Length == 5) {
//Console.WriteLine(m[0]);
if(m[0] == "") {
//Console.WriteLine("Name Match Fail");
return false;
}
for (Int32 i = 1; i < 4; i++) {
//Console.WriteLine(m[i]);
if (!Regex.Match(m[i], "[A-F0-9]{12},[-0-9]+,[0-9]+").Success) {
return false;
}
}
if (!Regex.Match(m[4], "[0-9]+.[0-9]{5,10},[0-9]+.[0-9]{5,10},[0-9]{6},[0-9]+.[0-9]{2},[0-9]+").Success) {
return false;
}
return true;
}
if (m.Length == 2) {
//Console.WriteLine("L2");
if (m[0] == "") {
//Console.WriteLine("Name Match Fail");
return false;
}
if (!Regex.Match(m[1], "[0-9]+.[0-9]{5,10},[0-9]+.[0-9]{5,10},[0-9]{6},[0-9]+.[0-9]{2},[0-9]+").Success) {
//Console.WriteLine("GPS Match Fail");
return false;
}
return true;
}
return false;
}
public static String GetName(String message) {
return message.Split(new String[] { "\r\n" }, StringSplitOptions.None)[0].Trim();
}
public static String GetName(Byte[] data) {
if(data.Length >= 9) {
Byte[] ret = new Byte[8];
for (Int32 i = 0; i < 8; i++) {
ret[i] = data[i + 1];
}
return System.Text.Encoding.ASCII.GetString(ret).Trim();
}
return "";
}
public override String MqttTopic() {
return base.MqttTopic() + "-" + this.Name;
}
}
}
using System;
using Fraunhofer.Fit.Iot.Lora.Interfaces;
namespace Fraunhofer.Fit.Iot.Lora.Devices {
public class WlanNetwork : AConnector {
public WlanNetwork(String str) {
String[] infos = str.Split(',');
String mac = infos[0];
if(mac == "000000000000") {
this.Success = false;
return;
}
try {
this.MacAddr = mac[0].ToString() + mac[1].ToString();
for (Int32 i = 2; i < 12; i = i + 2) {
this.MacAddr += ":" + mac[i] + mac[i + 1];
}
} catch { }
if (Int32.TryParse(infos[1], out Int32 rssi)) {
this.Rssi = rssi;
}
if (Int32.TryParse(infos[2], out Int32 channel)) {
this.Channel = channel;
}
this.Success = true;
}
public String MacAddr { get; private set; }
public Int32 Rssi { get; private set; }
public Int32 Channel { get; private set; }
public Boolean Success { get; private set; }
public override String ToString() {
return "MAC: " + this.MacAddr + "(" + this.Channel + ") RSSI:" + this.Rssi;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Fraunhofer.Fit.Iot.Lora.Events {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Fraunhofer.Fit.Iot.Lora.Events {
public class LoraClientEvent : EventArgs {
public LoraClientEvent() {
}
public LoraClientEvent(Byte Length, String Text, Double Snr, Byte PacketRssi, Byte Rssi) {
this.Length = Length;
this.Text = Text;
this.Snr = Snr;
this.Packetrssi = PacketRssi;
this.Rssi = Rssi;
this.UpdateTime = DateTime.Now;
}
public Byte Length { get; }
public String Text { get; }
public Double Snr { get; }
public Byte Packetrssi { get; }
public Byte Rssi { get; }
public DateTime UpdateTime { get; }
}
public class DeviceUpdateEvent : EventArgs {
public DeviceUpdateEvent() {
}
public DeviceUpdateEvent(Byte Length, String Text, Double Snr, Byte PacketRssi, Byte Rssi) {
this.Length = Length;
this.Text = Text;
this.Snr = Snr;
this.Packetrssi = PacketRssi;
this.Rssi = Rssi;
this.UpdateTime = DateTime.Now;
public DeviceUpdateEvent(Object value, DateTime time, Object parent) {
this.GetValue = value;
this.UpdateTime = time;
this.Parent = parent;
}
public Byte Length { get; }
public String Text { get; }
public Double Snr { get; }
public Byte Packetrssi { get; }
public Byte Rssi { get; }
public Object GetValue { get; }
public DateTime UpdateTime { get; }
}
}
public Object Parent { get; private set; }
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using BlubbFish.Utils.IoT.Bots;
using BlubbFish.Utils.IoT.Interfaces;
using LitJson;
namespace Fraunhofer.Fit.Iot.Lora.Interfaces {
public class AConnector : IMqtt {
#region IMqtt
public String ToJson() {
return JsonMapper.ToJson(this.ToDictionary());
}
public virtual String MqttTopic() {
return "Lora";
}
#endregion
public virtual Dictionary<String, Object> ToDictionary() {
Dictionary<String, Object> dictionary = new Dictionary<String, Object>();
foreach (PropertyInfo item in this.GetType().GetProperties()) {
if (item.CanRead && item.GetValue(this) != null) {
if (item.GetValue(this).GetType().GetMethod("ToDictionary") != null) {
dictionary.Add(item.Name, item.GetValue(this).GetType().GetMethod("ToDictionary").Invoke(item.GetValue(this), null));
} else if (item.GetValue(this).GetType().HasInterface(typeof(IDictionary))) {
Dictionary<String, Object> subdict = new Dictionary<String, Object>();
foreach (DictionaryEntry subitem in (IDictionary)item.GetValue(this)) {
if (subitem.Value.GetType().GetMethod("ToDictionary") != null) {
subdict.Add(subitem.Key.ToString(), subitem.Value.GetType().GetMethod("ToDictionary").Invoke(subitem.Value, null));
}
}
dictionary.Add(item.Name, subdict);
} else if (item.GetValue(this).GetType().BaseType == typeof(Enum)) {
dictionary.Add(item.Name, Helper.GetEnumDescription((Enum)item.GetValue(this)));
} else {
dictionary.Add(item.Name, item.GetValue(this));
}
}
}
return dictionary;
}
}
}
......@@ -51,7 +51,11 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Devices\GpsInfo.cs" />
<Compile Include="Devices\LoraClient.cs" />
<Compile Include="Devices\WlanNetwork.cs" />
<Compile Include="Events\DeviceUpdateEvent.cs" />
<Compile Include="Interfaces\AConnector.cs" />
<Compile Include="lib\LoraConnector.cs" />
<Compile Include="LoraController.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
......@@ -59,6 +63,19 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\..\Librarys\litjson\litjson\litjson_4.7.1.csproj">
<Project>{91a14cd2-2940-4500-8193-56d37edddbaa}</Project>
<Name>litjson_4.7.1</Name>
</ProjectReference>
<ProjectReference Include="..\..\Utils\Bot-Utils\Bot-Utils.csproj">
<Project>{bb7bfcb5-3db0-49e1-802a-3ce3eecc59f9}</Project>
<Name>Bot-Utils</Name>
</ProjectReference>
<ProjectReference Include="..\..\Utils\IoT\Interfaces\Iot-Interfaces.csproj">
<Project>{4daada29-c600-4cf3-8ad3-9c97c8d7f632}</Project>
<Name>Iot-Interfaces</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BlubbFish.Utils.IoT.Bots;
using Fraunhofer.Fit.Iot.Lora.Devices;
using Fraunhofer.Fit.Iot.Lora.Events;
using Fraunhofer.Fit.Iot.Lora.lib;
// Hope RFM96
// http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
// The RFM97 offers bandwidth options ranging from 7.8 kHz to 500 kHz with spreading factors ranging from 6 to 12, and covering all available frequency bands.
namespace Fraunhofer.Fit.Iot.Lora {
public class LoraController {
public LoraController() {
Int64 freq = 868100000;
LoraConnector l = new LoraConnector(Unosquare.RaspberryIO.Pi.Gpio.Pin06, Unosquare.RaspberryIO.Pi.Gpio.Pin07, Unosquare.RaspberryIO.Pi.Gpio.Pin00);
l.Begin(freq);
l.EnableCrc();
l.Receive(0);
l.Update += this.ReceivePacket;
Console.WriteLine("Listening at SF"+ l.GetSpreadingFactor() + " on "+((Double)freq / 1000000) +" Mhz.");
Console.WriteLine("------------------");
l.OnReceive();
while (true) {
System.Threading.Thread.Sleep(1);
public class LoraController : IDisposable {
private LoraConnector loraconnector;
private readonly Dictionary<String, String> settings;
public delegate void DataUpdate(Object sender, DeviceUpdateEvent e);
public event DataUpdate Update;
public Dictionary<String, LoraClient> devices = new Dictionary<String, LoraClient>();
public LoraController(Dictionary<String, String> settings) {
Console.WriteLine("LoraController.LoraController()");
this.settings = settings;
try {
this.CreateLoraController(true);
this.loraconnector.Update += this.ReceivePacket;
this.loraconnector.OnReceive();
} catch { }
}
private void CreateLoraController(Boolean rescieve = true) {
if(!this.settings.ContainsKey("frequency") || !this.settings.ContainsKey("spreadingfactor") | !this.settings.ContainsKey("signalbandwith") || !this.settings.ContainsKey("codingrate")) {
Helper.WriteError("Not all Settings set!: [lora]\nfrequency=868100000\nspreadingfactor=8\nsignalbandwith=125000\ncodingrate=6 missing");
return;
}
this.loraconnector = new LoraConnector(Unosquare.RaspberryIO.Pi.Gpio.Pin06, Unosquare.RaspberryIO.Pi.Gpio.Pin07, Unosquare.RaspberryIO.Pi.Gpio.Pin00);
this.loraconnector.Begin(Int64.Parse(this.settings["frequency"])); //868125100
this.loraconnector.SetSignalBandwith(Int64.Parse(this.settings["signalbandwith"])); //125000
this.loraconnector.SetSpreadingFactor(Byte.Parse(this.settings["spreadingfactor"])); //8 - 11
this.loraconnector.SetCodingRate4(Byte.Parse(this.settings["codingrate"]));
//this.loraconnector.EnableCrc();
this.loraconnector.DisableCrc();
if (rescieve) {
this.loraconnector.Receive(0);
} else {
this.loraconnector.SetTxPower(17);
while (true) {
this.loraconnector.BeginPacket();
this.loraconnector.Write(System.Text.Encoding.UTF8.GetBytes("TESTTESTTESTTESTTESTTESTTESTAsdasdasdh ahsdk jahsdkdja shdas"));
this.loraconnector.EndPacket();
Console.WriteLine("Send!");
System.Threading.Thread.Sleep(1000);
}
}
}
private void ReceivePacket(Object sender, Events.LoraClientEvent e) {
Console.WriteLine(e.Text.Length);
if (e.Text.StartsWith("b") && e.Text.Length == 27) {
Byte[] data = System.Text.Encoding.ASCII.GetBytes(e.Text);
Console.WriteLine("|" + BitConverter.ToString(data).Replace("-", " ") + "| PRSSI: " + e.Packetrssi + " RSSI:" + e.Rssi + " SNR:" + e.Snr);
String deviceName = LoraClient.GetName(data);
if (this.devices.ContainsKey(deviceName)) {
this.devices[deviceName].SetUpdate(e, data);
} else {
this.devices.Add(deviceName, new LoraClient(e, data));
this.devices[deviceName].Update += this.AllUpdate;
}
} else {
Console.WriteLine("|" + e.Text + "| PRSSI: " + e.Packetrssi + " RSSI:" + e.Rssi + " SNR:" + e.Snr);
if (LoraClient.CheckPacket(e.Text)) {
String deviceName = LoraClient.GetName(e.Text);
if (this.devices.ContainsKey(deviceName)) {
this.devices[deviceName].SetUpdate(e, e.Text);
} else {
this.devices.Add(deviceName, new LoraClient(e, e.Text));
this.devices[deviceName].Update += this.AllUpdate;
}
}
}
}
private void AllUpdate(Object sender, DeviceUpdateEvent e) {
this.Update?.Invoke(sender, e);
}
#region IDisposable Support
private Boolean disposedValue = false;
protected virtual void Dispose(Boolean disposing) {
Console.WriteLine("LoraController.Dispose(" + disposing + ")");
if (!this.disposedValue) {
if (disposing) {
if (this.loraconnector != null) {
this.loraconnector.Update -= this.ReceivePacket;
this.loraconnector.End();
this.loraconnector.Dispose();
}
}
this.loraconnector = null;
this.disposedValue = true;
}
}
private void ReceivePacket(Object sender, Events.DeviceUpdateEvent e) {
Console.WriteLine("Packet RSSI: "+e.Packetrssi+", RSSI: "+e.Rssi+", SNR: "+e.Snr+", Length: "+e.Length);
Console.WriteLine("Payload: "+e.Text);
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("Lora")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Lora")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("85a78b05-5843-4e4d-8c56-4bcb12613750")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// indem Sie "*" wie unten gezeigt eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("Lora")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Lora")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("85a78b05-5843-4e4d-8c56-4bcb12613750")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// indem Sie "*" wie unten gezeigt eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
File added
......@@ -7,7 +7,7 @@ using Unosquare.RaspberryIO.Gpio;
namespace Fraunhofer.Fit.Iot.Lora.lib
{
public class LoraConnector : IDisposable {
public delegate void DataUpdate(Object sender, DeviceUpdateEvent e);
public delegate void DataUpdate(Object sender, LoraClientEvent e);
public event DataUpdate Update;
private const Byte MaxPKTLength = 255;
......@@ -15,10 +15,10 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
private Int64 _frequency = 0;
private Byte _packetIndex = 0;
private Boolean _implictHeaderMode = false;
private GpioPin ssPin;
private GpioPin dio0;
private GpioPin RST;
private Boolean _init;
private GpioPin PinSlaveSelect;
private GpioPin PinDataInput;
private GpioPin PinReset;
private Boolean _init = false;
private Boolean disposedValue = false;
#endregion
......@@ -67,8 +67,10 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
LONG_RANGE_MODE = 0x80
};
enum Pa : Byte {
BOOST = 0x80
public enum Pa : Byte {
BOOST = 0x80,
OUTPUT_RFO_PIN = 0,
OUTPUT_PA_BOOST_PIN = 1
};
enum Irq : Byte {
......@@ -80,9 +82,9 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
#region Constructor
public LoraConnector(GpioPin ssPin, GpioPin dio0, GpioPin RST) {
this.ssPin = ssPin;
this.dio0 = dio0;
this.RST = RST;
this.PinSlaveSelect = ssPin;
this.PinDataInput = dio0;
this.PinReset = RST;
}
public void Dispose() {
......@@ -93,12 +95,18 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
protected virtual void Dispose(Boolean disposing) {
if(!this.disposedValue) {
if(disposing) {
this.PinDataInput = null;
this.PinSlaveSelect = null;
this.PinReset = null;
}
this.disposedValue = true;
}
}
public Boolean Begin(Int64 freq) {
if(this._init) {
return false;
}
this.SetupIO();
this.Reset();
Byte version = this.ReadRegister(Registers.VERSION);
......@@ -116,6 +124,7 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
this.WriteRegister(Registers.MODEM_CONFIG_3, 0x04);
this.SetTxPower(17);
this.Ilde();
this._init = true;
return true;
}
......@@ -126,7 +135,7 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
#endregion
#region Packets, Read, Write
public Boolean BeginPacket(Boolean implictHeader) {
public Boolean BeginPacket(Boolean implictHeader = false) {
this.Ilde();
if (implictHeader) {
this.ImplicitHeaderMode();
......@@ -173,7 +182,7 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
return packetLenth;
}
Byte Write(Byte[] buffer) {
public Byte Write(Byte[] buffer) {
Byte currentLength = this.ReadRegister(Registers.PAYLOAD_LENGTH);
Byte size = buffer.Length > 255 ? MaxPKTLength : (Byte)buffer.Length;
if ((currentLength + buffer.Length) > MaxPKTLength) {
......@@ -381,37 +390,39 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
}
private void HandleOnDio0Rise() {
Byte irqFlags = this.ReadRegister(Registers.IRQ_FLAGS);
// clear IRQ's
this.WriteRegister(Registers.IRQ_FLAGS, irqFlags);
if ((irqFlags & (Byte)Irq.PAYLOAD_CRC_ERROR_MASK) == 0) {
// received a packet
this._packetIndex = 0;
// read packet length
Byte packetLength = this._implictHeaderMode ? this.ReadRegister(Registers.PAYLOAD_LENGTH) : this.ReadRegister(Registers.RX_NB_BYTES);
// set FIFO address to current RX address
this.WriteRegister(Registers.FIFO_ADDR_PTR, this.ReadRegister(Registers.FIFO_RX_CURRENT_ADDR));
Byte[] ms = new Byte[packetLength];
for (Byte i = 0; i < packetLength; i++) {
Int16 c = this.Read();
if (c != -1) {
ms[i] = (Byte)c;
} else {
throw new Exception("Message to Short");
if (!this.disposedValue) {
Byte irqFlags = this.ReadRegister(Registers.IRQ_FLAGS);
// clear IRQ's
this.WriteRegister(Registers.IRQ_FLAGS, irqFlags);
if ((irqFlags & (Byte)Irq.PAYLOAD_CRC_ERROR_MASK) == 0) {
// received a packet
this._packetIndex = 0;
// read packet length
Byte packetLength = this._implictHeaderMode ? this.ReadRegister(Registers.PAYLOAD_LENGTH) : this.ReadRegister(Registers.RX_NB_BYTES);
// set FIFO address to current RX address
this.WriteRegister(Registers.FIFO_ADDR_PTR, this.ReadRegister(Registers.FIFO_RX_CURRENT_ADDR));
Byte[] ms = new Byte[packetLength];
for (Byte i = 0; i < packetLength; i++) {
Int16 c = this.Read();
if (c != -1) {
ms[i] = (Byte)c;
} else {
throw new Exception("Message to Short");
}
}
}
Double snr = this.PacketSnr();
Byte prssi = this.PacketRssi();
Byte rssi = this.Rssi();
this.Update?.Invoke(this, new DeviceUpdateEvent(packetLength, Encoding.ASCII.GetString(ms), snr, prssi, rssi));
Double snr = this.PacketSnr();
Byte prssi = this.PacketRssi();
Byte rssi = this.Rssi();
this.Update?.Invoke(this, new LoraClientEvent(packetLength, Encoding.ASCII.GetString(ms).Trim(), snr, prssi, rssi));
// reset FIFO address
this.WriteRegister(Registers.FIFO_ADDR_PTR, 0);
// reset FIFO address
this.WriteRegister(Registers.FIFO_ADDR_PTR, 0);
}
}
}
......@@ -445,8 +456,8 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
this.WriteRegister(Registers.OP_MODE, (Byte)Modes.LONG_RANGE_MODE | (Byte)Modes.SLEEP);
}
public void SetTxPower(Int32 level, Int32 outputPin = 1) {
if (outputPin == 1) {
public void SetTxPower(Int32 level, Pa outputPin = Pa.OUTPUT_PA_BOOST_PIN) {
if (outputPin == Pa.OUTPUT_RFO_PIN) {
if (level < 0) {
level = 0;
} else if (level > 14) {
......@@ -491,31 +502,31 @@ namespace Fraunhofer.Fit.Iot.Lora.lib
#region Hardware IO
private void Reset() {
this.RST.Write(false);
this.PinReset.Write(false);
System.Threading.Thread.Sleep(100);
this.RST.Write(true);
this.PinReset.Write(true);
System.Threading.Thread.Sleep(100);
}
private void SetupIO() {
Pi.Spi.Channel0Frequency = 250000;
this.ssPin.PinMode = GpioPinDriveMode.Output;
this.dio0.PinMode = GpioPinDriveMode.Input;
this.RST.PinMode = GpioPinDriveMode.Output;
this.PinSlaveSelect.PinMode = GpioPinDriveMode.Output;
this.PinDataInput.PinMode = GpioPinDriveMode.Input;
this.PinReset.PinMode = GpioPinDriveMode.Output;
}
private void Selectreceiver() {
this.ssPin.Write(false);
this.PinSlaveSelect.Write(false);
}
private void Unselectreceiver() {
this.ssPin.Write(true);
this.PinSlaveSelect.Write(true);
}
public void OnReceive() {
if (this.Update != null) {
this.WriteRegister(Registers.DIO_MAPPING_1, 0x00);
this.dio0.RegisterInterruptCallback(EdgeDetection.RisingEdge, this.OnDio0Rise);
this.PinDataInput.RegisterInterruptCallback(EdgeDetection.RisingEdge, this.OnDio0Rise);
}
}
#endregion
......
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Unosquare.Raspberry.IO" version="0.14.0" targetFramework="net471" />
<package id="Unosquare.Swan" version="0.28.1" targetFramework="net471" />
<package id="Unosquare.Swan.Lite" version="0.28.0" targetFramework="net471" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Unosquare.Raspberry.IO" version="0.14.0" targetFramework="net471" />
<package id="Unosquare.Swan" version="0.28.1" targetFramework="net471" />
<package id="Unosquare.Swan.Lite" version="0.28.0" targetFramework="net471" />
</packages>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment