From 0d055da58c5f0020a4e2fb42bbe914115e071868 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 25 Dec 2023 09:51:45 +0100 Subject: [PATCH 01/31] Build up infrastructure for new binding --- src/devices/Seatalk1/README.md | 21 +++ src/devices/Seatalk1/Seatalk1.csproj | 16 +++ src/devices/Seatalk1/Seatalk1.sln | 84 ++++++++++++ src/devices/Seatalk1/Seatalk1Parser.cs | 126 ++++++++++++++++++ src/devices/Seatalk1/samples/README.md | 3 + .../Seatalk1/samples/Seatalk1.Samples.cs | 10 ++ .../Seatalk1/samples/Seatalk1.Samples.csproj | 12 ++ src/devices/Seatalk1/tests/Seatalk1.csproj | 14 ++ src/devices/Seatalk1/tests/Seatalk1Tests.cs | 16 +++ 9 files changed, 302 insertions(+) create mode 100644 src/devices/Seatalk1/README.md create mode 100644 src/devices/Seatalk1/Seatalk1.csproj create mode 100644 src/devices/Seatalk1/Seatalk1.sln create mode 100644 src/devices/Seatalk1/Seatalk1Parser.cs create mode 100644 src/devices/Seatalk1/samples/README.md create mode 100644 src/devices/Seatalk1/samples/Seatalk1.Samples.cs create mode 100644 src/devices/Seatalk1/samples/Seatalk1.Samples.csproj create mode 100644 src/devices/Seatalk1/tests/Seatalk1.csproj create mode 100644 src/devices/Seatalk1/tests/Seatalk1Tests.cs diff --git a/src/devices/Seatalk1/README.md b/src/devices/Seatalk1/README.md new file mode 100644 index 0000000000..0c30d9f360 --- /dev/null +++ b/src/devices/Seatalk1/README.md @@ -0,0 +1,21 @@ +# Seatalk 1 Interface + +## Summary + +Provide a brief description on what the component is and its functionality. + +## Device Family + +Provide a list of component names and link to datasheets (if available) the binding will work with. + +**Seatalk 1 Datagrams**: [http://www.thomasknauf.de/rap/seatalk2.htm] + +## Binding Notes + +Provide any specifics related to binding API. This could include how to configure component for particular functions and example code. + +**NOTE**: Don't repeat the basics related to System.Device.API* (e.g. connection settings, etc.). This helps keep text/steps down to a minimum for maintainability. + +## References + +Many tanks to Thomas Knauf for his extensive Seatalk protocol analysis. See http://www.thomasknauf.de/seatalk.htm \ No newline at end of file diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj new file mode 100644 index 0000000000..2dca9e08fc --- /dev/null +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -0,0 +1,16 @@ + + + + $(DefaultBindingTfms) + + false + 9 + Iot.Device.Seatalk1 + + + + + + + + diff --git a/src/devices/Seatalk1/Seatalk1.sln b/src/devices/Seatalk1/Seatalk1.sln new file mode 100644 index 0000000000..5b754f92dd --- /dev/null +++ b/src/devices/Seatalk1/Seatalk1.sln @@ -0,0 +1,84 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.33808.371 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seatalk1", "Seatalk1.csproj", "{B82C190A-642B-465B-BD3F-DB56FFF22253}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{03107CFF-FE00-467D-9B38-C00F7E12A7FE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seatalk1.Tests", "tests\Seatalk1.Tests.csproj", "{2B0F5D91-F38B-427D-84DB-5656D9661E1C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{6A4DE7B1-03F3-4EE0-BF73-A0BAEF88BA2B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seatalk1.Samples", "samples\Seatalk1.Samples.csproj", "{3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common", "..\Common\Common.csproj", "{A53E6BD4-A723-4B86-BC19-3B56D539D0B0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Debug|x64.ActiveCfg = Debug|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Debug|x64.Build.0 = Debug|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Debug|x86.ActiveCfg = Debug|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Debug|x86.Build.0 = Debug|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Release|Any CPU.Build.0 = Release|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Release|x64.ActiveCfg = Release|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Release|x64.Build.0 = Release|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Release|x86.ActiveCfg = Release|Any CPU + {B82C190A-642B-465B-BD3F-DB56FFF22253}.Release|x86.Build.0 = Release|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Debug|x64.ActiveCfg = Debug|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Debug|x64.Build.0 = Debug|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Debug|x86.ActiveCfg = Debug|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Debug|x86.Build.0 = Debug|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Release|Any CPU.Build.0 = Release|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Release|x64.ActiveCfg = Release|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Release|x64.Build.0 = Release|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Release|x86.ActiveCfg = Release|Any CPU + {2B0F5D91-F38B-427D-84DB-5656D9661E1C}.Release|x86.Build.0 = Release|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Debug|x64.Build.0 = Debug|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Debug|x86.Build.0 = Debug|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Release|Any CPU.Build.0 = Release|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Release|x64.ActiveCfg = Release|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Release|x64.Build.0 = Release|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Release|x86.ActiveCfg = Release|Any CPU + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF}.Release|x86.Build.0 = Release|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Debug|x64.ActiveCfg = Debug|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Debug|x64.Build.0 = Debug|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Debug|x86.ActiveCfg = Debug|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Debug|x86.Build.0 = Debug|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|Any CPU.Build.0 = Release|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|x64.ActiveCfg = Release|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|x64.Build.0 = Release|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|x86.ActiveCfg = Release|Any CPU + {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {2B0F5D91-F38B-427D-84DB-5656D9661E1C} = {03107CFF-FE00-467D-9B38-C00F7E12A7FE} + {3CFA13D6-1D29-4C87-B0C1-01A6901A50EF} = {6A4DE7B1-03F3-4EE0-BF73-A0BAEF88BA2B} + EndGlobalSection +EndGlobal diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs new file mode 100644 index 0000000000..6bd5fe7040 --- /dev/null +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -0,0 +1,126 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Device.Gpio; +using System.Device.I2c; +using System.Device.Spi; +using System.IO; +using System.Reflection; +using System.Text; +using System.Threading; +using Iot.Device.Common; +using Microsoft.Extensions.Logging; + +namespace Iot.Device.Seatalk1 +{ + /// + /// Decodes a Seatalk1 Message stream + /// + public sealed class Seatalk1Parser : IDisposable + { + private readonly Stream _inputStream; + private readonly BinaryReader _reader; + private readonly object _lock; + private readonly List _buffer; + private readonly ILogger _logger; + + private Thread? _parserThread; + private CancellationTokenSource? _cancellationTokenSource; + private bool _disposed; + + /// + /// Initializes a new instance of the class. + /// + /// The input stream. Must be non-null and readable + public Seatalk1Parser(Stream inputStream) + { + _lock = new object(); + _buffer = new List(20); + _disposed = false; + _logger = this.GetCurrentClassLogger(); + _inputStream = inputStream ?? throw new ArgumentNullException(nameof(inputStream)); + if (!inputStream.CanRead) + { + throw new ArgumentException("Input stream is not readable"); + } + + _reader = new BinaryReader(inputStream, Encoding.UTF8); + } + + /// + /// Starts the thread to decode packets + /// + /// The parser is already running + /// The parser has already been disposed. The parser cannot currently be restarted. + public void StartDecode() + { + lock (_lock) + { + if (_parserThread != null && _parserThread.IsAlive) + { + throw new InvalidOperationException("Parser thread already started"); + } + + if (_disposed) + { + throw new ObjectDisposedException(nameof(Seatalk1Parser), "The parser has already been disposed, please reopen the source stream"); + } + + _cancellationTokenSource = new CancellationTokenSource(); + _parserThread = new Thread(Parser); + _parserThread.Name = $"Seatalk1 Parser"; + _parserThread.Start(); + } + } + + /// + /// Terminates the decoding thread. + /// + public void StopDecode() + { + _cancellationTokenSource?.Cancel(); + + lock (_lock) + { + _reader.Close(); + _inputStream.Close(); + } + + _parserThread?.Join(); + } + + private void Parser() + { + _logger.LogInformation("Seatalk1 decoder started"); + if (_cancellationTokenSource == null) + { + return; + } + + while (!_cancellationTokenSource.IsCancellationRequested) + { + try + { + while (true) + { + byte nextByte = _reader.ReadByte(); + _buffer.Add(nextByte); + } + } + catch (Exception x) when (x is EndOfStreamException || x is IOException) + { + // Ignore + _logger.LogError(x, $"Seatalk Parser error: {x.Message}"); + } + } + } + + /// + public void Dispose() + { + StopDecode(); + } + } +} diff --git a/src/devices/Seatalk1/samples/README.md b/src/devices/Seatalk1/samples/README.md new file mode 100644 index 0000000000..c7e16de82f --- /dev/null +++ b/src/devices/Seatalk1/samples/README.md @@ -0,0 +1,3 @@ +# TODO: This needs to be determined + +Help Wanted Please diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs new file mode 100644 index 0000000000..43d5c8cefb --- /dev/null +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Device.Gpio; +using System.Device.I2c; +using System.Device.Spi; +using System.Threading; + +Console.WriteLine("Hello _DeviceBinding Sample!"); diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj b/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj new file mode 100644 index 0000000000..0d1d668f77 --- /dev/null +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj @@ -0,0 +1,12 @@ + + + + Exe + $(DefaultSampleTfms) + + + + + + + diff --git a/src/devices/Seatalk1/tests/Seatalk1.csproj b/src/devices/Seatalk1/tests/Seatalk1.csproj new file mode 100644 index 0000000000..cc513a3781 --- /dev/null +++ b/src/devices/Seatalk1/tests/Seatalk1.csproj @@ -0,0 +1,14 @@ + + + + $(DefaultSampleTfms) + 10 + false + false + + + + + + + diff --git a/src/devices/Seatalk1/tests/Seatalk1Tests.cs b/src/devices/Seatalk1/tests/Seatalk1Tests.cs new file mode 100644 index 0000000000..9b06be750e --- /dev/null +++ b/src/devices/Seatalk1/tests/Seatalk1Tests.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace Iot.Device._DeviceBinding.Tests +{ + public class _DeviceBindingTests + { + [Fact] + public void Test1() + { + // NOTE: THIS TEST PROJECT IS NOT REQUIRED AND CAN BE DELETED IF NOT USED. + } + } +} From 9f5d35eb3eb8927f2dc270913f7c6543a46a4362 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 25 Dec 2023 15:16:05 +0100 Subject: [PATCH 02/31] More stuff for first draft --- .../CompassHeadingAndRudderPosition.cs | 53 ++++++++++++ .../Messages/CompassHeadingAutopilotCourse.cs | 39 +++++++++ .../Seatalk1/Messages/SeatalkMessage.cs | 82 +++++++++++++++++++ .../Seatalk1/Messages/TurnDirection.cs | 14 ++++ src/devices/Seatalk1/Seatalk1.csproj | 10 +++ src/devices/Seatalk1/Seatalk1Parser.cs | 17 ++++ .../Seatalk1/samples/Seatalk1.Samples.cs | 22 ++++- .../Seatalk1/samples/Seatalk1.Samples.csproj | 1 + 8 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs create mode 100644 src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs create mode 100644 src/devices/Seatalk1/Messages/SeatalkMessage.cs create mode 100644 src/devices/Seatalk1/Messages/TurnDirection.cs diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs new file mode 100644 index 0000000000..4e7a3ee289 --- /dev/null +++ b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnitsNet; + +namespace Iot.Device.Seatalk1.Messages +{ + public record CompassHeadingAndRudderPosition : SeatalkMessage + { + public override byte CommandByte => 0x9c; + public override byte ExpectedLength => 4; + + public Angle CompassHeading + { + get; + init; + } + + public Angle RudderPosition + { + get; + init; + } + + public TurnDirection TurnDirection { get; init; } + + /// + /// 84 U6 VW XY 0Z 0M RR SS TT Compass heading Autopilot course + /// + /// Input data + /// A message of this type + public override SeatalkMessage CreateNewMessage(ReadOnlySpan data) + { + VerifyPacket(data); + + uint u = ((uint)data[1]) >> 4; + uint vw = data[2]; + // TODO: Verify last part. Actually, only one bit is required there, and the uppermost bit is also used for the turning direction, according to the docs + long heading = (u & 0x3) * 90 + (vw & 0x3F) * 2 + BitCount(u & 0xC); + Angle headingA = Angle.FromDegrees(heading); + sbyte rudder = (sbyte)data[3]; + + return new CompassHeadingAndRudderPosition() + { + CompassHeading = headingA, + RudderPosition = Angle.FromDegrees(rudder), + TurnDirection = (u & 0x80) == 0 ? TurnDirection.Port : TurnDirection.Starboard, + }; + } + } +} diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs new file mode 100644 index 0000000000..36150f5b14 --- /dev/null +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnitsNet; + +namespace Iot.Device.Seatalk1.Messages +{ + public record CompassHeadingAutopilotCourse : SeatalkMessage + { + public override byte CommandByte => 0x84; + public override byte ExpectedLength => 0x9; + + public Angle CompassHeading { get; init; } + + public TurnDirection TurnDirection { get; init; } + + public byte AutoPilotType { get; set; } + + public override SeatalkMessage CreateNewMessage(ReadOnlySpan data) + { + VerifyPacket(data); + + uint u = ((uint)data[1]) >> 4; + uint vw = data[2]; + // TODO: Verify last part. Actually, only one bit is required there, and the uppermost bit is also used for the turning direction, according to the docs + long heading = (u & 0x3) * 90 + (vw & 0x3F) * 2 + BitCount(u & 0xC); + Angle headingA = Angle.FromDegrees(heading); + + return new CompassHeadingAutopilotCourse() + { + CompassHeading = headingA, + TurnDirection = (u & 0x80) == 0 ? TurnDirection.Port : TurnDirection.Starboard, + AutoPilotType = data[8], + }; + } + } +} diff --git a/src/devices/Seatalk1/Messages/SeatalkMessage.cs b/src/devices/Seatalk1/Messages/SeatalkMessage.cs new file mode 100644 index 0000000000..ccfeff8b27 --- /dev/null +++ b/src/devices/Seatalk1/Messages/SeatalkMessage.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + /// + /// Base class for seatalk messages + /// + public abstract record SeatalkMessage + { + /// + /// The command byte for this message + /// + public abstract byte CommandByte + { + get; + } + + /// + /// The expected total length of this message type (lower nibble of the ATTR byte + 3) + /// + public abstract byte ExpectedLength + { + get; + } + + /// + /// Creates a new message from this template + /// + /// The sliced input data + /// + public abstract SeatalkMessage CreateNewMessage(ReadOnlySpan data); + + // To count the number of bits set in (U >> 4) & 0xc + protected int BitCount(uint v) + { + return v switch + { + 0 => 0, + 0xc => 2, + 0x8 => 1, + 0x4 => 1, + _ => throw new ArgumentOutOfRangeException(nameof(v), "That value was unexpected"), + }; + } + + /// + /// This checks the precondition for a valid input packet + /// + /// The sliced data + /// Data was null + /// The data does not match this instance + protected virtual void VerifyPacket(ReadOnlySpan data) + { + if (data == null) + { + throw new ArgumentNullException(nameof(data)); + } + + if (data.Length != ExpectedLength) + { + throw new InvalidOperationException($"Cannot decode data to {GetType()}- invalid data length."); + } + + if (data[0] != CommandByte) + { + throw new InvalidOperationException($"Command byte for {GetType()} was expected to be {CommandByte:X2} but was {data[0]:X2}"); + } + + if ((data[1] & 0xF) != (ExpectedLength - 3)) + { + throw new InvalidOperationException($"Length nibble for {GetType()} was expected to be {ExpectedLength}, but was {data[1] & 0xF}"); + } + } + } +} diff --git a/src/devices/Seatalk1/Messages/TurnDirection.cs b/src/devices/Seatalk1/Messages/TurnDirection.cs new file mode 100644 index 0000000000..949fa9800e --- /dev/null +++ b/src/devices/Seatalk1/Messages/TurnDirection.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + public enum TurnDirection + { + Port = 0, + Starboard = 1, + } +} diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index 2dca9e08fc..d094afb872 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -6,10 +6,20 @@ false 9 Iot.Device.Seatalk1 + $(NoWarn);CS1591 + + + + + + + + + diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index 6bd5fe7040..895dcb4583 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -107,6 +107,7 @@ private void Parser() { byte nextByte = _reader.ReadByte(); _buffer.Add(nextByte); + int msgLen = GetLengthOfNextMessage(); } } catch (Exception x) when (x is EndOfStreamException || x is IOException) @@ -117,6 +118,22 @@ private void Parser() } } + /// + /// Returns the length of the message in the input buffer + /// + /// The length of the message (max 18 bytes), 0 if the message in the buffer is probably incomplete and -1 if + /// the buffer contains invalid data or has lost sync. + private int GetLengthOfNextMessage() + { + // The minimum message length is 3 bytes + if (_buffer.Count < 3) + { + return 0; + } + + + } + /// public void Dispose() { diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 43d5c8cefb..c1359093f1 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -6,5 +6,25 @@ using System.Device.I2c; using System.Device.Spi; using System.Threading; +using System.IO.Ports; -Console.WriteLine("Hello _DeviceBinding Sample!"); +namespace Seatalk1Sample +{ + internal class Program + { + internal static int Main(string[] args) + { + Console.WriteLine("Hello Seatalk1 Sample!"); + + if (args.Length == 0) + { + Console.WriteLine("Error: Port not specified"); + return 1; + } + + SerialPort port1 = new SerialPort(); + + return 0; + } + } +} diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj b/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj index 0d1d668f77..4395899ef2 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj @@ -7,6 +7,7 @@ + From a369e7fe55588b9d7bcb8154390886b5d7b6540e Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 25 Dec 2023 16:14:21 +0100 Subject: [PATCH 03/31] Doesn't compile? --- .../Seatalk1/Messages/SeatalkMessage.cs | 31 ++++++++++- src/devices/Seatalk1/Seatalk1Parser.cs | 55 +++++++++++++++++-- .../Seatalk1/samples/Seatalk1.Samples.cs | 8 ++- .../Seatalk1/samples/Seatalk1.Samples.csproj | 1 - ...{Seatalk1.csproj => Seatalk1.Tests.csproj} | 3 +- src/devices/Seatalk1/tests/Seatalk1Tests.cs | 48 ++++++++++++++-- 6 files changed, 130 insertions(+), 16 deletions(-) rename src/devices/Seatalk1/tests/{Seatalk1.csproj => Seatalk1.Tests.csproj} (73%) diff --git a/src/devices/Seatalk1/Messages/SeatalkMessage.cs b/src/devices/Seatalk1/Messages/SeatalkMessage.cs index ccfeff8b27..ac312f280c 100644 --- a/src/devices/Seatalk1/Messages/SeatalkMessage.cs +++ b/src/devices/Seatalk1/Messages/SeatalkMessage.cs @@ -35,7 +35,7 @@ public abstract byte ExpectedLength /// /// The sliced input data /// - public abstract SeatalkMessage CreateNewMessage(ReadOnlySpan data); + public abstract SeatalkMessage CreateNewMessage(IReadOnlyList data); // To count the number of bits set in (U >> 4) & 0xc protected int BitCount(uint v) @@ -56,14 +56,14 @@ protected int BitCount(uint v) /// The sliced data /// Data was null /// The data does not match this instance - protected virtual void VerifyPacket(ReadOnlySpan data) + protected virtual void VerifyPacket(IReadOnlyList data) { if (data == null) { throw new ArgumentNullException(nameof(data)); } - if (data.Length != ExpectedLength) + if (data.Count != ExpectedLength) { throw new InvalidOperationException($"Cannot decode data to {GetType()}- invalid data length."); } @@ -78,5 +78,30 @@ protected virtual void VerifyPacket(ReadOnlySpan data) throw new InvalidOperationException($"Length nibble for {GetType()} was expected to be {ExpectedLength}, but was {data[1] & 0xF}"); } } + + public virtual bool MatchesMessageType(IReadOnlyList data) + { + if (data == null) + { + throw new ArgumentNullException(nameof(data)); + } + + if (data.Count != ExpectedLength) + { + return false; + } + + if (data[0] != CommandByte) + { + return false; + } + + if ((data[1] & 0xF) != (ExpectedLength - 3)) + { + return false; + } + + return true; + } } } diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index 895dcb4583..ba287317f2 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -11,6 +11,7 @@ using System.Text; using System.Threading; using Iot.Device.Common; +using Iot.Device.Seatalk1.Messages; using Microsoft.Extensions.Logging; namespace Iot.Device.Seatalk1 @@ -30,6 +31,8 @@ public sealed class Seatalk1Parser : IDisposable private CancellationTokenSource? _cancellationTokenSource; private bool _disposed; + private List _messageFactories; + /// /// Initializes a new instance of the class. /// @@ -47,8 +50,14 @@ public Seatalk1Parser(Stream inputStream) } _reader = new BinaryReader(inputStream, Encoding.UTF8); + _messageFactories = new List() + { + new CompassHeadingAndRudderPosition(), new CompassHeadingAutopilotCourse(), + }; } + public event Action? NewMessageDecoded; + /// /// Starts the thread to decode packets /// @@ -107,7 +116,22 @@ private void Parser() { byte nextByte = _reader.ReadByte(); _buffer.Add(nextByte); - int msgLen = GetLengthOfNextMessage(); + var msg = GetTypeOfNextMessage(out int messageLength); + if (msg == null) + { + if (messageLength == 0) + { + break; + } + else + { + _logger.LogWarning($"Seatalk parser sync lost. Next message was 0x{_buffer[0]:X2}, now skipping"); + _buffer.RemoveAt(0); + continue; + } + } + + NewMessageDecoded?.Invoke(msg); } } catch (Exception x) when (x is EndOfStreamException || x is IOException) @@ -115,23 +139,44 @@ private void Parser() // Ignore _logger.LogError(x, $"Seatalk Parser error: {x.Message}"); } + + Thread.Sleep(50); } } /// /// Returns the length of the message in the input buffer /// - /// The length of the message (max 18 bytes), 0 if the message in the buffer is probably incomplete and -1 if - /// the buffer contains invalid data or has lost sync. - private int GetLengthOfNextMessage() + /// The number of bytes in the next message. Returns 0 if not enough data, -1 if sync lost (to many bytes, but no valid sentence) + /// An instance that can be used as factory for the next message or null if nothing can be decoded. + private SeatalkMessage? GetTypeOfNextMessage(out int bytesInMessage) { // The minimum message length is 3 bytes if (_buffer.Count < 3) { - return 0; + bytesInMessage = 0; + return null; } + // The maximum length is 0xF + 3 = 18 + if (_buffer.Count > 18) + { + bytesInMessage = -1; + return null; + } + + foreach (var t in _messageFactories) + { + if (t.MatchesMessageType(_buffer)) + { + bytesInMessage = t.ExpectedLength; + return t.CreateNewMessage(_buffer); + } + } + _logger.LogWarning($"Unable to decode message. Stream is out of sync or unknown message type 0x{_buffer[0]:X2}."); + bytesInMessage = -1; + return null; } /// diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index c1359093f1..395e23bad8 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -22,8 +22,14 @@ internal static int Main(string[] args) return 1; } - SerialPort port1 = new SerialPort(); + SerialPort port1 = new SerialPort(args[0]); + port1.BaudRate = 4800; + port1.Parity = Parity.Even; + port1.StopBits = StopBits.One; + port1.DataBits = 8; + port1.Open(); + port1.Close(); return 0; } } diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj b/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj index 4395899ef2..23eaebe374 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj @@ -6,7 +6,6 @@ - diff --git a/src/devices/Seatalk1/tests/Seatalk1.csproj b/src/devices/Seatalk1/tests/Seatalk1.Tests.csproj similarity index 73% rename from src/devices/Seatalk1/tests/Seatalk1.csproj rename to src/devices/Seatalk1/tests/Seatalk1.Tests.csproj index cc513a3781..0e08b4d22b 100644 --- a/src/devices/Seatalk1/tests/Seatalk1.csproj +++ b/src/devices/Seatalk1/tests/Seatalk1.Tests.csproj @@ -5,10 +5,11 @@ 10 false false + Iot.Device.Tests.Seatalk1 - + diff --git a/src/devices/Seatalk1/tests/Seatalk1Tests.cs b/src/devices/Seatalk1/tests/Seatalk1Tests.cs index 9b06be750e..83b99da524 100644 --- a/src/devices/Seatalk1/tests/Seatalk1Tests.cs +++ b/src/devices/Seatalk1/tests/Seatalk1Tests.cs @@ -1,16 +1,54 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.ComponentModel; +using System.IO; +using System.Threading; +using Iot.Device.Seatalk1; +using Iot.Device.Seatalk1.Messages; +using UnitsNet; using Xunit; -namespace Iot.Device._DeviceBinding.Tests +namespace Iot.Device.Tests.Seatalk1 { - public class _DeviceBindingTests + public class Seatalk1Tests { [Fact] - public void Test1() + public void DecodeSomeSentences() { - // NOTE: THIS TEST PROJECT IS NOT REQUIRED AND CAN BE DELETED IF NOT USED. + string data = @"9c 01 12 00 +84 06 12 00 00 00 00 00 08 +86 01 02 fd +84 06 12 00 00 00 00 00 08 +9c 01 12 00 +84 06 12 00 00 00 00 00 08"; + byte[] input = Convert.FromHexString(data); + + MemoryStream ms = new MemoryStream(input); + + int numMessages = 0; + Seatalk1Parser parser = new Seatalk1Parser(ms); + parser.NewMessageDecoded += message => + { + numMessages++; + Assert.NotNull(message); + Assert.True(message.ExpectedLength >= 3); + if (message is CompassHeadingAndRudderPosition ch) + { + Assert.Equal(Angle.FromDegrees(40), ch.CompassHeading); + } + }; + parser.StartDecode(); + + while (numMessages != 6) + { + Thread.Sleep(100); + } + + parser.StopDecode(); + + parser.Dispose(); } } } From eefd7203e1b6acc2be94ad6ee5ee52d724d29feb Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Tue, 26 Dec 2023 09:54:04 +0100 Subject: [PATCH 04/31] First successful parser tests --- .../Seatalk1/Messages/AutopilotButtons.cs | 30 +++++++ .../Seatalk1/Messages/AutopilotStatus.cs | 24 ++++++ .../CompassHeadingAndRudderPosition.cs | 7 +- .../Messages/CompassHeadingAutopilotCourse.cs | 7 +- src/devices/Seatalk1/Messages/Keystroke.cs | 82 +++++++++++++++++++ .../Seatalk1/Messages/SeatalkMessage.cs | 14 +++- .../Seatalk1/Messages/TurnDirection.cs | 5 +- src/devices/Seatalk1/Seatalk1.csproj | 3 + src/devices/Seatalk1/Seatalk1Parser.cs | 48 ++++++++--- src/devices/Seatalk1/tests/Seatalk1Tests.cs | 59 +++++++++++-- 10 files changed, 257 insertions(+), 22 deletions(-) create mode 100644 src/devices/Seatalk1/Messages/AutopilotButtons.cs create mode 100644 src/devices/Seatalk1/Messages/AutopilotStatus.cs create mode 100644 src/devices/Seatalk1/Messages/Keystroke.cs diff --git a/src/devices/Seatalk1/Messages/AutopilotButtons.cs b/src/devices/Seatalk1/Messages/AutopilotButtons.cs new file mode 100644 index 0000000000..48594854ce --- /dev/null +++ b/src/devices/Seatalk1/Messages/AutopilotButtons.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + /// + /// The buttons of the auto-pilot controller (more or less standardized between manufacturers). + /// Note that for many functions, multiple buttons must be pressed simultaneously, therefore this is a flag enum. + /// + [Flags] + public enum AutopilotButtons + { + None = 0, + MinusOne = 1, + MinusTen = 2, + PlusOne = 4, + PlusTen = 8, + Auto = 16, + StandBy = 32, + Track = 64, + Disp = 128, + LongPress = 256, + } +} diff --git a/src/devices/Seatalk1/Messages/AutopilotStatus.cs b/src/devices/Seatalk1/Messages/AutopilotStatus.cs new file mode 100644 index 0000000000..b8c6ba5934 --- /dev/null +++ b/src/devices/Seatalk1/Messages/AutopilotStatus.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + /// + /// The current state of the auto pilot controller + /// + public enum AutopilotStatus + { + Offline, + Standby, + Auto, + Track, + Wind, + Display, + } +} diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs index 4e7a3ee289..8286db68d9 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs @@ -1,4 +1,7 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -31,7 +34,7 @@ public Angle RudderPosition /// /// Input data /// A message of this type - public override SeatalkMessage CreateNewMessage(ReadOnlySpan data) + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { VerifyPacket(data); diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index 36150f5b14..579190d49b 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -1,4 +1,7 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -18,7 +21,7 @@ public record CompassHeadingAutopilotCourse : SeatalkMessage public byte AutoPilotType { get; set; } - public override SeatalkMessage CreateNewMessage(ReadOnlySpan data) + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { VerifyPacket(data); diff --git a/src/devices/Seatalk1/Messages/Keystroke.cs b/src/devices/Seatalk1/Messages/Keystroke.cs new file mode 100644 index 0000000000..8363e3fd7a --- /dev/null +++ b/src/devices/Seatalk1/Messages/Keystroke.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + public record Keystroke : SeatalkMessage + { + public override byte CommandByte => 0x86; + public override byte ExpectedLength => 0x04; + + /// + /// Keypress source. Should probably be an enum, too + /// + public int Source + { + get; + init; + } + + public AutopilotButtons ButtonsPressed + { + get; + init; + } + + /// + /// The format of the message is + /// 86 X1 YY yy, where X is the sender (1 = Remote control, 0 = Autopilot unit) + /// and YY is the keycode. yy is the binary inverse of YY. + /// + /// The input data + /// A message + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) + { + VerifyPacket(data); + + int source = data[1] >> 4; + + AutopilotButtons buttons = GetButtons(data[2]); + + return new Keystroke() + { + ButtonsPressed = buttons, Source = source, + }; + } + + private AutopilotButtons GetButtons(int keyCode) + { + return keyCode switch + { + 0x01 => AutopilotButtons.Auto, + 0x02 => AutopilotButtons.StandBy, + _ => AutopilotButtons.None, + }; + } + + public override bool MatchesMessageType(IReadOnlyList data) + { + // Byte 4 must be the binary inverse of byte 3 + if (data.Count < 4) + { + return false; + } + + byte yy = data[2]; + byte yy2 = data[3]; + if ((~yy2 & 0xFF) != yy) + { + return false; + } + + return base.MatchesMessageType(data); + } + } +} diff --git a/src/devices/Seatalk1/Messages/SeatalkMessage.cs b/src/devices/Seatalk1/Messages/SeatalkMessage.cs index ac312f280c..0dd3c60e43 100644 --- a/src/devices/Seatalk1/Messages/SeatalkMessage.cs +++ b/src/devices/Seatalk1/Messages/SeatalkMessage.cs @@ -51,7 +51,8 @@ protected int BitCount(uint v) } /// - /// This checks the precondition for a valid input packet + /// This checks the precondition for a valid input packet. + /// Normally, derived classes do not need to override this, it's sufficient to override to add any per-message verifications. /// /// The sliced data /// Data was null @@ -77,8 +78,19 @@ protected virtual void VerifyPacket(IReadOnlyList data) { throw new InvalidOperationException($"Length nibble for {GetType()} was expected to be {ExpectedLength}, but was {data[1] & 0xF}"); } + + if (!MatchesMessageType(data)) + { + throw new InvalidOperationException($"A custom package verification failed"); + } } + /// + /// Checks whether the data could be a packet of the current type. Unlike the above, this does not throw exceptions, but only returns true or false. + /// + /// The input sequence + /// True if the input is likely a complete and valid packet of the current type, false otherwise. + /// The input is null public virtual bool MatchesMessageType(IReadOnlyList data) { if (data == null) diff --git a/src/devices/Seatalk1/Messages/TurnDirection.cs b/src/devices/Seatalk1/Messages/TurnDirection.cs index 949fa9800e..7cb257862a 100644 --- a/src/devices/Seatalk1/Messages/TurnDirection.cs +++ b/src/devices/Seatalk1/Messages/TurnDirection.cs @@ -1,4 +1,7 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index d094afb872..6166be699f 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -16,8 +16,11 @@ + + + diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index ba287317f2..b087f2cf75 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -52,7 +52,9 @@ public Seatalk1Parser(Stream inputStream) _reader = new BinaryReader(inputStream, Encoding.UTF8); _messageFactories = new List() { - new CompassHeadingAndRudderPosition(), new CompassHeadingAutopilotCourse(), + new CompassHeadingAndRudderPosition(), + new CompassHeadingAutopilotCourse(), + new Keystroke(), }; } @@ -108,6 +110,7 @@ private void Parser() return; } + bool isInSync = true; while (!_cancellationTokenSource.IsCancellationRequested) { try @@ -116,22 +119,45 @@ private void Parser() { byte nextByte = _reader.ReadByte(); _buffer.Add(nextByte); - var msg = GetTypeOfNextMessage(out int messageLength); + tryAgainWithoutFirstByte: + var msg = GetTypeOfNextMessage(_buffer, out int messageLength); + if (msg == null && !isInSync) + { + // In this case, we also need to check whether a substring of _buffer is a valid message (but still starting at index 0) + // This is because we have only chopped the first byte from an invalid message, but the remaining (up to 17) bytes may now + // form a valid message, but with a different length + for (int len = 3; len < _buffer.Count; len++) + { + msg = GetTypeOfNextMessage(_buffer.GetRange(0, len), out messageLength); + if (msg != null) + { + break; + } + } + } + if (msg == null) { if (messageLength == 0) { - break; + continue; } else { _logger.LogWarning($"Seatalk parser sync lost. Next message was 0x{_buffer[0]:X2}, now skipping"); _buffer.RemoveAt(0); - continue; + // We removed the first byte from the sequence, we need to try again before we add the next byte + isInSync = false; + goto tryAgainWithoutFirstByte; } } NewMessageDecoded?.Invoke(msg); + _buffer.RemoveRange(0, messageLength); + if (_buffer.Count == 0) + { + isInSync = true; + } } } catch (Exception x) when (x is EndOfStreamException || x is IOException) @@ -147,19 +173,20 @@ private void Parser() /// /// Returns the length of the message in the input buffer /// + /// The data to decode /// The number of bytes in the next message. Returns 0 if not enough data, -1 if sync lost (to many bytes, but no valid sentence) /// An instance that can be used as factory for the next message or null if nothing can be decoded. - private SeatalkMessage? GetTypeOfNextMessage(out int bytesInMessage) + private SeatalkMessage? GetTypeOfNextMessage(IReadOnlyList buffer, out int bytesInMessage) { // The minimum message length is 3 bytes - if (_buffer.Count < 3) + if (buffer.Count < 3) { bytesInMessage = 0; return null; } // The maximum length is 0xF + 3 = 18 - if (_buffer.Count > 18) + if (buffer.Count > 18) { bytesInMessage = -1; return null; @@ -167,15 +194,14 @@ private void Parser() foreach (var t in _messageFactories) { - if (t.MatchesMessageType(_buffer)) + if (t.MatchesMessageType(buffer)) { bytesInMessage = t.ExpectedLength; - return t.CreateNewMessage(_buffer); + return t.CreateNewMessage(buffer); } } - _logger.LogWarning($"Unable to decode message. Stream is out of sync or unknown message type 0x{_buffer[0]:X2}."); - bytesInMessage = -1; + bytesInMessage = 0; return null; } diff --git a/src/devices/Seatalk1/tests/Seatalk1Tests.cs b/src/devices/Seatalk1/tests/Seatalk1Tests.cs index 83b99da524..257f13258a 100644 --- a/src/devices/Seatalk1/tests/Seatalk1Tests.cs +++ b/src/devices/Seatalk1/tests/Seatalk1Tests.cs @@ -23,9 +23,7 @@ 86 01 02 fd 84 06 12 00 00 00 00 00 08 9c 01 12 00 84 06 12 00 00 00 00 00 08"; - byte[] input = Convert.FromHexString(data); - - MemoryStream ms = new MemoryStream(input); + MemoryStream ms = GetStreamFromInputString(data); int numMessages = 0; Seatalk1Parser parser = new Seatalk1Parser(ms); @@ -36,19 +34,70 @@ 9c 01 12 00 Assert.True(message.ExpectedLength >= 3); if (message is CompassHeadingAndRudderPosition ch) { - Assert.Equal(Angle.FromDegrees(40), ch.CompassHeading); + Assert.Equal(Angle.FromDegrees(36), ch.CompassHeading); + } + + if (message is Keystroke ks) + { + Assert.Equal(AutopilotButtons.StandBy, ks.ButtonsPressed); } }; parser.StartDecode(); - while (numMessages != 6) + int cnt = 10; + while (numMessages != 6 && cnt-- >= 0) { Thread.Sleep(100); } parser.StopDecode(); + Assert.True(cnt > 0); // timeout? + parser.Dispose(); } + + [Fact] + public void SkipSomeGarbage() + { + // The second row is garbled (for this test, at least 18 bytes must be in the input after the garbage) + string data = @"9c 01 12 00 +0A 02 12 00 00 FF DD 00 08 +86 01 02 fd +84 06 12 00 00 00 00 00 08 +9c 01 12 00 +84 06 12 00 00 00 00 00 08"; + MemoryStream ms = GetStreamFromInputString(data); + + int numMessages = 0; + Seatalk1Parser parser = new Seatalk1Parser(ms); + parser.NewMessageDecoded += message => + { + numMessages++; + }; + parser.StartDecode(); + + int cnt = 100; + while (numMessages != 5 && cnt-- >= 0) + { + Thread.Sleep(100); + } + + parser.StopDecode(); + + Assert.True(cnt > 0); // timeout? + + parser.Dispose(); + } + + private static MemoryStream GetStreamFromInputString(string data) + { + var split = data.Split(new char[] { '\n', '\r', ' ' }, StringSplitOptions.RemoveEmptyEntries); + // FromHexString expects an uninterrupted sequence of two-char pairs + byte[] input = Convert.FromHexString(string.Join(string.Empty, split)); + + MemoryStream ms = new MemoryStream(input); + return ms; + } } } From baba2802f0f7c30f9a388807c4ef1a70c5c4793d Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Tue, 26 Dec 2023 21:03:58 +0100 Subject: [PATCH 05/31] It starts to do something useful --- .../Seatalk1/Messages/AutopilotAlarms.cs | 16 +++++ .../Seatalk1/Messages/AutopilotStatus.cs | 1 + .../CompassHeadingAndRudderPosition.cs | 3 - .../Messages/CompassHeadingAutopilotCourse.cs | 45 ++++++++++++- src/devices/Seatalk1/Messages/Keystroke.cs | 36 +++++++++-- .../Seatalk1/Messages/SeatalkMessage.cs | 9 +++ src/devices/Seatalk1/Seatalk1.csproj | 1 + src/devices/Seatalk1/Seatalk1Parser.cs | 5 +- .../Seatalk1/samples/Seatalk1.Samples.cs | 63 ++++++++++++++++++- .../Seatalk1/samples/Seatalk1.Samples.csproj | 4 ++ 10 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 src/devices/Seatalk1/Messages/AutopilotAlarms.cs diff --git a/src/devices/Seatalk1/Messages/AutopilotAlarms.cs b/src/devices/Seatalk1/Messages/AutopilotAlarms.cs new file mode 100644 index 0000000000..2e20c8d80c --- /dev/null +++ b/src/devices/Seatalk1/Messages/AutopilotAlarms.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + [Flags] + public enum AutopilotAlarms + { + None = 0, + OffCourse = 4, + WindShift = 8, + } +} diff --git a/src/devices/Seatalk1/Messages/AutopilotStatus.cs b/src/devices/Seatalk1/Messages/AutopilotStatus.cs index b8c6ba5934..19be082fc6 100644 --- a/src/devices/Seatalk1/Messages/AutopilotStatus.cs +++ b/src/devices/Seatalk1/Messages/AutopilotStatus.cs @@ -20,5 +20,6 @@ public enum AutopilotStatus Track, Wind, Display, + Undefined, } } diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs index 8286db68d9..aca5e3b4bf 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs @@ -27,8 +27,6 @@ public Angle RudderPosition init; } - public TurnDirection TurnDirection { get; init; } - /// /// 84 U6 VW XY 0Z 0M RR SS TT Compass heading Autopilot course /// @@ -49,7 +47,6 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { CompassHeading = headingA, RudderPosition = Angle.FromDegrees(rudder), - TurnDirection = (u & 0x80) == 0 ? TurnDirection.Port : TurnDirection.Starboard, }; } } diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index 579190d49b..42e7fd3e63 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -17,9 +17,15 @@ public record CompassHeadingAutopilotCourse : SeatalkMessage public Angle CompassHeading { get; init; } - public TurnDirection TurnDirection { get; init; } + public byte AutoPilotType { get; init; } - public byte AutoPilotType { get; set; } + public Angle AutoPilotCourse { get; init; } + + public Angle RudderPosition { get; init; } + + public AutopilotStatus AutopilotStatus { get; init; } + + public AutopilotAlarms Alarms { get; init; } public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { @@ -31,11 +37,44 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) long heading = (u & 0x3) * 90 + (vw & 0x3F) * 2 + BitCount(u & 0xC); Angle headingA = Angle.FromDegrees(heading); + long desiredCourse = (vw >> 6) * 90 + data[3] / 2; + + AutopilotStatus status = GetAutopilotStatus(data[4]); + + sbyte rudder = (sbyte)data[6]; + + AutopilotAlarms alarms = AutopilotAlarms.None; + byte almByte = data[5]; + if ((almByte & 0x4) == 0x4) + { + alarms |= AutopilotAlarms.OffCourse; + } + + if ((almByte & 0x8) == 0x8) + { + alarms |= AutopilotAlarms.WindShift; + } + return new CompassHeadingAutopilotCourse() { CompassHeading = headingA, - TurnDirection = (u & 0x80) == 0 ? TurnDirection.Port : TurnDirection.Starboard, AutoPilotType = data[8], + AutoPilotCourse = Angle.FromDegrees(desiredCourse), + AutopilotStatus = status, + RudderPosition = Angle.FromDegrees(rudder), + Alarms = alarms, + }; + } + + private AutopilotStatus GetAutopilotStatus(byte z) + { + return (z & 0xf) switch + { + 0 => AutopilotStatus.Standby, + 2 => AutopilotStatus.Auto, + 4 => AutopilotStatus.Wind, + 8 => AutopilotStatus.Track, + _ => AutopilotStatus.Undefined, }; } } diff --git a/src/devices/Seatalk1/Messages/Keystroke.cs b/src/devices/Seatalk1/Messages/Keystroke.cs index 8363e3fd7a..5c1facf008 100644 --- a/src/devices/Seatalk1/Messages/Keystroke.cs +++ b/src/devices/Seatalk1/Messages/Keystroke.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace Iot.Device.Seatalk1.Messages { @@ -53,12 +54,37 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) private AutopilotButtons GetButtons(int keyCode) { - return keyCode switch + switch (keyCode) { - 0x01 => AutopilotButtons.Auto, - 0x02 => AutopilotButtons.StandBy, - _ => AutopilotButtons.None, - }; + case 0x01: return AutopilotButtons.Auto; + case 0x02: return AutopilotButtons.StandBy; + case 0x03: return AutopilotButtons.MinusTen | AutopilotButtons.PlusTen; + case 0x05: return AutopilotButtons.MinusOne; + case 0x06: return AutopilotButtons.MinusTen; + case 0x07: return AutopilotButtons.PlusOne; + case 0x08: return AutopilotButtons.PlusTen; + // These two are only sent in auto mode when +1 and -1 are pressed, possibly indicating whether in deadband mode or not (exact course hold mode) + // In standby mode, this keypress toggles the display illumination, but does not send out the keystroke command. + case 0x0A: + case 0x09: + return AutopilotButtons.PlusOne | AutopilotButtons.MinusOne; + case 0x20: return AutopilotButtons.PlusOne | AutopilotButtons.MinusOne; + case 0x21: return AutopilotButtons.MinusOne | AutopilotButtons.MinusTen; + case 0x22: return AutopilotButtons.PlusOne | AutopilotButtons.PlusTen; + case 0x23: return AutopilotButtons.StandBy | AutopilotButtons.Auto; + case 0x28: return AutopilotButtons.PlusTen | AutopilotButtons.MinusTen; + case 0x30: return AutopilotButtons.MinusOne | AutopilotButtons.PlusTen; + case 0x31: return AutopilotButtons.MinusTen | AutopilotButtons.PlusOne; + + case 0x41: return AutopilotButtons.Auto | AutopilotButtons.LongPress; + case 0x63: return AutopilotButtons.Auto | AutopilotButtons.LongPress | AutopilotButtons.StandBy; + + default: + { + Logger.LogWarning($"Unknown keycode 0x{keyCode:X2}!"); + return AutopilotButtons.None; + } + } } public override bool MatchesMessageType(IReadOnlyList data) diff --git a/src/devices/Seatalk1/Messages/SeatalkMessage.cs b/src/devices/Seatalk1/Messages/SeatalkMessage.cs index 0dd3c60e43..1b2b04418d 100644 --- a/src/devices/Seatalk1/Messages/SeatalkMessage.cs +++ b/src/devices/Seatalk1/Messages/SeatalkMessage.cs @@ -6,6 +6,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Iot.Device.Common; +using Microsoft.Extensions.Logging; namespace Iot.Device.Seatalk1.Messages { @@ -14,6 +16,11 @@ namespace Iot.Device.Seatalk1.Messages /// public abstract record SeatalkMessage { + protected SeatalkMessage() + { + Logger = this.GetCurrentClassLogger(); + } + /// /// The command byte for this message /// @@ -30,6 +37,8 @@ public abstract byte ExpectedLength get; } + protected ILogger Logger { get; } + /// /// Creates a new message from this template /// diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index 6166be699f..cc911aee9b 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -16,6 +16,7 @@ + diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index b087f2cf75..ffca6de9f1 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -144,7 +144,8 @@ private void Parser() } else { - _logger.LogWarning($"Seatalk parser sync lost. Next message was 0x{_buffer[0]:X2}, now skipping"); + var bytesFound = BitConverter.ToString(_buffer.ToArray()); + _logger.LogWarning($"Seatalk parser sync lost. Buffer contents: {bytesFound}, trying to resync"); _buffer.RemoveAt(0); // We removed the first byte from the sequence, we need to try again before we add the next byte isInSync = false; @@ -160,7 +161,7 @@ private void Parser() } } } - catch (Exception x) when (x is EndOfStreamException || x is IOException) + catch (Exception x) when (x is EndOfStreamException || x is IOException || x is ObjectDisposedException) { // Ignore _logger.LogError(x, $"Seatalk Parser error: {x.Message}"); diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 395e23bad8..9a5a9dbbe7 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -7,11 +7,18 @@ using System.Device.Spi; using System.Threading; using System.IO.Ports; +using Iot.Device.Common; +using Iot.Device.Seatalk1; +using Iot.Device.Seatalk1.Messages; +using Microsoft.Extensions.Logging; namespace Seatalk1Sample { internal class Program { + private CompassHeadingAndRudderPosition? _headingAndRudderPosition; + private CompassHeadingAutopilotCourse? _autopilotCourse; + internal static int Main(string[] args) { Console.WriteLine("Hello Seatalk1 Sample!"); @@ -22,6 +29,15 @@ internal static int Main(string[] args) return 1; } + var p = new Program(); + p.Run(args); + return 0; + } + + public void Run(string[] args) + { + LogDispatcher.LoggerFactory = new SimpleConsoleLoggerFactory(LogLevel.Trace); + SerialPort port1 = new SerialPort(args[0]); port1.BaudRate = 4800; port1.Parity = Parity.Even; @@ -29,8 +45,53 @@ internal static int Main(string[] args) port1.DataBits = 8; port1.Open(); + Seatalk1Parser parser = new Seatalk1Parser(port1.BaseStream); + parser.StartDecode(); + + parser.NewMessageDecoded += ParserOnNewMessageDecoded; + + while (!Console.KeyAvailable) + { + Thread.Sleep(500); + } + + parser.StopDecode(); + Console.ReadKey(true); + + Console.WriteLine("Program is terminating"); + parser.Dispose(); port1.Close(); - return 0; + } + + private void WriteCurrentState() + { + if (_headingAndRudderPosition == null || _autopilotCourse == null) + { + return; + } + + Console.Write("\r"); + Console.Write($"MAG: {_headingAndRudderPosition.CompassHeading} TRK: {_autopilotCourse.AutoPilotCourse} " + + $"STAT: {_autopilotCourse.AutopilotStatus} RUDDER: {_autopilotCourse.RudderPosition} ALRT: {_autopilotCourse.Alarms} "); + } + + private void ParserOnNewMessageDecoded(SeatalkMessage obj) + { + if (obj is CompassHeadingAutopilotCourse ch) + { + _autopilotCourse = ch; + WriteCurrentState(); + } + else if (obj is CompassHeadingAndRudderPosition rb) + { + _headingAndRudderPosition = rb; + WriteCurrentState(); + } + else if (obj is Keystroke keystroke) + { + Console.WriteLine(); + Console.WriteLine($"Pressed key(s): {keystroke}"); + } } } } diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj b/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj index 23eaebe374..a6066e17da 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.csproj @@ -9,4 +9,8 @@ + + + + From c92423c447520ed8a921f6519f0a73fffd21c2d2 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Wed, 27 Dec 2023 14:13:53 +0100 Subject: [PATCH 06/31] More messages, and high-level support --- .../Seatalk1/AutoPilotRemoteController.cs | 100 ++++++++++++++++++ .../Seatalk1/Messages/AutopilotAlarms.cs | 9 +- .../Messages/CompassHeadingAutopilotCourse.cs | 2 +- .../CompassHeadingAutopilotCourseAlt.cs | 20 ++++ src/devices/Seatalk1/Messages/DeadbandMode.cs | 12 +++ .../Seatalk1/Messages/DeadbandSetting.cs | 43 ++++++++ src/devices/Seatalk1/Seatalk1.csproj | 9 +- src/devices/Seatalk1/Seatalk1Parser.cs | 9 +- src/devices/Seatalk1/SeatalkInterface.cs | 76 +++++++++++++ .../Seatalk1/samples/Seatalk1.Samples.cs | 8 +- src/devices/Seatalk1/tests/MessageTests.cs | 60 +++++++++++ 11 files changed, 339 insertions(+), 9 deletions(-) create mode 100644 src/devices/Seatalk1/AutoPilotRemoteController.cs create mode 100644 src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourseAlt.cs create mode 100644 src/devices/Seatalk1/Messages/DeadbandMode.cs create mode 100644 src/devices/Seatalk1/Messages/DeadbandSetting.cs create mode 100644 src/devices/Seatalk1/SeatalkInterface.cs create mode 100644 src/devices/Seatalk1/tests/MessageTests.cs diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs new file mode 100644 index 0000000000..2b67638fd7 --- /dev/null +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Iot.Device.Seatalk1.Messages; +using UnitsNet; + +namespace Iot.Device.Seatalk1 +{ + public class AutoPilotRemoteController + { + private readonly SeatalkInterface _parentInterface; + private readonly object _lock = new object(); + + internal AutoPilotRemoteController(SeatalkInterface parentInterface) + { + _parentInterface = parentInterface ?? throw new ArgumentNullException(nameof(parentInterface)); + _parentInterface.MessageReceived += AutopilotMessageInterpretation; + RudderAngleAvailable = false; + Status = AutopilotStatus.Offline; + Alarms = AutopilotAlarms.None; + DeadbandMode = DeadbandMode.Automatic; + } + + public Angle? AutopilotHeading { get; private set; } + + public Angle? AutopilotDesiredHeading { get; private set; } + + public Angle? RudderAngle { get; private set; } + + public bool RudderAngleAvailable { get; private set; } + + public AutopilotStatus Status { get; private set; } + + public AutopilotAlarms Alarms { get; private set; } + + public DeadbandMode DeadbandMode { get; private set; } + + public event Action? AutopilotKeysPressed; + + private void AutopilotMessageInterpretation(SeatalkMessage obj) + { + lock (_lock) + { + if (obj is CompassHeadingAutopilotCourse ch) + { + Status = ch.AutopilotStatus; + AutopilotHeading = ch.CompassHeading; + AutopilotDesiredHeading = Status != AutopilotStatus.Standby ? ch.AutoPilotCourse : null; + if (!RudderAngleAvailable) + { + RudderAngleAvailable = !ch.RudderPosition.Equals(Angle.Zero, Angle.FromDegrees(0.5)); + } + + if (RudderAngleAvailable) + { + RudderAngle = ch.RudderPosition; + } + else + { + RudderAngle = null; + } + + Alarms = ch.Alarms; + } + else if (obj is CompassHeadingAndRudderPosition rb) + { + AutopilotHeading = rb.CompassHeading; + if (!RudderAngleAvailable) + { + RudderAngleAvailable = !rb.RudderPosition.Equals(Angle.Zero, Angle.FromDegrees(0.5)); + } + + if (RudderAngleAvailable) + { + RudderAngle = rb.RudderPosition; + } + else + { + RudderAngle = null; + } + } + else if (obj is DeadbandSetting dbs) + { + DeadbandMode = dbs.Mode; + } + else if (obj is Keystroke keystroke) + { + AutopilotKeysPressed?.Invoke(keystroke); + } + + if (Status == AutopilotStatus.Standby) + { + DeadbandMode = DeadbandMode.Automatic; // Resets automatically when going to standby (the message is not sent periodically) + } + } + } + } +} diff --git a/src/devices/Seatalk1/Messages/AutopilotAlarms.cs b/src/devices/Seatalk1/Messages/AutopilotAlarms.cs index 2e20c8d80c..ea2cab57f1 100644 --- a/src/devices/Seatalk1/Messages/AutopilotAlarms.cs +++ b/src/devices/Seatalk1/Messages/AutopilotAlarms.cs @@ -1,8 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; namespace Iot.Device.Seatalk1.Messages { diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index 42e7fd3e63..d0fdab6ed9 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -55,7 +55,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) alarms |= AutopilotAlarms.WindShift; } - return new CompassHeadingAutopilotCourse() + return this with { CompassHeading = headingA, AutoPilotType = data[8], diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourseAlt.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourseAlt.cs new file mode 100644 index 0000000000..33e7ec035c --- /dev/null +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourseAlt.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + /// + /// This message is sometimes sent instead of when the pilot is somehow busy + /// It seems we don't really need to distinguish. + /// + public record CompassHeadingAutopilotCourseAlt : CompassHeadingAutopilotCourse + { + public override byte CommandByte => 0x95; + } +} diff --git a/src/devices/Seatalk1/Messages/DeadbandMode.cs b/src/devices/Seatalk1/Messages/DeadbandMode.cs new file mode 100644 index 0000000000..755471ed9e --- /dev/null +++ b/src/devices/Seatalk1/Messages/DeadbandMode.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Iot.Device.Seatalk1.Messages +{ + public enum DeadbandMode + { + None = 0, + Automatic, + Minimal, + } +} diff --git a/src/devices/Seatalk1/Messages/DeadbandSetting.cs b/src/devices/Seatalk1/Messages/DeadbandSetting.cs new file mode 100644 index 0000000000..714bd61193 --- /dev/null +++ b/src/devices/Seatalk1/Messages/DeadbandSetting.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + public record DeadbandSetting : SeatalkMessage + { + public override byte CommandByte => 0x87; + public override byte ExpectedLength => 0x03; + + public DeadbandMode Mode { get; init; } + + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) + { + VerifyPacket(data); + DeadbandMode mode = DeadbandMode.None; + if (data[2] == 1) + { + mode = DeadbandMode.Automatic; + } + else if (data[2] == 2) + { + mode = DeadbandMode.Minimal; + } + + return new DeadbandSetting() + { + Mode = mode, + }; + } + + public override bool MatchesMessageType(IReadOnlyList data) + { + return base.MatchesMessageType(data) && data[1] == 0x0; + } + } +} diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index cc911aee9b..bc2ce4d319 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -21,10 +21,17 @@ + + + - + + + <_Parameter1>$(AssemblyName).Tests + + diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index ffca6de9f1..6bbd1d9d0a 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -54,12 +54,19 @@ public Seatalk1Parser(Stream inputStream) { new CompassHeadingAndRudderPosition(), new CompassHeadingAutopilotCourse(), + new CompassHeadingAutopilotCourseAlt(), new Keystroke(), + new DeadbandSetting(), }; } public event Action? NewMessageDecoded; + public void RegisterMessageType(SeatalkMessage message) + { + _messageFactories.Add(message); + } + /// /// Starts the thread to decode packets /// @@ -177,7 +184,7 @@ private void Parser() /// The data to decode /// The number of bytes in the next message. Returns 0 if not enough data, -1 if sync lost (to many bytes, but no valid sentence) /// An instance that can be used as factory for the next message or null if nothing can be decoded. - private SeatalkMessage? GetTypeOfNextMessage(IReadOnlyList buffer, out int bytesInMessage) + internal SeatalkMessage? GetTypeOfNextMessage(IReadOnlyList buffer, out int bytesInMessage) { // The minimum message length is 3 bytes if (buffer.Count < 3) diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs new file mode 100644 index 0000000000..4e8377c749 --- /dev/null +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -0,0 +1,76 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Ports; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Iot.Device.Seatalk1.Messages; + +namespace Iot.Device.Seatalk1 +{ + public class SeatalkInterface : IDisposable + { + private readonly SerialPort _port; + private readonly Seatalk1Parser _parser; + + public event Action? MessageReceived; + + /// + /// Creates a new instance of the SeatalkInterface, that provides high-level functions on a seatalk bus + /// + /// The Uart name that connects to the bus, e.g. /dev/ttyAMA2 or COM5 + /// The uart string is null + /// The port could not be opened + /// The port could not be accessed. Maybe it is already open by another application? + /// + /// Unlike other classes that communicate over a serial port, this object requires to own the serial port itself, as it needs to + /// set it up in a special way and change the communication parameters during operation. + /// + public SeatalkInterface(string uart) + { + if (uart == null) + { + throw new ArgumentNullException(nameof(uart)); + } + + _port = new SerialPort(uart); + _port.BaudRate = 4800; + _port.Parity = Parity.Even; // Can be anything but none, but "Mark" or "Space" won't have the desired effect on linux, causing garbage to be sent + _port.StopBits = StopBits.One; + _port.DataBits = 8; + _port.Open(); + + _parser = new Seatalk1Parser(_port.BaseStream); + _parser.NewMessageDecoded += OnNewMessage; + _parser.StartDecode(); + } + + public Seatalk1Parser Parser => _parser; + + private void OnNewMessage(SeatalkMessage obj) + { + MessageReceived?.Invoke(obj); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _parser.StopDecode(); + _parser.Dispose(); + _port.Close(); + _port.Dispose(); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 9a5a9dbbe7..7c84966978 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -18,6 +18,7 @@ internal class Program { private CompassHeadingAndRudderPosition? _headingAndRudderPosition; private CompassHeadingAutopilotCourse? _autopilotCourse; + private DeadbandMode _deadbandMode = DeadbandMode.None; internal static int Main(string[] args) { @@ -72,7 +73,7 @@ private void WriteCurrentState() Console.Write("\r"); Console.Write($"MAG: {_headingAndRudderPosition.CompassHeading} TRK: {_autopilotCourse.AutoPilotCourse} " + - $"STAT: {_autopilotCourse.AutopilotStatus} RUDDER: {_autopilotCourse.RudderPosition} ALRT: {_autopilotCourse.Alarms} "); + $"STAT: {_autopilotCourse.AutopilotStatus} RUDDER: {_autopilotCourse.RudderPosition} ALRT: {_autopilotCourse.Alarms} DB: {_deadbandMode} "); } private void ParserOnNewMessageDecoded(SeatalkMessage obj) @@ -87,6 +88,11 @@ private void ParserOnNewMessageDecoded(SeatalkMessage obj) _headingAndRudderPosition = rb; WriteCurrentState(); } + else if (obj is DeadbandSetting dbs) + { + _deadbandMode = dbs.Mode; + WriteCurrentState(); + } else if (obj is Keystroke keystroke) { Console.WriteLine(); diff --git a/src/devices/Seatalk1/tests/MessageTests.cs b/src/devices/Seatalk1/tests/MessageTests.cs new file mode 100644 index 0000000000..df85a634d7 --- /dev/null +++ b/src/devices/Seatalk1/tests/MessageTests.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Iot.Device.Seatalk1; +using Iot.Device.Seatalk1.Messages; +using UnitsNet; +using Xunit; + +namespace Iot.Device.Tests.Seatalk1 +{ + public class MessageTests + { + private Seatalk1Parser _parser; + public MessageTests() + { + _parser = new Seatalk1Parser(new MemoryStream()); + } + + [Theory] + [InlineData("95 86 26 97 02 00 00 00 08", typeof(CompassHeadingAutopilotCourseAlt))] + [InlineData("84 86 26 97 02 00 00 00 08", typeof(CompassHeadingAutopilotCourse))] + [InlineData("9c 01 12 00", typeof(CompassHeadingAndRudderPosition))] + [InlineData("87 00 01", typeof(DeadbandSetting))] + [InlineData("86 01 02 fd", typeof(Keystroke))] + public void KnownMessageTypeDecode(string msg, Type expectedType) + { + msg = msg.Replace(" ", string.Empty); + byte[] data = Convert.FromHexString(msg); + var actualType = _parser.GetTypeOfNextMessage(data, out int length); + Assert.NotNull(actualType); + Assert.Equal(data.Length, length); + + Assert.Equal(expectedType, actualType.GetType()); + } + + [Fact] + public void WithKeywordCreatesCopy() + { + var obj = new CompassHeadingAndRudderPosition() + { + CompassHeading = Angle.FromDegrees(10) + }; + + var copy = obj with + { + CompassHeading = Angle.FromDegrees(12) + }; + + Assert.False(ReferenceEquals(obj, copy)); + + Assert.NotEqual(obj, copy); + } + } +} From e534f9f1a94a6a56478958d92ca419865c72b775 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Fri, 29 Dec 2023 17:38:26 +0100 Subject: [PATCH 07/31] First messages can be sent --- .../Seatalk1/AutoPilotRemoteController.cs | 46 +++++++++- src/devices/Seatalk1/SeatalkInterface.cs | 92 +++++++++++++++++++ .../Seatalk1/samples/Seatalk1.Samples.cs | 82 +++++++++-------- 3 files changed, 177 insertions(+), 43 deletions(-) diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index 2b67638fd7..f37a32aeaa 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -1,4 +1,7 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,10 +11,17 @@ namespace Iot.Device.Seatalk1 { + /// + /// Remote controller for an autopilot connected via Seatalk1 + /// + /// + /// Type is not disposable, to prevent accidental disposal by clients. They don't get ownership of the instance. + /// public class AutoPilotRemoteController { private readonly SeatalkInterface _parentInterface; private readonly object _lock = new object(); + private DateTime _lastUpdateTime = new DateTime(0); internal AutoPilotRemoteController(SeatalkInterface parentInterface) { @@ -26,7 +36,7 @@ internal AutoPilotRemoteController(SeatalkInterface parentInterface) public Angle? AutopilotHeading { get; private set; } public Angle? AutopilotDesiredHeading { get; private set; } - + public Angle? RudderAngle { get; private set; } public bool RudderAngleAvailable { get; private set; } @@ -43,6 +53,7 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) { lock (_lock) { + _lastUpdateTime = DateTime.UtcNow; if (obj is CompassHeadingAutopilotCourse ch) { Status = ch.AutopilotStatus; @@ -90,11 +101,40 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) AutopilotKeysPressed?.Invoke(keystroke); } - if (Status == AutopilotStatus.Standby) + if (Status == AutopilotStatus.Standby || Status == AutopilotStatus.Offline) { DeadbandMode = DeadbandMode.Automatic; // Resets automatically when going to standby (the message is not sent periodically) } } } + + internal void UpdateStatus() + { + lock (_lock) + { + if (_lastUpdateTime + TimeSpan.FromSeconds(5) < DateTime.UtcNow) + { + // The autopilot hasn't sent anything for 5 seconds. Assume it's offline + Status = AutopilotStatus.Offline; + DeadbandMode = DeadbandMode.Automatic; + RudderAngle = null; + AutopilotDesiredHeading = null; + AutopilotHeading = null; + } + } + } + + /// + /// Returns a textual representation of the current AP status + /// + /// + public override string ToString() + { + string hdg = AutopilotHeading.HasValue ? AutopilotHeading.Value.ToString() : "N/A"; + string desiredHdg = AutopilotDesiredHeading.HasValue ? AutopilotDesiredHeading.Value.ToString() : "N/A"; + string rudderAngle = RudderAngleAvailable ? RudderAngle.GetValueOrDefault().ToString() : "N/A"; + string ret = $"MODE: {Status}; HDG: {hdg}; DESHDG: {desiredHdg}; RUD: {rudderAngle}; DB: {DeadbandMode}; ALRT: {Alarms}"; + return ret; + } } } diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index 4e8377c749..8bb846f613 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -7,6 +7,7 @@ using System.IO.Ports; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Iot.Device.Seatalk1.Messages; @@ -16,6 +17,9 @@ public class SeatalkInterface : IDisposable { private readonly SerialPort _port; private readonly Seatalk1Parser _parser; + private readonly Thread _watchDog; + private readonly CancellationTokenSource _cancellation; + private readonly AutoPilotRemoteController _autopilotController; public event Action? MessageReceived; @@ -47,23 +51,111 @@ public SeatalkInterface(string uart) _parser = new Seatalk1Parser(_port.BaseStream); _parser.NewMessageDecoded += OnNewMessage; _parser.StartDecode(); + + _autopilotController = new AutoPilotRemoteController(this); + + _cancellation = new CancellationTokenSource(); + _watchDog = new Thread(WatchDog); + _watchDog.Start(); } public Seatalk1Parser Parser => _parser; + /// + /// Periodic watchdog tasks + /// + private void WatchDog() + { + while (!_cancellation.IsCancellationRequested) + { + Thread.Sleep(1000); + _autopilotController.UpdateStatus(); + } + } + private void OnNewMessage(SeatalkMessage obj) { MessageReceived?.Invoke(obj); } + private int BitCount(int b) + { + int count = 0; + while (b != 0) + { + count++; + b &= (b - 1); // walking through all the bits which are set to one + } + + return count; + } + + public void SendDatagram(byte[] data) + { + // Send byte-by-byte + bool isCommandByte = true; + for (int i = 0; i < data.Length; i++) + { + byte b = data[i]; + // We need to send the first byte (the command byte) with a parity of "mark", all the remaining bytes with a parity of "space", + // but since Linux doesn't seem to properly support Mark or Space (on the raspberry pi, that setting results in no parity bit to be sent) + // we cheat here and count what the parity bit should be and use even or odd to achieve the desired result. + bool isEven = BitCount(b) % 2 == 0; + Parity parityToSend; + if (isEven) + { + if (isCommandByte) + { + // command byte so far is even, we need the parity bit to be 1, so use odd parity + // (because the parity setting "odd" means that the data bits including the parity bit count to odd) + parityToSend = Parity.Odd; + } + else + { + parityToSend = Parity.Even; + } + } + else + { + if (isCommandByte) + { + parityToSend = Parity.Even; + } + else + { + parityToSend = Parity.Odd; + } + } + + // parityToSend = parityToSend == Parity.Odd ? Parity.Even : Parity.Odd; + _port.Parity = parityToSend; + _port.Write(data, i, 1); + while (_port.BytesToWrite != 0) + { + Thread.Yield(); + } + + isCommandByte = false; + } + } + + /// + /// Get an interface to the Autopilot remote controller. + /// + /// An interface to monitor and control an Autopilot connected via Seatalk1 + public AutoPilotRemoteController GetAutopilotRemoteController() => _autopilotController; + protected virtual void Dispose(bool disposing) { if (disposing) { + _cancellation.Cancel(); _parser.StopDecode(); _parser.Dispose(); _port.Close(); _port.Dispose(); + _watchDog.Join(); + _cancellation.Dispose(); } } diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 7c84966978..f73bbd582d 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -16,9 +16,7 @@ namespace Seatalk1Sample { internal class Program { - private CompassHeadingAndRudderPosition? _headingAndRudderPosition; - private CompassHeadingAutopilotCourse? _autopilotCourse; - private DeadbandMode _deadbandMode = DeadbandMode.None; + private SeatalkInterface? _seatalk; internal static int Main(string[] args) { @@ -39,61 +37,65 @@ public void Run(string[] args) { LogDispatcher.LoggerFactory = new SimpleConsoleLoggerFactory(LogLevel.Trace); - SerialPort port1 = new SerialPort(args[0]); - port1.BaudRate = 4800; - port1.Parity = Parity.Even; - port1.StopBits = StopBits.One; - port1.DataBits = 8; - port1.Open(); + _seatalk = new SeatalkInterface(args[0]); - Seatalk1Parser parser = new Seatalk1Parser(port1.BaseStream); - parser.StartDecode(); + _seatalk.MessageReceived += ParserOnNewMessageDecoded; - parser.NewMessageDecoded += ParserOnNewMessageDecoded; - - while (!Console.KeyAvailable) + while (true) { + if (Console.KeyAvailable) + { + var key = Console.ReadKey(true); + if (key.Key == ConsoleKey.Escape) + { + break; + } + else if (key.Key == ConsoleKey.A) + { + // For testing only + byte[] keyPlus1 = new byte[] + { + 0x86, 0x11, 0x07, 0xf8 + }; + + _seatalk.SendDatagram(keyPlus1); + } + else if (key.Key == ConsoleKey.B) + { + // For testing only + byte[] keyPlus1 = new byte[] + { + 0x86, 0x11, 0x05, 0xfa + // 0xFF, 0xFF, + }; + + _seatalk.SendDatagram(keyPlus1); + } + } + Thread.Sleep(500); + WriteCurrentState(); } - parser.StopDecode(); - Console.ReadKey(true); + _seatalk.Dispose(); + _seatalk = null; Console.WriteLine("Program is terminating"); - parser.Dispose(); - port1.Close(); } private void WriteCurrentState() { - if (_headingAndRudderPosition == null || _autopilotCourse == null) + var ctrl = _seatalk?.GetAutopilotRemoteController(); + if (ctrl != null) { - return; + Console.Write("\r"); + Console.Write(ctrl.ToString()); } - - Console.Write("\r"); - Console.Write($"MAG: {_headingAndRudderPosition.CompassHeading} TRK: {_autopilotCourse.AutoPilotCourse} " + - $"STAT: {_autopilotCourse.AutopilotStatus} RUDDER: {_autopilotCourse.RudderPosition} ALRT: {_autopilotCourse.Alarms} DB: {_deadbandMode} "); } private void ParserOnNewMessageDecoded(SeatalkMessage obj) { - if (obj is CompassHeadingAutopilotCourse ch) - { - _autopilotCourse = ch; - WriteCurrentState(); - } - else if (obj is CompassHeadingAndRudderPosition rb) - { - _headingAndRudderPosition = rb; - WriteCurrentState(); - } - else if (obj is DeadbandSetting dbs) - { - _deadbandMode = dbs.Mode; - WriteCurrentState(); - } - else if (obj is Keystroke keystroke) + if (obj is Keystroke keystroke) { Console.WriteLine(); Console.WriteLine($"Pressed key(s): {keystroke}"); From 2629339961316d94594d6703023e8268b408bd03 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Fri, 29 Dec 2023 19:07:10 +0100 Subject: [PATCH 08/31] It works! --- src/devices/Seatalk1/SeatalkInterface.cs | 68 ++++++++++++------- .../Seatalk1/samples/Seatalk1.Samples.cs | 21 ++++++ src/devices/Seatalk1/tests/Seatalk1Tests.cs | 45 ++++++++++++ 3 files changed, 108 insertions(+), 26 deletions(-) diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index 8bb846f613..b0eecf5612 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -15,6 +15,7 @@ namespace Iot.Device.Seatalk1 { public class SeatalkInterface : IDisposable { + private const Parity DefaultParity = Parity.Even; private readonly SerialPort _port; private readonly Seatalk1Parser _parser; private readonly Thread _watchDog; @@ -43,7 +44,7 @@ public SeatalkInterface(string uart) _port = new SerialPort(uart); _port.BaudRate = 4800; - _port.Parity = Parity.Even; // Can be anything but none, but "Mark" or "Space" won't have the desired effect on linux, causing garbage to be sent + _port.Parity = DefaultParity; // Can be anything but none, but "Mark" or "Space" won't have the desired effect on linux, causing garbage to be sent _port.StopBits = StopBits.One; _port.DataBits = 8; _port.Open(); @@ -61,24 +62,7 @@ public SeatalkInterface(string uart) public Seatalk1Parser Parser => _parser; - /// - /// Periodic watchdog tasks - /// - private void WatchDog() - { - while (!_cancellation.IsCancellationRequested) - { - Thread.Sleep(1000); - _autopilotController.UpdateStatus(); - } - } - - private void OnNewMessage(SeatalkMessage obj) - { - MessageReceived?.Invoke(obj); - } - - private int BitCount(int b) + private static int BitCount(int b) { int count = 0; while (b != 0) @@ -90,10 +74,10 @@ private int BitCount(int b) return count; } - public void SendDatagram(byte[] data) + internal static List<(byte B, Parity P, int Index)> CalculateParityForEachByte(byte[] data) { - // Send byte-by-byte bool isCommandByte = true; + List<(byte, Parity, int)> ret = new(); for (int i = 0; i < data.Length; i++) { byte b = data[i]; @@ -127,16 +111,48 @@ public void SendDatagram(byte[] data) } } + ret.Add((data[i], parityToSend, i)); + isCommandByte = false; + } + + return ret; + } + + /// + /// Periodic watchdog tasks + /// + private void WatchDog() + { + while (!_cancellation.IsCancellationRequested) + { + Thread.Sleep(1000); + _autopilotController.UpdateStatus(); + } + } + + private void OnNewMessage(SeatalkMessage obj) + { + MessageReceived?.Invoke(obj); + } + + public void SendDatagram(byte[] data) + { + var dataWithParity = CalculateParityForEachByte(data); + foreach (var e in dataWithParity) + { // parityToSend = parityToSend == Parity.Odd ? Parity.Even : Parity.Odd; - _port.Parity = parityToSend; - _port.Write(data, i, 1); - while (_port.BytesToWrite != 0) + if (_port.Parity != e.P) { - Thread.Yield(); + _port.BaseStream.Flush(); + _port.Parity = e.P; + _port.BaseStream.Flush(); } - isCommandByte = false; + _port.Write(data, e.Index, 1); } + + _port.BaseStream.Flush(); + _port.Parity = DefaultParity; } /// diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index f73bbd582d..06c32c60cc 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -69,6 +69,27 @@ public void Run(string[] args) // 0xFF, 0xFF, }; + _seatalk.SendDatagram(keyPlus1); + } + else if (key.Key == ConsoleKey.C) + { + // For testing only + byte[] keyPlus1 = new byte[] + { + 0x86, 0x11, 0x08, 0xf7 + }; + + _seatalk.SendDatagram(keyPlus1); + } + else if (key.Key == ConsoleKey.D) + { + // For testing only + byte[] keyPlus1 = new byte[] + { + 0x86, 0x11, 0x06, 0xf9 + // 0xFF, 0xFF, + }; + _seatalk.SendDatagram(keyPlus1); } } diff --git a/src/devices/Seatalk1/tests/Seatalk1Tests.cs b/src/devices/Seatalk1/tests/Seatalk1Tests.cs index 257f13258a..d8d42105b6 100644 --- a/src/devices/Seatalk1/tests/Seatalk1Tests.cs +++ b/src/devices/Seatalk1/tests/Seatalk1Tests.cs @@ -4,6 +4,7 @@ using System; using System.ComponentModel; using System.IO; +using System.IO.Ports; using System.Threading; using Iot.Device.Seatalk1; using Iot.Device.Seatalk1.Messages; @@ -90,6 +91,50 @@ 9c 01 12 00 parser.Dispose(); } + [Fact] + public void ParityBitCheckForMessageThatWorks() + { + // This message (-10 key) worked right away + byte[] datagram = new byte[] + { + 0x86, 0x11, 0x06, 0xf9 + }; + + var withParity = SeatalkInterface.CalculateParityForEachByte(datagram); + Assert.Equal(0x86, withParity[0].B); + Assert.Equal(0, withParity[0].Index); + // 0x86 is odd (not the value, but it's bitcount), and we want the stopbit to be 1, so the parity should be even + Assert.Equal(Parity.Even, withParity[0].P); + // 0x11 is even, but we need the stopbit to be 0, so parity still needs to be even + Assert.Equal(Parity.Even, withParity[1].P); + // 0x06 is even, we need the stopbit to be 0, so parity still needs to be even + Assert.Equal(Parity.Even, withParity[2].P); + // 0xf9 is even, we need the stopbit to be 0, so parity still needs to be even + Assert.Equal(Parity.Even, withParity[3].P); + } + + [Fact] + public void ParityBitCheckForMessageThatMustWork() + { + // This message (+10 key) doesn't work yet. + byte[] datagram = new byte[] + { + 0x86, 0x11, 0x08, 0xf7 + }; + + var withParity = SeatalkInterface.CalculateParityForEachByte(datagram); + Assert.Equal(0x86, withParity[0].B); + Assert.Equal(0, withParity[0].Index); + // 0x86 is odd (not the value, but it's bitcount), and we want the stopbit to be 1, so the parity should be even + Assert.Equal(Parity.Even, withParity[0].P); + // 0x11 is even, but we need the stopbit to be 0, so parity still needs to be even + Assert.Equal(Parity.Even, withParity[1].P); + // 0x08 is odd, we need the stopbit to be 0, so parity needs to be odd + Assert.Equal(Parity.Odd, withParity[2].P); + // 0xf7 is odd, we need the stopbit to be 0, so parity needs to be odd + Assert.Equal(Parity.Odd, withParity[3].P); + } + private static MemoryStream GetStreamFromInputString(string data) { var split = data.Split(new char[] { '\n', '\r', ' ' }, StringSplitOptions.RemoveEmptyEntries); From f579d328c22be7163cfb6c24d6bca3cf889a3216 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sat, 30 Dec 2023 11:19:54 +0100 Subject: [PATCH 09/31] The most important commands work, I can control the AP remotely! --- .../Seatalk1/AutoPilotRemoteController.cs | 70 +++++++++++ .../CompassHeadingAndRudderPosition.cs | 5 + .../Messages/CompassHeadingAutopilotCourse.cs | 5 + .../Seatalk1/Messages/DeadbandSetting.cs | 5 + src/devices/Seatalk1/Messages/Keystroke.cs | 112 +++++++++++++----- .../Seatalk1/Messages/SeatalkMessage.cs | 2 + src/devices/Seatalk1/SeatalkInterface.cs | 59 +++++++-- .../Seatalk1/samples/Seatalk1.Samples.cs | 92 ++++++++------ 8 files changed, 274 insertions(+), 76 deletions(-) diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index f37a32aeaa..929046edaf 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -3,8 +3,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Iot.Device.Seatalk1.Messages; using UnitsNet; @@ -19,9 +21,11 @@ namespace Iot.Device.Seatalk1 /// public class AutoPilotRemoteController { + private static readonly TimeSpan MaximumTimeout = TimeSpan.FromSeconds(6); private readonly SeatalkInterface _parentInterface; private readonly object _lock = new object(); private DateTime _lastUpdateTime = new DateTime(0); + private bool _buttonOnApPressed = false; internal AutoPilotRemoteController(SeatalkInterface parentInterface) { @@ -31,6 +35,7 @@ internal AutoPilotRemoteController(SeatalkInterface parentInterface) Status = AutopilotStatus.Offline; Alarms = AutopilotAlarms.None; DeadbandMode = DeadbandMode.Automatic; + DefaultTimeout = TimeSpan.FromSeconds(3); } public Angle? AutopilotHeading { get; private set; } @@ -47,6 +52,8 @@ internal AutoPilotRemoteController(SeatalkInterface parentInterface) public DeadbandMode DeadbandMode { get; private set; } + public TimeSpan DefaultTimeout { get; set; } + public event Action? AutopilotKeysPressed; private void AutopilotMessageInterpretation(SeatalkMessage obj) @@ -98,6 +105,11 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) } else if (obj is Keystroke keystroke) { + if (keystroke.Source != 1) + { + _buttonOnApPressed = true; + } + AutopilotKeysPressed?.Invoke(keystroke); } @@ -108,6 +120,64 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) } } + public bool SetStatus(AutopilotStatus status) + { + return SetStatus(status, DefaultTimeout); + } + + /// + /// Attempts to set the Autopilot to the given state. + /// + /// The status to set + /// How long to try. For safety reasons (see remark) the maximum value is limited + /// True on success, false if the change didn't succeed within the timeout. + /// + /// Don't be tempted to attempt to set the mode to Auto with a large timeout, as this could + /// override the user's desire to disable the Autopilot and is therefore VERY DANGEROUS! + /// + public bool SetStatus(AutopilotStatus newStatus, TimeSpan timeout) + { + if (Status == newStatus) + { + return true; // nothing to do + } + + if (timeout > MaximumTimeout) + { + throw new ArgumentOutOfRangeException(nameof(timeout), $"The maximum timeout is {MaximumTimeout}, see remarks in documentation"); + } + + _buttonOnApPressed = false; + Stopwatch sw = Stopwatch.StartNew(); + while (sw.Elapsed < timeout) + { + // If a button on the AP was pressed, abort immediately, as that one must always have precedence. + if (_buttonOnApPressed) + { + return false; + } + + if (Status == newStatus) + { + return true; + } + + AutopilotButtons buttonToPress = newStatus switch + { + AutopilotStatus.Auto => AutopilotButtons.Auto, + AutopilotStatus.Standby => AutopilotButtons.StandBy, + AutopilotStatus.Track => AutopilotButtons.Track, + AutopilotStatus.Wind => AutopilotButtons.Auto | AutopilotButtons.StandBy, + _ => throw new ArgumentException($"Status {newStatus} is not valid", nameof(newStatus)), + }; + + _parentInterface.SendMessage(new Keystroke(buttonToPress, 1)); + Thread.Sleep(137); // Some random number + } + + return false; + } + internal void UpdateStatus() { lock (_lock) diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs index aca5e3b4bf..d24971d527 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs @@ -49,5 +49,10 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) RudderPosition = Angle.FromDegrees(rudder), }; } + + public override byte[] CreateDatagram() + { + throw new NotImplementedException(); + } } } diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index d0fdab6ed9..ad144de998 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -66,6 +66,11 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + public override byte[] CreateDatagram() + { + throw new NotImplementedException(); + } + private AutopilotStatus GetAutopilotStatus(byte z) { return (z & 0xf) switch diff --git a/src/devices/Seatalk1/Messages/DeadbandSetting.cs b/src/devices/Seatalk1/Messages/DeadbandSetting.cs index 714bd61193..a7cc8c2a47 100644 --- a/src/devices/Seatalk1/Messages/DeadbandSetting.cs +++ b/src/devices/Seatalk1/Messages/DeadbandSetting.cs @@ -35,6 +35,11 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + public override byte[] CreateDatagram() + { + throw new NotImplementedException(); + } + public override bool MatchesMessageType(IReadOnlyList data) { return base.MatchesMessageType(data) && data[1] == 0x0; diff --git a/src/devices/Seatalk1/Messages/Keystroke.cs b/src/devices/Seatalk1/Messages/Keystroke.cs index 5c1facf008..55928d9699 100644 --- a/src/devices/Seatalk1/Messages/Keystroke.cs +++ b/src/devices/Seatalk1/Messages/Keystroke.cs @@ -13,11 +13,70 @@ namespace Iot.Device.Seatalk1.Messages { public record Keystroke : SeatalkMessage { + private static readonly Dictionary s_codeToButtonMap; + private static readonly Dictionary s_buttonToCodeMap; + + static Keystroke() + { + s_codeToButtonMap = new Dictionary() + { + { 0x01, AutopilotButtons.Auto }, + { 0x02, AutopilotButtons.StandBy }, + { 0x03, AutopilotButtons.MinusTen | AutopilotButtons.PlusTen }, + { 0x04, AutopilotButtons.Disp }, + { 0x05, AutopilotButtons.MinusOne }, + { 0x06, AutopilotButtons.MinusTen }, + { 0x07, AutopilotButtons.PlusOne }, + { 0x08, AutopilotButtons.PlusTen }, + // These two are only sent in auto mode when +1 and -1 are pressed. + // Whether 0x0A or ox09 is used is possibly indicating whether in deadband mode or not (exact course hold mode). + // In standby mode, this keypress toggles the display illumination, but does not send out the keystroke command. + { 0x0A, AutopilotButtons.PlusOne | AutopilotButtons.MinusOne }, + { 0x09, AutopilotButtons.PlusOne | AutopilotButtons.MinusOne }, + { 0x20, AutopilotButtons.PlusOne | AutopilotButtons.MinusOne }, + { 0x21, AutopilotButtons.MinusOne | AutopilotButtons.MinusTen }, + { 0x22, AutopilotButtons.PlusOne | AutopilotButtons.PlusTen }, + { 0x23, AutopilotButtons.StandBy | AutopilotButtons.Auto }, + { 0x28, AutopilotButtons.PlusTen | AutopilotButtons.MinusTen }, + { 0x30, AutopilotButtons.MinusOne | AutopilotButtons.PlusTen }, + { 0x31, AutopilotButtons.MinusTen | AutopilotButtons.PlusOne }, + { 0x41, AutopilotButtons.Auto | AutopilotButtons.LongPress }, + { 0x63, AutopilotButtons.Auto | AutopilotButtons.LongPress | AutopilotButtons.StandBy } + }; + + s_buttonToCodeMap = new Dictionary(); + foreach (var e in s_codeToButtonMap) + { + // The above list is not perfectly reversible (see 0x0A and 0x09) therefore use TryAdd + s_buttonToCodeMap.TryAdd(e.Value, e.Key); + } + } + + public Keystroke() + { + ButtonsPressed = AutopilotButtons.None; + Source = 0; + } + + public Keystroke(AutopilotButtons buttonsToPress, int source = 1) + { + ButtonsPressed = buttonsToPress; + Source = source; + } + + /// + /// The command byte for keypresses is 0x86 + /// public override byte CommandByte => 0x86; + + /// + /// This message is always 4 bytes long + /// public override byte ExpectedLength => 0x04; /// - /// Keypress source. Should probably be an enum, too + /// Keypress source. This is 0 for ST1000+ or ST2000+, 2 for ST4000 or ST600R, and 1 for remote controllers. + /// So when we send a keypress command to the autopilot, we need to set it to 1 /// public int Source { @@ -52,39 +111,32 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } - private AutopilotButtons GetButtons(int keyCode) + public override byte[] CreateDatagram() { - switch (keyCode) + byte keyCode = 0; + if (s_buttonToCodeMap.TryGetValue(ButtonsPressed, out int code)) { - case 0x01: return AutopilotButtons.Auto; - case 0x02: return AutopilotButtons.StandBy; - case 0x03: return AutopilotButtons.MinusTen | AutopilotButtons.PlusTen; - case 0x05: return AutopilotButtons.MinusOne; - case 0x06: return AutopilotButtons.MinusTen; - case 0x07: return AutopilotButtons.PlusOne; - case 0x08: return AutopilotButtons.PlusTen; - // These two are only sent in auto mode when +1 and -1 are pressed, possibly indicating whether in deadband mode or not (exact course hold mode) - // In standby mode, this keypress toggles the display illumination, but does not send out the keystroke command. - case 0x0A: - case 0x09: - return AutopilotButtons.PlusOne | AutopilotButtons.MinusOne; - case 0x20: return AutopilotButtons.PlusOne | AutopilotButtons.MinusOne; - case 0x21: return AutopilotButtons.MinusOne | AutopilotButtons.MinusTen; - case 0x22: return AutopilotButtons.PlusOne | AutopilotButtons.PlusTen; - case 0x23: return AutopilotButtons.StandBy | AutopilotButtons.Auto; - case 0x28: return AutopilotButtons.PlusTen | AutopilotButtons.MinusTen; - case 0x30: return AutopilotButtons.MinusOne | AutopilotButtons.PlusTen; - case 0x31: return AutopilotButtons.MinusTen | AutopilotButtons.PlusOne; - - case 0x41: return AutopilotButtons.Auto | AutopilotButtons.LongPress; - case 0x63: return AutopilotButtons.Auto | AutopilotButtons.LongPress | AutopilotButtons.StandBy; - - default: + keyCode = (byte)code; + byte inverseCode = (byte)~keyCode; + int attributeByte = ExpectedLength - 3 | (Source << 4); + return new byte[] { - Logger.LogWarning($"Unknown keycode 0x{keyCode:X2}!"); - return AutopilotButtons.None; - } + CommandByte, (byte)attributeByte, keyCode, inverseCode + }; } + + throw new ArgumentException($"The button combination {ButtonsPressed} is not a valid button combination"); + } + + private AutopilotButtons GetButtons(int keyCode) + { + if (s_codeToButtonMap.TryGetValue(keyCode, out var result)) + { + return result; + } + + Logger.LogWarning($"Unknown keycode {keyCode} in command"); + return AutopilotButtons.None; } public override bool MatchesMessageType(IReadOnlyList data) diff --git a/src/devices/Seatalk1/Messages/SeatalkMessage.cs b/src/devices/Seatalk1/Messages/SeatalkMessage.cs index 1b2b04418d..e2a6d3e027 100644 --- a/src/devices/Seatalk1/Messages/SeatalkMessage.cs +++ b/src/devices/Seatalk1/Messages/SeatalkMessage.cs @@ -46,6 +46,8 @@ public abstract byte ExpectedLength /// public abstract SeatalkMessage CreateNewMessage(IReadOnlyList data); + public abstract byte[] CreateDatagram(); + // To count the number of bits set in (U >> 4) & 0xc protected int BitCount(uint v) { diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index b0eecf5612..1fe42b234d 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -21,6 +21,7 @@ public class SeatalkInterface : IDisposable private readonly Thread _watchDog; private readonly CancellationTokenSource _cancellation; private readonly AutoPilotRemoteController _autopilotController; + private readonly object _lock; public event Action? MessageReceived; @@ -42,6 +43,7 @@ public SeatalkInterface(string uart) throw new ArgumentNullException(nameof(uart)); } + _lock = new object(); _port = new SerialPort(uart); _port.BaudRate = 4800; _port.Parity = DefaultParity; // Can be anything but none, but "Mark" or "Space" won't have the desired effect on linux, causing garbage to be sent @@ -74,6 +76,16 @@ private static int BitCount(int b) return count; } + /// + /// This calculates the correct parity for each byte in the datagram. + /// + /// The datagram to send (first byte is the command byte, remainder are the arguments) + /// A list of bytes with parity information + /// + /// We need to send the first byte (the command byte) with a parity of "mark" (=1), all the remaining bytes with a parity of "space" (=0), + /// but since Linux doesn't seem to properly support Mark or Space parity settings (on the raspberry pi, that setting results in no parity bit to be sent) + /// we cheat and count what the parity bit should be and use even or odd to achieve the desired result. + /// internal static List<(byte B, Parity P, int Index)> CalculateParityForEachByte(byte[] data) { bool isCommandByte = true; @@ -81,9 +93,6 @@ private static int BitCount(int b) for (int i = 0; i < data.Length; i++) { byte b = data[i]; - // We need to send the first byte (the command byte) with a parity of "mark", all the remaining bytes with a parity of "space", - // but since Linux doesn't seem to properly support Mark or Space (on the raspberry pi, that setting results in no parity bit to be sent) - // we cheat here and count what the parity bit should be and use even or odd to achieve the desired result. bool isEven = BitCount(b) % 2 == 0; Parity parityToSend; if (isEven) @@ -135,24 +144,50 @@ private void OnNewMessage(SeatalkMessage obj) MessageReceived?.Invoke(obj); } + /// + /// Synchronously send a datagram. This is a low-level function, prefer instead. + /// + /// The datagram public void SendDatagram(byte[] data) { + // First calculate the required parity setting for each byte. var dataWithParity = CalculateParityForEachByte(data); - foreach (var e in dataWithParity) + // Only one thread at a time, please! + lock (_lock) { - // parityToSend = parityToSend == Parity.Odd ? Parity.Even : Parity.Odd; - if (_port.Parity != e.P) + foreach (var e in dataWithParity) { - _port.BaseStream.Flush(); - _port.Parity = e.P; - _port.BaseStream.Flush(); + // The many flushes here appear to be necessary to make sure the parity correctly applies to the next byte we send (and only to the next) + if (_port.Parity != e.P) + { + _port.BaseStream.Flush(); + _port.Parity = e.P; + _port.BaseStream.Flush(); + } + + _port.Write(data, e.Index, 1); } - _port.Write(data, e.Index, 1); + _port.BaseStream.Flush(); + _port.Parity = DefaultParity; } + } + + /// + /// Synchronously send the given message + /// + /// The message to send + /// Transmission of Seatalk messages can be very slow and include considerable delays. Also, there's no guarantee the + /// message is successfully transmitted or received anywhere. + public void SendMessage(SeatalkMessage message) + { + byte[] bytes = message.CreateDatagram(); + SendDatagram(bytes); + } - _port.BaseStream.Flush(); - _port.Parity = DefaultParity; + public Task SendMessageAsync(SeatalkMessage message) + { + return Task.Factory.StartNew(() => SendMessage(message)); } /// diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 06c32c60cc..2d474cfb59 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -41,6 +41,8 @@ public void Run(string[] args) _seatalk.MessageReceived += ParserOnNewMessageDecoded; + var ctrl = _seatalk.GetAutopilotRemoteController(); + while (true) { if (Console.KeyAvailable) @@ -50,47 +52,69 @@ public void Run(string[] args) { break; } - else if (key.Key == ConsoleKey.A) - { - // For testing only - byte[] keyPlus1 = new byte[] - { - 0x86, 0x11, 0x07, 0xf8 - }; - _seatalk.SendDatagram(keyPlus1); - } - else if (key.Key == ConsoleKey.B) + Keystroke ks = new Keystroke(); + switch (key.Key) { - // For testing only - byte[] keyPlus1 = new byte[] + case ConsoleKey.A: + ks = new Keystroke(AutopilotButtons.MinusOne); + break; + case ConsoleKey.D: + ks = new Keystroke(AutopilotButtons.PlusOne); + break; + case ConsoleKey.Q: + ks = new Keystroke(AutopilotButtons.MinusTen); + break; + case ConsoleKey.E: + ks = new Keystroke(AutopilotButtons.PlusTen); + break; + case ConsoleKey.W: { - 0x86, 0x11, 0x05, 0xfa - // 0xFF, 0xFF, - }; - - _seatalk.SendDatagram(keyPlus1); - } - else if (key.Key == ConsoleKey.C) - { - // For testing only - byte[] keyPlus1 = new byte[] + if (ctrl.SetStatus(AutopilotStatus.Auto)) + { + Console.WriteLine("Autopilot set to AUTO mode"); + } + else + { + Console.WriteLine("Setting AUTO mode FAILED!"); + } + + break; + } + + case ConsoleKey.L: { - 0x86, 0x11, 0x08, 0xf7 - }; + ks = new Keystroke(AutopilotButtons.Disp); + break; + } - _seatalk.SendDatagram(keyPlus1); - } - else if (key.Key == ConsoleKey.D) - { - // For testing only - byte[] keyPlus1 = new byte[] + case ConsoleKey.I: { - 0x86, 0x11, 0x06, 0xf9 - // 0xFF, 0xFF, - }; + // This is expected to fail if the AP has no wind data + if (ctrl.SetStatus(AutopilotStatus.Wind)) + { + Console.WriteLine("Autopilot set to WIND mode"); + } + else + { + Console.WriteLine("Setting WIND mode FAILED!"); + } + + break; + } + + case ConsoleKey.S: + if (ctrl.SetStatus(AutopilotStatus.Standby)) + { + Console.WriteLine("Autopilot set to STANDBY mode"); + } + + break; + } - _seatalk.SendDatagram(keyPlus1); + if (ks.ButtonsPressed != AutopilotButtons.None) + { + _seatalk.SendMessage(ks); } } From 4ecbf0ce48d237971e79cde037eeea78f17f0373 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sat, 30 Dec 2023 13:19:33 +0100 Subject: [PATCH 10/31] Deadband mode selection works --- .../Seatalk1/AutoPilotRemoteController.cs | 64 +++++++++++++++---- .../Seatalk1/Messages/DeadbandSetting.cs | 2 +- src/devices/Seatalk1/Messages/Keystroke.cs | 58 ++++++++++++----- .../Seatalk1/samples/Seatalk1.Samples.cs | 13 ++++ 4 files changed, 106 insertions(+), 31 deletions(-) diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index 929046edaf..2c654f8968 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -142,6 +142,53 @@ public bool SetStatus(AutopilotStatus newStatus, TimeSpan timeout) return true; // nothing to do } + AutopilotButtons buttonToPress = newStatus switch + { + AutopilotStatus.Auto => AutopilotButtons.Auto, + AutopilotStatus.Standby => AutopilotButtons.StandBy, + AutopilotStatus.Track => AutopilotButtons.Track, + AutopilotStatus.Wind => AutopilotButtons.Auto | AutopilotButtons.StandBy, + _ => throw new ArgumentException($"Status {newStatus} is not valid", nameof(newStatus)), + }; + + return SendMessageAndVerifyStatus(new Keystroke(buttonToPress, 1), timeout, () => Status == newStatus); + } + + public bool SetDeadbandMode(DeadbandMode mode) + { + if (Status == AutopilotStatus.Offline || Status == AutopilotStatus.Standby) + { + // The Deadband mode can only be set in auto mode + return false; + } + + if (mode != DeadbandMode.Automatic && mode != DeadbandMode.Minimal) + { + throw new ArgumentException("Invalid Deadband mode", nameof(mode)); + } + + if (mode == DeadbandMode) + { + return true; + } + + Keystroke ks; + // If we are in automatic (default) mode, we need to send 0x0a to enter minimal deadband mode, + // but if we already are in minimal deadband mode, we need to send 0x09 to leave. + if (DeadbandMode == DeadbandMode.Automatic) + { + ks = new Keystroke(0x0A); + } + else + { + ks = new Keystroke(0x09); + } + + return SendMessageAndVerifyStatus(ks, DefaultTimeout, () => DeadbandMode == mode); + } + + private bool SendMessageAndVerifyStatus(SeatalkMessage message, TimeSpan timeout, Func successCondition) + { if (timeout > MaximumTimeout) { throw new ArgumentOutOfRangeException(nameof(timeout), $"The maximum timeout is {MaximumTimeout}, see remarks in documentation"); @@ -154,28 +201,19 @@ public bool SetStatus(AutopilotStatus newStatus, TimeSpan timeout) // If a button on the AP was pressed, abort immediately, as that one must always have precedence. if (_buttonOnApPressed) { - return false; + return successCondition(); } - if (Status == newStatus) + if (successCondition()) { return true; } - AutopilotButtons buttonToPress = newStatus switch - { - AutopilotStatus.Auto => AutopilotButtons.Auto, - AutopilotStatus.Standby => AutopilotButtons.StandBy, - AutopilotStatus.Track => AutopilotButtons.Track, - AutopilotStatus.Wind => AutopilotButtons.Auto | AutopilotButtons.StandBy, - _ => throw new ArgumentException($"Status {newStatus} is not valid", nameof(newStatus)), - }; - - _parentInterface.SendMessage(new Keystroke(buttonToPress, 1)); + _parentInterface.SendMessage(message); Thread.Sleep(137); // Some random number } - return false; + return successCondition(); } internal void UpdateStatus() diff --git a/src/devices/Seatalk1/Messages/DeadbandSetting.cs b/src/devices/Seatalk1/Messages/DeadbandSetting.cs index a7cc8c2a47..428d2ddb7e 100644 --- a/src/devices/Seatalk1/Messages/DeadbandSetting.cs +++ b/src/devices/Seatalk1/Messages/DeadbandSetting.cs @@ -37,7 +37,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) public override byte[] CreateDatagram() { - throw new NotImplementedException(); + throw new NotSupportedException("Send the respective keycodes instead (0x09 or 0x0a)"); } public override bool MatchesMessageType(IReadOnlyList data) diff --git a/src/devices/Seatalk1/Messages/Keystroke.cs b/src/devices/Seatalk1/Messages/Keystroke.cs index 55928d9699..123dfac24c 100644 --- a/src/devices/Seatalk1/Messages/Keystroke.cs +++ b/src/devices/Seatalk1/Messages/Keystroke.cs @@ -20,6 +20,7 @@ static Keystroke() { s_codeToButtonMap = new Dictionary() { + { 0x00, AutopilotButtons.None }, { 0x01, AutopilotButtons.Auto }, { 0x02, AutopilotButtons.StandBy }, { 0x03, AutopilotButtons.MinusTen | AutopilotButtons.PlusTen }, @@ -54,14 +55,28 @@ static Keystroke() public Keystroke() { - ButtonsPressed = AutopilotButtons.None; + KeyCode = 0; Source = 0; } public Keystroke(AutopilotButtons buttonsToPress, int source = 1) { - ButtonsPressed = buttonsToPress; Source = source; + + if (s_buttonToCodeMap.TryGetValue(buttonsToPress, out int code)) + { + KeyCode = code; + } + else + { + throw new ArgumentException($"The button combination {buttonsToPress} is not a valid button combination"); + } + } + + public Keystroke(byte keyCode, int source = 1) + { + Source = source; + KeyCode = keyCode; } /// @@ -85,6 +100,14 @@ public int Source } public AutopilotButtons ButtonsPressed + { + get + { + return GetButtons(KeyCode); + } + } + + public int KeyCode { get; init; @@ -103,29 +126,23 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) int source = data[1] >> 4; - AutopilotButtons buttons = GetButtons(data[2]); + // Just as a verification step + GetButtons(data[2]); return new Keystroke() { - ButtonsPressed = buttons, Source = source, + Source = source, KeyCode = data[2] }; } public override byte[] CreateDatagram() { - byte keyCode = 0; - if (s_buttonToCodeMap.TryGetValue(ButtonsPressed, out int code)) + byte inverseCode = (byte)~KeyCode; + int attributeByte = ExpectedLength - 3 | (Source << 4); + return new byte[] { - keyCode = (byte)code; - byte inverseCode = (byte)~keyCode; - int attributeByte = ExpectedLength - 3 | (Source << 4); - return new byte[] - { - CommandByte, (byte)attributeByte, keyCode, inverseCode - }; - } - - throw new ArgumentException($"The button combination {ButtonsPressed} is not a valid button combination"); + CommandByte, (byte)attributeByte, (byte)KeyCode, inverseCode + }; } private AutopilotButtons GetButtons(int keyCode) @@ -135,7 +152,7 @@ private AutopilotButtons GetButtons(int keyCode) return result; } - Logger.LogWarning($"Unknown keycode {keyCode} in command"); + Logger.LogWarning($"Unknown keycode 0x{keyCode:X2} in command"); return AutopilotButtons.None; } @@ -156,5 +173,12 @@ public override bool MatchesMessageType(IReadOnlyList data) return base.MatchesMessageType(data); } + + protected override bool PrintMembers(StringBuilder stringBuilder) + { + base.PrintMembers(stringBuilder); + stringBuilder.Append($", Source = {Source}, KeyCode = 0x{KeyCode:X2}, Buttons = {GetButtons(KeyCode)}"); + return true; + } } } diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 2d474cfb59..769d9a2409 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -84,10 +84,23 @@ public void Run(string[] args) case ConsoleKey.L: { + // Doesn't seem to do anything on the ST2000+, even though it is documented that remote-controlling the display backlight should work ks = new Keystroke(AutopilotButtons.Disp); break; } + case ConsoleKey.K: + if (ctrl.DeadbandMode == DeadbandMode.Automatic) + { + ctrl.SetDeadbandMode(DeadbandMode.Minimal); + } + else + { + ctrl.SetDeadbandMode(DeadbandMode.Automatic); + } + + break; + case ConsoleKey.I: { // This is expected to fail if the AP has no wind data From 68f2d9efab7944c29367b6f29a0f383577b7e721 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sat, 30 Dec 2023 21:09:48 +0100 Subject: [PATCH 11/31] Lots of unit testing --- .../Seatalk1/AutoPilotRemoteController.cs | 119 +++++++++++++++ .../Seatalk1/Messages/SeatalkMessage.cs | 17 +++ src/devices/Seatalk1/SeatalkInterface.cs | 40 +++-- .../Seatalk1/samples/Seatalk1.Samples.cs | 22 ++- .../tests/AutoPilotRemoteControllerTests.cs | 143 ++++++++++++++++++ src/devices/Seatalk1/tests/MessageTests.cs | 20 +++ 6 files changed, 349 insertions(+), 12 deletions(-) create mode 100644 src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index 2c654f8968..d42dd6a162 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Iot.Device.Common; using Iot.Device.Seatalk1.Messages; using UnitsNet; @@ -21,6 +22,7 @@ namespace Iot.Device.Seatalk1 /// public class AutoPilotRemoteController { + private const double AngleEpsilon = 1.1; // The protocol can only give angles in whole degrees private static readonly TimeSpan MaximumTimeout = TimeSpan.FromSeconds(6); private readonly SeatalkInterface _parentInterface; private readonly object _lock = new object(); @@ -54,6 +56,8 @@ internal AutoPilotRemoteController(SeatalkInterface parentInterface) public TimeSpan DefaultTimeout { get; set; } + public bool IsOperating => Status is AutopilotStatus.Auto or AutopilotStatus.Track or AutopilotStatus.Wind; + public event Action? AutopilotKeysPressed; private void AutopilotMessageInterpretation(SeatalkMessage obj) @@ -187,6 +191,121 @@ public bool SetDeadbandMode(DeadbandMode mode) return SendMessageAndVerifyStatus(ks, DefaultTimeout, () => DeadbandMode == mode); } + public bool TurnTo(Angle degrees, TurnDirection? direction) + { + return TurnTo(degrees, direction, CancellationToken.None); + } + + public Task TurnToAsync(Angle degrees, TurnDirection? direction, CancellationToken token) + { + return Task.Factory.StartNew(() => TurnTo(degrees, direction, token)); + } + + public Task TurnByAsync(Angle degrees, TurnDirection direction, CancellationToken token) + { + return Task.Factory.StartNew(() => TurnBy(degrees, direction, token)); + } + + public bool TurnTo(Angle degrees, TurnDirection? direction, CancellationToken token) + { + degrees = degrees.Normalize(true); + + var currentHeading1 = AutopilotDesiredHeading; + if (!IsOperating || !currentHeading1.HasValue) + { + return false; + } + + var currentDesiredHeading = currentHeading1.Value; + + if (!direction.HasValue) + { + Angle diff = AngleExtensions.Difference(currentDesiredHeading, degrees); + if (diff < Angle.Zero) + { + direction = TurnDirection.Starboard; + } + else + { + direction = TurnDirection.Port; + } + } + + while (!AnglesAreClose(currentDesiredHeading, degrees)) + { + // Should also work if diff is small, but we intend to go the other way (make a full 360) + Angle diff = AngleExtensions.Difference(currentDesiredHeading, degrees); + if (diff.Abs() > Angle.FromDegrees(10)) + { + SendMessage(new Keystroke(direction == TurnDirection.Starboard ? AutopilotButtons.PlusTen : AutopilotButtons.PlusOne)); + } + else + { + SendMessage(new Keystroke(direction == TurnDirection.Starboard ? AutopilotButtons.PlusOne : AutopilotButtons.MinusOne)); + } + + token.WaitHandle.WaitOne(TimeSpan.FromSeconds(2)); + + if (token.IsCancellationRequested || !IsOperating) + { + break; + } + + currentHeading1 = AutopilotDesiredHeading; + if (currentHeading1.HasValue == false) + { + break; + } + + currentDesiredHeading = currentHeading1.Value; + } + + return currentHeading1.HasValue && AnglesAreClose(currentHeading1.Value, degrees); + } + + private bool AnglesAreClose(Angle angle1, Angle angle2) + { + if (angle1.Equals(angle2, Angle.FromDegrees(AngleEpsilon))) + { + return true; + } + + if (angle1 >= Angle.FromDegrees(359) && angle2 <= Angle.FromDegrees(1)) + { + return true; + } + + if (angle2 >= Angle.FromDegrees(359) && angle1 <= Angle.FromDegrees(1)) + { + return true; + } + + return false; + } + + public bool TurnBy(Angle degrees, TurnDirection direction, CancellationToken token) + { + if (degrees < Angle.Zero) + { + throw new ArgumentOutOfRangeException(nameof(degrees), "Turn amount must be positive. User the direction argument instead of a sign"); + } + + var currentHeading1 = AutopilotDesiredHeading; + if (!IsOperating || !currentHeading1.HasValue) + { + return false; + } + + Angle target = direction == TurnDirection.Starboard ? currentHeading1.Value + degrees : currentHeading1.Value - degrees; + target = target.Normalize(true); + return TurnTo(target, direction, token); + } + + private bool SendMessage(SeatalkMessage message) + { + return _parentInterface.SendMessage(message); + } + private bool SendMessageAndVerifyStatus(SeatalkMessage message, TimeSpan timeout, Func successCondition) { if (timeout > MaximumTimeout) diff --git a/src/devices/Seatalk1/Messages/SeatalkMessage.cs b/src/devices/Seatalk1/Messages/SeatalkMessage.cs index e2a6d3e027..f63fd68789 100644 --- a/src/devices/Seatalk1/Messages/SeatalkMessage.cs +++ b/src/devices/Seatalk1/Messages/SeatalkMessage.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using Iot.Device.Common; @@ -37,6 +38,7 @@ public abstract byte ExpectedLength get; } + [IgnoreDataMember] protected ILogger Logger { get; } /// @@ -96,6 +98,21 @@ protected virtual void VerifyPacket(IReadOnlyList data) } } + public virtual bool Equals(SeatalkMessage? other) + { + if (other == null) + { + return false; + } + + return ExpectedLength == other.ExpectedLength && CommandByte == other.CommandByte; + } + + public override int GetHashCode() + { + return CommandByte << 8 | ExpectedLength; + } + /// /// Checks whether the data could be a packet of the current type. Unlike the above, this does not throw exceptions, but only returns true or false. /// diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index 1fe42b234d..23a0582b64 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -37,13 +37,13 @@ public class SeatalkInterface : IDisposable /// set it up in a special way and change the communication parameters during operation. /// public SeatalkInterface(string uart) + : this() { if (uart == null) { throw new ArgumentNullException(nameof(uart)); } - _lock = new object(); _port = new SerialPort(uart); _port.BaudRate = 4800; _port.Parity = DefaultParity; // Can be anything but none, but "Mark" or "Space" won't have the desired effect on linux, causing garbage to be sent @@ -55,11 +55,20 @@ public SeatalkInterface(string uart) _parser.NewMessageDecoded += OnNewMessage; _parser.StartDecode(); - _autopilotController = new AutoPilotRemoteController(this); + _watchDog.Start(); + } + /// + /// This constructor is for mocking only! + /// + protected SeatalkInterface() + { + _lock = new object(); + _port = null!; + _parser = null!; + _autopilotController = new AutoPilotRemoteController(this); _cancellation = new CancellationTokenSource(); - _watchDog = new Thread(WatchDog); - _watchDog.Start(); + _watchDog = new Thread(WatchDogStarter); } public Seatalk1Parser Parser => _parser; @@ -130,16 +139,21 @@ private static int BitCount(int b) /// /// Periodic watchdog tasks /// - private void WatchDog() + private void WatchDogStarter() { while (!_cancellation.IsCancellationRequested) { + WatchDog(); Thread.Sleep(1000); - _autopilotController.UpdateStatus(); } } - private void OnNewMessage(SeatalkMessage obj) + protected virtual void WatchDog() + { + _autopilotController.UpdateStatus(); + } + + internal void OnNewMessage(SeatalkMessage obj) { MessageReceived?.Invoke(obj); } @@ -148,7 +162,11 @@ private void OnNewMessage(SeatalkMessage obj) /// Synchronously send a datagram. This is a low-level function, prefer instead. /// /// The datagram - public void SendDatagram(byte[] data) + /// + /// True on success, false otherwise. May fail e.g. if the bus is busy all the time. + /// Todo: This doesn't do any checks for collisions just yet. + /// + public virtual bool SendDatagram(byte[] data) { // First calculate the required parity setting for each byte. var dataWithParity = CalculateParityForEachByte(data); @@ -171,6 +189,8 @@ public void SendDatagram(byte[] data) _port.BaseStream.Flush(); _port.Parity = DefaultParity; } + + return true; } /// @@ -179,10 +199,10 @@ public void SendDatagram(byte[] data) /// The message to send /// Transmission of Seatalk messages can be very slow and include considerable delays. Also, there's no guarantee the /// message is successfully transmitted or received anywhere. - public void SendMessage(SeatalkMessage message) + public virtual bool SendMessage(SeatalkMessage message) { byte[] bytes = message.CreateDatagram(); - SendDatagram(bytes); + return SendDatagram(bytes); } public Task SendMessageAsync(SeatalkMessage message) diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 769d9a2409..dabd65ede9 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -7,10 +7,12 @@ using System.Device.Spi; using System.Threading; using System.IO.Ports; +using System.Threading.Tasks; using Iot.Device.Common; using Iot.Device.Seatalk1; using Iot.Device.Seatalk1.Messages; using Microsoft.Extensions.Logging; +using UnitsNet; namespace Seatalk1Sample { @@ -33,7 +35,7 @@ internal static int Main(string[] args) return 0; } - public void Run(string[] args) + public async void Run(string[] args) { LogDispatcher.LoggerFactory = new SimpleConsoleLoggerFactory(LogLevel.Trace); @@ -43,6 +45,8 @@ public void Run(string[] args) var ctrl = _seatalk.GetAutopilotRemoteController(); + WriteCurrentState(); + while (true) { if (Console.KeyAvailable) @@ -89,6 +93,20 @@ public void Run(string[] args) break; } + case ConsoleKey.U: + { + await ctrl.TurnByAsync(Angle.FromDegrees(90), TurnDirection.Starboard, CancellationToken.None); + + break; + } + + case ConsoleKey.Z: + { + await ctrl.TurnByAsync(Angle.FromDegrees(-90), TurnDirection.Port, CancellationToken.None); + + break; + } + case ConsoleKey.K: if (ctrl.DeadbandMode == DeadbandMode.Automatic) { @@ -131,7 +149,7 @@ public void Run(string[] args) } } - Thread.Sleep(500); + await Task.Delay(500); WriteCurrentState(); } diff --git a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs new file mode 100644 index 0000000000..1a54a348bd --- /dev/null +++ b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs @@ -0,0 +1,143 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Iot.Device.Seatalk1; +using Iot.Device.Seatalk1.Messages; +using Moq; +using UnitsNet; +using Xunit; + +namespace Iot.Device.Tests.Seatalk1 +{ + public sealed class AutoPilotRemoteControllerTests + { + private readonly Mock _interface; + private readonly AutoPilotRemoteController _testee; + private readonly CancellationTokenSource _tokenSource; + + public AutoPilotRemoteControllerTests() + { + _interface = new Mock(MockBehavior.Strict); + _testee = new AutoPilotRemoteController(_interface.Object); + _tokenSource = new CancellationTokenSource(); + } + + [Fact] + public void StartupWasSuccessful() + { + Assert.Equal(AutopilotStatus.Offline, _testee.Status); + Assert.Null(_testee.AutopilotDesiredHeading); + Assert.Null(_testee.AutopilotHeading); + Assert.Equal(AutopilotAlarms.None, _testee.Alarms); + Assert.False(_testee.RudderAngleAvailable); + } + + [Fact] + public void MakeReady() + { + var msg = new CompassHeadingAutopilotCourse() + { + AutopilotStatus = AutopilotStatus.Standby, AutoPilotCourse = Angle.FromDegrees(100), CompassHeading = Angle.FromDegrees(95) + }; + + _interface.Object.OnNewMessage(msg); + Assert.Equal(AutopilotStatus.Standby, _testee.Status); + Assert.Null(_testee.AutopilotDesiredHeading); + Assert.Equal(Angle.FromDegrees(95), _testee.AutopilotHeading); + Assert.Equal(AutopilotAlarms.None, _testee.Alarms); + Assert.False(_testee.RudderAngleAvailable); + } + + [Fact] + public void SetToAuto() + { + var msg = new CompassHeadingAutopilotCourse() + { + AutopilotStatus = AutopilotStatus.Auto, + AutoPilotCourse = Angle.FromDegrees(100), + CompassHeading = Angle.FromDegrees(95), + Alarms = AutopilotAlarms.OffCourse, + AutoPilotType = 2, + RudderPosition = Angle.FromDegrees(-10) + }; + + _interface.Object.OnNewMessage(msg); + Assert.Equal(AutopilotStatus.Auto, _testee.Status); + Assert.Equal(Angle.FromDegrees(100), _testee.AutopilotDesiredHeading); + Assert.Equal(Angle.FromDegrees(95), _testee.AutopilotHeading); + Assert.Equal(AutopilotAlarms.OffCourse, _testee.Alarms); + Assert.True(_testee.RudderAngleAvailable); + Assert.Equal(Angle.FromDegrees(-10), _testee.RudderAngle); + } + + [Fact] + public void AnglesOnly() + { + var msg = new CompassHeadingAndRudderPosition() + { + CompassHeading = Angle.FromDegrees(90), + RudderPosition = Angle.Zero, + }; + + _interface.Object.OnNewMessage(msg); + Assert.Null(_testee.AutopilotDesiredHeading); + Assert.Equal(Angle.FromDegrees(90), _testee.AutopilotHeading); + Assert.Equal(AutopilotAlarms.None, _testee.Alarms); + Assert.False(_testee.RudderAngleAvailable); + } + + [Fact] + public void TurnToStarboard() + { + // Ap is in auto mode + var msg = new CompassHeadingAutopilotCourse() + { + AutopilotStatus = AutopilotStatus.Auto, + AutoPilotCourse = Angle.FromDegrees(10), + CompassHeading = Angle.FromDegrees(9), + }; + + _interface.Object.OnNewMessage(msg); + + Keystroke ks = new Keystroke(AutopilotButtons.PlusTen, 1); + _interface.Setup(x => x.SendMessage(It.IsAny())).Callback(i => + { + Assert.True(ks.Equals(i)); + }).Returns(true); + _tokenSource.Cancel(); // Cancellation is only tested after the first command was sent + Assert.False(_testee.TurnBy(Angle.FromDegrees(90), TurnDirection.Starboard, _tokenSource.Token)); + + _interface.Verify(x => x.SendMessage(ks)); + } + + [Fact] + public void TurnToPort() + { + // Ap is in auto mode + var msg = new CompassHeadingAutopilotCourse() + { + AutopilotStatus = AutopilotStatus.Auto, + AutoPilotCourse = Angle.FromDegrees(10), + CompassHeading = Angle.FromDegrees(9), + }; + + _interface.Object.OnNewMessage(msg); + + Keystroke ks = new Keystroke(AutopilotButtons.MinusTen, 1); + _interface.Setup(x => x.SendMessage(It.IsAny())).Callback(i => + { + Assert.Equal(ks, i); + }).Returns(true); + _tokenSource.Cancel(); // Cancellation is only tested after the first command was sent + Assert.False(_testee.TurnBy(Angle.FromDegrees(90), TurnDirection.Port, _tokenSource.Token)); + + _interface.Verify(x => x.SendMessage(ks)); + } + } +} diff --git a/src/devices/Seatalk1/tests/MessageTests.cs b/src/devices/Seatalk1/tests/MessageTests.cs index df85a634d7..df9145dc18 100644 --- a/src/devices/Seatalk1/tests/MessageTests.cs +++ b/src/devices/Seatalk1/tests/MessageTests.cs @@ -56,5 +56,25 @@ public void WithKeywordCreatesCopy() Assert.NotEqual(obj, copy); } + + [Fact] + public void EqualKeysAreEqual() + { + Keystroke ks1 = new Keystroke(AutopilotButtons.PlusTen, 1); + Keystroke ks2 = new Keystroke(AutopilotButtons.PlusTen, 1); + Assert.Equal(ks1, ks2); + Assert.True(ks1.Equals(ks2)); + Assert.Equal(ks1.GetHashCode(), ks2.GetHashCode()); + } + + [Fact] + public void UnEqualKeysAreNotEqual() + { + Keystroke ks1 = new Keystroke(AutopilotButtons.PlusTen, 1); + Keystroke ks2 = new Keystroke(AutopilotButtons.MinusTen, 1); + Assert.NotEqual(ks1, ks2); + Assert.False(ks1.Equals(ks2)); + Assert.NotEqual(ks1.GetHashCode(), ks2.GetHashCode()); + } } } From 1d84b44e40006ebbbb3520809db6132bd118f911 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 31 Dec 2023 11:49:30 +0100 Subject: [PATCH 12/31] Testing and bugfixing --- .../Seatalk1/AutoPilotRemoteController.cs | 2 +- .../tests/AutoPilotRemoteControllerTests.cs | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index d42dd6a162..5b69726ce0 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -237,7 +237,7 @@ public bool TurnTo(Angle degrees, TurnDirection? direction, CancellationToken to Angle diff = AngleExtensions.Difference(currentDesiredHeading, degrees); if (diff.Abs() > Angle.FromDegrees(10)) { - SendMessage(new Keystroke(direction == TurnDirection.Starboard ? AutopilotButtons.PlusTen : AutopilotButtons.PlusOne)); + SendMessage(new Keystroke(direction == TurnDirection.Starboard ? AutopilotButtons.PlusTen : AutopilotButtons.MinusTen)); } else { diff --git a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs index 1a54a348bd..985daed493 100644 --- a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs +++ b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs @@ -139,5 +139,58 @@ public void TurnToPort() _interface.Verify(x => x.SendMessage(ks)); } + + [Fact] + public void TurnToPortFullSequence() + { + // Ap is in auto mode + var msg = new CompassHeadingAutopilotCourse() + { + AutopilotStatus = AutopilotStatus.Auto, + AutoPilotCourse = Angle.FromDegrees(10), + CompassHeading = Angle.FromDegrees(9), + }; + + _interface.Object.OnNewMessage(msg); + + int indexOfCommand = 0; + _interface.Setup(x => x.SendMessage(It.IsAny())).Callback(i => + { + var ks = (Keystroke)i; + if (indexOfCommand == 0) + { + Assert.True(ks.ButtonsPressed == AutopilotButtons.MinusTen); + msg = msg with + { + AutoPilotCourse = Angle.Zero + }; + } + else if (indexOfCommand == 1) + { + Assert.True(ks.ButtonsPressed == AutopilotButtons.MinusOne); + msg = msg with + { + AutoPilotCourse = Angle.FromDegrees(359) + }; + } + else if (indexOfCommand == 2) + { + Assert.True(ks.ButtonsPressed == AutopilotButtons.MinusOne); + msg = msg with + { + AutoPilotCourse = Angle.FromDegrees(358) + }; + } + else + { + Assert.Fail("More commands sent than necessary"); + } + + _interface.Object.OnNewMessage(msg); + indexOfCommand++; + }).Returns(true); + + Assert.True(_testee.TurnBy(Angle.FromDegrees(12), TurnDirection.Port, _tokenSource.Token)); + } } } From 65badd93d47444730fb41d4e48a7178d965e16da Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 31 Dec 2023 17:46:48 +0100 Subject: [PATCH 13/31] Some new messages added --- .../Seatalk1/AutoPilotRemoteController.cs | 103 +++++++++++++++- .../Messages/AutopilotCalibrationParameter.cs | 41 +++++++ .../AutopilotCalibrationParameterMessage.cs | 61 ++++++++++ .../Seatalk1/Messages/AutopilotStatus.cs | 2 +- .../Messages/CompassHeadingAutopilotCourse.cs | 33 ++++-- .../Messages/DisplayBacklightLevel.cs | 19 +++ src/devices/Seatalk1/Messages/Keystroke.cs | 7 +- .../Seatalk1/Messages/SetLampIntensity.cs | 69 +++++++++++ src/devices/Seatalk1/Seatalk1.csproj | 4 + src/devices/Seatalk1/Seatalk1Parser.cs | 2 + src/devices/Seatalk1/SeatalkInterface.cs | 13 +- .../Seatalk1/samples/Seatalk1.Samples.cs | 21 ++-- .../tests/AutoPilotRemoteControllerTests.cs | 112 +++++++++++++++++- src/devices/Seatalk1/tests/MessageTests.cs | 1 + src/devices/Seatalk1/tests/Seatalk1Tests.cs | 21 +++- 15 files changed, 485 insertions(+), 24 deletions(-) create mode 100644 src/devices/Seatalk1/Messages/AutopilotCalibrationParameter.cs create mode 100644 src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs create mode 100644 src/devices/Seatalk1/Messages/DisplayBacklightLevel.cs create mode 100644 src/devices/Seatalk1/Messages/SetLampIntensity.cs diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index 5b69726ce0..f94e033bd3 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -10,6 +11,7 @@ using System.Threading.Tasks; using Iot.Device.Common; using Iot.Device.Seatalk1.Messages; +using Microsoft.Extensions.Logging; using UnitsNet; namespace Iot.Device.Seatalk1 @@ -20,17 +22,22 @@ namespace Iot.Device.Seatalk1 /// /// Type is not disposable, to prevent accidental disposal by clients. They don't get ownership of the instance. /// - public class AutoPilotRemoteController + public class AutoPilotRemoteController : MarshalByRefObject { private const double AngleEpsilon = 1.1; // The protocol can only give angles in whole degrees private static readonly TimeSpan MaximumTimeout = TimeSpan.FromSeconds(6); private readonly SeatalkInterface _parentInterface; private readonly object _lock = new object(); + private readonly ILogger _logger; + private ConcurrentDictionary _calibrationParameters; + private DateTime _lastUpdateTime = new DateTime(0); private bool _buttonOnApPressed = false; internal AutoPilotRemoteController(SeatalkInterface parentInterface) { + _logger = this.GetCurrentClassLogger(); + _calibrationParameters = new(); _parentInterface = parentInterface ?? throw new ArgumentNullException(nameof(parentInterface)); _parentInterface.MessageReceived += AutopilotMessageInterpretation; RudderAngleAvailable = false; @@ -116,6 +123,11 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) AutopilotKeysPressed?.Invoke(keystroke); } + else if (obj is AutopilotCalibrationParameterMessage calibParam) + { + _logger.LogInformation($"Received calibration value for {calibParam.Parameter}. Current {calibParam.CurrentSetting} Min {calibParam.MinValue} Max {calibParam.MaxValue}"); + _calibrationParameters.AddOrUpdate(calibParam.Parameter, x => calibParam, (a, b) => calibParam); + } if (Status == AutopilotStatus.Standby || Status == AutopilotStatus.Offline) { @@ -129,6 +141,16 @@ public bool SetStatus(AutopilotStatus status) return SetStatus(status, DefaultTimeout); } + /// + /// Returns the currently known parameter values. + /// Note: The values can currently only be read out by manually entering the calibration mode once. + /// + /// A list of parameter values + public List GetCalibrationParameters() + { + return _calibrationParameters.Values.ToList(); + } + /// /// Attempts to set the Autopilot to the given state. /// @@ -231,6 +253,8 @@ public bool TurnTo(Angle degrees, TurnDirection? direction, CancellationToken to } } + _logger.LogInformation($"New desired heading: {degrees}"); + while (!AnglesAreClose(currentDesiredHeading, degrees)) { // Should also work if diff is small, but we intend to go the other way (make a full 360) @@ -246,8 +270,15 @@ public bool TurnTo(Angle degrees, TurnDirection? direction, CancellationToken to token.WaitHandle.WaitOne(TimeSpan.FromSeconds(2)); - if (token.IsCancellationRequested || !IsOperating) + if (token.IsCancellationRequested) + { + _logger.LogWarning("Turning cancelled because operation was externally aborted"); + break; + } + + if (!IsOperating) { + _logger.LogWarning($"Turning cancelled because Autopilot is no longer in the correct state. Current State {Status}"); break; } @@ -260,10 +291,20 @@ public bool TurnTo(Angle degrees, TurnDirection? direction, CancellationToken to currentDesiredHeading = currentHeading1.Value; } - return currentHeading1.HasValue && AnglesAreClose(currentHeading1.Value, degrees); + bool ret = currentHeading1.HasValue && AnglesAreClose(currentHeading1.Value, degrees); + if (ret) + { + _logger.LogInformation($"Reached new desired course {currentHeading1.GetValueOrDefault()}"); + } + else + { + _logger.LogWarning($"TurnTo terminated prematurely, desired new heading not reached"); + } + + return ret; } - private bool AnglesAreClose(Angle angle1, Angle angle2) + internal bool AnglesAreClose(Angle angle1, Angle angle2) { if (angle1.Equals(angle2, Angle.FromDegrees(AngleEpsilon))) { @@ -347,10 +388,64 @@ internal void UpdateStatus() RudderAngle = null; AutopilotDesiredHeading = null; AutopilotHeading = null; + _logger.LogWarning("Autopilot connection timed out. Assuming it's offline"); } } } + /* Unfortunately, the exact sequence to remotely enter calibration mode appears to be different for each type of remote control and autopilot + I have not found out how it works for the ST2000+. I also have not found out how to read out parameter values without entering calibration mode + public bool ReadCalibrationValues() + { + if (Status != AutopilotStatus.Standby) + { + return false; + } + + _calibrationParameters.Clear(); + + Keystroke ks; + + Thread.Sleep(100); + ks = new Keystroke(0x42); + SendMessage(ks); + Thread.Sleep(200); + ks = new Keystroke(0x68); + SendMessage(ks); + Thread.Sleep(500); + ks = new Keystroke(0x84); + SendMessage(ks); + Thread.Sleep(500); + + ks = new Keystroke(0x04); + SendMessage(ks); + + ks = new Keystroke(AutopilotButtons.MinusOne | AutopilotButtons.PlusOne); + SendMessage(ks); + + Stopwatch sw = Stopwatch.StartNew(); + int currentEntries = _calibrationParameters.Count; + while (sw.ElapsedMilliseconds < 3500) + { + ks = new Keystroke(AutopilotButtons.Auto); + SendMessage(ks); + _parentInterface.SendDatagram(new byte[] + { + 0x92, 1, 1 + }); + Thread.Sleep(1500); + if (currentEntries != _calibrationParameters.Count) + { + currentEntries = _calibrationParameters.Count; + sw.Restart(); + } + } + + ks = new Keystroke(AutopilotButtons.StandBy); + SendMessage(ks); + return true; + }*/ + /// /// Returns a textual representation of the current AP status /// diff --git a/src/devices/Seatalk1/Messages/AutopilotCalibrationParameter.cs b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameter.cs new file mode 100644 index 0000000000..e95dd3fed5 --- /dev/null +++ b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameter.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + public enum AutopilotCalibrationParameter + { + None = 0, + RudderGain = 1, + CounterRudder = 2, + RudderLimit = 3, + TurnRateLimit = 4, + Speed = 5, + OffCourseLimit = 6, + AutoTrim = 7, + PowerSteer = 9, + DriveType = 0xa, + RudderDamping = 0xb, + Variation = 0xc, + AutoAdapt = 0xd, + AutoAdaptLatitude = 0xe, + AutoRelease = 0xf, + RudderAlignment = 0x10, + WindTrim = 0x11, + Response = 0x12, + BoatType = 0x13, + CalLock = 0x15, + AutoTackAngle = 0x1d, + + /// + /// This value is sent (with current=min=max=0, while calibration mode is being entered) + /// + EnteringCalibration = 0x50, + } +} diff --git a/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs new file mode 100644 index 0000000000..e46cc80628 --- /dev/null +++ b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs @@ -0,0 +1,61 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + public record AutopilotCalibrationParameterMessage : SeatalkMessage + { + public override byte CommandByte => 0x88; + public override byte ExpectedLength => 0x06; + + public AutopilotCalibrationParameter Parameter + { + get; + init; + } + + public int CurrentSetting + { + get; + init; + } + + public int MinValue + { + get; + init; + } + + public int MaxValue + { + get; + init; + } + + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) + { + int param = data[2]; + int value = Convert.ToInt32(data[3]); + int max = Convert.ToInt32(data[4]); + int min = Convert.ToInt32(data[5]); + return new AutopilotCalibrationParameterMessage() + { + Parameter = (AutopilotCalibrationParameter)param, + CurrentSetting = value, + MinValue = min, + MaxValue = max, + }; + } + + public override byte[] CreateDatagram() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/devices/Seatalk1/Messages/AutopilotStatus.cs b/src/devices/Seatalk1/Messages/AutopilotStatus.cs index 19be082fc6..4957d5d2bd 100644 --- a/src/devices/Seatalk1/Messages/AutopilotStatus.cs +++ b/src/devices/Seatalk1/Messages/AutopilotStatus.cs @@ -19,7 +19,7 @@ public enum AutopilotStatus Auto, Track, Wind, - Display, + Calibration, Undefined, } } diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index ad144de998..c95a3cf7bd 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using UnitsNet; namespace Iot.Device.Seatalk1.Messages @@ -41,6 +42,11 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) AutopilotStatus status = GetAutopilotStatus(data[4]); + if (status == AutopilotStatus.Undefined) + { + Logger.LogWarning($"Unknown autopilot status byte {data[4]}"); + } + sbyte rudder = (sbyte)data[6]; AutopilotAlarms alarms = AutopilotAlarms.None; @@ -73,14 +79,27 @@ public override byte[] CreateDatagram() private AutopilotStatus GetAutopilotStatus(byte z) { - return (z & 0xf) switch + switch (z) { - 0 => AutopilotStatus.Standby, - 2 => AutopilotStatus.Auto, - 4 => AutopilotStatus.Wind, - 8 => AutopilotStatus.Track, - _ => AutopilotStatus.Undefined, - }; + case 0: + return AutopilotStatus.Standby; + case 2: + return AutopilotStatus.Auto; + case 4: + return AutopilotStatus.Wind; + case 8: + return AutopilotStatus.Track; + case 0x10: + return AutopilotStatus.Calibration; + default: + return AutopilotStatus.Undefined; + } + } + + public override bool MatchesMessageType(IReadOnlyList data) + { + // Add some additional tests to make sure the message is not messed up + return base.MatchesMessageType(data) && GetAutopilotStatus(data[4]) != AutopilotStatus.Undefined && (data[5] & 0xF0) == 0 && (data[8] & 0xF0) == 0; } } } diff --git a/src/devices/Seatalk1/Messages/DisplayBacklightLevel.cs b/src/devices/Seatalk1/Messages/DisplayBacklightLevel.cs new file mode 100644 index 0000000000..e97b4443f0 --- /dev/null +++ b/src/devices/Seatalk1/Messages/DisplayBacklightLevel.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + public enum DisplayBacklightLevel + { + Off = 0, + Level1 = 4, + Level2 = 8, + Level3 = 0xC, + } +} diff --git a/src/devices/Seatalk1/Messages/Keystroke.cs b/src/devices/Seatalk1/Messages/Keystroke.cs index 123dfac24c..d02439fbe2 100644 --- a/src/devices/Seatalk1/Messages/Keystroke.cs +++ b/src/devices/Seatalk1/Messages/Keystroke.cs @@ -42,7 +42,12 @@ static Keystroke() { 0x30, AutopilotButtons.MinusOne | AutopilotButtons.PlusTen }, { 0x31, AutopilotButtons.MinusTen | AutopilotButtons.PlusOne }, { 0x41, AutopilotButtons.Auto | AutopilotButtons.LongPress }, - { 0x63, AutopilotButtons.Auto | AutopilotButtons.LongPress | AutopilotButtons.StandBy } + { 0x42, AutopilotButtons.StandBy | AutopilotButtons.LongPress }, + { 0x63, AutopilotButtons.Auto | AutopilotButtons.LongPress | AutopilotButtons.StandBy }, + + // This one can mean: Return to previous track, but is also sent when Standby is pressed for more than 5 seconds (entering calibration) + // In the later case, it comes after 0x42 + { 0x68, AutopilotButtons.PlusTen | AutopilotButtons.MinusTen | AutopilotButtons.LongPress }, }; s_buttonToCodeMap = new Dictionary(); diff --git a/src/devices/Seatalk1/Messages/SetLampIntensity.cs b/src/devices/Seatalk1/Messages/SetLampIntensity.cs new file mode 100644 index 0000000000..24f317f336 --- /dev/null +++ b/src/devices/Seatalk1/Messages/SetLampIntensity.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + public record SetLampIntensity : SeatalkMessage + { + private readonly DisplayBacklightLevel _intensity; + + public SetLampIntensity() + { + Intensity = DisplayBacklightLevel.Off; + } + + public SetLampIntensity(DisplayBacklightLevel intensity) + { + Intensity = intensity; + } + + public override byte CommandByte => 0x30; + public override byte ExpectedLength => 0x3; + + public DisplayBacklightLevel Intensity + { + get + { + return _intensity; + } + init + { + if (!Enum.IsDefined(typeof(DisplayBacklightLevel), value)) + { + throw new ArgumentOutOfRangeException(nameof(value), "The display backlight value setting is unknown"); + } + + _intensity = value; + } + } + + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) + { + int newIntensity = data[2] & 0xF; + + return new SetLampIntensity() + { + Intensity = (DisplayBacklightLevel)newIntensity, + }; + } + + public override byte[] CreateDatagram() + { + return new byte[] + { + CommandByte, (byte)(ExpectedLength - 3), (byte)Intensity + }; + } + + public override bool MatchesMessageType(IReadOnlyList data) + { + return base.MatchesMessageType(data) && data[2] is 0 or 0x4 or 0x8 or 0xC; + } + } +} diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index bc2ce4d319..93aa8c8b7e 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -18,14 +18,18 @@ + + + + diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index 6bbd1d9d0a..ba0b9f1c88 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -57,6 +57,8 @@ public Seatalk1Parser(Stream inputStream) new CompassHeadingAutopilotCourseAlt(), new Keystroke(), new DeadbandSetting(), + new SetLampIntensity(), + new AutopilotCalibrationParameterMessage() }; } diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index 23a0582b64..535f095210 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -13,7 +13,7 @@ namespace Iot.Device.Seatalk1 { - public class SeatalkInterface : IDisposable + public class SeatalkInterface : MarshalByRefObject, IDisposable { private const Parity DefaultParity = Parity.Even; private readonly SerialPort _port; @@ -216,6 +216,17 @@ public Task SendMessageAsync(SeatalkMessage message) /// An interface to monitor and control an Autopilot connected via Seatalk1 public AutoPilotRemoteController GetAutopilotRemoteController() => _autopilotController; + /// + /// Configures the display backlight of all devices connected to the bus, as far as this is supported + /// (e.g. the ST2000 autopilot only supports on or off) + /// + /// The new backlight level + public void SetLampIntensity(DisplayBacklightLevel intensity) + { + var msg = new SetLampIntensity(intensity); + SendMessage(msg); + } + protected virtual void Dispose(bool disposing) { if (disposing) diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index dabd65ede9..c0c29bbd2a 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -86,13 +86,6 @@ public async void Run(string[] args) break; } - case ConsoleKey.L: - { - // Doesn't seem to do anything on the ST2000+, even though it is documented that remote-controlling the display backlight should work - ks = new Keystroke(AutopilotButtons.Disp); - break; - } - case ConsoleKey.U: { await ctrl.TurnByAsync(Angle.FromDegrees(90), TurnDirection.Starboard, CancellationToken.None); @@ -102,7 +95,7 @@ public async void Run(string[] args) case ConsoleKey.Z: { - await ctrl.TurnByAsync(Angle.FromDegrees(-90), TurnDirection.Port, CancellationToken.None); + await ctrl.TurnByAsync(Angle.FromDegrees(90), TurnDirection.Port, CancellationToken.None); break; } @@ -141,6 +134,18 @@ public async void Run(string[] args) } break; + case ConsoleKey.L: + if (key.Modifiers == ConsoleModifiers.Shift) + { + _seatalk.SetLampIntensity(DisplayBacklightLevel.Off); + } + else + { + _seatalk.SetLampIntensity(DisplayBacklightLevel.Level3); + } + + break; + } if (ks.ButtonsPressed != AutopilotButtons.None) diff --git a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs index 985daed493..2011143291 100644 --- a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs +++ b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs @@ -39,7 +39,7 @@ public void StartupWasSuccessful() } [Fact] - public void MakeReady() + public void SetToStandby() { var msg = new CompassHeadingAutopilotCourse() { @@ -92,6 +92,15 @@ public void AnglesOnly() Assert.False(_testee.RudderAngleAvailable); } + [Fact] + public void TurnToHasNoEffectWhenStandby() + { + SetToStandby(); + Assert.Equal(AutopilotStatus.Standby, _testee.Status); + // Also: Shouldn't block, despite no Cancellation given + Assert.False(_testee.TurnTo(Angle.FromDegrees(100), TurnDirection.Starboard)); + } + [Fact] public void TurnToStarboard() { @@ -192,5 +201,106 @@ public void TurnToPortFullSequence() Assert.True(_testee.TurnBy(Angle.FromDegrees(12), TurnDirection.Port, _tokenSource.Token)); } + + [Fact] + public void TurnTo() + { + // Ap is in auto mode + var msg = new CompassHeadingAutopilotCourse() + { + AutopilotStatus = AutopilotStatus.Auto, + AutoPilotCourse = Angle.FromDegrees(10), + CompassHeading = Angle.FromDegrees(9), + }; + + _interface.Object.OnNewMessage(msg); + + Keystroke ks = new Keystroke(AutopilotButtons.PlusTen, 1); // We expect that it's automatically guessing the "nearer" direction right + _interface.Setup(x => x.SendMessage(It.IsAny())).Callback(i => + { + Assert.Equal(ks, i); + }).Returns(true); + _tokenSource.Cancel(); // Cancellation is only tested after the first command was sent + Assert.False(_testee.TurnTo(Angle.FromDegrees(100), null, _tokenSource.Token)); + + _interface.Verify(x => x.SendMessage(ks)); + } + + [Fact] + public void SetAndResetDeadbandMode() + { + SetToStandby(); + Assert.Equal(DeadbandMode.Automatic, _testee.DeadbandMode); + Assert.False(_testee.SetDeadbandMode(DeadbandMode.Minimal)); + SetToAuto(); + + int num = 0; + Keystroke ks = new Keystroke(0x0a); // We expect that it's automatically guessing the "nearer" direction right + _interface.Setup(x => x.SendMessage(It.IsAny())).Callback(i => + { + if (num == 0) + { + Assert.Equal(ks, i); + var msg = new DeadbandSetting() + { + Mode = DeadbandMode.Minimal, + }; + + _interface.Object.OnNewMessage(msg); + } + else + { + var ks2 = (Keystroke)i; + Assert.Equal(0x09, ks2.KeyCode); + var msg = new DeadbandSetting() + { + Mode = DeadbandMode.Automatic, + }; + + _interface.Object.OnNewMessage(msg); + } + + num++; + }).Returns(true); + + Assert.True(_testee.SetDeadbandMode(DeadbandMode.Minimal)); + Assert.True(_testee.SetDeadbandMode(DeadbandMode.Automatic)); + } + + [Fact] + public void AnglesAreClose() + { + Assert.True(_testee.AnglesAreClose(Angle.FromDegrees(359), Angle.FromDegrees(0.1))); + Assert.True(_testee.AnglesAreClose(Angle.FromDegrees(360), Angle.FromDegrees(359))); + Assert.True(_testee.AnglesAreClose(Angle.FromDegrees(0), Angle.FromDegrees(359))); + Assert.True(_testee.AnglesAreClose(Angle.FromDegrees(181), Angle.FromDegrees(180))); + } + + [Fact] + public void ToStringTest() + { + Assert.NotEmpty(_testee.ToString()); + } + + [Fact] + public void SetToAutoRemotely() + { + Keystroke ks = new Keystroke(AutopilotButtons.Auto, 1); // We expect that it's automatically guessing the "nearer" direction right + _interface.Setup(x => x.SendMessage(It.IsAny())).Callback(i => + { + Assert.Equal(ks, i); + var msg = new CompassHeadingAutopilotCourse() + { + AutopilotStatus = AutopilotStatus.Auto, + AutoPilotCourse = Angle.FromDegrees(10), + CompassHeading = Angle.FromDegrees(9), + }; + + _interface.Object.OnNewMessage(msg); + + }).Returns(true); + + Assert.True(_testee.SetStatus(AutopilotStatus.Auto)); + } } } diff --git a/src/devices/Seatalk1/tests/MessageTests.cs b/src/devices/Seatalk1/tests/MessageTests.cs index df9145dc18..d04015af19 100644 --- a/src/devices/Seatalk1/tests/MessageTests.cs +++ b/src/devices/Seatalk1/tests/MessageTests.cs @@ -24,6 +24,7 @@ public MessageTests() [Theory] [InlineData("95 86 26 97 02 00 00 00 08", typeof(CompassHeadingAutopilotCourseAlt))] + [InlineData("95 86 0E 00 10 00 00 04 08", typeof(CompassHeadingAutopilotCourseAlt))] [InlineData("84 86 26 97 02 00 00 00 08", typeof(CompassHeadingAutopilotCourse))] [InlineData("9c 01 12 00", typeof(CompassHeadingAndRudderPosition))] [InlineData("87 00 01", typeof(DeadbandSetting))] diff --git a/src/devices/Seatalk1/tests/Seatalk1Tests.cs b/src/devices/Seatalk1/tests/Seatalk1Tests.cs index d8d42105b6..199dbff073 100644 --- a/src/devices/Seatalk1/tests/Seatalk1Tests.cs +++ b/src/devices/Seatalk1/tests/Seatalk1Tests.cs @@ -116,7 +116,7 @@ public void ParityBitCheckForMessageThatWorks() [Fact] public void ParityBitCheckForMessageThatMustWork() { - // This message (+10 key) doesn't work yet. + // This message took a bit to get right byte[] datagram = new byte[] { 0x86, 0x11, 0x08, 0xf7 @@ -135,6 +135,25 @@ public void ParityBitCheckForMessageThatMustWork() Assert.Equal(Parity.Odd, withParity[3].P); } + [Fact] + public void ParityBitCheckForMessageWithOddCommandByte() + { + byte[] datagram = new byte[] + { + 0x9C, 0x01, 0x03, 0x0f + }; + + var withParity = SeatalkInterface.CalculateParityForEachByte(datagram); + Assert.Equal(0x9c, withParity[0].B); + Assert.Equal(0, withParity[0].Index); + // 0x9c is even (not the value, but it's bitcount), and we want the stopbit to be 1, so the parity should be odd + Assert.Equal(Parity.Odd, withParity[0].P); + // 0x01 is odd, we need the stopbit to be 0, so parity needs to be odd + Assert.Equal(Parity.Odd, withParity[1].P); + // 0x03 is even, we need the stopbit to be 0, so parity needs to be even + Assert.Equal(Parity.Even, withParity[2].P); + } + private static MemoryStream GetStreamFromInputString(string data) { var split = data.Split(new char[] { '\n', '\r', ' ' }, StringSplitOptions.RemoveEmptyEntries); From 15dd3e90589e7bb711af1b431a76d0974dd2edb2 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 31 Dec 2023 21:05:01 +0100 Subject: [PATCH 14/31] Apparent wind command appears to work Can't really verify whether the angle is provided correctly, though --- .../Seatalk1/AutoPilotRemoteController.cs | 20 ++++- .../Seatalk1/Messages/ApparentWindAngle.cs | 73 +++++++++++++++++++ .../Seatalk1/Messages/AutopilotStatus.cs | 2 + .../Messages/CompassHeadingAutopilotCourse.cs | 6 +- src/devices/Seatalk1/Seatalk1.csproj | 1 + src/devices/Seatalk1/Seatalk1Parser.cs | 5 +- src/devices/Seatalk1/SeatalkInterface.cs | 8 ++ .../Seatalk1/samples/Seatalk1.Samples.cs | 11 +++ src/devices/Seatalk1/tests/MessageTests.cs | 13 ++++ 9 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 src/devices/Seatalk1/Messages/ApparentWindAngle.cs diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index f94e033bd3..7a305fa58d 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -71,9 +71,11 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) { lock (_lock) { - _lastUpdateTime = DateTime.UtcNow; if (obj is CompassHeadingAutopilotCourse ch) { + // Only update this when we see an autopilot message, otherwise we declare the autopilot as online + // if all we see is the echo of some of the repeating messages we send out. + _lastUpdateTime = DateTime.UtcNow; Status = ch.AutopilotStatus; AutopilotHeading = ch.CompassHeading; AutopilotDesiredHeading = Status != AutopilotStatus.Standby ? ch.AutoPilotCourse : null; @@ -177,6 +179,16 @@ public bool SetStatus(AutopilotStatus newStatus, TimeSpan timeout) _ => throw new ArgumentException($"Status {newStatus} is not valid", nameof(newStatus)), }; + // For setting wind or track modes, we need to first set auto mode. + // Setting wind mode without auto works (and is returned as status 0x4), but has no visible effect. + if (newStatus == AutopilotStatus.Wind || newStatus == AutopilotStatus.Track) + { + if (!SendMessageAndVerifyStatus(new Keystroke(AutopilotButtons.Auto, 1), timeout, () => Status is AutopilotStatus.Auto or AutopilotStatus.Wind or AutopilotStatus.Track)) + { + return false; + } + } + return SendMessageAndVerifyStatus(new Keystroke(buttonToPress, 1), timeout, () => Status == newStatus); } @@ -383,12 +395,16 @@ internal void UpdateStatus() if (_lastUpdateTime + TimeSpan.FromSeconds(5) < DateTime.UtcNow) { // The autopilot hasn't sent anything for 5 seconds. Assume it's offline + if (Status != AutopilotStatus.Offline) // don't repeat message + { + _logger.LogWarning("Autopilot connection timed out. Assuming it's offline"); + } + Status = AutopilotStatus.Offline; DeadbandMode = DeadbandMode.Automatic; RudderAngle = null; AutopilotDesiredHeading = null; AutopilotHeading = null; - _logger.LogWarning("Autopilot connection timed out. Assuming it's offline"); } } } diff --git a/src/devices/Seatalk1/Messages/ApparentWindAngle.cs b/src/devices/Seatalk1/Messages/ApparentWindAngle.cs new file mode 100644 index 0000000000..fbaad608aa --- /dev/null +++ b/src/devices/Seatalk1/Messages/ApparentWindAngle.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Iot.Device.Common; +using UnitsNet; + +namespace Iot.Device.Seatalk1.Messages +{ + public record ApparentWindAngle : SeatalkMessage + { + private readonly Angle _apparentAngle; + + public ApparentWindAngle() + { + ApparentAngle = Angle.Zero; + } + + public ApparentWindAngle(Angle apparentAngle) + { + ApparentAngle = apparentAngle; + } + + public override byte CommandByte => 0x10; + public override byte ExpectedLength => 0x4; + + /// + /// Apparent wind angle, relative to bow. + /// Positive for right of bow (wind from starboard) + /// + public Angle ApparentAngle + { + get + { + return _apparentAngle; + } + init + { + value = value.Normalize(false); + _apparentAngle = value; + } + } + + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) + { + uint angle10u = Convert.ToUInt32(data[2] << 8 | data[3]); + if ((angle10u & 0x8000) != 0) + { + angle10u |= 0xFFFF0000; + } + + int angle10 = unchecked((int)angle10u); + Angle angle = Angle.FromDegrees(angle10 / 2.0); + return new ApparentWindAngle() + { + ApparentAngle = angle, + }; + } + + public override byte[] CreateDatagram() + { + short angle10 = (short)Math.Round(ApparentAngle.Degrees * 2); + return new byte[] + { + CommandByte, (byte)(ExpectedLength - 3), (byte)(angle10 >> 8), (byte)(angle10 & 0xFF) + }; + } + } +} diff --git a/src/devices/Seatalk1/Messages/AutopilotStatus.cs b/src/devices/Seatalk1/Messages/AutopilotStatus.cs index 4957d5d2bd..fae0f61844 100644 --- a/src/devices/Seatalk1/Messages/AutopilotStatus.cs +++ b/src/devices/Seatalk1/Messages/AutopilotStatus.cs @@ -19,6 +19,8 @@ public enum AutopilotStatus Auto, Track, Wind, + InactiveTrack, + InactiveWind, Calibration, Undefined, } diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index c95a3cf7bd..3a94510564 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -85,9 +85,13 @@ private AutopilotStatus GetAutopilotStatus(byte z) return AutopilotStatus.Standby; case 2: return AutopilotStatus.Auto; - case 4: + case 4: // Wind mode may be on its own and together with the auto flag + return AutopilotStatus.InactiveWind; + case 6: return AutopilotStatus.Wind; case 8: + return AutopilotStatus.InactiveTrack; + case 10: return AutopilotStatus.Track; case 0x10: return AutopilotStatus.Calibration; diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index 93aa8c8b7e..10366fb8fd 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -16,6 +16,7 @@ + diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index ba0b9f1c88..28b1702068 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -58,10 +58,13 @@ public Seatalk1Parser(Stream inputStream) new Keystroke(), new DeadbandSetting(), new SetLampIntensity(), - new AutopilotCalibrationParameterMessage() + new AutopilotCalibrationParameterMessage(), + new ApparentWindAngle() }; } + public bool IsBufferEmpty => _buffer.Count == 0; + public event Action? NewMessageDecoded; public void RegisterMessageType(SeatalkMessage message) diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index 535f095210..e8a5e00010 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -170,6 +170,14 @@ public virtual bool SendDatagram(byte[] data) { // First calculate the required parity setting for each byte. var dataWithParity = CalculateParityForEachByte(data); + + // Only start sending if the buffer is empty. This should hopefully avoid to many collisions + while (!_parser.IsBufferEmpty) + { + // Sending a message takes 1 - 2ms, so wait a bit (knowing that this sleep isn't precise) + Thread.Sleep(1); + } + // Only one thread at a time, please! lock (_lock) { diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index c0c29bbd2a..bb2ad19db7 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -47,6 +47,8 @@ public async void Run(string[] args) WriteCurrentState(); + Angle windAngle = Angle.Zero; + while (true) { if (Console.KeyAvailable) @@ -86,6 +88,12 @@ public async void Run(string[] args) break; } + case ConsoleKey.X: + { + ctrl.SetStatus(AutopilotStatus.Wind); + break; + } + case ConsoleKey.U: { await ctrl.TurnByAsync(Angle.FromDegrees(90), TurnDirection.Starboard, CancellationToken.None); @@ -155,6 +163,9 @@ public async void Run(string[] args) } await Task.Delay(500); + windAngle = windAngle + Angle.FromDegrees(1.5); + var windMsg = new ApparentWindAngle(windAngle); + _seatalk.SendMessage(windMsg); WriteCurrentState(); } diff --git a/src/devices/Seatalk1/tests/MessageTests.cs b/src/devices/Seatalk1/tests/MessageTests.cs index d04015af19..935782827d 100644 --- a/src/devices/Seatalk1/tests/MessageTests.cs +++ b/src/devices/Seatalk1/tests/MessageTests.cs @@ -29,6 +29,7 @@ public MessageTests() [InlineData("9c 01 12 00", typeof(CompassHeadingAndRudderPosition))] [InlineData("87 00 01", typeof(DeadbandSetting))] [InlineData("86 01 02 fd", typeof(Keystroke))] + [InlineData("10 01 00 01", typeof(ApparentWindAngle))] public void KnownMessageTypeDecode(string msg, Type expectedType) { msg = msg.Replace(" ", string.Empty); @@ -77,5 +78,17 @@ public void UnEqualKeysAreNotEqual() Assert.False(ks1.Equals(ks2)); Assert.NotEqual(ks1.GetHashCode(), ks2.GetHashCode()); } + + [Theory] + [InlineData(10.0)] + [InlineData(0.0)] + [InlineData(-11.0)] + public void SignIsMaintainedInWindAngle(double value) + { + ApparentWindAngle angle = new ApparentWindAngle(Angle.FromDegrees(value)); + byte[] data = angle.CreateDatagram(); + var angle2 = angle.CreateNewMessage(data); + Assert.Equal(angle, angle2); + } } } From c5b5df5603b741f6ac6f5698ec116b2410374064 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 1 Jan 2024 15:14:58 +0100 Subject: [PATCH 15/31] Track message and Autopilot Track Mode work --- .../Seatalk1/AutoPilotRemoteController.cs | 75 ++++++++-- .../Seatalk1/Messages/AutopilotButtons.cs | 1 - .../Seatalk1/Messages/CourseComputerStatus.cs | 46 ++++++ .../Messages/CourseComputerWarnings.cs | 35 +++++ .../Seatalk1/Messages/NavigationToWaypoint.cs | 138 ++++++++++++++++++ src/devices/Seatalk1/Seatalk1.csproj | 3 + src/devices/Seatalk1/Seatalk1Parser.cs | 24 ++- .../Seatalk1/samples/Seatalk1.Samples.cs | 54 +++++-- src/devices/Seatalk1/tests/MessageTests.cs | 58 ++++++++ 9 files changed, 411 insertions(+), 23 deletions(-) create mode 100644 src/devices/Seatalk1/Messages/CourseComputerStatus.cs create mode 100644 src/devices/Seatalk1/Messages/CourseComputerWarnings.cs create mode 100644 src/devices/Seatalk1/Messages/NavigationToWaypoint.cs diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index 7a305fa58d..8428a1e1eb 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -61,10 +61,16 @@ internal AutoPilotRemoteController(SeatalkInterface parentInterface) public DeadbandMode DeadbandMode { get; private set; } + public int AutopilotType { get; private set; } + public TimeSpan DefaultTimeout { get; set; } public bool IsOperating => Status is AutopilotStatus.Auto or AutopilotStatus.Track or AutopilotStatus.Wind; + public bool IsStandby => Status is AutopilotStatus.Standby or AutopilotStatus.InactiveTrack or AutopilotStatus.InactiveWind; + + public CourseComputerWarnings CourseComputerStatus { get; private set; } + public event Action? AutopilotKeysPressed; private void AutopilotMessageInterpretation(SeatalkMessage obj) @@ -78,7 +84,8 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) _lastUpdateTime = DateTime.UtcNow; Status = ch.AutopilotStatus; AutopilotHeading = ch.CompassHeading; - AutopilotDesiredHeading = Status != AutopilotStatus.Standby ? ch.AutoPilotCourse : null; + AutopilotDesiredHeading = !IsStandby ? ch.AutoPilotCourse : null; + AutopilotType = ch.AutoPilotType; if (!RudderAngleAvailable) { RudderAngleAvailable = !ch.RudderPosition.Equals(Angle.Zero, Angle.FromDegrees(0.5)); @@ -130,17 +137,23 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) _logger.LogInformation($"Received calibration value for {calibParam.Parameter}. Current {calibParam.CurrentSetting} Min {calibParam.MinValue} Max {calibParam.MaxValue}"); _calibrationParameters.AddOrUpdate(calibParam.Parameter, x => calibParam, (a, b) => calibParam); } + else if (obj is CourseComputerStatus status) + { + _logger.LogWarning($"Course computer has warnings: {status.Warnings}"); + CourseComputerStatus = status.Warnings; + } - if (Status == AutopilotStatus.Standby || Status == AutopilotStatus.Offline) + if (IsStandby || Status == AutopilotStatus.Offline) { DeadbandMode = DeadbandMode.Automatic; // Resets automatically when going to standby (the message is not sent periodically) + CourseComputerStatus = CourseComputerWarnings.None; } } } - public bool SetStatus(AutopilotStatus status) + public bool SetStatus(AutopilotStatus status, ref TurnDirection? directionConfirmation) { - return SetStatus(status, DefaultTimeout); + return SetStatus(status, DefaultTimeout, ref directionConfirmation); } /// @@ -158,23 +171,30 @@ public List GetCalibrationParameters() /// /// The status to set /// How long to try. For safety reasons (see remark) the maximum value is limited - /// True on success, false if the change didn't succeed within the timeout. + /// If entering track mode (==), confirm a turn + /// in the given direction. If left null, will return the required direction for the turn. The method has then to be called again with the parameter set + /// True on success, false if the change didn't succeed within the timeout. Also returns false if a change to track mode wasn't confirmed yet. /// /// Don't be tempted to attempt to set the mode to Auto with a large timeout, as this could /// override the user's desire to disable the Autopilot and is therefore VERY DANGEROUS! /// - public bool SetStatus(AutopilotStatus newStatus, TimeSpan timeout) + public bool SetStatus(AutopilotStatus newStatus, TimeSpan timeout, ref TurnDirection? directionConfirmation) { - if (Status == newStatus) + if (Status == newStatus && CourseComputerStatus == 0) { return true; // nothing to do } + if (Status == AutopilotStatus.Offline) + { + return false; + } + AutopilotButtons buttonToPress = newStatus switch { AutopilotStatus.Auto => AutopilotButtons.Auto, AutopilotStatus.Standby => AutopilotButtons.StandBy, - AutopilotStatus.Track => AutopilotButtons.Track, + AutopilotStatus.Track => AutopilotButtons.PlusTen | AutopilotButtons.MinusTen, AutopilotStatus.Wind => AutopilotButtons.Auto | AutopilotButtons.StandBy, _ => throw new ArgumentException($"Status {newStatus} is not valid", nameof(newStatus)), }; @@ -189,12 +209,46 @@ public bool SetStatus(AutopilotStatus newStatus, TimeSpan timeout) } } - return SendMessageAndVerifyStatus(new Keystroke(buttonToPress, 1), timeout, () => Status == newStatus); + bool ret = SendMessageAndVerifyStatus(new Keystroke(buttonToPress, 1), timeout, () => (Status == newStatus) || ((newStatus == AutopilotStatus.Standby) && IsStandby)); + + if (ret && newStatus == AutopilotStatus.Track) + { + // Wait until the AP reports a course computer warning - and then just confirm it. + Stopwatch sw = Stopwatch.StartNew(); + // This needs a longer timeout, since it can take several seconds for the confirmation to appear + while (sw.Elapsed < TimeSpan.FromSeconds(5)) + { + if ((CourseComputerStatus & CourseComputerWarnings.DriveFailure) != 0) + { + TurnDirection directionRequired = + (CourseComputerStatus & CourseComputerWarnings.CourseChangeToPort) == CourseComputerWarnings.CourseChangeToPort ? TurnDirection.Port : TurnDirection.Starboard; + if (directionConfirmation == null) + { + directionConfirmation = directionRequired; + return false; + } + + if (directionRequired == directionConfirmation && + SendMessageAndVerifyStatus(new Keystroke(0x28, 1), timeout, + () => Status == AutopilotStatus.Track)) + { + CourseComputerStatus = 0; // Apparently, the clearance of this warning is not sent + break; + } + } + + Thread.Sleep(150); + } + + ret = Status == AutopilotStatus.Track && CourseComputerStatus == CourseComputerWarnings.None; + } + + return ret; } public bool SetDeadbandMode(DeadbandMode mode) { - if (Status == AutopilotStatus.Offline || Status == AutopilotStatus.Standby) + if (Status == AutopilotStatus.Offline || IsStandby) { // The Deadband mode can only be set in auto mode return false; @@ -405,6 +459,7 @@ internal void UpdateStatus() RudderAngle = null; AutopilotDesiredHeading = null; AutopilotHeading = null; + CourseComputerStatus = CourseComputerWarnings.None; } } } diff --git a/src/devices/Seatalk1/Messages/AutopilotButtons.cs b/src/devices/Seatalk1/Messages/AutopilotButtons.cs index 48594854ce..1b363ba35b 100644 --- a/src/devices/Seatalk1/Messages/AutopilotButtons.cs +++ b/src/devices/Seatalk1/Messages/AutopilotButtons.cs @@ -23,7 +23,6 @@ public enum AutopilotButtons PlusTen = 8, Auto = 16, StandBy = 32, - Track = 64, Disp = 128, LongPress = 256, } diff --git a/src/devices/Seatalk1/Messages/CourseComputerStatus.cs b/src/devices/Seatalk1/Messages/CourseComputerStatus.cs new file mode 100644 index 0000000000..92267d7b72 --- /dev/null +++ b/src/devices/Seatalk1/Messages/CourseComputerStatus.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Iot.Device.Seatalk1.Messages +{ + public record CourseComputerStatus : SeatalkMessage + { + public override byte CommandByte => 0x83; + public override byte ExpectedLength => 0x0a; // this message has 10 bytes, despite only 3 used. + + public CourseComputerWarnings Warnings + { + get; + init; + } + + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) + { + Logger.LogInformation($"Course computer warning msg: {string.Join("-", data.Select(x => x.ToString("X2")))}"); + return this with + { + Warnings = (CourseComputerWarnings)data[2], + }; + } + + public override byte[] CreateDatagram() + { + return new byte[] + { + CommandByte, (byte)(ExpectedLength - 3), (byte)Warnings, 0, 0, 0, 0, 0, 0, 0 + }; + } + + public override bool MatchesMessageType(IReadOnlyList data) + { + return base.MatchesMessageType(data) && data[3] == 0; + } + } +} diff --git a/src/devices/Seatalk1/Messages/CourseComputerWarnings.cs b/src/devices/Seatalk1/Messages/CourseComputerWarnings.cs new file mode 100644 index 0000000000..1d3739a37c --- /dev/null +++ b/src/devices/Seatalk1/Messages/CourseComputerWarnings.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Seatalk1.Messages +{ + [Flags] + public enum CourseComputerWarnings + { + /// + /// No warnings (some APs apparently set this explicitly, others never reset the value) + /// + None = 0, + + /// + /// There was an autopilot drive error + /// + DriveReleaseFailure = 1, + + /// + /// The drive is not working (or: The command needs confirmation, e.g. after attempting to enter track mode) + /// + DriveFailure = 2, + + /// + /// Together with DriveFailure, this indicates that a turn to port is required. If it's not set, a course change to starboard is required. + /// + CourseChangeToPort = 4, + } +} diff --git a/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs b/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs new file mode 100644 index 0000000000..c6ca577f8c --- /dev/null +++ b/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs @@ -0,0 +1,138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnitsNet; + +namespace Iot.Device.Seatalk1.Messages +{ + public record NavigationToWaypoint : SeatalkMessage + { + public override byte CommandByte => 0x85; + public override byte ExpectedLength => 0x9; + + public Length? CrossTrackError + { + get; + init; + } + + public Angle? BearingToDestination + { + get; + init; + } + + public bool BearingIsTrue + { + get; + init; + } + + public Length? DistanceToDestination + { + get; + init; + } + + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) + { + return new NavigationToWaypoint(); + } + + public override byte[] CreateDatagram() + { + // 85 X6 XX VU ZW ZZ YF 00 yf + byte flags = 0; + byte[] data = new byte[9]; + data[0] = CommandByte; + data[1] = ExpectedLength; + if (CrossTrackError.HasValue) + { + double nmTimes100 = CrossTrackError.Value.NauticalMiles * 100.0; + int v = (int)Math.Round(Math.Abs(nmTimes100)); + if (v > 0xfff) + { + v = 0xfff; + } + + data[1] = (byte)((v & 0x00f) << 4 | 0x6); // This is the attr byte + data[2] = (byte)(v >> 4); + if (nmTimes100 < 0) // Xtrack error negative -> Steer right to correct + { + data[6] |= 0x40; // this is indicated on y bit 2 + } + + flags |= 1; + if (Math.Abs(CrossTrackError.Value.NauticalMiles) >= 0.3) + { + flags |= 8; + } + } + + if (BearingToDestination.HasValue) + { + double angle = BearingToDestination.Value.Degrees; + int u = 0; + if (angle >= 270) + { + u = 3; + angle -= 270; + } + else if (angle >= 180) + { + u = 2; + angle -= 180; + } + else if (angle >= 90) + { + u = 1; + angle -= 90; + } + + int lowerPart = (int)Math.Round(angle * 2); + + data[3] |= (byte)u; + if (BearingIsTrue) + { + data[3] |= 0x8; + } + + data[3] |= (byte)(lowerPart << 4); // V, lower nibble of remainder + data[4] |= (byte)((lowerPart >> 4) & 0xF); // upper nibble of remainder (upper nibble of this byte is used in DistanceToDestination) + flags |= 2; + } + + if (DistanceToDestination.HasValue) + { + double distanceNm = DistanceToDestination.Value.NauticalMiles; + if (distanceNm <= 9.9) + { + int decoding = (int)Math.Round(distanceNm * 100.0); + data[4] |= (byte)((decoding & 0x00F) << 4); + data[5] = (byte)(((decoding & 0xFF0) >> 4)); + data[6] |= 0x10; // Set scale bit Y + } + else + { + int decoding = (int)Math.Round(distanceNm * 10.0); + data[4] |= (byte)((decoding & 0x00F) << 4); + data[5] = (byte)(((decoding & 0xFF0) >> 4)); + // Bit in Y is not set + } + + flags |= 4; + } + + data[6] |= flags; + data[7] = 0; + data[8] = (byte)(~data[6]); + + return data; + } + } +} diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index 10366fb8fd..e180cffe35 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -25,10 +25,13 @@ + + + diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index 28b1702068..5dc1de8971 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -7,12 +7,14 @@ using System.Device.I2c; using System.Device.Spi; using System.IO; +using System.Linq; using System.Reflection; using System.Text; using System.Threading; using Iot.Device.Common; using Iot.Device.Seatalk1.Messages; using Microsoft.Extensions.Logging; +using UnitsNet; namespace Iot.Device.Seatalk1 { @@ -59,17 +61,33 @@ public Seatalk1Parser(Stream inputStream) new DeadbandSetting(), new SetLampIntensity(), new AutopilotCalibrationParameterMessage(), - new ApparentWindAngle() + new ApparentWindAngle(), + new NavigationToWaypoint(), + new CourseComputerStatus(), }; + + MaxMessageLength = _messageFactories.Select(x => x.ExpectedLength).Max(); + if (MaxMessageLength > 18) + { + throw new InvalidOperationException("At least one message reports an expected length > 18 bytes. This is illegal"); + } } + public int MaxMessageLength { get; private set; } + public bool IsBufferEmpty => _buffer.Count == 0; public event Action? NewMessageDecoded; public void RegisterMessageType(SeatalkMessage message) { + if (message.ExpectedLength > 18) + { + throw new ArgumentException("The maximum length of a message is 18 bytes", nameof(message)); + } + _messageFactories.Add(message); + MaxMessageLength = _messageFactories.Select(x => x.ExpectedLength).Max(); } /// @@ -198,8 +216,8 @@ private void Parser() return null; } - // The maximum length is 0xF + 3 = 18 - if (buffer.Count > 18) + // The maximum length is 0xF + 3 = 18 or the maximum message length we know about + if (buffer.Count > MaxMessageLength) { bytesInMessage = -1; return null; diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index bb2ad19db7..34ca260326 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -49,6 +49,8 @@ public async void Run(string[] args) Angle windAngle = Angle.Zero; + TurnDirection? directionConfirmation = null; + while (true) { if (Console.KeyAvailable) @@ -76,7 +78,7 @@ public async void Run(string[] args) break; case ConsoleKey.W: { - if (ctrl.SetStatus(AutopilotStatus.Auto)) + if (ctrl.SetStatus(AutopilotStatus.Auto, ref directionConfirmation)) { Console.WriteLine("Autopilot set to AUTO mode"); } @@ -90,7 +92,16 @@ public async void Run(string[] args) case ConsoleKey.X: { - ctrl.SetStatus(AutopilotStatus.Wind); + // This is expected to fail if the AP has no wind data + if (ctrl.SetStatus(AutopilotStatus.Wind, ref directionConfirmation)) + { + Console.WriteLine("Autopilot set to WIND mode"); + } + else + { + Console.WriteLine("Setting WIND mode FAILED!"); + } + break; } @@ -120,23 +131,33 @@ public async void Run(string[] args) break; - case ConsoleKey.I: + case ConsoleKey.T: { // This is expected to fail if the AP has no wind data - if (ctrl.SetStatus(AutopilotStatus.Wind)) + if (ctrl.SetStatus(AutopilotStatus.Track, ref directionConfirmation)) { - Console.WriteLine("Autopilot set to WIND mode"); + Console.WriteLine("Autopilot set to TRACK mode"); + directionConfirmation = null; } else { - Console.WriteLine("Setting WIND mode FAILED!"); + Console.WriteLine("Setting TRACK mode incomplete!"); + if (directionConfirmation == TurnDirection.Port) + { + Console.WriteLine("Press T again to confirm a turn to Port"); + } + else + { + Console.WriteLine("Press T again to confirm a turn to Starboard"); + } } break; } case ConsoleKey.S: - if (ctrl.SetStatus(AutopilotStatus.Standby)) + directionConfirmation = null; + if (ctrl.SetStatus(AutopilotStatus.Standby, ref directionConfirmation)) { Console.WriteLine("Autopilot set to STANDBY mode"); } @@ -163,9 +184,18 @@ public async void Run(string[] args) } await Task.Delay(500); + + NavigationToWaypoint wp = new NavigationToWaypoint() + { + BearingToDestination = Angle.FromDegrees(10), + CrossTrackError = Length.FromNauticalMiles(-0.11), + DistanceToDestination = Length.FromNauticalMiles(51.3), + }; + + _seatalk.SendMessage(wp); + windAngle = windAngle + Angle.FromDegrees(1.5); - var windMsg = new ApparentWindAngle(windAngle); - _seatalk.SendMessage(windMsg); + // SendRandomWindAngle(windAngle); WriteCurrentState(); } @@ -175,6 +205,12 @@ public async void Run(string[] args) Console.WriteLine("Program is terminating"); } + private void SendRandomWindAngle(Angle angle) + { + var windMsg = new ApparentWindAngle(angle); + _seatalk?.SendMessage(windMsg); + } + private void WriteCurrentState() { var ctrl = _seatalk?.GetAutopilotRemoteController(); diff --git a/src/devices/Seatalk1/tests/MessageTests.cs b/src/devices/Seatalk1/tests/MessageTests.cs index 935782827d..645f37d0c4 100644 --- a/src/devices/Seatalk1/tests/MessageTests.cs +++ b/src/devices/Seatalk1/tests/MessageTests.cs @@ -30,6 +30,7 @@ public MessageTests() [InlineData("87 00 01", typeof(DeadbandSetting))] [InlineData("86 01 02 fd", typeof(Keystroke))] [InlineData("10 01 00 01", typeof(ApparentWindAngle))] + [InlineData("85 06 00 00 C0 0D 1F 00 E0", typeof(NavigationToWaypoint))] public void KnownMessageTypeDecode(string msg, Type expectedType) { msg = msg.Replace(" ", string.Empty); @@ -90,5 +91,62 @@ public void SignIsMaintainedInWindAngle(double value) var angle2 = angle.CreateNewMessage(data); Assert.Equal(angle, angle2); } + + [Fact] + public void NavigationToWaypointMessage1() + { + var n = new NavigationToWaypoint() + { + BearingToDestination = Angle.FromDegrees(230), + CrossTrackError = Length.FromNauticalMiles(2.61), + DistanceToDestination = Length.FromNauticalMiles(5.13), + }; + + byte[] data = n.CreateDatagram(); + // Cross track error + Assert.Equal(0x85, data[0]); + Assert.Equal(0x56, data[1]); + Assert.Equal(0x10, data[2]); + + // Distance + Assert.Equal(0x10, data[4] & 0xF0); + Assert.Equal(0x20, data[5]); + Assert.Equal(0x10, data[6] & 0xF0); + + // Bearing + Assert.Equal(0x42, data[3]); + Assert.Equal(0x06, data[4] & 0x0F); + + Assert.Equal(0x0F, data[6] & 0xF); // flags + } + + [Fact] + public void NavigationToWaypointMessage2() + { + var n = new NavigationToWaypoint() + { + BearingToDestination = Angle.FromDegrees(0), + BearingIsTrue = true, + CrossTrackError = Length.FromNauticalMiles(-2.61), + DistanceToDestination = Length.FromNauticalMiles(51.3), + }; + + byte[] data = n.CreateDatagram(); + // Cross track error + Assert.Equal(0x85, data[0]); + Assert.Equal(0xb6, data[1]); + Assert.Equal(0xef, data[2]); + + // Distance + Assert.Equal(0x10, data[4] & 0xF0); + Assert.Equal(0x20, data[5]); + Assert.Equal(0x00, data[6] & 0xF0); + + // Bearing + Assert.Equal(0x08, data[3]); + Assert.Equal(0x00, data[4] & 0x0F); + + Assert.Equal(0x0F, data[6] & 0xF); // flags + } } } From d5e052a4ef0492e038f141bd59856369cda33044 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 1 Jan 2024 22:07:36 +0100 Subject: [PATCH 16/31] Basic roundtrip for all messages fixed Still need to verify individual arguments --- .../Seatalk1/AutoPilotRemoteController.cs | 6 +- .../AutopilotCalibrationParameterMessage.cs | 9 +- .../CompassHeadingAndRudderPosition.cs | 51 ++++++++- .../Messages/CompassHeadingAutopilotCourse.cs | 106 +++++++++++++++++- .../Seatalk1/Messages/DeadbandSetting.cs | 26 ++++- .../Seatalk1/Messages/NavigationToWaypoint.cs | 14 ++- .../Seatalk1/Messages/SeatalkMessage.cs | 2 +- src/devices/Seatalk1/Seatalk1Parser.cs | 2 + .../tests/AutoPilotRemoteControllerTests.cs | 4 +- src/devices/Seatalk1/tests/MessageTests.cs | 6 +- src/devices/Seatalk1/tests/Seatalk1Tests.cs | 19 ++++ 11 files changed, 227 insertions(+), 18 deletions(-) diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index 8428a1e1eb..e9b273c7b1 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -65,6 +65,8 @@ internal AutoPilotRemoteController(SeatalkInterface parentInterface) public TimeSpan DefaultTimeout { get; set; } + public TurnDirection TurnDirection { get; private set; } + public bool IsOperating => Status is AutopilotStatus.Auto or AutopilotStatus.Track or AutopilotStatus.Wind; public bool IsStandby => Status is AutopilotStatus.Standby or AutopilotStatus.InactiveTrack or AutopilotStatus.InactiveWind; @@ -86,6 +88,7 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) AutopilotHeading = ch.CompassHeading; AutopilotDesiredHeading = !IsStandby ? ch.AutoPilotCourse : null; AutopilotType = ch.AutoPilotType; + TurnDirection = ch.TurnDirection; if (!RudderAngleAvailable) { RudderAngleAvailable = !ch.RudderPosition.Equals(Angle.Zero, Angle.FromDegrees(0.5)); @@ -105,6 +108,7 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) else if (obj is CompassHeadingAndRudderPosition rb) { AutopilotHeading = rb.CompassHeading; + TurnDirection = rb.TurnDirection; if (!RudderAngleAvailable) { RudderAngleAvailable = !rb.RudderPosition.Equals(Angle.Zero, Angle.FromDegrees(0.5)); @@ -526,7 +530,7 @@ public override string ToString() string hdg = AutopilotHeading.HasValue ? AutopilotHeading.Value.ToString() : "N/A"; string desiredHdg = AutopilotDesiredHeading.HasValue ? AutopilotDesiredHeading.Value.ToString() : "N/A"; string rudderAngle = RudderAngleAvailable ? RudderAngle.GetValueOrDefault().ToString() : "N/A"; - string ret = $"MODE: {Status}; HDG: {hdg}; DESHDG: {desiredHdg}; RUD: {rudderAngle}; DB: {DeadbandMode}; ALRT: {Alarms}"; + string ret = $"MODE:{Status}; HDG:{hdg}; DES:{desiredHdg}; RUD:{rudderAngle}; DB:{DeadbandMode}; ALRT:{Alarms}; TD:{TurnDirection}"; return ret; } } diff --git a/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs index e46cc80628..861ef672a2 100644 --- a/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs +++ b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs @@ -55,7 +55,14 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) public override byte[] CreateDatagram() { - throw new NotImplementedException(); + byte[] data = new byte[ExpectedLength]; + data[0] = CommandByte; + data[1] = (byte)(ExpectedLength - 3); + data[2] = (byte)Parameter; + data[3] = (byte)CurrentSetting; + data[4] = (byte)MaxValue; + data[5] = (byte)MinValue; + return data; } } } diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs index d24971d527..5aa1b24066 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Iot.Device.Common; using UnitsNet; namespace Iot.Device.Seatalk1.Messages @@ -27,6 +28,12 @@ public Angle RudderPosition init; } + public TurnDirection TurnDirection + { + get; + init; + } + /// /// 84 U6 VW XY 0Z 0M RR SS TT Compass heading Autopilot course /// @@ -38,21 +45,59 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) uint u = ((uint)data[1]) >> 4; uint vw = data[2]; - // TODO: Verify last part. Actually, only one bit is required there, and the uppermost bit is also used for the turning direction, according to the docs - long heading = (u & 0x3) * 90 + (vw & 0x3F) * 2 + BitCount(u & 0xC); + long heading = (u & 0x3) * 90 + (vw & 0x3F) * 2 + ((u & 0x4) == 0x4 ? 1 : 0); Angle headingA = Angle.FromDegrees(heading); + + Messages.TurnDirection td = (u & 0x8) == 0x8 ? TurnDirection.Starboard : TurnDirection.Port; sbyte rudder = (sbyte)data[3]; return new CompassHeadingAndRudderPosition() { CompassHeading = headingA, RudderPosition = Angle.FromDegrees(rudder), + TurnDirection = td, }; } public override byte[] CreateDatagram() { - throw new NotImplementedException(); + byte[] data = new byte[4]; + data[0] = CommandByte; + int heading = (int)Math.Round(CompassHeading.Normalize(true).Degrees); + int u = 0; + if (heading >= 270) + { + u = 3; + heading -= 270; + } + else if (heading >= 180) + { + u = 2; + heading -= 180; + } + else if (heading >= 90) + { + u = 1; + heading -= 90; + } + + if (TurnDirection == TurnDirection.Starboard) + { + u |= 0x8; + } + + if (heading % 2 == 1) + { + u |= 0x4; + } + + sbyte rudder = Convert.ToSByte(RudderPosition.Degrees); + + data[1] = (byte)(u << 4 | (ExpectedLength - 3)); + data[2] = (byte)((heading >> 1) & 0xff); + data[3] = (byte)rudder; + + return data; } } } diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index 3a94510564..77bb617478 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Iot.Device.Common; using Microsoft.Extensions.Logging; using UnitsNet; @@ -24,21 +25,24 @@ public record CompassHeadingAutopilotCourse : SeatalkMessage public Angle RudderPosition { get; init; } - public AutopilotStatus AutopilotStatus { get; init; } + public AutopilotStatus AutopilotStatus { get; init; } = AutopilotStatus.Standby; public AutopilotAlarms Alarms { get; init; } + public TurnDirection TurnDirection { get; init; } + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { VerifyPacket(data); uint u = ((uint)data[1]) >> 4; uint vw = data[2]; - // TODO: Verify last part. Actually, only one bit is required there, and the uppermost bit is also used for the turning direction, according to the docs - long heading = (u & 0x3) * 90 + (vw & 0x3F) * 2 + BitCount(u & 0xC); + long heading = (u & 0x3) * 90 + (vw & 0x3F) * 2 + ((u & 0x4) == 0x4 ? 1 : 0); Angle headingA = Angle.FromDegrees(heading); - long desiredCourse = (vw >> 6) * 90 + data[3] / 2; + Messages.TurnDirection td = (u & 0x8) == 0x8 ? TurnDirection.Starboard : TurnDirection.Port; + + double desiredCourse = ((vw >> 6) * 90) + (data[3] / 2.0); AutopilotStatus status = GetAutopilotStatus(data[4]); @@ -69,12 +73,87 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) AutopilotStatus = status, RudderPosition = Angle.FromDegrees(rudder), Alarms = alarms, + TurnDirection = td, }; } public override byte[] CreateDatagram() { - throw new NotImplementedException(); + byte[] data = new byte[ExpectedLength]; + data[0] = CommandByte; + int heading = (int)Math.Round(CompassHeading.Normalize(true).Degrees); + int u = 0; + if (heading >= 270) + { + u = 3; + heading -= 270; + } + else if (heading >= 180) + { + u = 2; + heading -= 180; + } + else if (heading >= 90) + { + u = 1; + heading -= 90; + } + + if (TurnDirection == TurnDirection.Starboard) + { + u |= 0x8; + } + + if (heading % 2 == 1) + { + u |= 0x4; + } + + sbyte rudder = Convert.ToSByte(RudderPosition.Degrees); + + data[1] = (byte)(u << 4 | (ExpectedLength - 3)); + data[2] = (byte)((heading >> 1) & 0x3f); + + byte almByte = 0; + if ((Alarms & AutopilotAlarms.OffCourse) == AutopilotAlarms.OffCourse) + { + almByte |= 4; + } + + if ((Alarms & AutopilotAlarms.WindShift) == AutopilotAlarms.WindShift) + { + almByte |= 8; + } + + int vw = 0; + double desiredCourse = AutoPilotCourse.Normalize(true).Degrees; + if (desiredCourse >= 270) + { + vw = 0xC0; + desiredCourse -= 270; + } + else if (desiredCourse >= 180) + { + vw = 0x80; + desiredCourse -= 180; + } + else if (desiredCourse >= 90) + { + vw = 0x40; + desiredCourse -= 90; + } + + int xy = (int)Math.Round(desiredCourse * 2); + + data[2] |= (byte)vw; + data[3] |= (byte)xy; + data[4] = GetAutopilotStatusByte(AutopilotStatus); + data[5] = almByte; + data[6] = (byte)rudder; + data[7] = 0; + data[8] = AutoPilotType; + + return data; } private AutopilotStatus GetAutopilotStatus(byte z) @@ -91,7 +170,7 @@ private AutopilotStatus GetAutopilotStatus(byte z) return AutopilotStatus.Wind; case 8: return AutopilotStatus.InactiveTrack; - case 10: + case 0x0a: return AutopilotStatus.Track; case 0x10: return AutopilotStatus.Calibration; @@ -100,6 +179,21 @@ private AutopilotStatus GetAutopilotStatus(byte z) } } + private byte GetAutopilotStatusByte(AutopilotStatus status) + { + return AutopilotStatus switch + { + AutopilotStatus.Standby => 0, + AutopilotStatus.Auto => 2, + AutopilotStatus.Track => 10, + AutopilotStatus.Wind => 6, + AutopilotStatus.Calibration => 16, + AutopilotStatus.InactiveTrack => 8, + AutopilotStatus.InactiveWind => 4, + _ => 0, + }; + } + public override bool MatchesMessageType(IReadOnlyList data) { // Add some additional tests to make sure the message is not messed up diff --git a/src/devices/Seatalk1/Messages/DeadbandSetting.cs b/src/devices/Seatalk1/Messages/DeadbandSetting.cs index 428d2ddb7e..c00a8c7c5f 100644 --- a/src/devices/Seatalk1/Messages/DeadbandSetting.cs +++ b/src/devices/Seatalk1/Messages/DeadbandSetting.cs @@ -9,6 +9,16 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Sent by the auto pilot when the automatic deadband mode is changed. + /// If set to "Automatic" (the default) the Autopilot tries to compensate for the effect of waves and reduces the + /// rudder movement to a minimum. If set to "Minimum", the Autopilot tries to minimize the off-track error, at the + /// expense of additional movements and thus higher power consumption. The latter is particularly useful when navigating + /// on narrow waterways. + /// + /// + /// To change the setting, send the respective keycodes (0x09 or 0x0a) instead of a message with the desired new value. + /// public record DeadbandSetting : SeatalkMessage { public override byte CommandByte => 0x87; @@ -35,9 +45,23 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// + /// Creates a Deadband status change message. + /// + /// The datagram public override byte[] CreateDatagram() { - throw new NotSupportedException("Send the respective keycodes instead (0x09 or 0x0a)"); + byte mode = Mode switch + { + DeadbandMode.Automatic => 1, + DeadbandMode.Minimal => 2, + _ => 0, + }; + + return new byte[] + { + CommandByte, (byte)(ExpectedLength - 3), mode + }; } public override bool MatchesMessageType(IReadOnlyList data) diff --git a/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs b/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs index c6ca577f8c..edfa49f5a4 100644 --- a/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs +++ b/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs @@ -12,6 +12,18 @@ namespace Iot.Device.Seatalk1.Messages { public record NavigationToWaypoint : SeatalkMessage { + public NavigationToWaypoint() + { + } + + public NavigationToWaypoint(Length? crossTrackError, Angle? bearingToDestination, bool bearingIsTrue, Length? distanceToDestination) + { + CrossTrackError = crossTrackError; + BearingToDestination = bearingToDestination; + BearingIsTrue = bearingIsTrue; + DistanceToDestination = distanceToDestination; + } + public override byte CommandByte => 0x85; public override byte ExpectedLength => 0x9; @@ -50,7 +62,7 @@ public override byte[] CreateDatagram() byte flags = 0; byte[] data = new byte[9]; data[0] = CommandByte; - data[1] = ExpectedLength; + data[1] = (byte)(ExpectedLength - 3); if (CrossTrackError.HasValue) { double nmTimes100 = CrossTrackError.Value.NauticalMiles * 100.0; diff --git a/src/devices/Seatalk1/Messages/SeatalkMessage.cs b/src/devices/Seatalk1/Messages/SeatalkMessage.cs index f63fd68789..f9ece71d7f 100644 --- a/src/devices/Seatalk1/Messages/SeatalkMessage.cs +++ b/src/devices/Seatalk1/Messages/SeatalkMessage.cs @@ -100,7 +100,7 @@ protected virtual void VerifyPacket(IReadOnlyList data) public virtual bool Equals(SeatalkMessage? other) { - if (other == null) + if (ReferenceEquals(other, null)) { return false; } diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index 5dc1de8971..57996ab8ce 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -79,6 +79,8 @@ public Seatalk1Parser(Stream inputStream) public event Action? NewMessageDecoded; + internal List MessageTypes => _messageFactories; + public void RegisterMessageType(SeatalkMessage message) { if (message.ExpectedLength > 18) diff --git a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs index 2011143291..6ca88f3dcf 100644 --- a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs +++ b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs @@ -285,6 +285,7 @@ public void ToStringTest() [Fact] public void SetToAutoRemotely() { + SetToStandby(); Keystroke ks = new Keystroke(AutopilotButtons.Auto, 1); // We expect that it's automatically guessing the "nearer" direction right _interface.Setup(x => x.SendMessage(It.IsAny())).Callback(i => { @@ -300,7 +301,8 @@ public void SetToAutoRemotely() }).Returns(true); - Assert.True(_testee.SetStatus(AutopilotStatus.Auto)); + TurnDirection? ignore = TurnDirection.Starboard; + Assert.True(_testee.SetStatus(AutopilotStatus.Auto, ref ignore)); } } } diff --git a/src/devices/Seatalk1/tests/MessageTests.cs b/src/devices/Seatalk1/tests/MessageTests.cs index 645f37d0c4..4e8a217ca1 100644 --- a/src/devices/Seatalk1/tests/MessageTests.cs +++ b/src/devices/Seatalk1/tests/MessageTests.cs @@ -134,13 +134,13 @@ public void NavigationToWaypointMessage2() byte[] data = n.CreateDatagram(); // Cross track error Assert.Equal(0x85, data[0]); - Assert.Equal(0xb6, data[1]); - Assert.Equal(0xef, data[2]); + Assert.Equal(0x56, data[1]); + Assert.Equal(0x10, data[2]); // Distance Assert.Equal(0x10, data[4] & 0xF0); Assert.Equal(0x20, data[5]); - Assert.Equal(0x00, data[6] & 0xF0); + Assert.Equal(0x40, data[6] & 0xF0); // Bearing Assert.Equal(0x08, data[3]); diff --git a/src/devices/Seatalk1/tests/Seatalk1Tests.cs b/src/devices/Seatalk1/tests/Seatalk1Tests.cs index 199dbff073..c185ae5ed0 100644 --- a/src/devices/Seatalk1/tests/Seatalk1Tests.cs +++ b/src/devices/Seatalk1/tests/Seatalk1Tests.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using System.IO; using System.IO.Ports; +using System.Security.Cryptography.X509Certificates; using System.Threading; using Iot.Device.Seatalk1; using Iot.Device.Seatalk1.Messages; @@ -154,6 +155,24 @@ public void ParityBitCheckForMessageWithOddCommandByte() Assert.Equal(Parity.Even, withParity[2].P); } + [Fact] + public void CanBasicRoundTripMessages() + { + MemoryStream ms = new MemoryStream(); + + Seatalk1Parser parser = new Seatalk1Parser(ms); + foreach (var m in parser.MessageTypes) + { + // we already have an instance of each message type + byte[] data = m.CreateDatagram(); + var decoded = parser.GetTypeOfNextMessage(data, out int bytesOfNewMessage); + Assert.NotNull(decoded); + Assert.NotEqual(0, bytesOfNewMessage); + Assert.Equal(m.GetType(), decoded.GetType()); + Assert.Equal(m, decoded); + } + } + private static MemoryStream GetStreamFromInputString(string data) { var split = data.Split(new char[] { '\n', '\r', ' ' }, StringSplitOptions.RemoveEmptyEntries); From bfa3c70b81e86affccd8c9347b1edd41e0387de9 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Wed, 3 Jan 2024 20:45:26 +0100 Subject: [PATCH 17/31] Add Schematic for interface --- .../schematics/SeaTalk1/BC547_and_BC557.lib | 26 + .../Seatalk1/schematics/SeaTalk1/Leds.lib | 3 + .../schematics/SeaTalk1/SeaTalk1.kicad_pcb | 2 + .../schematics/SeaTalk1/SeaTalk1.kicad_prl | 77 + .../schematics/SeaTalk1/SeaTalk1.kicad_pro | 340 ++ .../schematics/SeaTalk1/SeaTalk1.kicad_sch | 2752 +++++++++++++++++ .../Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk | 17 + 7 files changed, 3217 insertions(+) create mode 100644 src/devices/Seatalk1/schematics/SeaTalk1/BC547_and_BC557.lib create mode 100644 src/devices/Seatalk1/schematics/SeaTalk1/Leds.lib create mode 100644 src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb create mode 100644 src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl create mode 100644 src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro create mode 100644 src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch create mode 100644 src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/BC547_and_BC557.lib b/src/devices/Seatalk1/schematics/SeaTalk1/BC547_and_BC557.lib new file mode 100644 index 0000000000..d085164072 --- /dev/null +++ b/src/devices/Seatalk1/schematics/SeaTalk1/BC547_and_BC557.lib @@ -0,0 +1,26 @@ +*Models for bc547a and similar transistors + +.model bc547a NPN BF=400 NE=1.3 ISE=10.3F IKF=50M IS=10F VAF=80 ikr=12m ++ BR=9.5 NC=2 VAR=10 RB=280 RE=1 RC=40 VJE=0.48 tr=0.3u tf=0.5n ++ cje=12p vje=0.48 mje=0.5 cjc=6p vjc=0.7 ++ mjc=0.33 isc=47p kf=2f + +.model bc547b NPN BF=500 NE=1.3 ISE=9.72F IKF=80M IS=20F VAF=50 ikr=12m ++ BR=10 NC=2 VAR=10 RB=280 RE=1 RC=40 VJE=.48 tr=.3u tf=.5n ++cje=12p vje=.48 mje=.5 cjc=6p vjc=.7 mjc=.33 isc=47p kf=2f + +.model bc547c NPN BF=730 NE=1.4 ISE=29.5F IKF=80M IS=60F VAF=25 ikr=12m ++ BR=10 NC=2 VAR=10 RB=280 RE=1 RC=40 VJE=.48 tr=.3u tf=.5n ++cje=12p vje=.48 mje=.5 cjc=6p vjc=.7 mjc=.33 isc=47.6p kf=2f + +.model BC557a PNP BF=190 NE=1.5 ISE=12F IKF=90M IS=10F VAF=50 ikr=12m ++ nc=2 br=4 var=10 rb=280 re=1 rc=40 vje=.48 tf=.5n tr=.3u ++cje=12p vje=.48 mje=.5 cjc=6p vjc=.7 mjc=.33 isc=47.6p kf=2f + +.model BC557b PNP BF=335 NE=1.5 ISE=7.35F IKF=82M IS=10F VAF=40 ikr=12m ++ nc=2 br=4 var=10 rb=280 re=1 rc=40 vje=.48 tf=.5n tr=.3u ++cje=12p vje=.48 mje=.5 cjc=6p vjc=.7 mjc=.33 isc=47.6p kf=2f + +.model BC557c PNP BF=490 NE=1.5 ISE=12.4F IKF=78M IS=60F VAF=36 ikr=12m ++ nc=2 br=4 var=10 rb=280 re=1 rc=40 vje=.48 tf=.5n tr=.3u ++cje=12p vje=.48 mje=.5 cjc=6p vjc=.7 mjc=.33 isc=47.6p kf=2f diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/Leds.lib b/src/devices/Seatalk1/schematics/SeaTalk1/Leds.lib new file mode 100644 index 0000000000..9b2a9a6ad7 --- /dev/null +++ b/src/devices/Seatalk1/schematics/SeaTalk1/Leds.lib @@ -0,0 +1,3 @@ +.model DLED_Sim D (IS=1a RS=3.3 N=1.8) + +.model DLED_Nichia D (IS=2.5939E-13 N=4.0113 RS=0.24229 IKF=0 EG=3 XTI=25) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb new file mode 100644 index 0000000000..2b8ba102de --- /dev/null +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb @@ -0,0 +1,2 @@ +(kicad_pcb (version 20221018) (generator pcbnew) +) \ No newline at end of file diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl new file mode 100644 index 0000000000..30061e2286 --- /dev/null +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl @@ -0,0 +1,77 @@ +{ + "board": { + "active_layer": 0, + "active_layer_preset": "", + "auto_track_width": true, + "hidden_netclasses": [], + "hidden_nets": [], + "high_contrast_mode": 0, + "net_color_mode": 1, + "opacity": { + "images": 0.6, + "pads": 1.0, + "tracks": 1.0, + "vias": 1.0, + "zones": 0.6 + }, + "selection_filter": { + "dimensions": true, + "footprints": true, + "graphics": true, + "keepouts": true, + "lockedItems": false, + "otherItems": true, + "pads": true, + "text": true, + "tracks": true, + "vias": true, + "zones": true + }, + "visible_items": [ + 0, + 1, + 2, + 3, + 4, + 5, + 8, + 9, + 10, + 11, + 12, + 13, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 32, + 33, + 34, + 35, + 36, + 39, + 40 + ], + "visible_layers": "fffffff_ffffffff", + "zone_display_mode": 0 + }, + "meta": { + "filename": "SeaTalk1.kicad_prl", + "version": 3 + }, + "project": { + "files": [] + } +} diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro new file mode 100644 index 0000000000..a89b285be6 --- /dev/null +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro @@ -0,0 +1,340 @@ +{ + "board": { + "3dviewports": [], + "design_settings": { + "defaults": { + "board_outline_line_width": 0.1, + "copper_line_width": 0.2, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "other_line_width": 0.15, + "silk_line_width": 0.15, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.15 + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "rules": { + "min_copper_edge_clearance": 0.0, + "solder_mask_clearance": 0.0, + "solder_mask_min_width": 0.0 + }, + "track_widths": [], + "via_dimensions": [] + }, + "layer_presets": [], + "viewports": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "conflicting_netclasses": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "endpoint_off_grid": "warning", + "extra_units": "error", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "lib_symbol_issues": "warning", + "missing_bidi_pin": "warning", + "missing_input_pin": "warning", + "missing_power_pin": "error", + "missing_unit": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "warning", + "pin_not_driven": "error", + "pin_to_pin": "error", + "power_pin_not_driven": "error", + "similar_labels": "warning", + "simulation_model_issue": "warning", + "unannotated": "error", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "SeaTalk1.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.25, + "via_diameter": 0.8, + "via_drill": 0.4, + "wire_width": 6 + } + ], + "meta": { + "version": 3 + }, + "net_colors": null, + "netclass_assignments": null, + "netclass_patterns": [] + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "specctra_dsn": "", + "step": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "drawing": { + "dashed_lines_dash_length_ratio": 12.0, + "dashed_lines_gap_length_ratio": 3.0, + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "field_names": [], + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.375, + "pin_symbol_size": 25.0, + "text_offset_ratio": 0.15 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "ngspice": { + "fix_include_paths": true, + "meta": { + "version": 0 + }, + "model_mode": 1, + "workbook_filename": "SeaTalk1.wbk" + }, + "page_layout_descr_file": "", + "plot_directory": "", + "spice_current_sheet_as_root": false, + "spice_external_command": "spice \"%I\"", + "spice_model_current_sheet_as_root": true, + "spice_save_all_currents": false, + "spice_save_all_voltages": false, + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "fef6b826-4a15-4295-9e8e-e163f69cffe7", + "" + ] + ], + "text_variables": {} +} diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch new file mode 100644 index 0000000000..d522ba0690 --- /dev/null +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch @@ -0,0 +1,2752 @@ +(kicad_sch (version 20230121) (generator eeschema) + + (uuid fef6b826-4a15-4295-9e8e-e163f69cffe7) + + (paper "A4") + + (title_block + (title "Seatalk1 Interface") + (date "2023-12-27") + (rev "1") + (comment 1 "This schematic is available under the MIT license") + ) + + (lib_symbols + (symbol "Connector:Conn_01x03_Pin" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes) + (property "Reference" "J" (at 0 5.08 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "Conn_01x03_Pin" (at 0 -5.08 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_locked" "" (at 0 0 0) + (effects (font (size 1.27 1.27))) + ) + (property "ki_keywords" "connector" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Generic connector, single row, 01x03, script generated" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "Connector*:*_1x??_*" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "Conn_01x03_Pin_1_1" + (polyline + (pts + (xy 1.27 -2.54) + (xy 0.8636 -2.54) + ) + (stroke (width 0.1524) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 0) + (xy 0.8636 0) + ) + (stroke (width 0.1524) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 2.54) + (xy 0.8636 2.54) + ) + (stroke (width 0.1524) (type default)) + (fill (type none)) + ) + (rectangle (start 0.8636 -2.413) (end 0 -2.667) + (stroke (width 0.1524) (type default)) + (fill (type outline)) + ) + (rectangle (start 0.8636 0.127) (end 0 -0.127) + (stroke (width 0.1524) (type default)) + (fill (type outline)) + ) + (rectangle (start 0.8636 2.667) (end 0 2.413) + (stroke (width 0.1524) (type default)) + (fill (type outline)) + ) + (pin passive line (at 5.08 2.54 180) (length 3.81) + (name "Pin_1" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 0 180) (length 3.81) + (name "Pin_2" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -2.54 180) (length 3.81) + (name "Pin_3" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Connector:Raspberry_Pi_2_3" (pin_names (offset 1.016)) (in_bom yes) (on_board yes) + (property "Reference" "J" (at -17.78 31.75 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Value" "Raspberry_Pi_2_3" (at 10.16 -31.75 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + (property "Footprint" "" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/rpi_SCH_3bplus_1p0_reduced.pdf" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "raspberrypi gpio" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "expansion header for Raspberry Pi 2 & 3" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "PinHeader*2x20*P2.54mm*Vertical* PinSocket*2x20*P2.54mm*Vertical*" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "Raspberry_Pi_2_3_0_1" + (rectangle (start -17.78 30.48) (end 17.78 -30.48) + (stroke (width 0.254) (type default)) + (fill (type background)) + ) + ) + (symbol "Raspberry_Pi_2_3_1_1" + (rectangle (start -16.891 -17.526) (end -17.78 -18.034) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 -14.986) (end -17.78 -15.494) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 -12.446) (end -17.78 -12.954) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 -9.906) (end -17.78 -10.414) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 -7.366) (end -17.78 -7.874) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 -4.826) (end -17.78 -5.334) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 0.254) (end -17.78 -0.254) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 2.794) (end -17.78 2.286) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 5.334) (end -17.78 4.826) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 10.414) (end -17.78 9.906) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 12.954) (end -17.78 12.446) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 15.494) (end -17.78 14.986) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 20.574) (end -17.78 20.066) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -16.891 23.114) (end -17.78 22.606) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -10.414 -29.591) (end -9.906 -30.48) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -7.874 -29.591) (end -7.366 -30.48) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -5.334 -29.591) (end -4.826 -30.48) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -5.334 30.48) (end -4.826 29.591) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -2.794 -29.591) (end -2.286 -30.48) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -2.794 30.48) (end -2.286 29.591) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start -0.254 -29.591) (end 0.254 -30.48) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 2.286 -29.591) (end 2.794 -30.48) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 2.286 30.48) (end 2.794 29.591) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 4.826 -29.591) (end 5.334 -30.48) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 4.826 30.48) (end 5.334 29.591) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 7.366 -29.591) (end 7.874 -30.48) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 -20.066) (end 16.891 -20.574) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 -17.526) (end 16.891 -18.034) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 -12.446) (end 16.891 -12.954) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 -9.906) (end 16.891 -10.414) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 -7.366) (end 16.891 -7.874) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 -4.826) (end 16.891 -5.334) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 -2.286) (end 16.891 -2.794) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 2.794) (end 16.891 2.286) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 5.334) (end 16.891 4.826) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 7.874) (end 16.891 7.366) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 12.954) (end 16.891 12.446) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 15.494) (end 16.891 14.986) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 20.574) (end 16.891 20.066) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 17.78 23.114) (end 16.891 22.606) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (pin power_in line (at 2.54 33.02 270) (length 2.54) + (name "3V3" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 20.32 0) (length 2.54) + (name "GPIO15/RXD" (effects (font (size 1.27 1.27)))) + (number "10" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 12.7 0) (length 2.54) + (name "GPIO17" (effects (font (size 1.27 1.27)))) + (number "11" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 10.16 0) (length 2.54) + (name "GPIO18/PWM0" (effects (font (size 1.27 1.27)))) + (number "12" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 -17.78 0) (length 2.54) + (name "GPIO27" (effects (font (size 1.27 1.27)))) + (number "13" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at -5.08 -33.02 90) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "14" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 -5.08 0) (length 2.54) + (name "GPIO22" (effects (font (size 1.27 1.27)))) + (number "15" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 -7.62 0) (length 2.54) + (name "GPIO23" (effects (font (size 1.27 1.27)))) + (number "16" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at 5.08 33.02 270) (length 2.54) + (name "3V3" (effects (font (size 1.27 1.27)))) + (number "17" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 -10.16 0) (length 2.54) + (name "GPIO24" (effects (font (size 1.27 1.27)))) + (number "18" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 -10.16 180) (length 2.54) + (name "MOSI0/GPIO10" (effects (font (size 1.27 1.27)))) + (number "19" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at -5.08 33.02 270) (length 2.54) + (name "5V" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at -2.54 -33.02 90) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "20" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 -7.62 180) (length 2.54) + (name "MISO0/GPIO9" (effects (font (size 1.27 1.27)))) + (number "21" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 -12.7 0) (length 2.54) + (name "GPIO25" (effects (font (size 1.27 1.27)))) + (number "22" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 -12.7 180) (length 2.54) + (name "SCLK0/GPIO11" (effects (font (size 1.27 1.27)))) + (number "23" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 -5.08 180) (length 2.54) + (name "~{CE0}/GPIO8" (effects (font (size 1.27 1.27)))) + (number "24" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at 0 -33.02 90) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "25" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 -2.54 180) (length 2.54) + (name "~{CE1}/GPIO7" (effects (font (size 1.27 1.27)))) + (number "26" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 22.86 180) (length 2.54) + (name "ID_SD/GPIO0" (effects (font (size 1.27 1.27)))) + (number "27" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 20.32 180) (length 2.54) + (name "ID_SC/GPIO1" (effects (font (size 1.27 1.27)))) + (number "28" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 5.08 180) (length 2.54) + (name "GCLK1/GPIO5" (effects (font (size 1.27 1.27)))) + (number "29" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 15.24 180) (length 2.54) + (name "SDA/GPIO2" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at 2.54 -33.02 90) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "30" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 2.54 180) (length 2.54) + (name "GCLK2/GPIO6" (effects (font (size 1.27 1.27)))) + (number "31" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 -17.78 180) (length 2.54) + (name "PWM0/GPIO12" (effects (font (size 1.27 1.27)))) + (number "32" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 -20.32 180) (length 2.54) + (name "PWM1/GPIO13" (effects (font (size 1.27 1.27)))) + (number "33" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at 5.08 -33.02 90) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "34" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 5.08 0) (length 2.54) + (name "GPIO19/MISO1" (effects (font (size 1.27 1.27)))) + (number "35" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 15.24 0) (length 2.54) + (name "GPIO16" (effects (font (size 1.27 1.27)))) + (number "36" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 -15.24 0) (length 2.54) + (name "GPIO26" (effects (font (size 1.27 1.27)))) + (number "37" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 2.54 0) (length 2.54) + (name "GPIO20/MOSI1" (effects (font (size 1.27 1.27)))) + (number "38" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at 7.62 -33.02 90) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "39" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at -2.54 33.02 270) (length 2.54) + (name "5V" (effects (font (size 1.27 1.27)))) + (number "4" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 0 0) (length 2.54) + (name "GPIO21/SCLK1" (effects (font (size 1.27 1.27)))) + (number "40" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 12.7 180) (length 2.54) + (name "SCL/GPIO3" (effects (font (size 1.27 1.27)))) + (number "5" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at -10.16 -33.02 90) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "6" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at 20.32 7.62 180) (length 2.54) + (name "GCLK0/GPIO4" (effects (font (size 1.27 1.27)))) + (number "7" (effects (font (size 1.27 1.27)))) + ) + (pin bidirectional line (at -20.32 22.86 0) (length 2.54) + (name "GPIO14/TXD" (effects (font (size 1.27 1.27)))) + (number "8" (effects (font (size 1.27 1.27)))) + ) + (pin power_in line (at -7.62 -33.02 90) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "9" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Device:C_Polarized" (pin_numbers hide) (pin_names (offset 0.254)) (in_bom yes) (on_board yes) + (property "Reference" "C" (at 0.635 2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "C_Polarized" (at 0.635 -2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 0.9652 -3.81 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "cap capacitor" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Polarized capacitor" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "CP_*" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "C_Polarized_0_1" + (rectangle (start -2.286 0.508) (end 2.286 1.016) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy -1.778 2.286) + (xy -0.762 2.286) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy -1.27 2.794) + (xy -1.27 1.778) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (rectangle (start 2.286 -0.508) (end -2.286 -1.016) + (stroke (width 0) (type default)) + (fill (type outline)) + ) + ) + (symbol "C_Polarized_1_1" + (pin passive line (at 0 3.81 270) (length 2.794) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -3.81 90) (length 2.794) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Device:LED" (pin_numbers hide) (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes) + (property "Reference" "D" (at 0 2.54 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "LED" (at 0 -2.54 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "LED diode" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Light emitting diode" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "LED* LED_SMD:* LED_THT:*" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "LED_0_1" + (polyline + (pts + (xy -1.27 -1.27) + (xy -1.27 1.27) + ) + (stroke (width 0.254) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy -1.27 0) + (xy 1.27 0) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 -1.27) + (xy 1.27 1.27) + (xy -1.27 0) + (xy 1.27 -1.27) + ) + (stroke (width 0.254) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy -3.048 -0.762) + (xy -4.572 -2.286) + (xy -3.81 -2.286) + (xy -4.572 -2.286) + (xy -4.572 -1.524) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy -1.778 -0.762) + (xy -3.302 -2.286) + (xy -2.54 -2.286) + (xy -3.302 -2.286) + (xy -3.302 -1.524) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + ) + (symbol "LED_1_1" + (pin passive line (at -3.81 0 0) (length 2.54) + (name "K" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 3.81 0 180) (length 2.54) + (name "A" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "R" (at 2.032 0 90) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "R" (at 0 0 90) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (at -1.778 0 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "R res resistor" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Resistor" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "R_*" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "R_0_1" + (rectangle (start -1.016 -2.54) (end 1.016 2.54) + (stroke (width 0.254) (type default)) + (fill (type none)) + ) + ) + (symbol "R_1_1" + (pin passive line (at 0 3.81 270) (length 1.27) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -3.81 90) (length 1.27) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Simulation_SPICE:0" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "#GND" (at 0 -2.54 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "0" (at 0 -1.778 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "simulation" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "0V reference potential for simulation" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "0_0_1" + (polyline + (pts + (xy -1.27 0) + (xy 0 -1.27) + (xy 1.27 0) + (xy -1.27 0) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + ) + (symbol "0_1_1" + (pin power_in line (at 0 0 0) (length 0) hide + (name "0" (effects (font (size 1.016 1.016)))) + (number "1" (effects (font (size 1.016 1.016)))) + ) + ) + ) + (symbol "Simulation_SPICE:VDC" (pin_numbers hide) (pin_names (offset 0.0254)) (in_bom yes) (on_board yes) + (property "Reference" "V" (at 2.54 2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "1" (at 2.54 0 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "DC" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "V" (at 0 0 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "ki_keywords" "simulation" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Voltage source, DC" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "VDC_0_0" + (polyline + (pts + (xy -1.27 0.254) + (xy 1.27 0.254) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy -0.762 -0.254) + (xy -1.27 -0.254) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 0.254 -0.254) + (xy -0.254 -0.254) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 -0.254) + (xy 0.762 -0.254) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (text "+" (at 0 1.905 0) + (effects (font (size 1.27 1.27))) + ) + ) + (symbol "VDC_0_1" + (circle (center 0 0) (radius 2.54) + (stroke (width 0.254) (type default)) + (fill (type background)) + ) + ) + (symbol "VDC_1_1" + (pin passive line (at 0 5.08 270) (length 2.54) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -5.08 90) (length 2.54) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Simulation_SPICE:VPULSE" (pin_numbers hide) (pin_names (offset 0.0254)) (in_bom yes) (on_board yes) + (property "Reference" "V" (at 2.54 2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "VPULSE" (at 2.54 0 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "PULSE" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "V" (at 0 0 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Params" "y1=0 y2=1 td=2n tr=2n tf=2n tw=50n per=100n" (at 2.54 -2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "ki_keywords" "simulation" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Voltage source, pulse" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "VPULSE_0_0" + (polyline + (pts + (xy -2.032 -0.762) + (xy -1.397 -0.762) + (xy -1.143 0.762) + (xy -0.127 0.762) + (xy 0.127 -0.762) + (xy 1.143 -0.762) + (xy 1.397 0.762) + (xy 2.032 0.762) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (text "+" (at 0 1.905 0) + (effects (font (size 1.27 1.27))) + ) + ) + (symbol "VPULSE_0_1" + (circle (center 0 0) (radius 2.54) + (stroke (width 0.254) (type default)) + (fill (type background)) + ) + ) + (symbol "VPULSE_1_1" + (pin passive line (at 0 5.08 270) (length 2.54) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -5.08 90) (length 2.54) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Transistor_BJT:BC547" (pin_names (offset 0) hide) (in_bom yes) (on_board yes) + (property "Reference" "Q" (at 5.08 1.905 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "BC547" (at 5.08 0 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" (at 5.08 -1.905 0) + (effects (font (size 1.27 1.27) italic) (justify left) hide) + ) + (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC550-D.pdf" (at 0 0 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "ki_keywords" "NPN Transistor" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "0.1A Ic, 45V Vce, Small Signal NPN Transistor, TO-92" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "TO?92*" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "BC547_0_1" + (polyline + (pts + (xy 0 0) + (xy 0.635 0) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 0.635 0.635) + (xy 2.54 2.54) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 0.635 -0.635) + (xy 2.54 -2.54) + (xy 2.54 -2.54) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 0.635 1.905) + (xy 0.635 -1.905) + (xy 0.635 -1.905) + ) + (stroke (width 0.508) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 -1.778) + (xy 1.778 -1.27) + (xy 2.286 -2.286) + (xy 1.27 -1.778) + (xy 1.27 -1.778) + ) + (stroke (width 0) (type default)) + (fill (type outline)) + ) + (circle (center 1.27 0) (radius 2.8194) + (stroke (width 0.254) (type default)) + (fill (type none)) + ) + ) + (symbol "BC547_1_1" + (pin passive line (at 2.54 5.08 270) (length 2.54) + (name "C" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin input line (at -5.08 0 0) (length 5.08) + (name "B" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 2.54 -5.08 90) (length 2.54) + (name "E" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Transistor_BJT:BC557" (pin_names (offset 0) hide) (in_bom yes) (on_board yes) + (property "Reference" "Q" (at 5.08 1.905 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "BC557" (at 5.08 0 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" (at 5.08 -1.905 0) + (effects (font (size 1.27 1.27) italic) (justify left) hide) + ) + (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC556BTA-D.pdf" (at 0 0 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "ki_keywords" "PNP Transistor" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "0.1A Ic, 45V Vce, PNP Small Signal Transistor, TO-92" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "TO?92*" (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "BC557_0_1" + (polyline + (pts + (xy 0.635 0.635) + (xy 2.54 2.54) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 0.635 -0.635) + (xy 2.54 -2.54) + (xy 2.54 -2.54) + ) + (stroke (width 0) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 0.635 1.905) + (xy 0.635 -1.905) + (xy 0.635 -1.905) + ) + (stroke (width 0.508) (type default)) + (fill (type none)) + ) + (polyline + (pts + (xy 2.286 -1.778) + (xy 1.778 -2.286) + (xy 1.27 -1.27) + (xy 2.286 -1.778) + (xy 2.286 -1.778) + ) + (stroke (width 0) (type default)) + (fill (type outline)) + ) + (circle (center 1.27 0) (radius 2.8194) + (stroke (width 0.254) (type default)) + (fill (type none)) + ) + ) + (symbol "BC557_1_1" + (pin passive line (at 2.54 5.08 270) (length 2.54) + (name "C" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin input line (at -5.08 0 0) (length 5.715) + (name "B" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 2.54 -5.08 90) (length 2.54) + (name "E" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + ) + ) + ) + + (junction (at 124.46 71.12) (diameter 0) (color 0 0 0 0) + (uuid 028aff48-ca27-466e-9422-74624f32b8cd) + ) + (junction (at 241.3 91.44) (diameter 0) (color 0 0 0 0) + (uuid 1bd6faf5-4bcf-4469-a296-cc4f8440ffc6) + ) + (junction (at 129.54 100.33) (diameter 0) (color 0 0 0 0) + (uuid 1d5b8504-e375-4cd5-8629-f63c0589cfe0) + ) + (junction (at 148.59 19.05) (diameter 0) (color 0 0 0 0) + (uuid 1edc3883-1a25-415d-a670-4f9ec9685d65) + ) + (junction (at 228.6 91.44) (diameter 0) (color 0 0 0 0) + (uuid 2add554f-bc83-4d86-bf9c-de1d81a86847) + ) + (junction (at 236.22 161.29) (diameter 0) (color 0 0 0 0) + (uuid 2c3a7927-41d0-47b5-bc63-3a1da5f562c0) + ) + (junction (at 148.59 38.1) (diameter 0) (color 0 0 0 0) + (uuid 2f9af179-68d0-4e40-8430-c84ef94f7bdc) + ) + (junction (at 241.3 19.05) (diameter 0) (color 0 0 0 0) + (uuid 333af6be-105f-445a-8f3e-7e986caf4e58) + ) + (junction (at 168.91 100.33) (diameter 0) (color 0 0 0 0) + (uuid 3f6cc0ad-4335-47bd-b211-8a6bf336c025) + ) + (junction (at 168.91 115.57) (diameter 0) (color 0 0 0 0) + (uuid 48ec1d09-fa57-46c9-a54d-1785131bde38) + ) + (junction (at 124.46 62.23) (diameter 0) (color 0 0 0 0) + (uuid 4c622de1-cfc3-4e54-8fc9-64c3a58efa2b) + ) + (junction (at 85.09 53.34) (diameter 0) (color 0 0 0 0) + (uuid 60ad26a4-e5a2-4756-8545-cb8a8d066d88) + ) + (junction (at 93.98 91.44) (diameter 0) (color 0 0 0 0) + (uuid 63fe69d5-daec-4ed7-b05f-c3dc00e2414b) + ) + (junction (at 134.62 91.44) (diameter 0) (color 0 0 0 0) + (uuid 67635d2e-145c-4c1d-baec-0db0d64f69dd) + ) + (junction (at 93.98 22.86) (diameter 0) (color 0 0 0 0) + (uuid 6f997379-7c7b-4a48-8f4b-8cc545de0b46) + ) + (junction (at 78.74 91.44) (diameter 0) (color 0 0 0 0) + (uuid 6fde8244-ba92-4977-b00e-d5e5037505c0) + ) + (junction (at 55.88 67.31) (diameter 0) (color 0 0 0 0) + (uuid 71951e16-a954-4080-9836-02765d3bee3b) + ) + (junction (at 104.14 91.44) (diameter 0) (color 0 0 0 0) + (uuid 913843ae-a42d-4ec5-bc54-9bb74f618eb8) + ) + (junction (at 248.92 161.29) (diameter 0) (color 0 0 0 0) + (uuid 99cee904-8167-43d9-b5a1-75d8d52fa7af) + ) + (junction (at 148.59 120.65) (diameter 0) (color 0 0 0 0) + (uuid 9e4eddb0-78e8-40fb-a65e-89bf9efd3ed3) + ) + (junction (at 104.14 71.12) (diameter 0) (color 0 0 0 0) + (uuid a0a84e92-30a2-487e-a1ae-a95c01d2941d) + ) + (junction (at 124.46 91.44) (diameter 0) (color 0 0 0 0) + (uuid a7d268f7-32e9-4092-9d89-5d1361add476) + ) + (junction (at 233.68 22.86) (diameter 0) (color 0 0 0 0) + (uuid bb34be9b-b9cd-40cd-97fe-549557c0e323) + ) + (junction (at 238.76 91.44) (diameter 0) (color 0 0 0 0) + (uuid bd060b68-f50f-4a4b-a001-e41b25bba6b6) + ) + (junction (at 262.89 161.29) (diameter 0) (color 0 0 0 0) + (uuid cb75efd0-5091-475c-b9a4-a383ad8715b8) + ) + (junction (at 113.03 125.73) (diameter 0) (color 0 0 0 0) + (uuid d1f7b90a-841d-429a-97bc-3ef1f3ad9d22) + ) + (junction (at 243.84 91.44) (diameter 0) (color 0 0 0 0) + (uuid d51a1750-dc4f-4048-97ed-fa6d6ef5d6da) + ) + (junction (at 148.59 100.33) (diameter 0) (color 0 0 0 0) + (uuid d5f51a30-dfcb-4196-aac5-a0d7f0bc744c) + ) + (junction (at 93.98 71.12) (diameter 0) (color 0 0 0 0) + (uuid d736eead-cbaa-43b0-8dc3-22839d3ea164) + ) + (junction (at 231.14 22.86) (diameter 0) (color 0 0 0 0) + (uuid da35b086-93cc-486a-90d1-17aa47b306d8) + ) + (junction (at 231.14 91.44) (diameter 0) (color 0 0 0 0) + (uuid dbea0063-2988-4ef5-b7fd-ef6aadf5096d) + ) + (junction (at 236.22 91.44) (diameter 0) (color 0 0 0 0) + (uuid e434f566-99fd-4163-ab46-60221e8ba1c6) + ) + (junction (at 233.68 91.44) (diameter 0) (color 0 0 0 0) + (uuid e642a0de-7bac-4eeb-a493-b1206ed4421b) + ) + (junction (at 148.59 160.02) (diameter 0) (color 0 0 0 0) + (uuid e7916721-4296-490d-8c91-bb53f40e85d3) + ) + (junction (at 71.12 53.34) (diameter 0) (color 0 0 0 0) + (uuid e7c05ab6-2bd8-49c0-a635-d0d1fd09c595) + ) + (junction (at 226.06 91.44) (diameter 0) (color 0 0 0 0) + (uuid e8fb63b5-ae2c-42e1-96ce-007c7f91b427) + ) + (junction (at 113.03 160.02) (diameter 0) (color 0 0 0 0) + (uuid ea535c8c-76c3-4fbb-b79e-0dea7f5993cc) + ) + (junction (at 148.59 91.44) (diameter 0) (color 0 0 0 0) + (uuid eb95f643-f29a-46e0-9eb6-27dc165dc446) + ) + (junction (at 238.76 19.05) (diameter 0) (color 0 0 0 0) + (uuid f137c567-e6a0-4665-9b41-c4f1bff4e3b2) + ) + + (wire (pts (xy 129.54 118.11) (xy 129.54 125.73)) + (stroke (width 0) (type default)) + (uuid 00c299e7-faaa-4c4d-8b68-982f28ddbc93) + ) + (wire (pts (xy 233.68 22.86) (xy 266.7 22.86)) + (stroke (width 0) (type default)) + (uuid 01976d1f-e857-47fc-ad6b-71a4c59c2029) + ) + (wire (pts (xy 124.46 91.44) (xy 134.62 91.44)) + (stroke (width 0) (type default)) + (uuid 06afda85-d153-4ddb-ad6e-6d6085e8a731) + ) + (wire (pts (xy 57.15 53.34) (xy 71.12 53.34)) + (stroke (width 0) (type default)) + (uuid 07616570-01cf-4d5f-a6fe-efdb7e5ff878) + ) + (wire (pts (xy 224.79 161.29) (xy 236.22 161.29)) + (stroke (width 0) (type default)) + (uuid 0cdb394d-7b35-4730-8a70-762a1875597f) + ) + (wire (pts (xy 243.84 91.44) (xy 270.51 91.44)) + (stroke (width 0) (type default)) + (uuid 0d2d4a60-9d17-456a-8f29-b95dafcc3d81) + ) + (wire (pts (xy 238.76 91.44) (xy 236.22 91.44)) + (stroke (width 0) (type default)) + (uuid 0e90cdb9-539c-4382-89f3-fb2797a773b4) + ) + (wire (pts (xy 262.89 161.29) (xy 248.92 161.29)) + (stroke (width 0) (type default)) + (uuid 0f4ff432-ab4e-4582-99c1-e76b1e69c085) + ) + (wire (pts (xy 148.59 120.65) (xy 148.59 125.73)) + (stroke (width 0) (type default)) + (uuid 182dcdc1-058b-4a60-9535-239abab67be4) + ) + (wire (pts (xy 93.98 68.58) (xy 93.98 71.12)) + (stroke (width 0) (type default)) + (uuid 19807358-ad40-49e4-93cb-138c1cd3fc58) + ) + (wire (pts (xy 106.68 95.25) (xy 104.14 95.25)) + (stroke (width 0) (type default)) + (uuid 1c27f105-cb8e-432f-b0ff-1055c36422b0) + ) + (wire (pts (xy 241.3 19.05) (xy 238.76 19.05)) + (stroke (width 0) (type default)) + (uuid 1dd160da-7789-4e91-bb49-101ae6cc53ae) + ) + (wire (pts (xy 224.79 132.08) (xy 224.79 137.16)) + (stroke (width 0) (type default)) + (uuid 202ca01e-ec29-4afa-873b-86d103569e2b) + ) + (wire (pts (xy 241.3 19.05) (xy 266.7 19.05)) + (stroke (width 0) (type default)) + (uuid 206c205f-8dab-4ec0-a8bd-bac5347724a5) + ) + (wire (pts (xy 129.54 107.95) (xy 129.54 100.33)) + (stroke (width 0) (type default)) + (uuid 20bc100d-4e13-4951-8cae-306aaeb10e92) + ) + (wire (pts (xy 124.46 53.34) (xy 127 53.34)) + (stroke (width 0) (type default)) + (uuid 222e42b3-d6b3-4ce3-956c-527dd6d7efd8) + ) + (wire (pts (xy 148.59 135.89) (xy 148.59 160.02)) + (stroke (width 0) (type default)) + (uuid 22370f96-3779-412b-8d13-ab550cd9d766) + ) + (wire (pts (xy 104.14 71.12) (xy 104.14 73.66)) + (stroke (width 0) (type default)) + (uuid 24f66ba9-5e65-45aa-9769-2649e40f195f) + ) + (wire (pts (xy 231.14 91.44) (xy 228.6 91.44)) + (stroke (width 0) (type default)) + (uuid 28e430a3-cdd7-4697-9b02-ca9708701734) + ) + (wire (pts (xy 236.22 91.44) (xy 233.68 91.44)) + (stroke (width 0) (type default)) + (uuid 2a2ca6ea-8390-498d-8a09-2378bc201b0c) + ) + (wire (pts (xy 58.42 113.03) (xy 96.52 113.03)) + (stroke (width 0) (type default)) + (uuid 2abb512a-db72-4e2a-9120-c1aacf308d65) + ) + (wire (pts (xy 55.88 64.77) (xy 78.74 64.77)) + (stroke (width 0) (type default)) + (uuid 2b9a13b7-2a69-42f5-920e-efd345e7e88c) + ) + (wire (pts (xy 238.76 19.05) (xy 238.76 25.4)) + (stroke (width 0) (type default)) + (uuid 332c1d5f-cdf1-4103-9fe1-0e1d703602f2) + ) + (wire (pts (xy 93.98 22.86) (xy 231.14 22.86)) + (stroke (width 0) (type default)) + (uuid 3504c25b-c266-4edc-bf23-66089abff71a) + ) + (wire (pts (xy 93.98 71.12) (xy 104.14 71.12)) + (stroke (width 0) (type default)) + (uuid 3d5ea4ae-a29c-4afc-99c6-4f313dfb4cab) + ) + (wire (pts (xy 78.74 91.44) (xy 93.98 91.44)) + (stroke (width 0) (type default)) + (uuid 40862c9d-c9cf-436f-828f-d8fe8ad5169c) + ) + (wire (pts (xy 93.98 22.86) (xy 85.09 22.86)) + (stroke (width 0) (type default)) + (uuid 41eed07a-a86b-4a64-9cf1-023e913aa4c3) + ) + (wire (pts (xy 22.86 91.44) (xy 78.74 91.44)) + (stroke (width 0) (type default)) + (uuid 4481d758-7dcf-4af6-86df-5a2940430e75) + ) + (wire (pts (xy 93.98 58.42) (xy 93.98 60.96)) + (stroke (width 0) (type default)) + (uuid 450e7a3b-76d3-47b6-b23b-7b8e9883ce80) + ) + (wire (pts (xy 203.2 35.56) (xy 215.9 35.56)) + (stroke (width 0) (type default)) + (uuid 452060c5-3f97-48a1-b7a2-74ca2d0d8252) + ) + (wire (pts (xy 71.12 30.48) (xy 71.12 53.34)) + (stroke (width 0) (type default)) + (uuid 45710f38-26a7-4688-85be-54a6e32b00b3) + ) + (wire (pts (xy 168.91 105.41) (xy 168.91 100.33)) + (stroke (width 0) (type default)) + (uuid 47e32fdd-b11f-4fde-b4ca-3adcbfe4169c) + ) + (wire (pts (xy 104.14 95.25) (xy 104.14 91.44)) + (stroke (width 0) (type default)) + (uuid 48a0cf6f-de36-49d7-909f-349dd7930b6f) + ) + (wire (pts (xy 85.09 53.34) (xy 86.36 53.34)) + (stroke (width 0) (type default)) + (uuid 4b3d62dd-3687-43ec-940f-620f9b3c93a5) + ) + (wire (pts (xy 96.52 113.03) (xy 96.52 120.65)) + (stroke (width 0) (type default)) + (uuid 4daf8146-08c3-4f61-aa4b-20b19fa66d7f) + ) + (wire (pts (xy 113.03 152.4) (xy 113.03 160.02)) + (stroke (width 0) (type default)) + (uuid 4e1338f4-b971-43b9-8d89-4ddf46fe4423) + ) + (wire (pts (xy 168.91 100.33) (xy 184.15 100.33)) + (stroke (width 0) (type default)) + (uuid 5203ffb6-b70a-4af4-88ed-839ac948ccb8) + ) + (wire (pts (xy 93.98 22.86) (xy 93.98 48.26)) + (stroke (width 0) (type default)) + (uuid 53986d54-588b-4b19-b64f-297fc6b169e9) + ) + (wire (pts (xy 148.59 105.41) (xy 148.59 100.33)) + (stroke (width 0) (type default)) + (uuid 5445dd0f-6996-4b88-a6fc-1b4ac493827c) + ) + (wire (pts (xy 93.98 71.12) (xy 93.98 73.66)) + (stroke (width 0) (type default)) + (uuid 5616785c-633b-44aa-98f6-1077520da460) + ) + (wire (pts (xy 124.46 83.82) (xy 124.46 91.44)) + (stroke (width 0) (type default)) + (uuid 5638611c-6a9e-4022-9054-5f7c3068d555) + ) + (wire (pts (xy 228.6 91.44) (xy 226.06 91.44)) + (stroke (width 0) (type default)) + (uuid 5a2bfc69-993b-4173-8737-f7ff8f3d85d0) + ) + (wire (pts (xy 148.59 160.02) (xy 167.64 160.02)) + (stroke (width 0) (type default)) + (uuid 5e2215c9-0b9a-4480-b70b-5e0fffc6842f) + ) + (wire (pts (xy 138.43 113.03) (xy 138.43 120.65)) + (stroke (width 0) (type default)) + (uuid 621877c7-134b-4bdb-9eeb-a62f425b71c4) + ) + (wire (pts (xy 71.12 53.34) (xy 77.47 53.34)) + (stroke (width 0) (type default)) + (uuid 6536fb26-c818-4a30-a617-fa2ec6d474ba) + ) + (wire (pts (xy 148.59 35.56) (xy 148.59 38.1)) + (stroke (width 0) (type default)) + (uuid 659c9797-24f8-4c5b-bd1d-8a54b51a02cf) + ) + (wire (pts (xy 231.14 22.86) (xy 231.14 25.4)) + (stroke (width 0) (type default)) + (uuid 6669daa5-08f0-4acc-9c79-01c1455e0f88) + ) + (wire (pts (xy 22.86 30.48) (xy 22.86 59.69)) + (stroke (width 0) (type default)) + (uuid 668aaf4a-bf41-4c80-952f-ee5222a99d3b) + ) + (wire (pts (xy 233.68 91.44) (xy 231.14 91.44)) + (stroke (width 0) (type default)) + (uuid 67c5b6b1-ca68-41b1-833b-5fb5d67e21e2) + ) + (wire (pts (xy 104.14 71.12) (xy 110.49 71.12)) + (stroke (width 0) (type default)) + (uuid 68eb80fe-cb1e-47ca-8f0f-51c4d30013c8) + ) + (wire (pts (xy 134.62 91.44) (xy 148.59 91.44)) + (stroke (width 0) (type default)) + (uuid 6e4d9651-109b-4b8a-b523-e05257cdb63b) + ) + (wire (pts (xy 233.68 22.86) (xy 233.68 25.4)) + (stroke (width 0) (type default)) + (uuid 6f7b28ef-1ebc-4e0e-a7ed-804c1ad2fe50) + ) + (wire (pts (xy 148.59 38.1) (xy 148.59 57.15)) + (stroke (width 0) (type default)) + (uuid 70743eba-8649-4837-9280-0ed6ff392396) + ) + (wire (pts (xy 134.62 58.42) (xy 134.62 91.44)) + (stroke (width 0) (type default)) + (uuid 73616a01-4faa-4ffd-8d94-19ab712113f5) + ) + (wire (pts (xy 248.92 118.11) (xy 248.92 130.81)) + (stroke (width 0) (type default)) + (uuid 79063825-2d82-4234-a3b2-778ed97a0592) + ) + (wire (pts (xy 22.86 69.85) (xy 22.86 91.44)) + (stroke (width 0) (type default)) + (uuid 7b2f8535-2f2b-4780-aff5-9bf439d12c0a) + ) + (wire (pts (xy 93.98 81.28) (xy 93.98 91.44)) + (stroke (width 0) (type default)) + (uuid 7c4e1592-28c8-420d-8373-6adc2654f538) + ) + (wire (pts (xy 129.54 100.33) (xy 148.59 100.33)) + (stroke (width 0) (type default)) + (uuid 7d30ac54-087c-46a4-98ba-b71ed6d78be2) + ) + (wire (pts (xy 134.62 31.75) (xy 134.62 35.56)) + (stroke (width 0) (type default)) + (uuid 7d6f7221-3f56-4282-82d4-91289b95ec3f) + ) + (wire (pts (xy 241.3 91.44) (xy 238.76 91.44)) + (stroke (width 0) (type default)) + (uuid 820f511d-21c1-4109-abe1-26f33a54f148) + ) + (wire (pts (xy 243.84 91.44) (xy 241.3 91.44)) + (stroke (width 0) (type default)) + (uuid 89ce8bc6-7f6b-4856-a39e-4a545f9d4cda) + ) + (wire (pts (xy 168.91 115.57) (xy 168.91 119.38)) + (stroke (width 0) (type default)) + (uuid 8bf79e71-8dda-4e02-992f-9d684eab025c) + ) + (wire (pts (xy 104.14 81.28) (xy 104.14 91.44)) + (stroke (width 0) (type default)) + (uuid 8c37fbd4-42fa-4ab8-ba24-57cdc86bb211) + ) + (wire (pts (xy 148.59 91.44) (xy 226.06 91.44)) + (stroke (width 0) (type default)) + (uuid 8fa3d46c-f729-415b-adac-1f48951af633) + ) + (wire (pts (xy 93.98 91.44) (xy 93.98 93.98)) + (stroke (width 0) (type default)) + (uuid 901fa84e-927a-4e0a-ad84-2514050ba4df) + ) + (wire (pts (xy 138.43 113.03) (xy 137.16 113.03)) + (stroke (width 0) (type default)) + (uuid 902cd960-7a30-489d-b4b1-29b820037f7a) + ) + (wire (pts (xy 134.62 19.05) (xy 148.59 19.05)) + (stroke (width 0) (type default)) + (uuid 9129feb5-19a4-45a0-a250-e6248498a9f9) + ) + (wire (pts (xy 236.22 118.11) (xy 236.22 130.81)) + (stroke (width 0) (type default)) + (uuid 936c209f-d533-41e4-a51c-089c25ee45a7) + ) + (wire (pts (xy 148.59 19.05) (xy 148.59 27.94)) + (stroke (width 0) (type default)) + (uuid 97fc6270-b096-4834-a0f7-3b73adc27269) + ) + (wire (pts (xy 134.62 19.05) (xy 134.62 24.13)) + (stroke (width 0) (type default)) + (uuid 986df6be-4177-47a1-a0a6-67759be10eac) + ) + (wire (pts (xy 148.59 100.33) (xy 168.91 100.33)) + (stroke (width 0) (type default)) + (uuid 9cfa7a0a-9409-411c-a970-09a18b3031cd) + ) + (wire (pts (xy 148.59 38.1) (xy 215.9 38.1)) + (stroke (width 0) (type default)) + (uuid 9e2a6478-96e0-4aa7-bdff-e15f09055971) + ) + (wire (pts (xy 124.46 62.23) (xy 124.46 71.12)) + (stroke (width 0) (type default)) + (uuid 9fb53aa7-3322-410e-8134-3ed110349727) + ) + (wire (pts (xy 248.92 161.29) (xy 248.92 140.97)) + (stroke (width 0) (type default)) + (uuid a208ba4c-b337-404e-b00f-fde003eb3019) + ) + (wire (pts (xy 129.54 125.73) (xy 113.03 125.73)) + (stroke (width 0) (type default)) + (uuid a96bd147-5b5e-437a-836e-3a7dd78175c8) + ) + (wire (pts (xy 138.43 120.65) (xy 148.59 120.65)) + (stroke (width 0) (type default)) + (uuid a9996425-63e3-4b86-9f15-0a87760adb39) + ) + (wire (pts (xy 156.21 130.81) (xy 168.91 130.81)) + (stroke (width 0) (type default)) + (uuid acf4034f-3bba-4c21-a0fb-e57002a1e0f4) + ) + (wire (pts (xy 46.99 67.31) (xy 55.88 67.31)) + (stroke (width 0) (type default)) + (uuid acf7adc9-995b-4c9a-b999-d816bf39474b) + ) + (wire (pts (xy 262.89 140.97) (xy 262.89 161.29)) + (stroke (width 0) (type default)) + (uuid b1aaa67c-8dd8-4b91-b0aa-079a442b7051) + ) + (wire (pts (xy 118.11 71.12) (xy 124.46 71.12)) + (stroke (width 0) (type default)) + (uuid b2e64cf4-c6fd-4372-b178-0d34f67d5c9b) + ) + (wire (pts (xy 113.03 105.41) (xy 113.03 100.33)) + (stroke (width 0) (type default)) + (uuid b3e88ad6-41c3-49fc-8773-9139c38916fd) + ) + (wire (pts (xy 124.46 53.34) (xy 124.46 62.23)) + (stroke (width 0) (type default)) + (uuid b50b33f9-9974-4323-80bb-00b3c2c55d4e) + ) + (wire (pts (xy 113.03 125.73) (xy 113.03 144.78)) + (stroke (width 0) (type default)) + (uuid b5710270-de76-41aa-b8fe-9f009f8cff25) + ) + (wire (pts (xy 124.46 71.12) (xy 124.46 76.2)) + (stroke (width 0) (type default)) + (uuid b6dfa58d-df5c-46de-843e-c44e82e2388b) + ) + (wire (pts (xy 85.09 44.45) (xy 85.09 53.34)) + (stroke (width 0) (type default)) + (uuid b6edb122-0d4a-408b-a38f-95303db9b51c) + ) + (wire (pts (xy 71.12 53.34) (xy 71.12 67.31)) + (stroke (width 0) (type default)) + (uuid bd458123-e665-4795-9ae8-450cb8a79e3a) + ) + (wire (pts (xy 148.59 19.05) (xy 238.76 19.05)) + (stroke (width 0) (type default)) + (uuid bdab5554-e4c4-45de-ae0e-034832ab27a1) + ) + (wire (pts (xy 78.74 64.77) (xy 78.74 91.44)) + (stroke (width 0) (type default)) + (uuid be0cb463-2824-4c93-a3e4-68c50010e20b) + ) + (wire (pts (xy 224.79 147.32) (xy 224.79 161.29)) + (stroke (width 0) (type default)) + (uuid bf23c6b2-8776-4bae-a52d-d247198afb25) + ) + (wire (pts (xy 85.09 22.86) (xy 85.09 36.83)) + (stroke (width 0) (type default)) + (uuid bf64f970-ef53-4c36-8ac4-49c8b60f02c6) + ) + (wire (pts (xy 267.97 161.29) (xy 262.89 161.29)) + (stroke (width 0) (type default)) + (uuid bfb84e88-4141-45ae-954d-626ec12e011c) + ) + (wire (pts (xy 236.22 161.29) (xy 248.92 161.29)) + (stroke (width 0) (type default)) + (uuid c3065789-50d3-42bb-b0a3-807b4379f96b) + ) + (wire (pts (xy 134.62 43.18) (xy 134.62 48.26)) + (stroke (width 0) (type default)) + (uuid c4547859-0ba7-4c68-a227-2f8f006e8aa9) + ) + (wire (pts (xy 113.03 160.02) (xy 148.59 160.02)) + (stroke (width 0) (type default)) + (uuid c71ebad9-22f3-496c-9b73-5ef0d8a5e47f) + ) + (wire (pts (xy 55.88 67.31) (xy 71.12 67.31)) + (stroke (width 0) (type default)) + (uuid cca0a654-af1e-47e5-b55a-03ca6521b2e8) + ) + (wire (pts (xy 148.59 113.03) (xy 148.59 120.65)) + (stroke (width 0) (type default)) + (uuid ce7d71ee-cdce-412d-be7e-f57b471cc858) + ) + (wire (pts (xy 148.59 67.31) (xy 148.59 91.44)) + (stroke (width 0) (type default)) + (uuid d457545d-3fcc-4d1a-ad12-230425332698) + ) + (wire (pts (xy 140.97 62.23) (xy 124.46 62.23)) + (stroke (width 0) (type default)) + (uuid d6e94bbc-4b7e-406e-a14d-dd9b76c1d3f5) + ) + (wire (pts (xy 60.96 30.48) (xy 71.12 30.48)) + (stroke (width 0) (type default)) + (uuid d6f65a1f-1882-48da-b571-8c495f1ab874) + ) + (wire (pts (xy 96.52 160.02) (xy 113.03 160.02)) + (stroke (width 0) (type default)) + (uuid d9261f2e-2e0c-4e7b-9727-310fd7c8d4d3) + ) + (wire (pts (xy 168.91 115.57) (xy 190.5 115.57)) + (stroke (width 0) (type default)) + (uuid d9f3c6f9-48b5-4430-84b2-b3cdddd985cf) + ) + (wire (pts (xy 113.03 113.03) (xy 113.03 125.73)) + (stroke (width 0) (type default)) + (uuid db011b32-8b32-41ec-8cb9-34117c3ec79c) + ) + (wire (pts (xy 236.22 140.97) (xy 236.22 161.29)) + (stroke (width 0) (type default)) + (uuid dbafdac4-99b9-4ed5-8c8c-8a8fd2aaa381) + ) + (wire (pts (xy 104.14 91.44) (xy 124.46 91.44)) + (stroke (width 0) (type default)) + (uuid e311e9f0-1479-4d99-89df-432133f88945) + ) + (wire (pts (xy 241.3 19.05) (xy 241.3 25.4)) + (stroke (width 0) (type default)) + (uuid e3f73ef8-9f90-4c4a-b4bc-223ac5ce04a7) + ) + (wire (pts (xy 224.79 116.84) (xy 224.79 124.46)) + (stroke (width 0) (type default)) + (uuid e98e9d13-3d71-4ee6-bf72-fa58ce31813e) + ) + (wire (pts (xy 168.91 130.81) (xy 168.91 127)) + (stroke (width 0) (type default)) + (uuid ecb8e0e5-c49a-4c34-a69c-95e4acc4c3cd) + ) + (wire (pts (xy 104.14 125.73) (xy 113.03 125.73)) + (stroke (width 0) (type default)) + (uuid ed4258d0-f82f-4d1e-a000-02800815b56f) + ) + (wire (pts (xy 233.68 22.86) (xy 231.14 22.86)) + (stroke (width 0) (type default)) + (uuid ef541797-9c16-4a14-92a0-5181a5882cca) + ) + (wire (pts (xy 96.52 130.81) (xy 96.52 160.02)) + (stroke (width 0) (type default)) + (uuid efc38956-8ea5-409e-97d1-667213bb5655) + ) + (wire (pts (xy 53.34 30.48) (xy 22.86 30.48)) + (stroke (width 0) (type default)) + (uuid f3936039-5ab9-45b6-8934-c7a9c8962258) + ) + (wire (pts (xy 93.98 91.44) (xy 104.14 91.44)) + (stroke (width 0) (type default)) + (uuid f8293061-f56a-4bbc-91ed-4f1237ae0700) + ) + (wire (pts (xy 168.91 113.03) (xy 168.91 115.57)) + (stroke (width 0) (type default)) + (uuid fbb335b9-473f-40dc-9a76-eccb62aeca08) + ) + (wire (pts (xy 129.54 100.33) (xy 113.03 100.33)) + (stroke (width 0) (type default)) + (uuid fbe9c3d3-0fdc-4ffd-9ee0-d54b0d4365f0) + ) + (wire (pts (xy 262.89 118.11) (xy 262.89 130.81)) + (stroke (width 0) (type default)) + (uuid fe05c879-b14e-440a-ac6b-1542adaabac9) + ) + + (rectangle (start 215.9 102.87) (end 275.59 163.83) + (stroke (width 0) (type default)) + (fill (type color) (color 194 194 194 1)) + (uuid 88379ac3-85fc-4435-b3d8-63c3b7351833) + ) + + (text ".options warn=1" (at 179.07 180.34 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + (uuid 5b2393dc-2858-4734-a0ae-f5fb98f18dac) + ) + (text "Simulation components only" (at 217.17 101.6 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + (uuid b3445cbc-3a63-4202-b51c-b28d86bcef27) + ) + + (global_label "SEATALK" (shape bidirectional) (at 57.15 53.34 180) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid 198f52c9-cf71-4edd-8633-37b8f7313a76) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 45.2521 53.34 0) (show_name) + (effects (font (size 1.27 1.27)) (justify right) hide) + ) + ) + (global_label "SIM_BUS" (shape output) (at 224.79 116.84 90) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 29f71db3-7bff-4ff6-acaa-84fe0e08e66a) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 224.79 105.8115 90) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "TXD" (shape output) (at 203.2 35.56 180) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid 3121f960-5443-441a-b6eb-0e5528d78a8c) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 196.7677 35.56 0) + (effects (font (size 1.27 1.27)) (justify right) hide) + ) + ) + (global_label "GND" (shape passive) (at 167.64 160.02 0) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 3f93229d-0f0b-4294-928e-4f5b5813613b) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 173.3844 160.02 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "SEATALK" (shape bidirectional) (at 58.42 113.03 180) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid 407c5812-314e-49c3-9938-6ef288831654) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 46.5221 113.03 0) (show_name) + (effects (font (size 1.27 1.27)) (justify right) hide) + ) + ) + (global_label "SIM_BUS" (shape input) (at 46.99 67.31 180) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid 5121d1cc-153d-4518-b61d-4b58c488e25b) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 35.9615 67.31 0) + (effects (font (size 1.27 1.27)) (justify right) hide) + ) + ) + (global_label "VCC_3.3" (shape passive) (at 236.22 118.11 90) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 7a64d7eb-50df-4fe0-9ac5-7878eacbbce8) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 236.22 108.6161 90) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "GND" (shape passive) (at 106.68 95.25 0) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 7c64d0e5-79f6-4427-9ac5-d7eff9427f5b) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 112.4244 95.25 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "VCC_5.0" (shape passive) (at 266.7 22.86 0) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 7e710555-a55f-4988-9494-128d9a9b57c7) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 276.1939 22.86 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "VCC_3.3" (shape passive) (at 184.15 100.33 0) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 81042077-9ece-4974-ad5f-149377f8095b) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 193.6439 100.33 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "GND" (shape passive) (at 267.97 161.29 0) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid b45a8b0b-a002-4b9f-af67-752912951233) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 273.7144 161.29 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "VCC_5.0" (shape passive) (at 248.92 118.11 90) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid b580814b-c917-4700-9f80-e80a097ae25b) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 248.92 108.6161 90) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "TXD" (shape output) (at 262.89 118.11 90) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid c69bd050-d2e8-49b7-9f18-ee59dd42d211) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 262.89 111.6777 90) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "TXD" (shape input) (at 190.5 115.57 0) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid dc2ec9f7-8865-4a96-b3b2-310f10e92d85) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 196.9323 115.57 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + (global_label "VCC_3.3" (shape passive) (at 266.7 19.05 0) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid ee191e7e-23b9-4b3a-9f08-b4ef5174e3ff) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 276.1939 19.05 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + ) + + (symbol (lib_id "Device:R") (at 148.59 31.75 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 05087989-f568-4ae5-b297-c298921fe111) + (property "Reference" "R8" (at 151.13 30.48 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "2.2k" (at 151.13 33.02 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 146.812 31.75 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 148.59 31.75 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "R" (at 148.59 31.75 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 148.59 31.75 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 23fd5977-895a-4de9-b4aa-29e651b6afaa)) + (pin "1" (uuid 579306a8-864d-4547-a3b8-09bc519fc2a9)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R8") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 93.98 64.77 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 0512ba43-5f13-4592-bd94-7ec2752829fa) + (property "Reference" "R3" (at 96.52 63.5 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "2.2k" (at 96.52 66.04 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 92.202 64.77 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 93.98 64.77 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "R" (at 93.98 64.77 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 93.98 64.77 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid c5fb0546-c935-4b56-89dd-7cbc18cddd58)) + (pin "1" (uuid dd1e4fb9-6fed-486e-92dd-45d7a391daf4)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R3") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Simulation_SPICE:0") (at 93.98 93.98 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 19fcdd91-a2f5-4b2b-9f11-e0127d3cfd92) + (property "Reference" "#GND01" (at 93.98 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "0" (at 93.98 91.44 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (at 93.98 93.98 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 93.98 93.98 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 811cdd2d-378b-4564-948a-18b0194f45e1)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "#GND01") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 124.46 80.01 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 1e712663-9f97-4762-926c-2b4ce56e9875) + (property "Reference" "R7" (at 127 78.74 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "22k" (at 127 81.28 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 122.682 80.01 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 124.46 80.01 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 718bcf05-afb0-4f58-b927-a125fbb3677b)) + (pin "2" (uuid d4c2291f-b5b5-493c-a651-fd336fabe2c2)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R7") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 224.79 128.27 180) (unit 1) + (in_bom no) (on_board no) (dnp no) (fields_autoplaced) + (uuid 2380401b-e9df-4f16-9e3b-08b946053151) + (property "Reference" "R11" (at 227.33 127 0) + (effects (font (size 1.27 1.27)) (justify right)) + ) + (property "Value" "100" (at 227.33 129.54 0) + (effects (font (size 1.27 1.27)) (justify right)) + ) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 226.568 128.27 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 224.79 128.27 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Remarks" "Simulates wire" (at 224.79 128.27 90) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid b7c93cf5-6831-400a-b49a-f48d2ed2d31a)) + (pin "2" (uuid bab0e589-52b6-450b-a0c0-2819a167d32c)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R11") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Simulation_SPICE:VDC") (at 22.86 64.77 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 27f6dfc4-6d11-4993-be5b-18f0ba52532f) + (property "Reference" "V2" (at 26.67 63.3702 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "12" (at 26.67 65.9102 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 22.86 64.77 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 22.86 64.77 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 22.86 64.77 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "DC" (at 22.86 64.77 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "V" (at 22.86 64.77 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (pin "2" (uuid 22a64731-0d02-4297-846d-46b0f43ff1a9)) + (pin "1" (uuid bfd63275-e1fe-44f8-b205-974e4ec469ed)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "V2") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Transistor_BJT:BC547") (at 99.06 125.73 0) (mirror y) (unit 1) + (in_bom yes) (on_board yes) (dnp no) + (uuid 4e0376b7-268d-4d3c-bc7b-c625228f33d1) + (property "Reference" "Q4" (at 93.98 124.46 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "BC547" (at 93.98 127 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" (at 93.98 127.635 0) + (effects (font (size 1.27 1.27) italic) (justify left) hide) + ) + (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC550-D.pdf" (at 99.06 125.73 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Device" "NPN" (at 99.06 125.73 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "GUMMELPOON" (at 99.06 125.73 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=C 2=B 3=E" (at 99.06 125.73 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Library" "BC547_and_BC557.lib" (at 99.06 125.73 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Name" "bc547b" (at 99.06 125.73 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 3367cd39-97f8-464b-a87a-4f6f3199fd61)) + (pin "1" (uuid 668ea38e-27e2-4722-a035-b12c5a7fa846)) + (pin "3" (uuid 9398563b-f3b1-42a7-8eb5-9b0ec735eed4)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "Q4") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 104.14 77.47 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 4f117a73-66ee-4224-8fe8-71a32870a260) + (property "Reference" "R6" (at 106.68 76.2 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "4.7k" (at 106.68 78.74 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 102.362 77.47 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 104.14 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "R" (at 104.14 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 104.14 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 8808513d-8069-4fe3-9b6d-d064a3065192)) + (pin "1" (uuid 205b156d-26ef-41b7-b527-501fe06c5a82)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R6") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Simulation_SPICE:VPULSE") (at 224.79 142.24 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 520cf6fd-7c36-4222-967b-e5d1fe5a143a) + (property "Reference" "V1" (at 228.6 139.5702 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "VPULSE" (at 228.6 142.1102 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 224.79 142.24 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 224.79 142.24 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 224.79 142.24 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "PULSE" (at 224.79 142.24 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "V" (at 224.79 142.24 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Params" "y1=12 y2=2 td=1m tr=2n tf=2n tw=1m per=2m np=3" (at 228.6 144.6502 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (pin "1" (uuid 075f54ff-0140-4922-8631-014e613fcc3b)) + (pin "2" (uuid e9d8303d-59c0-48cd-883e-9775b2b743e0)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "V1") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 168.91 123.19 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 579a3129-1551-4263-8c06-93d703fd61dd) + (property "Reference" "R10" (at 171.45 121.92 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "1.5k" (at 171.45 124.46 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 167.132 123.19 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 168.91 123.19 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid fadcfb61-48cc-4b27-9352-2a82bf72a90c)) + (pin "2" (uuid fcda8fed-3e64-4caf-bd2d-e14e11e0feb1)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R10") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Connector:Raspberry_Pi_2_3") (at 236.22 58.42 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 58887779-90ab-4780-98be-8f57c4f8f78b) + (property "Reference" "J1" (at 243.4941 22.86 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "Raspberry_Pi_2_3" (at 243.4941 25.4 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Connector_PinSocket_2.54mm:PinSocket_2x20_P2.54mm_Vertical" (at 236.22 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/rpi_SCH_3bplus_1p0_reduced.pdf" (at 236.22 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Enable" "0" (at 236.22 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "30" (uuid 9480ed7e-078d-410d-a689-dc84c1e25f24)) + (pin "35" (uuid 9630f1c2-f63c-4d2b-a862-14f7b46dad99)) + (pin "10" (uuid 47751548-b485-4658-a3cc-455edcd0d745)) + (pin "13" (uuid cc3a8932-8890-470f-a5bc-060adb2583d2)) + (pin "14" (uuid 961490a7-bb94-4450-9326-6da8f7d68030)) + (pin "2" (uuid 59275134-53c4-4f1b-89dd-89d8f70f4071)) + (pin "32" (uuid 66194a78-33f0-44b7-958b-6ddbab6b48b8)) + (pin "37" (uuid dffdac9d-b2f1-4ac9-be42-85771e5b3c92)) + (pin "20" (uuid 99723dac-830e-4798-9b2a-1e8e97efcd9e)) + (pin "12" (uuid 21f8a5d7-1582-43be-b763-dc15e2599ec7)) + (pin "31" (uuid df3a96ed-cdd8-4d0c-9100-d079e4880fd8)) + (pin "23" (uuid f68f7ba2-47fc-47ba-99ff-95af47627038)) + (pin "16" (uuid 98944481-1ba3-4ccd-9e95-ae67c1f6bf7e)) + (pin "21" (uuid ecd1adcc-68c1-42c9-b0aa-a54e6aef7762)) + (pin "6" (uuid 0ca6ab34-7822-459d-b829-d0de68e831bf)) + (pin "19" (uuid afbfedd7-7c68-4c29-8371-8cdc9050141a)) + (pin "28" (uuid 9186a61f-8094-4f45-b162-66bad66a3075)) + (pin "9" (uuid ac1752c3-5834-4710-be1b-deb5958858b0)) + (pin "25" (uuid 4d6044fb-43dc-4410-9ccd-16b5a269ac1b)) + (pin "33" (uuid a2158618-4b7f-4173-8f76-ecc839b3c43f)) + (pin "40" (uuid 14419fc0-0565-46de-9da4-98bc3c67a247)) + (pin "7" (uuid 81c4ec06-f27f-4a3c-aec8-ee65302ad913)) + (pin "29" (uuid 8c6c8ada-657f-4c95-850a-b7b59d05ceeb)) + (pin "4" (uuid 0097ad2e-70c6-4d68-836d-b4fb54fbab2b)) + (pin "34" (uuid c368e4c2-66a7-4f9e-821c-236fd0ce2710)) + (pin "26" (uuid a7dac948-7c59-48ec-b865-5db6f6b5bd48)) + (pin "17" (uuid 484a6157-4f5a-4a2d-aecd-d50ca5adff3d)) + (pin "5" (uuid 978f7a18-95e4-49f5-af64-4cb861e7a5a4)) + (pin "27" (uuid bdde28df-1d31-4583-95f8-5131b173e59d)) + (pin "22" (uuid b5ecece4-a6ca-4f7d-950c-1255e62e554b)) + (pin "39" (uuid 98d2ace0-fac0-4edb-a2fa-78d7f3a8def2)) + (pin "1" (uuid cab3a939-966a-490e-b0dd-deeeddf0d348)) + (pin "15" (uuid 327f3e04-9548-4592-99da-517332607cd3)) + (pin "36" (uuid cb646cf3-2206-40aa-95d8-1efdb95b7e63)) + (pin "38" (uuid c4159ad3-663a-45dd-86c2-6de777616765)) + (pin "8" (uuid 58bbf9f8-a1e7-4e44-bf09-004e70b99514)) + (pin "18" (uuid 8c99e4b4-3bb8-4c9f-ad09-4ac285a133a8)) + (pin "11" (uuid 20de94e6-63c1-453a-a87c-018e12bfc525)) + (pin "3" (uuid 5300d9b1-54b6-4771-8c22-aaf5394ed8ef)) + (pin "24" (uuid e189ee54-0dcd-49e5-b6af-d94cb720711c)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "J1") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 57.15 30.48 270) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 71be8ad0-bfd2-4f59-afd6-b1bb5fcc5604) + (property "Reference" "R12" (at 57.15 24.13 90) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "10k" (at 57.15 26.67 90) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (at 57.15 28.702 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 57.15 30.48 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Remarks" "External pull-up from bus" (at 57.15 30.48 90) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid c7b42ef2-f5f0-4e97-a1ad-b69fd4fc0dba)) + (pin "2" (uuid a5409b60-43b9-4437-b794-08fad3c810ac)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R12") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 134.62 27.94 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 72ecdcab-4412-431f-ae1a-4d8a433bda34) + (property "Reference" "R9" (at 137.16 26.67 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "100" (at 137.16 29.21 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Resistor_THT:R_Axial_DIN0414_L11.9mm_D4.5mm_P15.24mm_Horizontal" (at 132.842 27.94 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 134.62 27.94 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "R" (at 134.62 27.94 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "=" (at 134.62 27.94 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Params" "r=100" (at 134.62 27.94 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 134.62 27.94 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 861f3a84-52ac-43ea-9c29-79b0d54de8c7)) + (pin "1" (uuid 1d8c2ac8-ec61-4c66-b17e-6cb52d228bf2)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R9") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Transistor_BJT:BC547") (at 132.08 53.34 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 7762f63f-936a-4d38-a129-b66d3e12b33b) + (property "Reference" "Q3" (at 137.16 52.07 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "BC547" (at 137.16 54.61 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" (at 137.16 55.245 0) + (effects (font (size 1.27 1.27) italic) (justify left) hide) + ) + (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC550-D.pdf" (at 132.08 53.34 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Device" "NPN" (at 132.08 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "GUMMELPOON" (at 132.08 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=C 2=B 3=E" (at 132.08 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Library" "BC547_and_BC557.lib" (at 132.08 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Name" "bc547b" (at 132.08 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Params" "temp=20" (at 132.08 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid da7fff44-1bca-4aef-a89e-947384f9e451)) + (pin "1" (uuid b9f98078-d730-4e82-9708-1d0ddae25c5c)) + (pin "3" (uuid fc87a471-71b7-4dbe-a28d-8169194fe763)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "Q3") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Transistor_BJT:BC547") (at 151.13 130.81 0) (mirror y) (unit 1) + (in_bom yes) (on_board yes) (dnp no) + (uuid 7a1d8624-75b3-40d9-8367-28b38d93d05c) + (property "Reference" "Q5" (at 146.05 129.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "BC547" (at 146.05 132.08 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" (at 146.05 132.715 0) + (effects (font (size 1.27 1.27) italic) (justify left) hide) + ) + (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC550-D.pdf" (at 151.13 130.81 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Device" "NPN" (at 151.13 130.81 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "GUMMELPOON" (at 151.13 130.81 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=C 2=B 3=E" (at 151.13 130.81 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Library" "BC547_and_BC557.lib" (at 151.13 130.81 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Name" "bc547b" (at 151.13 130.81 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid c62ca8e2-0dde-4551-a266-35e461e0adf1)) + (pin "1" (uuid e752aa40-be11-4ed0-9746-1d2ee4306350)) + (pin "3" (uuid ac05d841-5c8d-43b4-9b40-a905ed79695b)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "Q5") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Connector:Conn_01x03_Pin") (at 50.8 67.31 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 8008b50a-ac2b-42d5-8e97-ecafe76dc831) + (property "Reference" "J3" (at 51.435 59.69 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "Conn_01x03_Pin" (at 51.435 62.23 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical" (at 50.8 67.31 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 50.8 67.31 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Enable" "0" (at 50.8 67.31 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "3" (uuid fd27ed41-2fab-4a7f-8599-5c70cb840497)) + (pin "1" (uuid fa94d794-5b25-4185-bd0b-e430b6cdfa7d)) + (pin "2" (uuid 01af7c04-95fa-4882-b7de-0ead8b96d27d)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "J3") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 93.98 77.47 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 873fd484-3122-4533-8a3d-0b6694e5decf) + (property "Reference" "R4" (at 96.52 76.2 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "4.7k" (at 96.52 78.74 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 92.202 77.47 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 93.98 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "R" (at 93.98 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 93.98 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 850c0ff1-5cfb-432d-b559-5ae329c5e9d9)) + (pin "1" (uuid 81bd7a99-e543-4e2e-b5e9-dc3f85d690d8)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R4") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:LED") (at 134.62 39.37 90) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 88a72208-5af9-4097-94e1-8cb31aaadfea) + (property "Reference" "D1" (at 138.43 39.6875 90) + (effects (font (size 1.27 1.27)) (justify right)) + ) + (property "Value" "LED" (at 138.43 42.2275 90) + (effects (font (size 1.27 1.27)) (justify right)) + ) + (property "Footprint" "LED_THT:LED_D3.0mm_Horizontal_O3.81mm_Z6.0mm" (at 134.62 39.37 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 134.62 39.37 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "D" (at 134.62 39.37 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=A 2=K" (at 134.62 39.37 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Params" "is=259.39f rs=0.24229 n=4.0113 ikf=0 eg=3 xtitun=25" (at 134.62 39.37 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 2a7e67eb-09da-4759-853a-db9309bb07cf)) + (pin "1" (uuid cd299df1-148c-4e6a-a30a-37e9b22e3db4)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "D1") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 113.03 148.59 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 8b0fd059-b19f-4565-852a-74e3223bfaf1) + (property "Reference" "R14" (at 115.57 147.32 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "2.2k" (at 115.57 149.86 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 111.252 148.59 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 113.03 148.59 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid dd913944-28c9-4746-9bd0-f01dc889dc9b)) + (pin "1" (uuid c8ea70aa-f98f-4467-bd6e-a45a7d9e8df2)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R14") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Simulation_SPICE:VDC") (at 236.22 135.89 0) (unit 1) + (in_bom no) (on_board no) (dnp no) (fields_autoplaced) + (uuid 8d319acf-73f1-4920-a135-ca5006e07087) + (property "Reference" "V_USB2" (at 240.03 134.4902 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "3.3" (at 240.03 137.0302 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 236.22 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 236.22 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 236.22 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "DC" (at 236.22 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "V" (at 236.22 135.89 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (pin "2" (uuid da8006eb-4425-4fa4-a55a-89cc621706f3)) + (pin "1" (uuid ec7fd62e-9e1a-4a7a-9978-745ed62e78a0)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "V_USB2") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 148.59 109.22 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 94c334ed-1cb5-4404-a652-a5f07f1cffb8) + (property "Reference" "R15" (at 151.13 107.95 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "10k" (at 151.13 110.49 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 146.812 109.22 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 148.59 109.22 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 80d6861b-799a-4c03-9151-b8da83629859)) + (pin "2" (uuid 5892eb60-8354-4c13-bb54-aef39919887d)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R15") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Transistor_BJT:BC547") (at 146.05 62.23 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid 9fb6ea96-3606-4642-89c7-d6759aecd3a2) + (property "Reference" "Q2" (at 151.13 60.96 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "BC547" (at 151.13 63.5 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" (at 151.13 64.135 0) + (effects (font (size 1.27 1.27) italic) (justify left) hide) + ) + (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC550-D.pdf" (at 146.05 62.23 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Device" "NPN" (at 146.05 62.23 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "GUMMELPOON" (at 146.05 62.23 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=C 2=B 3=E" (at 146.05 62.23 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Library" "BC547_and_BC557.lib" (at 146.05 62.23 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Name" "bc547b" (at 146.05 62.23 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid f888593a-740f-4651-be6d-4f4e520939dc)) + (pin "1" (uuid a651270e-f665-4a52-bb8e-5d3c497f6ef6)) + (pin "3" (uuid c431e722-4bcb-4b1b-9d79-759516162690)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "Q2") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 168.91 109.22 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid a88aec3a-89e0-4123-9d67-40bd4310a5ef) + (property "Reference" "R13" (at 171.45 107.95 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "10k" (at 171.45 110.49 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 167.132 109.22 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 168.91 109.22 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 6c7738cd-1b88-47c6-8a3a-d5f1150da7ec)) + (pin "1" (uuid ef7c36bc-0b03-41cb-8993-5066ede9bf19)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R13") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Transistor_BJT:BC547") (at 132.08 113.03 0) (mirror y) (unit 1) + (in_bom yes) (on_board yes) (dnp no) + (uuid aab4eea5-37eb-4106-bd44-0c724bfeaa6e) + (property "Reference" "Q6" (at 127 111.76 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "BC547" (at 127 114.3 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" (at 127 114.935 0) + (effects (font (size 1.27 1.27) italic) (justify left) hide) + ) + (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC550-D.pdf" (at 132.08 113.03 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Device" "NPN" (at 132.08 113.03 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "GUMMELPOON" (at 132.08 113.03 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=C 2=B 3=E" (at 132.08 113.03 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Library" "BC547_and_BC557.lib" (at 132.08 113.03 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Name" "bc547b" (at 132.08 113.03 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 4380ce94-2ec6-4b4e-9d24-a57ee5255d53)) + (pin "1" (uuid 8a32c0a2-5157-46c1-9ffc-90073642e9d0)) + (pin "3" (uuid e20180c7-5e2a-45fe-8ae0-08449c33597e)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "Q6") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 113.03 109.22 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid c3004251-8088-4827-aa14-0a4ce9cc2dcb) + (property "Reference" "R1" (at 115.57 107.95 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "22k" (at 115.57 110.49 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 111.252 109.22 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 113.03 109.22 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 437993f0-7a9d-42e6-87c6-e461b227a337)) + (pin "2" (uuid 88a52db0-12c4-46d5-a901-1dc788c2190d)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R1") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Transistor_BJT:BC557") (at 91.44 53.34 0) (mirror x) (unit 1) + (in_bom yes) (on_board yes) (dnp no) + (uuid e18074c3-15bb-48dd-a644-780be992a99a) + (property "Reference" "Q1" (at 96.52 54.61 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "BC557" (at 96.52 52.07 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" (at 96.52 51.435 0) + (effects (font (size 1.27 1.27) italic) (justify left) hide) + ) + (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC556BTA-D.pdf" (at 91.44 53.34 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Device" "PNP" (at 91.44 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "GUMMELPOON" (at 91.44 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=C 2=B 3=E" (at 91.44 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Library" "BC547_and_BC557.lib" (at 91.44 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Name" "BC557b" (at 91.44 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid ac39719a-1b38-4901-adf8-afb9c6f1b1fc)) + (pin "2" (uuid 4d97f581-84ec-472f-b952-ecd17c27be04)) + (pin "3" (uuid b1b4cd83-1026-4a05-bb55-6c7551efa209)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "Q1") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 81.28 53.34 90) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid e7236bba-1884-40d5-b2d5-3b06582681db) + (property "Reference" "R5" (at 81.28 46.99 90) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "4.7k" (at 81.28 49.53 90) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (at 81.28 55.118 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 81.28 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "R" (at 81.28 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 81.28 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid d1a69e02-ddfd-4458-9128-a98a4aa419f2)) + (pin "1" (uuid 73b8599c-47ea-4703-9d21-eca93a510f81)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R5") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Simulation_SPICE:VPULSE") (at 262.89 135.89 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid e7e16ff2-fd42-4d7f-b3c0-2d8d792d9503) + (property "Reference" "V_TXD1" (at 266.7 133.2202 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "VPULSE" (at 266.7 135.7602 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 262.89 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 262.89 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 262.89 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "PULSE" (at 262.89 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "V" (at 262.89 135.89 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Sim.Params" "y1=3.3 y2=0 td=5m tr=2n tf=2n tw=0.4m per=2m np=3" (at 266.7 138.3002 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (pin "2" (uuid 226f822e-d132-4c9f-8e6f-dd413c9023a7)) + (pin "1" (uuid bcd28291-277f-47d5-8d9e-84e712dfbef2)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "V_TXD1") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:R") (at 85.09 40.64 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid efcaf01a-542f-4f53-800a-efe3e3979d0e) + (property "Reference" "R2" (at 87.63 39.37 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "2.2k" (at 87.63 41.91 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 83.312 40.64 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 85.09 40.64 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "R" (at 85.09 40.64 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 85.09 40.64 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid 20e40ffc-d633-4828-b531-961997cde439)) + (pin "1" (uuid 39844626-9c50-41ef-8860-1ae0bdb583c0)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "R2") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Simulation_SPICE:VDC") (at 248.92 135.89 0) (unit 1) + (in_bom no) (on_board no) (dnp no) (fields_autoplaced) + (uuid f69ca6e6-c1ae-4ffe-9afd-f64ccc3b1066) + (property "Reference" "V_USB1" (at 252.73 134.4902 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "5" (at 252.73 137.0302 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (at 248.92 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 248.92 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 248.92 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Type" "DC" (at 248.92 135.89 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "V" (at 248.92 135.89 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (pin "2" (uuid 9218efc9-de31-4ced-a14a-f0c6e792cf1b)) + (pin "1" (uuid 40938104-262a-45b7-bc29-b13133e3a182)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "V_USB1") (unit 1) + ) + ) + ) + ) + + (symbol (lib_id "Device:C_Polarized") (at 114.3 71.12 90) (unit 1) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (uuid ff3cc76a-1a65-43c7-a10c-c52bf541e8be) + (property "Reference" "C1" (at 113.411 63.5 90) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "150u" (at 113.411 66.04 90) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "Capacitor_THT:CP_Radial_D10.0mm_P5.00mm" (at 118.11 70.1548 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 114.3 71.12 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Device" "C" (at 114.3 71.12 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Pins" "1=+ 2=-" (at 114.3 71.12 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "2" (uuid dc84e234-298d-4b41-9f14-bfab0168c5e4)) + (pin "1" (uuid 32d8b955-5d5f-4f9e-ba02-1fa97f21c210)) + (instances + (project "SeaTalk1" + (path "/fef6b826-4a15-4295-9e8e-e163f69cffe7" + (reference "C1") (unit 1) + ) + ) + ) + ) + + (sheet_instances + (path "/" (page "1")) + ) +) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk new file mode 100644 index 0000000000..96062ab5b3 --- /dev/null +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk @@ -0,0 +1,17 @@ +version 2 +1 +9 +.tran 100u 15m{return}{return}.kicad adjustpaths{return}.save all{return}.probe alli +4 +1 +V(Net-_D1-K_) + +1 +V(Net-_J1-GPIO15/RXD_) + +1 +V(Net-_Q2-B_) + +1 +V(SEATALK) + From 83710e2b539f1f19deabbd7d697bd93e21ecb591 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Wed, 3 Jan 2024 20:47:24 +0100 Subject: [PATCH 18/31] Ignore KCad backup directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 01eb8a521c..6ff7c7909b 100644 --- a/.gitignore +++ b/.gitignore @@ -336,3 +336,4 @@ ASALocalRun/ # Ignore Mac DS_Store files .DS_Store +/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1-backups From db1237ebcda6a08240d3d7366b2d5a918282e6af Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sat, 6 Jan 2024 16:41:05 +0100 Subject: [PATCH 19/31] HTD sentence supported Not yet tested on real system, poorly documented --- .../Nmea0183/Sentences/AutopilotStatus.cs | 67 +++++ .../Sentences/HeadingAndTrackControl.cs | 274 ++++++++++++++++++ .../Nmea0183/Sentences/NmeaSentence.cs | 2 +- src/devices/Nmea0183/TalkerSentence.cs | 1 + src/devices/Nmea0183/tests/SentenceTests.cs | 14 + 5 files changed, 357 insertions(+), 1 deletion(-) create mode 100644 src/devices/Nmea0183/Sentences/AutopilotStatus.cs create mode 100644 src/devices/Nmea0183/Sentences/HeadingAndTrackControl.cs diff --git a/src/devices/Nmea0183/Sentences/AutopilotStatus.cs b/src/devices/Nmea0183/Sentences/AutopilotStatus.cs new file mode 100644 index 0000000000..7e327932b9 --- /dev/null +++ b/src/devices/Nmea0183/Sentences/AutopilotStatus.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iot.Device.Nmea0183.Sentences +{ + /// + /// The current state of the autopilot + /// + public enum AutopilotStatus + { + /// + /// The autopilot controller is offline or not present + /// + Offline, + + /// + /// The autopilot is in standby mode (= manual steering is active) + /// + Standby, + + /// + /// The autopilot is in auto mode. For most controllers, this means "desired heading" mode. + /// + Auto, + + /// + /// The autopilot is in desired track mode (following a planned route) + /// + Track, + + /// + /// The autopilot is in Wind mode (keeping the relative wind angle constant) + /// + Wind, + + /// + /// The autopilot is in track mode, but inactive + /// + InactiveTrack, + + /// + /// The autopilot is in wind mode, but inactive + /// + InactiveWind, + + /// + /// The autopilot is in calibration mode + /// + Calibration, + + /// + /// Direct rudder control mode + /// + RudderControl, + + /// + /// The state is unknown + /// + Undefined, + } +} diff --git a/src/devices/Nmea0183/Sentences/HeadingAndTrackControl.cs b/src/devices/Nmea0183/Sentences/HeadingAndTrackControl.cs new file mode 100644 index 0000000000..13091fb1f4 --- /dev/null +++ b/src/devices/Nmea0183/Sentences/HeadingAndTrackControl.cs @@ -0,0 +1,274 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnitsNet; + +namespace Iot.Device.Nmea0183.Sentences +{ + /// + /// HDC sequence. This is used to control an attached auto-pilot. + /// Documentation of this sentence is very poor, and one has to dig deep + /// to find information about it. + /// Since the actual encoding might be autopilot-dependent, this message outputs all values in raw format. + /// + /// + /// This class is preliminary and pending verification. + /// + public class HeadingAndTrackControl : NmeaSentence + { + /// + /// This sentence's id + /// + public static SentenceId Id => new SentenceId("HTC"); + private static bool Matches(SentenceId sentence) => Id == sentence; + private static bool Matches(TalkerSentence sentence) => Matches(sentence.Id); + + /// + /// Initialize a new instance of this type. + /// See the individual properties for further explanation to the parameters. + /// + /// Status of Autopilot (see ) + /// Commanded rudder angle + /// Rudder direction + /// Turn mode + /// Rudder limit + /// Off-Heading limit + /// Desired turn radius + /// Desired rate of turn + /// Desired heading + /// Desired off-track limit + /// Commanded track direction + /// Heading uses true angles + public HeadingAndTrackControl(string status, Angle? commandedRudderAngle, string commandedRudderDirection, string turnMode, + Angle? rudderLimit, Angle? offHeadingLimit, Length? turnRadius, RotationalSpeed? rateOfTurn, Angle? desiredHeading, Length? offTrackLimit, Angle? commandedTrack, bool headingIsTrue) + : base(OwnTalkerId, Id, DateTimeOffset.UtcNow) + { + Valid = true; + Status = status; + DesiredHeading = desiredHeading; + CommandedRudderAngle = commandedRudderAngle; + HeadingIsTrue = headingIsTrue; + CommandedRudderDirection = commandedRudderDirection; + TurnMode = turnMode; + RudderLimit = rudderLimit; + OffHeadingLimit = offHeadingLimit; + TurnRadius = turnRadius; + RateOfTurn = rateOfTurn; + OffTrackLimit = offTrackLimit; + CommandedTrack = commandedTrack; + } + + /// + /// Internal constructor + /// + public HeadingAndTrackControl(TalkerSentence sentence, DateTimeOffset time) + : this(sentence.TalkerId, Matches(sentence) ? sentence.Fields : throw new ArgumentException($"SentenceId does not match expected id '{Id}'"), time) + { + } + + /// + /// Parsing constructor. + /// + public HeadingAndTrackControl(TalkerId talkerId, IEnumerable fields, DateTimeOffset time) + : base(talkerId, Id, time) + { + IEnumerator field = fields.GetEnumerator(); + + string manualOverride = ReadString(field); + CommandedRudderAngle = AsAngle(ReadValue(field)); + CommandedRudderDirection = ReadString(field); + + string autoPilotMode = ReadString(field); + TurnMode = ReadString(field); + RudderLimit = AsAngle(ReadValue(field)); + OffHeadingLimit = AsAngle(ReadValue(field)); + TurnRadius = AsLength(ReadValue(field)); + double? turnRate = ReadValue(field); + RateOfTurn = turnRate.HasValue ? RotationalSpeed.FromDegreesPerSecond(turnRate.Value) : null; + DesiredHeading = AsAngle(ReadValue(field)); + OffTrackLimit = AsLength(ReadValue(field)); + CommandedTrack = AsAngle(ReadValue(field)); + string headingReference = ReadString(field); + + // If override is active ("A"), then we treat this as standby + if (manualOverride == "A") + { + Status = "A"; + Valid = true; + } + else + { + // It appears that on the NMEA2000 side, various proprietary messages are also used to control the autopilot, + // hence this is missing some states, such as Wind mode. + Status = autoPilotMode; + Valid = true; + } + + HeadingIsTrue = headingReference == "T"; + } + + /// + /// Autopilot status. Known values: + /// M = Manual + /// S = Stand-alone heading control + /// H = Heading control with external source + /// T = Track control + /// R = Direct rudder control + /// Anything else = ??? + /// + public string Status { get; private set; } + + /// + /// Heading to steer. + /// + public Angle? DesiredHeading { get; private set; } + + /// + /// Angle for directly controlling the rudder. Unsigned. (See ) + /// + public Angle? CommandedRudderAngle { get; private set; } + + /// + /// True if all angles are true, otherwise false. + /// + public bool HeadingIsTrue { get; private set; } + + /// + /// Commanded rudder direction "L" or "R" for port/starboard. + /// + public string CommandedRudderDirection { get; private set; } + + /// + /// Turn mode (probably only valid for very expensive autopilots) + /// Known values: + /// R = Radius controlled + /// T = Turn rate controlled + /// N = Neither + /// + public string TurnMode { get; private set; } + + /// + /// Maximum rudder angle + /// + public Angle? RudderLimit { get; private set; } + + /// + /// Maximum off-heading limit (in heading control mode) + /// + public Angle? OffHeadingLimit { get; private set; } + + /// + /// Desired turn Radius (when is "R") + /// + public Length? TurnRadius { get; private set; } + + /// + /// Desired turn rate (when is "T") + /// Base unit is degrees/second + /// + public RotationalSpeed? RateOfTurn { get; private set; } + + /// + /// Off-track warning limit, unsigned. + /// + public Length? OffTrackLimit { get; private set; } + + /// + /// Commanded track + /// + public Angle? CommandedTrack { get; private set; } + + /// + public override bool ReplacesOlderInstance => true; + + /// + public override string ToNmeaParameterList() + { + if (!Valid) + { + return string.Empty; + } + + StringBuilder b = new StringBuilder(); + b.Append(Status == "M" ? "A," : "V,"); + b.Append(FromAngle(CommandedRudderAngle)); + b.Append(CommandedRudderDirection + ","); + b.Append(Status + ","); + b.Append(TurnMode + ","); + b.Append(FromAngle(RudderLimit)); + b.Append(FromAngle(OffHeadingLimit)); + b.Append(FromLength(TurnRadius)); + if (RateOfTurn.HasValue) + { + b.Append(RateOfTurn.Value.DeciradiansPerSecond.ToString("F1", CultureInfo.InvariantCulture) + ","); + } + else + { + b.Append(','); + } + + b.Append(FromAngle(DesiredHeading)); + b.Append(FromLength(OffTrackLimit)); + b.Append(FromAngle(CommandedTrack)); + b.Append(HeadingIsTrue ? "T" : "M"); + + return b.ToString(); + } + + /// + public override string ToReadableContent() + { + return $"Mode: {Status}, CommandedTrack: {CommandedTrack}, TurnMode: {TurnMode}"; + } + + private static Angle? AsAngle(double? value) + { + if (value.HasValue) + { + return Angle.FromDegrees(value.Value); + } + + return null; + } + + private static string FromAngle(Angle? angle) + { + if (!angle.HasValue) + { + return ","; + } + else + { + return angle.Value.Degrees.ToString("F1", CultureInfo.InvariantCulture) + ","; + } + } + + private static Length? AsLength(double? value) + { + if (value.HasValue) + { + return Length.FromNauticalMiles(value.Value); + } + + return null; + } + + private static string FromLength(Length? length) + { + if (length.HasValue == false) + { + return ","; + } + else + { + return length.Value.NauticalMiles.ToString("F1", CultureInfo.InvariantCulture) + ","; + } + } + } +} diff --git a/src/devices/Nmea0183/Sentences/NmeaSentence.cs b/src/devices/Nmea0183/Sentences/NmeaSentence.cs index 086335dc5b..5bac28e4eb 100644 --- a/src/devices/Nmea0183/Sentences/NmeaSentence.cs +++ b/src/devices/Nmea0183/Sentences/NmeaSentence.cs @@ -205,7 +205,7 @@ protected string ReadString(IEnumerator field) return string.Empty; } - return field.Current; + return field.Current ?? string.Empty; } /// diff --git a/src/devices/Nmea0183/TalkerSentence.cs b/src/devices/Nmea0183/TalkerSentence.cs index dd1d029f31..d5c62ee40b 100644 --- a/src/devices/Nmea0183/TalkerSentence.cs +++ b/src/devices/Nmea0183/TalkerSentence.cs @@ -47,6 +47,7 @@ public class TalkerSentence knownSentences[SatellitesInView.Id] = (sentence, time) => new SatellitesInView(sentence, time); knownSentences[WindDirectionWithRespectToNorth.Id] = (sentence, time) => new WindDirectionWithRespectToNorth(sentence, time); + knownSentences[HeadingAndTrackControl.Id] = (sentence, time) => new HeadingAndTrackControl(sentence, time); knownSentences[ProprietaryMessage.Id] = (sentence, time) => { var specificMessageId = sentence.Fields.FirstOrDefault(); diff --git a/src/devices/Nmea0183/tests/SentenceTests.cs b/src/devices/Nmea0183/tests/SentenceTests.cs index 8cc6099f9c..671b6e3beb 100644 --- a/src/devices/Nmea0183/tests/SentenceTests.cs +++ b/src/devices/Nmea0183/tests/SentenceTests.cs @@ -495,6 +495,18 @@ public void DontCrashOnTheseInvalidSentences(string sentence) } } + [Fact] + public void HtdEncode() + { + var hdt = new HeadingAndTrackControl("M", null, "L", "N", null, null, null, null, null, null, null, true); + var msg = hdt.ToNmeaParameterList(); + Assert.Equal("A,,L,M,N,,,,,,,,T", msg); + + hdt = new HeadingAndTrackControl("H", Angle.FromDegrees(10.21), "L", "N", null, null, Length.FromNauticalMiles(22.29), null, null, null, Angle.FromDegrees(2), false); + msg = hdt.ToNmeaParameterList(); + Assert.Equal("V,10.2,L,H,N,,,22.3,,,,2.0,M", msg); + } + [Theory] [InlineData("$GPRMC,211730.997,A,3511.28000,S,13823.26000,E,7.000,229.000,190120,,*19")] [InlineData("$GPRMC,115613.000,A,4729.49750,N,00930.39830,E,1.600,36.200,240520,1.900,E,D*34")] @@ -603,6 +615,7 @@ public void CanParseAllTheseMessages(string input) [InlineData("$YDVHW,,T,,M,3.1,N,5.7,K,")] [InlineData("$YDGSV,5,1,18,19,29,257,45,22,30,102,45,04,76,143,44,06,47,295,42")] [InlineData("$YDMWD,336.8,T,333.8,M,21.6,N,11.1,M")] + [InlineData("$APHTD,V,10.0,L,R,N,12,13,2.0,1.0,15.1,0.5,16.2,T")] public void SentenceRoundTripIsUnaffectedByCulture(string input) { // de-DE has "," as decimal separator. Big trouble if using CurrentCulture for any parsing or formatting here @@ -639,6 +652,7 @@ public void SentenceRoundTripIsUnaffectedByCulture(string input) [InlineData("$YDVHW,,T,,M,3.1,N,5.7,K,")] [InlineData("$YDGSV,5,1,18,19,29,257,45,22,30,102,45,04,76,143,44,06,47,295,42")] [InlineData("$YDMWD,336.8,T,333.8,M,21.6,N,11.1,M")] + [InlineData("$APHTD,V,10.0,L,R,N,12,13,2.5,1.0,15.1,0.5,16.2,M")] public void TwoWaysOfGettingSentenceAreEqual(string input) { // de-DE has "," as decimal separator. Big trouble if using CurrentCulture for any parsing or formatting here From 4164586537d39e7f371476920a418b5d36801d45 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sat, 6 Jan 2024 20:41:07 +0100 Subject: [PATCH 20/31] Add support for $STALK message --- .../Nmea0183/Sentences/SeatalkNmeaMessage.cs | 89 +++++++++++++++++++ .../Nmea0183/Sentences/WaterSpeedAndAngle.cs | 2 +- src/devices/Nmea0183/TalkerId.cs | 5 ++ .../samples/NmeaSimulator/NmeaSimulator.cs | 26 +++++- .../samples/NmeaSimulator/SimulatorData.cs | 15 +++- src/devices/Nmea0183/tests/SentenceTests.cs | 15 ++++ .../Seatalk1/AutoPilotRemoteController.cs | 1 + .../Seatalk1/Messages/AutopilotStatus.cs | 27 ------ .../Messages/CompassHeadingAutopilotCourse.cs | 1 + src/devices/Seatalk1/Seatalk1.csproj | 4 +- src/devices/Seatalk1/Seatalk1.sln | 16 +++- .../Seatalk1/samples/Seatalk1.Samples.cs | 1 + .../tests/AutoPilotRemoteControllerTests.cs | 1 + 13 files changed, 167 insertions(+), 36 deletions(-) create mode 100644 src/devices/Nmea0183/Sentences/SeatalkNmeaMessage.cs delete mode 100644 src/devices/Seatalk1/Messages/AutopilotStatus.cs diff --git a/src/devices/Nmea0183/Sentences/SeatalkNmeaMessage.cs b/src/devices/Nmea0183/Sentences/SeatalkNmeaMessage.cs new file mode 100644 index 0000000000..33e2dde5bf --- /dev/null +++ b/src/devices/Nmea0183/Sentences/SeatalkNmeaMessage.cs @@ -0,0 +1,89 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnitsNet; + +namespace Iot.Device.Nmea0183.Sentences +{ + /// + /// This message wraps a Seatalk1 binary message into an NMEA0183 message + /// This is supported by some OpenCPN plugins, such as "Raymarine Autopilot" + /// The message is always sent with the identifier $STALK + /// + public class SeatalkNmeaMessage : NmeaSentence + { + /// + /// This sentence ID "ALK" + /// + public static SentenceId Id => new SentenceId("ALK"); + private static bool Matches(SentenceId sentence) => Id == sentence; + private static bool Matches(TalkerSentence sentence) => Matches(sentence.Id); + + /// + /// Constructs a new MWV sentence + /// + public SeatalkNmeaMessage(byte[] datagram) + : base(Nmea0183.TalkerId.Seatalk, Id, DateTimeOffset.UtcNow) + { + Datagram = datagram; + } + + /// + /// Internal constructor + /// + public SeatalkNmeaMessage(TalkerSentence sentence, DateTimeOffset time) + : this(sentence.TalkerId, Matches(sentence) ? sentence.Fields : throw new ArgumentException($"SentenceId does not match expected id '{Id}'"), time) + { + } + + /// + /// Standard decoding constructor + /// + public SeatalkNmeaMessage(TalkerId talkerId, IEnumerable fields, DateTimeOffset time) + : base(talkerId, Id, time) + { + List datagram = new List(20); + foreach (var field in fields) + { + if (byte.TryParse(field, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out byte b)) + { + datagram.Add(b); + } + else + { + throw new FormatException($"Invalid value in $TALK sequence: {field} is not a valid hex number"); + } + } + + Datagram = datagram.ToArray(); + } + + /// + /// This message type can embed various messages, some of them are not repeating (e.g. Keypresses) + /// + public override bool ReplacesOlderInstance => false; + + /// + public override string ToNmeaParameterList() + { + return string.Join(",", Datagram.Select(x => x.ToString("X2", CultureInfo.InvariantCulture))); + } + + /// + public override string ToReadableContent() + { + return $"$STALK," + string.Join(",", Datagram.Select(x => x.ToString("X2", CultureInfo.InvariantCulture))); + } + + /// + /// The Seatalk1 raw Datagram (up to 18 bytes) + /// + public byte[] Datagram { get; private set; } + } +} diff --git a/src/devices/Nmea0183/Sentences/WaterSpeedAndAngle.cs b/src/devices/Nmea0183/Sentences/WaterSpeedAndAngle.cs index a0ebb1541e..9a3bb1f10b 100644 --- a/src/devices/Nmea0183/Sentences/WaterSpeedAndAngle.cs +++ b/src/devices/Nmea0183/Sentences/WaterSpeedAndAngle.cs @@ -25,7 +25,7 @@ public class WaterSpeedAndAngle : NmeaSentence /// /// Constructs a new MWV sentence /// - public WaterSpeedAndAngle(Angle headingTrue, Angle headingMagnetic, Speed speed) + public WaterSpeedAndAngle(Angle? headingTrue, Angle? headingMagnetic, Speed speed) : base(OwnTalkerId, Id, DateTimeOffset.UtcNow) { Speed = speed; diff --git a/src/devices/Nmea0183/TalkerId.cs b/src/devices/Nmea0183/TalkerId.cs index 4180c8322b..ed276f1083 100644 --- a/src/devices/Nmea0183/TalkerId.cs +++ b/src/devices/Nmea0183/TalkerId.cs @@ -303,5 +303,10 @@ public bool Equals(TalkerId other) /// Filter placeholder for any talker id /// public static TalkerId Any => new TalkerId('*', ' '); + + /// + /// Seatalk messages wrapped up as NMEA data should always be prefixed $STALK + /// + public static TalkerId Seatalk => new TalkerId('S', 'T'); } } diff --git a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs index b74d77cdb1..16597b54d5 100644 --- a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs +++ b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Net.Sockets; using System.Threading; +using Iot.Device; using Iot.Device.Common; using Iot.Device.Nmea0183; using Iot.Device.Nmea0183.Sentences; @@ -23,11 +24,13 @@ internal class Simulator private SimulatorData _activeData; private NmeaTcpServer? _tcpServer; private NmeaUdpServer? _udpServer; + private Random _random; public Simulator() { _activeData = new SimulatorData(); ReplayFiles = new List(); + _random = new Random(); } private List ReplayFiles @@ -135,7 +138,7 @@ private void SendNewData() var data = _activeData; RecommendedMinimumNavigationInformation rmc = new RecommendedMinimumNavigationInformation(DateTimeOffset.UtcNow, NavigationStatus.Valid, data.Position, - data.Speed, data.Course, null); + data.SpeedOverGround, data.Course, null); SendSentence(rmc); GlobalPositioningSystemFixData gga = new GlobalPositioningSystemFixData( @@ -145,6 +148,18 @@ private void SendNewData() TimeDate zda = new TimeDate(DateTimeOffset.UtcNow); SendSentence(zda); + + WindSpeedAndAngle mwv = new WindSpeedAndAngle(data.WindDirectionRelative, data.WindSpeedRelative, true); + SendSentence(mwv); + + WaterSpeedAndAngle vhw = new WaterSpeedAndAngle(null, null, data.SpeedTroughWater); + SendSentence(vhw); + + RawSentence sentence = new RawSentence(new TalkerId('S', 'T'), new SentenceId("ALK"), new string[] + { + "84", "86", "26", "97", "02", "00", "00", "00", "08" + }, DateTimeOffset.UtcNow); + SendSentence(sentence); } catch (IOException x) { @@ -171,8 +186,13 @@ private void MainSimulator() while (!_terminate) { var newData = _activeData.Clone(); - GeographicPosition newPosition = GreatCircle.CalcCoords(newData.Position, _activeData.Course, - _activeData.Speed * UpdateRate); + newData.SpeedOverGround = UnitMath.Clamp(newData.SpeedOverGround + Speed.FromKnots(_random.NextDouble() - 0.5), Speed.Zero, Speed.FromKnots(12)); + newData.SpeedTroughWater = UnitMath.Clamp(newData.SpeedOverGround + Speed.FromKnots(1.5), Speed.Zero, Speed.FromKnots(10.0)); + newData.WindSpeedRelative = UnitMath.Clamp(newData.WindSpeedRelative + Speed.FromKnots(_random.NextDouble() - 0.5), Speed.Zero, Speed.FromKnots(65)); + newData.WindDirectionRelative = newData.WindDirectionRelative + Angle.FromDegrees(_random.NextDouble() * 2.0); + newData.WindDirectionRelative = newData.WindDirectionRelative.Normalize(true); + GeographicPosition newPosition = GreatCircle.CalcCoords(newData.Position, newData.Course, + newData.SpeedOverGround * UpdateRate); newData.Position = newPosition; _activeData = newData; diff --git a/src/devices/Nmea0183/samples/NmeaSimulator/SimulatorData.cs b/src/devices/Nmea0183/samples/NmeaSimulator/SimulatorData.cs index 421d1450fc..78106de6f7 100644 --- a/src/devices/Nmea0183/samples/NmeaSimulator/SimulatorData.cs +++ b/src/devices/Nmea0183/samples/NmeaSimulator/SimulatorData.cs @@ -14,11 +14,18 @@ internal class SimulatorData : ICloneable { public SimulatorData() { - Position = new GeographicPosition(47.45, 9.59, 451.2); + Position = new GeographicPosition(47.49, 9.50, 451.2); Course = Angle.FromDegrees(350); - Speed = Speed.FromKnots(4.8); + SpeedOverGround = Speed.FromKnots(4.8); + WindSpeedRelative = Speed.FromKnots(10.2); + WindDirectionRelative = Angle.FromDegrees(-10.0); + SpeedTroughWater = Speed.FromKnots(5.2); } + public Angle WindDirectionRelative { get; set; } + + public Speed WindSpeedRelative { get; set; } + public GeographicPosition Position { get; @@ -31,12 +38,14 @@ public Angle Course set; } - public Speed Speed + public Speed SpeedOverGround { get; set; } + public Speed SpeedTroughWater { get; set; } + object ICloneable.Clone() { return MemberwiseClone(); diff --git a/src/devices/Nmea0183/tests/SentenceTests.cs b/src/devices/Nmea0183/tests/SentenceTests.cs index 671b6e3beb..796d6d0f9e 100644 --- a/src/devices/Nmea0183/tests/SentenceTests.cs +++ b/src/devices/Nmea0183/tests/SentenceTests.cs @@ -507,6 +507,18 @@ public void HtdEncode() Assert.Equal("V,10.2,L,H,N,,,22.3,,,,2.0,M", msg); } + [Fact] + public void StalkEncode() + { + var talk = new SeatalkNmeaMessage(new byte[] + { + 0x9c, 00, 01 + }); + + var msg = talk.ToNmeaParameterList(); + Assert.Equal("9C,00,01", msg); + } + [Theory] [InlineData("$GPRMC,211730.997,A,3511.28000,S,13823.26000,E,7.000,229.000,190120,,*19")] [InlineData("$GPRMC,115613.000,A,4729.49750,N,00930.39830,E,1.600,36.200,240520,1.900,E,D*34")] @@ -535,6 +547,7 @@ public void HtdEncode() [InlineData("$ECMDA,30.12,I,1.020,B,18.5,C,,C,38.7,,4.2,C,,T,,M,,N,,M*37")] [InlineData("$YDGSV,5,1,18,19,29,257,45,22,30,102,45,04,76,143,44,06,47,295,42*73")] [InlineData("!AIVDM,1,1,,B,ENk`sR9`92ah97PR9h0W1T@1@@@=MTpS<7GFP00003vP000,2*4B")] + [InlineData("$STALK,84,86,26,97,02,00,00,00,08*6F")] public void SentenceRoundTrip(string input) { var inSentence = TalkerSentence.FromSentenceString(input, out var error); @@ -616,6 +629,8 @@ public void CanParseAllTheseMessages(string input) [InlineData("$YDGSV,5,1,18,19,29,257,45,22,30,102,45,04,76,143,44,06,47,295,42")] [InlineData("$YDMWD,336.8,T,333.8,M,21.6,N,11.1,M")] [InlineData("$APHTD,V,10.0,L,R,N,12,13,2.0,1.0,15.1,0.5,16.2,T")] + [InlineData("$STALK,84,86,26,97,02,00,00,00,08")] + [InlineData("$STALK,9c,01,12,00")] public void SentenceRoundTripIsUnaffectedByCulture(string input) { // de-DE has "," as decimal separator. Big trouble if using CurrentCulture for any parsing or formatting here diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index e9b273c7b1..4a3633ac69 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Iot.Device.Common; +using Iot.Device.Nmea0183.Sentences; using Iot.Device.Seatalk1.Messages; using Microsoft.Extensions.Logging; using UnitsNet; diff --git a/src/devices/Seatalk1/Messages/AutopilotStatus.cs b/src/devices/Seatalk1/Messages/AutopilotStatus.cs deleted file mode 100644 index fae0f61844..0000000000 --- a/src/devices/Seatalk1/Messages/AutopilotStatus.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Iot.Device.Seatalk1.Messages -{ - /// - /// The current state of the auto pilot controller - /// - public enum AutopilotStatus - { - Offline, - Standby, - Auto, - Track, - Wind, - InactiveTrack, - InactiveWind, - Calibration, - Undefined, - } -} diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index 77bb617478..0376102ed3 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading.Tasks; using Iot.Device.Common; +using Iot.Device.Nmea0183.Sentences; using Microsoft.Extensions.Logging; using UnitsNet; diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index e180cffe35..da8bf3f2b7 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -21,7 +21,6 @@ - @@ -42,4 +41,7 @@ <_Parameter1>$(AssemblyName).Tests + + + diff --git a/src/devices/Seatalk1/Seatalk1.sln b/src/devices/Seatalk1/Seatalk1.sln index 5b754f92dd..657f84cab2 100644 --- a/src/devices/Seatalk1/Seatalk1.sln +++ b/src/devices/Seatalk1/Seatalk1.sln @@ -7,7 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seatalk1", "Seatalk1.csproj EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{03107CFF-FE00-467D-9B38-C00F7E12A7FE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seatalk1.Tests", "tests\Seatalk1.Tests.csproj", "{2B0F5D91-F38B-427D-84DB-5656D9661E1C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seatalk1.Tests", "tests\Seatalk1.Tests.csproj", "{2B0F5D91-F38B-427D-84DB-5656D9661E1C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{6A4DE7B1-03F3-4EE0-BF73-A0BAEF88BA2B}" EndProject @@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seatalk1.Samples", "samples EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common", "..\Common\Common.csproj", "{A53E6BD4-A723-4B86-BC19-3B56D539D0B0}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nmea0183", "..\Nmea0183\Nmea0183.csproj", "{4715C6A2-09E1-4ECD-962C-7875D124EEA8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,6 +75,18 @@ Global {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|x64.Build.0 = Release|Any CPU {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|x86.ActiveCfg = Release|Any CPU {A53E6BD4-A723-4B86-BC19-3B56D539D0B0}.Release|x86.Build.0 = Release|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Debug|x64.ActiveCfg = Debug|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Debug|x64.Build.0 = Debug|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Debug|x86.ActiveCfg = Debug|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Debug|x86.Build.0 = Debug|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Release|Any CPU.Build.0 = Release|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Release|x64.ActiveCfg = Release|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Release|x64.Build.0 = Release|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Release|x86.ActiveCfg = Release|Any CPU + {4715C6A2-09E1-4ECD-962C-7875D124EEA8}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 34ca260326..6f2acf0846 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -9,6 +9,7 @@ using System.IO.Ports; using System.Threading.Tasks; using Iot.Device.Common; +using Iot.Device.Nmea0183.Sentences; using Iot.Device.Seatalk1; using Iot.Device.Seatalk1.Messages; using Microsoft.Extensions.Logging; diff --git a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs index 6ca88f3dcf..7187f97ec5 100644 --- a/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs +++ b/src/devices/Seatalk1/tests/AutoPilotRemoteControllerTests.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Iot.Device.Nmea0183.Sentences; using Iot.Device.Seatalk1; using Iot.Device.Seatalk1.Messages; using Moq; From 007db2fb83abefc1f9d2e1ad86fd523a28ca62be Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 7 Jan 2024 12:00:25 +0100 Subject: [PATCH 21/31] Raw Seatalk1 to NMEA conversion works --- src/devices/Nmea0183/Nmea0183.sln | 14 ++++ .../Nmea0183/Sentences/SeatalkNmeaMessage.cs | 13 ++++ src/devices/Nmea0183/TalkerSentence.cs | 1 + .../samples/NmeaSimulator/NmeaSimulator.cs | 38 +++++++++-- .../NmeaSimulator/NmeaSimulator.csproj | 1 + src/devices/Seatalk1/SeatalkInterface.cs | 20 +++++- .../Seatalk1/SeatalkToNmeaConverter.cs | 64 +++++++++++++++++++ .../Seatalk1/samples/Seatalk1.Samples.cs | 2 + 8 files changed, 144 insertions(+), 9 deletions(-) create mode 100644 src/devices/Seatalk1/SeatalkToNmeaConverter.cs diff --git a/src/devices/Nmea0183/Nmea0183.sln b/src/devices/Nmea0183/Nmea0183.sln index 8f26c24003..511dd20c10 100644 --- a/src/devices/Nmea0183/Nmea0183.sln +++ b/src/devices/Nmea0183/Nmea0183.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common", "..\Common\Common. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleParser", "samples\SimpleParser\SimpleParser.csproj", "{C66E7575-9ECA-4329-A145-1DCADE028DDC}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seatalk1", "..\Seatalk1\Seatalk1.csproj", "{4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -83,6 +85,18 @@ Global {C66E7575-9ECA-4329-A145-1DCADE028DDC}.Windows-Debug|Any CPU.Build.0 = Debug|Any CPU {C66E7575-9ECA-4329-A145-1DCADE028DDC}.Windows-Release|Any CPU.ActiveCfg = Release|Any CPU {C66E7575-9ECA-4329-A145-1DCADE028DDC}.Windows-Release|Any CPU.Build.0 = Release|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Linux-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Linux-Debug|Any CPU.Build.0 = Debug|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Linux-Release|Any CPU.ActiveCfg = Release|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Linux-Release|Any CPU.Build.0 = Release|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Release|Any CPU.Build.0 = Release|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Windows-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Windows-Debug|Any CPU.Build.0 = Debug|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Windows-Release|Any CPU.ActiveCfg = Release|Any CPU + {4C6A3828-5AC7-42AD-BE8A-111DF1D46C8E}.Windows-Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/devices/Nmea0183/Sentences/SeatalkNmeaMessage.cs b/src/devices/Nmea0183/Sentences/SeatalkNmeaMessage.cs index 33e2dde5bf..36bb1517d7 100644 --- a/src/devices/Nmea0183/Sentences/SeatalkNmeaMessage.cs +++ b/src/devices/Nmea0183/Sentences/SeatalkNmeaMessage.cs @@ -62,6 +62,19 @@ public SeatalkNmeaMessage(TalkerId talkerId, IEnumerable fields, DateTim } Datagram = datagram.ToArray(); + Valid = true; + } + + /// + /// Directly create a message from a datagram + /// + /// Datagram, byte array + /// The current time + public SeatalkNmeaMessage(byte[] datagram, DateTimeOffset time) + : base(TalkerId.Seatalk, Id, time) + { + Datagram = datagram; + Valid = true; } /// diff --git a/src/devices/Nmea0183/TalkerSentence.cs b/src/devices/Nmea0183/TalkerSentence.cs index d5c62ee40b..49016446d4 100644 --- a/src/devices/Nmea0183/TalkerSentence.cs +++ b/src/devices/Nmea0183/TalkerSentence.cs @@ -48,6 +48,7 @@ public class TalkerSentence knownSentences[WindDirectionWithRespectToNorth.Id] = (sentence, time) => new WindDirectionWithRespectToNorth(sentence, time); knownSentences[HeadingAndTrackControl.Id] = (sentence, time) => new HeadingAndTrackControl(sentence, time); + knownSentences[SeatalkNmeaMessage.Id] = (sentence, time) => new SeatalkNmeaMessage(sentence, time); knownSentences[ProprietaryMessage.Id] = (sentence, time) => { var specificMessageId = sentence.Fields.FirstOrDefault(); diff --git a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs index 16597b54d5..a9249a2be7 100644 --- a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs +++ b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs @@ -12,6 +12,7 @@ using Iot.Device.Common; using Iot.Device.Nmea0183; using Iot.Device.Nmea0183.Sentences; +using Iot.Device.Seatalk1; using UnitsNet; namespace Nmea.Simulator @@ -24,6 +25,7 @@ internal class Simulator private SimulatorData _activeData; private NmeaTcpServer? _tcpServer; private NmeaUdpServer? _udpServer; + private SeatalkToNmeaConverter? _seatalkInterface; private Random _random; public Simulator() @@ -88,6 +90,12 @@ private void StartServer() _udpServer.StartDecode(); _udpServer.OnNewSequence += OnNewSequenceFromServer; + // Also optionally directly connect to the Seatalk1 bus. + // For simplicity, this example is not using a MessageRouter. + _seatalkInterface = new SeatalkToNmeaConverter("Seatalk1", "/dev/ttyAMA2"); + _seatalkInterface.OnNewSequence += SeatalkNewSequence; + _seatalkInterface.StartDecode(); + Console.WriteLine("Waiting for connections. Press x to quit"); while (true) { @@ -109,6 +117,8 @@ private void StartServer() } finally { + _seatalkInterface?.StopDecode(); + _seatalkInterface?.Dispose(); _tcpServer?.StopDecode(); _udpServer?.StopDecode(); if (_simulatorThread != null) @@ -122,6 +132,11 @@ private void StartServer() } } + private void SeatalkNewSequence(NmeaSinkAndSource source, NmeaSentence sentence) + { + SendSentence(sentence); + } + // We're not really expecting input here. private void OnNewSequenceFromServer(NmeaSinkAndSource source, NmeaSentence sentence) { @@ -129,6 +144,11 @@ private void OnNewSequenceFromServer(NmeaSinkAndSource source, NmeaSentence sent { Console.WriteLine($"Received message: {sentence.ToReadableContent()} from {source.InterfaceName}"); } + + if (_seatalkInterface != null) + { + _seatalkInterface.SendSentence(source, sentence); + } } private void SendNewData() @@ -155,11 +175,12 @@ private void SendNewData() WaterSpeedAndAngle vhw = new WaterSpeedAndAngle(null, null, data.SpeedTroughWater); SendSentence(vhw); - RawSentence sentence = new RawSentence(new TalkerId('S', 'T'), new SentenceId("ALK"), new string[] - { - "84", "86", "26", "97", "02", "00", "00", "00", "08" - }, DateTimeOffset.UtcNow); - SendSentence(sentence); + // Test Seatalk message (understood by some OpenCPN plugins) + ////RawSentence sentence = new RawSentence(new TalkerId('S', 'T'), new SentenceId("ALK"), new string[] + ////{ + //// "84", "86", "26", "97", "02", "00", "00", "00", "08" + ////}, DateTimeOffset.UtcNow); + ////SendSentence(sentence); } catch (IOException x) { @@ -171,7 +192,7 @@ private void SendSentence(NmeaSentence sentence) { if (_tcpServer != null) { - Console.WriteLine($"Sending {sentence.ToReadableContent()}"); + // Console.WriteLine($"Sending {sentence.ToReadableContent()}"); _tcpServer.SendSentence(sentence); } @@ -179,6 +200,11 @@ private void SendSentence(NmeaSentence sentence) { _udpServer.SendSentence(sentence); } + + if (_seatalkInterface != null) + { + _seatalkInterface.SendSentence(sentence); + } } private void MainSimulator() diff --git a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.csproj b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.csproj index 6058abc43b..7976cffe70 100644 --- a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.csproj +++ b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.csproj @@ -8,6 +8,7 @@ + diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index e8a5e00010..1c6bcdf62a 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -22,6 +22,7 @@ public class SeatalkInterface : MarshalByRefObject, IDisposable private readonly CancellationTokenSource _cancellation; private readonly AutoPilotRemoteController _autopilotController; private readonly object _lock; + private bool _disposed; public event Action? MessageReceived; @@ -53,9 +54,6 @@ public SeatalkInterface(string uart) _parser = new Seatalk1Parser(_port.BaseStream); _parser.NewMessageDecoded += OnNewMessage; - _parser.StartDecode(); - - _watchDog.Start(); } /// @@ -69,10 +67,20 @@ protected SeatalkInterface() _autopilotController = new AutoPilotRemoteController(this); _cancellation = new CancellationTokenSource(); _watchDog = new Thread(WatchDogStarter); + _disposed = false; } public Seatalk1Parser Parser => _parser; + /// + /// Starts listening on the port + /// + public void StartDecode() + { + _parser.StartDecode(); + _watchDog.Start(); + } + private static int BitCount(int b) { int count = 0; @@ -237,6 +245,11 @@ public void SetLampIntensity(DisplayBacklightLevel intensity) protected virtual void Dispose(bool disposing) { + if (_disposed) + { + return; + } + if (disposing) { _cancellation.Cancel(); @@ -246,6 +259,7 @@ protected virtual void Dispose(bool disposing) _port.Dispose(); _watchDog.Join(); _cancellation.Dispose(); + _disposed = true; } } diff --git a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs new file mode 100644 index 0000000000..afd51e47b2 --- /dev/null +++ b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs @@ -0,0 +1,64 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Iot.Device.Common; +using Iot.Device.Nmea0183; +using Iot.Device.Nmea0183.Sentences; +using Iot.Device.Seatalk1.Messages; +using Microsoft.Extensions.Logging; + +namespace Iot.Device.Seatalk1 +{ + public class SeatalkToNmeaConverter : NmeaSinkAndSource + { + private SeatalkInterface _seatalkInterface; + private bool _isDisposed; + private ILogger _logger; + + public SeatalkToNmeaConverter(string interfaceName, string portName) + : base(interfaceName) + { + _logger = this.GetCurrentClassLogger(); + _seatalkInterface = new SeatalkInterface(portName); + _seatalkInterface.MessageReceived += SeatalkMessageReceived; + _isDisposed = false; + } + + private void SeatalkMessageReceived(SeatalkMessage stalk) + { + var nmeaMsg = new SeatalkNmeaMessage(stalk.CreateDatagram(), DateTimeOffset.UtcNow); + _logger.LogDebug($"Received Seatalk message: {stalk}"); + DispatchSentenceEvents(nmeaMsg); + } + + public override void StartDecode() + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(SeatalkToNmeaConverter)); + } + + _seatalkInterface.StartDecode(); + } + + public override void SendSentence(NmeaSinkAndSource source, NmeaSentence sentence) + { + if (sentence.Valid && sentence.SentenceId == SeatalkNmeaMessage.Id) + { + // Since we get all commands we send out back on this interface, we must make sure we're not bouncing those again + if (sentence is SeatalkNmeaMessage msg && source != this) + { + var data = msg.Datagram; + _seatalkInterface.SendDatagram(data); + } + } + } + + public override void StopDecode() + { + _seatalkInterface.Dispose(); + _isDisposed = true; + } + } +} diff --git a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs index 6f2acf0846..17f81dfba6 100644 --- a/src/devices/Seatalk1/samples/Seatalk1.Samples.cs +++ b/src/devices/Seatalk1/samples/Seatalk1.Samples.cs @@ -44,6 +44,8 @@ public async void Run(string[] args) _seatalk.MessageReceived += ParserOnNewMessageDecoded; + _seatalk.StartDecode(); + var ctrl = _seatalk.GetAutopilotRemoteController(); WriteCurrentState(); From b95310fbc355f4d5208729582c0bb6e65c682cb1 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 7 Jan 2024 15:36:12 +0100 Subject: [PATCH 22/31] More simulation stuff Unfortunately, the ST2000 doesn't contain a rudder sensor, but at least the data could be sent. --- .../Sentences/HeadingAndTrackControl.cs | 18 ++- .../Sentences/HeadingAndTrackControlStatus.cs | 114 +++++++++++++++ .../Nmea0183/Sentences/RudderSensorAngle.cs | 130 ++++++++++++++++++ src/devices/Nmea0183/TalkerSentence.cs | 1 + .../samples/NmeaSimulator/NmeaSimulator.cs | 47 +++++-- .../NmeaSimulator/NmeaSimulator.csproj | 4 + .../NmeaSimulator/SimulatorArguments.cs | 30 ++++ src/devices/Nmea0183/tests/SentenceTests.cs | 8 +- .../Seatalk1/SeatalkToNmeaConverter.cs | 37 +++++ 9 files changed, 370 insertions(+), 19 deletions(-) create mode 100644 src/devices/Nmea0183/Sentences/HeadingAndTrackControlStatus.cs create mode 100644 src/devices/Nmea0183/Sentences/RudderSensorAngle.cs create mode 100644 src/devices/Nmea0183/samples/NmeaSimulator/SimulatorArguments.cs diff --git a/src/devices/Nmea0183/Sentences/HeadingAndTrackControl.cs b/src/devices/Nmea0183/Sentences/HeadingAndTrackControl.cs index 13091fb1f4..f8f8fc3878 100644 --- a/src/devices/Nmea0183/Sentences/HeadingAndTrackControl.cs +++ b/src/devices/Nmea0183/Sentences/HeadingAndTrackControl.cs @@ -12,7 +12,7 @@ namespace Iot.Device.Nmea0183.Sentences { /// - /// HDC sequence. This is used to control an attached auto-pilot. + /// HTC sequence. This is used to control an attached auto-pilot. /// Documentation of this sentence is very poor, and one has to dig deep /// to find information about it. /// Since the actual encoding might be autopilot-dependent, this message outputs all values in raw format. @@ -206,7 +206,7 @@ public override string ToNmeaParameterList() b.Append(FromLength(TurnRadius)); if (RateOfTurn.HasValue) { - b.Append(RateOfTurn.Value.DeciradiansPerSecond.ToString("F1", CultureInfo.InvariantCulture) + ","); + b.Append(RateOfTurn.Value.DegreesPerSecond.ToString("F1", CultureInfo.InvariantCulture) + ","); } else { @@ -227,7 +227,12 @@ public override string ToReadableContent() return $"Mode: {Status}, CommandedTrack: {CommandedTrack}, TurnMode: {TurnMode}"; } - private static Angle? AsAngle(double? value) + /// + /// Get a nullable double field as angle + /// + /// Input angle + /// An angle or null, if the input is null + protected static Angle? AsAngle(double? value) { if (value.HasValue) { @@ -237,7 +242,12 @@ public override string ToReadableContent() return null; } - private static string FromAngle(Angle? angle) + /// + /// Translate as nullable angle to a value in degrees with one digit + /// + /// Angle to translate + /// The translated angle or just a comma + protected static string FromAngle(Angle? angle) { if (!angle.HasValue) { diff --git a/src/devices/Nmea0183/Sentences/HeadingAndTrackControlStatus.cs b/src/devices/Nmea0183/Sentences/HeadingAndTrackControlStatus.cs new file mode 100644 index 0000000000..868f9bb90b --- /dev/null +++ b/src/devices/Nmea0183/Sentences/HeadingAndTrackControlStatus.cs @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnitsNet; + +namespace Iot.Device.Nmea0183.Sentences +{ + /// + /// This is the status reply from the autopilot. It is similar to the HTC message with 4 extra fields. + /// + public class HeadingAndTrackControlStatus : HeadingAndTrackControl + { + /// + /// This sentence's id + /// + public static new SentenceId Id => new SentenceId("HTD"); + + private static bool Matches(SentenceId sentence) => Id == sentence; + + private static bool Matches(TalkerSentence sentence) => Matches(sentence.Id); + + /// + /// Initialize a new instance of this type. + /// See the individual properties for further explanation to the parameters. + /// + /// Status of Autopilot + /// Commanded rudder angle + /// Rudder direction + /// Turn mode + /// Rudder limit + /// Off-Heading limit + /// Desired turn radius + /// Desired rate of turn + /// Desired heading + /// Desired off-track limit + /// Commanded track direction + /// Heading uses true angles + /// True if rudder limit is exceeded + /// True if the heading is out of limits + /// True if the track limits are exceeded + /// Heading from the Autopilot's onw heading sensor + public HeadingAndTrackControlStatus(string status, Angle? commandedRudderAngle, string commandedRudderDirection, string turnMode, + Angle? rudderLimit, Angle? offHeadingLimit, Length? turnRadius, RotationalSpeed? rateOfTurn, Angle? desiredHeading, + Length? offTrackLimit, Angle? commandedTrack, bool headingIsTrue, + bool rudderLimitExceeded, bool headingLimitExceeded, bool trackLimitExceeded, Angle? actualHeading) + : base(status, commandedRudderAngle, commandedRudderDirection, turnMode, rudderLimit, offHeadingLimit, turnRadius, + rateOfTurn, desiredHeading, offTrackLimit, commandedTrack, headingIsTrue) + { + RudderLimitExceeded = rudderLimitExceeded; + HeadingLimitExceeded = headingLimitExceeded; + TrackLimitExceeded = trackLimitExceeded; + ActualHeading = actualHeading; + } + + /// + /// Internal constructor + /// + public HeadingAndTrackControlStatus(TalkerSentence sentence, DateTimeOffset time) + : base(sentence, time) + { + } + + /// + /// Decoding constructor + /// + public HeadingAndTrackControlStatus(TalkerId talkerId, IEnumerable fields, DateTimeOffset time) + : base(talkerId, fields, time) + { + IEnumerator field = fields.GetEnumerator(); + for (int i = 0; i < 13; i++) + { + field.MoveNext(); + } + + RudderLimitExceeded = ReadString(field) == "V"; + HeadingLimitExceeded = ReadString(field) == "V"; + TrackLimitExceeded = ReadString(field) == "V"; + ActualHeading = AsAngle(ReadValue(field)); + } + + /// + /// True if the rudder limit is exceeded + /// + public bool RudderLimitExceeded { get; } + + /// + /// True if the heading limit is exceeded + /// + public bool HeadingLimitExceeded { get; } + + /// + /// True if the track limit is exceeded + /// + public bool TrackLimitExceeded { get; } + + /// + /// The actual heading, from the Autopilot's own heading sensor + /// + public Angle? ActualHeading { get; } + + /// + public override string ToNmeaParameterList() + { + string ret = base.ToNmeaParameterList(); + var angleString = FromAngle(ActualHeading).Replace(",", string.Empty); // the last comma is not needed + return ret + FormattableString.Invariant($",{(RudderLimitExceeded ? "V" : "A")},{(HeadingLimitExceeded ? "V" : "A")},{(TrackLimitExceeded ? "V" : "A")},{angleString}"); + } + } +} diff --git a/src/devices/Nmea0183/Sentences/RudderSensorAngle.cs b/src/devices/Nmea0183/Sentences/RudderSensorAngle.cs new file mode 100644 index 0000000000..07ab2e4fa0 --- /dev/null +++ b/src/devices/Nmea0183/Sentences/RudderSensorAngle.cs @@ -0,0 +1,130 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Iot.Device.Common; +using UnitsNet; + +namespace Iot.Device.Nmea0183.Sentences +{ + /// + /// Rudder angle from rudder angle sensor (if fitted) + /// + public class RudderSensorAngle : NmeaSentence + { + /// + /// This sentence ID "RSA" + /// + public static SentenceId Id => new SentenceId("RSA"); + private static bool Matches(SentenceId sentence) => Id == sentence; + private static bool Matches(TalkerSentence sentence) => Matches(sentence.Id); + + /// + /// Constructs a new RSA sentence + /// + /// Starboard or single rudder angle (0 = centered) + /// Port rudder angle, if fitted + public RudderSensorAngle(Angle starboard, Angle? port) + : base(OwnTalkerId, Id, DateTimeOffset.UtcNow) + { + Starboard = starboard; + Port = port; + Valid = true; + } + + /// + /// Internal constructor + /// + public RudderSensorAngle(TalkerSentence sentence, DateTimeOffset time) + : this(sentence.TalkerId, Matches(sentence) ? sentence.Fields : throw new ArgumentException($"SentenceId does not match expected id '{Id}'"), time) + { + } + + /// + /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it. + /// + public RudderSensorAngle(TalkerId talkerId, IEnumerable fields, DateTimeOffset time) + : base(talkerId, Id, time) + { + IEnumerator field = fields.GetEnumerator(); + + double? starboard = ReadValue(field); + string valid = ReadString(field); + if (starboard.HasValue && valid == "A") + { + Starboard = Angle.FromDegrees(starboard.Value); + Valid = true; // The message is only valid if there's at least a stb sensor. + } + + double? port = ReadValue(field); + valid = ReadString(field); + if (port.HasValue && valid == "A") + { + Port = Angle.FromDegrees(port.Value); + } + } + + /// + /// This is true for this message type + /// + public override bool ReplacesOlderInstance => true; + + /// + /// Starboard or single rudder angle 0 = center, negative for turning to port. A negative rudder angle will thus reduce the heading. + /// + public Angle Starboard + { + get; + private set; + } + + /// + /// Port rudder angle. Null if not fitted (most boats will only have one rudder sensor, if at all) + /// + public Angle? Port + { + get; + private set; + } + + /// + /// Presents this message as output + /// + public override string ToNmeaParameterList() + { + if (Valid) + { + StringBuilder sb = new StringBuilder(); + sb.Append(Starboard.ToString("F1", CultureInfo.InvariantCulture) + ",A,"); + if (Port.HasValue) + { + sb.Append(Port.Value.ToString("F1", CultureInfo.InvariantCulture) + ",A"); + } + else + { + sb.Append(",V"); + } + + return sb.ToString(); + } + + return string.Empty; + } + + /// + public override string ToReadableContent() + { + if (Valid) + { + return $"Rudder Angle: {Starboard.Normalize(false).Degrees:F1}°"; + } + + return "No rudder sensor"; + } + } +} diff --git a/src/devices/Nmea0183/TalkerSentence.cs b/src/devices/Nmea0183/TalkerSentence.cs index 49016446d4..698d25394a 100644 --- a/src/devices/Nmea0183/TalkerSentence.cs +++ b/src/devices/Nmea0183/TalkerSentence.cs @@ -49,6 +49,7 @@ public class TalkerSentence (sentence, time) => new WindDirectionWithRespectToNorth(sentence, time); knownSentences[HeadingAndTrackControl.Id] = (sentence, time) => new HeadingAndTrackControl(sentence, time); knownSentences[SeatalkNmeaMessage.Id] = (sentence, time) => new SeatalkNmeaMessage(sentence, time); + knownSentences[RudderSensorAngle.Id] = (sentence, time) => new RudderSensorAngle(sentence, time); knownSentences[ProprietaryMessage.Id] = (sentence, time) => { var specificMessageId = sentence.Fields.FirstOrDefault(); diff --git a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs index a9249a2be7..571393d798 100644 --- a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs +++ b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Net; using System.Linq; @@ -14,6 +15,7 @@ using Iot.Device.Nmea0183.Sentences; using Iot.Device.Seatalk1; using UnitsNet; +using CommandLine; namespace Nmea.Simulator { @@ -40,27 +42,43 @@ private List ReplayFiles get; } - public static void Main(string[] args) + public static int Main(string[] args) { Console.WriteLine("Simple GNSS simulator"); Console.WriteLine("Usage: NmeaSimulator [options]"); - Console.WriteLine("Options are:"); - Console.WriteLine("--replay files Plays back the given NMEA log file in real time (only with shifted timestamps). Wildcards supported."); - Console.WriteLine(); + var parser = new Parser(x => + { + x.AutoHelp = true; + x.AutoVersion = true; + x.CaseInsensitiveEnumValues = true; + x.ParsingCulture = CultureInfo.InvariantCulture; + x.CaseSensitive = false; + x.HelpWriter = Console.Out; + }); + + var parsed = parser.ParseArguments(args); + if (parsed.Errors.Any()) + { + Console.WriteLine("Error in command line"); + return 1; + } + var sim = new Simulator(); - if (args.Length >= 2 && args[0] == "--replay") + if (!string.IsNullOrWhiteSpace(parsed.Value.ReplayFiles)) { - var wildCards = args[1]; + var wildCards = parsed.Value.ReplayFiles; FileInfo fi = new FileInfo(wildCards); string path = fi.DirectoryName ?? string.Empty; sim.ReplayFiles.AddRange(Directory.GetFiles(path, fi.Name)); } - sim.StartServer(); + sim.StartServer(parsed.Value.SeatalkInterface); + + return 0; } - private void StartServer() + private void StartServer(string seatalk) { _tcpServer = null; _udpServer = null; @@ -92,9 +110,14 @@ private void StartServer() // Also optionally directly connect to the Seatalk1 bus. // For simplicity, this example is not using a MessageRouter. - _seatalkInterface = new SeatalkToNmeaConverter("Seatalk1", "/dev/ttyAMA2"); - _seatalkInterface.OnNewSequence += SeatalkNewSequence; - _seatalkInterface.StartDecode(); + if (!string.IsNullOrWhiteSpace(seatalk)) + { + _seatalkInterface = new SeatalkToNmeaConverter("Seatalk1", seatalk); + _seatalkInterface.OnNewSequence += SeatalkNewSequence; + _seatalkInterface.SentencesToTranslate.Add(HeadingAndTrackControlStatus.Id); + _seatalkInterface.SentencesToTranslate.Add(RudderSensorAngle.Id); + _seatalkInterface.StartDecode(); + } Console.WriteLine("Waiting for connections. Press x to quit"); while (true) @@ -190,9 +213,9 @@ private void SendNewData() private void SendSentence(NmeaSentence sentence) { + Console.WriteLine($"Sending {sentence.ToReadableContent()}"); if (_tcpServer != null) { - // Console.WriteLine($"Sending {sentence.ToReadableContent()}"); _tcpServer.SendSentence(sentence); } diff --git a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.csproj b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.csproj index 7976cffe70..cc55cef8f5 100644 --- a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.csproj +++ b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.csproj @@ -6,6 +6,10 @@ Nmea.Simulator + + + + diff --git a/src/devices/Nmea0183/samples/NmeaSimulator/SimulatorArguments.cs b/src/devices/Nmea0183/samples/NmeaSimulator/SimulatorArguments.cs new file mode 100644 index 0000000000..e628762962 --- /dev/null +++ b/src/devices/Nmea0183/samples/NmeaSimulator/SimulatorArguments.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using CommandLine; + +namespace Nmea.Simulator +{ + internal class SimulatorArguments + { + public SimulatorArguments() + { + ReplayFiles = string.Empty; + SeatalkInterface = string.Empty; + } + + [Option("replay", HelpText = "Plays back the given NMEA log file in real time (only with shifted timestamps). Wildcards supported")] + public string ReplayFiles + { + get; + set; + } + + [Option("seatalk", HelpText = "Seatalk1 interface to connect to (for testing converters or autopilots)")] + public string SeatalkInterface + { + get; + set; + } + } +} diff --git a/src/devices/Nmea0183/tests/SentenceTests.cs b/src/devices/Nmea0183/tests/SentenceTests.cs index 796d6d0f9e..4072d73678 100644 --- a/src/devices/Nmea0183/tests/SentenceTests.cs +++ b/src/devices/Nmea0183/tests/SentenceTests.cs @@ -496,7 +496,7 @@ public void DontCrashOnTheseInvalidSentences(string sentence) } [Fact] - public void HtdEncode() + public void HtcEncode() { var hdt = new HeadingAndTrackControl("M", null, "L", "N", null, null, null, null, null, null, null, true); var msg = hdt.ToNmeaParameterList(); @@ -599,6 +599,7 @@ public void SentenceRoundTrip(string input) [InlineData("$HCHDG,30.9,,,1.9,E")] [InlineData("$YDVHW,,T,,M,3.1,N,5.7,K,*64")] [InlineData("$YDMWD,336.8,T,333.8,M,21.6,N,11.1,M*58")] + [InlineData("$APRSA,12.2,A,,V")] public void CanParseAllTheseMessages(string input) { var inSentence = TalkerSentence.FromSentenceString(input, out var error); @@ -628,9 +629,10 @@ public void CanParseAllTheseMessages(string input) [InlineData("$YDVHW,,T,,M,3.1,N,5.7,K,")] [InlineData("$YDGSV,5,1,18,19,29,257,45,22,30,102,45,04,76,143,44,06,47,295,42")] [InlineData("$YDMWD,336.8,T,333.8,M,21.6,N,11.1,M")] - [InlineData("$APHTD,V,10.0,L,R,N,12,13,2.0,1.0,15.1,0.5,16.2,T")] + [InlineData("$APHTC,V,10.0,L,R,N,12.3,13.4,2.0,1.0,15.1,0.5,16.2,T")] + [InlineData("$APHTD,V,10.0,L,R,N,12.0,13.5,2.0,1.0,15.1,0.5,16.2,T,V,A,V,123.2")] [InlineData("$STALK,84,86,26,97,02,00,00,00,08")] - [InlineData("$STALK,9c,01,12,00")] + [InlineData("$STALK,9C,01,12,00")] public void SentenceRoundTripIsUnaffectedByCulture(string input) { // de-DE has "," as decimal separator. Big trouble if using CurrentCulture for any parsing or formatting here diff --git a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs index afd51e47b2..8570111388 100644 --- a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs +++ b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs @@ -2,16 +2,19 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using Iot.Device.Common; using Iot.Device.Nmea0183; using Iot.Device.Nmea0183.Sentences; using Iot.Device.Seatalk1.Messages; using Microsoft.Extensions.Logging; +using UnitsNet; namespace Iot.Device.Seatalk1 { public class SeatalkToNmeaConverter : NmeaSinkAndSource { + private readonly List _sentencesToTranslate; private SeatalkInterface _seatalkInterface; private bool _isDisposed; private ILogger _logger; @@ -19,17 +22,51 @@ public class SeatalkToNmeaConverter : NmeaSinkAndSource public SeatalkToNmeaConverter(string interfaceName, string portName) : base(interfaceName) { + _sentencesToTranslate = new(); _logger = this.GetCurrentClassLogger(); _seatalkInterface = new SeatalkInterface(portName); _seatalkInterface.MessageReceived += SeatalkMessageReceived; _isDisposed = false; } + /// + /// List of sentences to translate between Seatalk and NMEA. + /// + /// + /// The following sentences are currently supported: + /// HTD (only Seatalk->Nmea) + /// + public List SentencesToTranslate => _sentencesToTranslate; + private void SeatalkMessageReceived(SeatalkMessage stalk) { var nmeaMsg = new SeatalkNmeaMessage(stalk.CreateDatagram(), DateTimeOffset.UtcNow); _logger.LogDebug($"Received Seatalk message: {stalk}"); DispatchSentenceEvents(nmeaMsg); + if (stalk is CompassHeadingAutopilotCourse apStatus) + { + if (SentencesToTranslate.Contains(HeadingAndTrackControlStatus.Id)) + { + string status = apStatus.AutopilotStatus switch + { + AutopilotStatus.Standby => "M", + AutopilotStatus.Auto => "S", + AutopilotStatus.Track => "T", + AutopilotStatus.Wind => "W", // This one is just guess + _ => "M", + }; + var htd = new HeadingAndTrackControlStatus(status, apStatus.RudderPosition.Abs(), apStatus.RudderPosition > Angle.Zero ? "R" : "L", "N", + null, null, null, null, apStatus.AutoPilotCourse, null, apStatus.AutoPilotCourse, false, false, false, apStatus.Alarms != 0, apStatus.CompassHeading); + DispatchSentenceEvents(htd); + } + + if (SentencesToTranslate.Contains(RudderSensorAngle.Id)) + { + var angle = apStatus.RudderPosition; + var rsa = new RudderSensorAngle(angle, null); + DispatchSentenceEvents(rsa); + } + } } public override void StartDecode() From 96c53d0015efc228460bb90ed8e446c645873d8a Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 7 Jan 2024 19:16:44 +0100 Subject: [PATCH 23/31] Schema cleanup --- .../schematics/SeaTalk1/SeaTalk1.kicad_pcb | 99 ++++++++++++++++++- .../schematics/SeaTalk1/SeaTalk1.kicad_prl | 2 +- .../schematics/SeaTalk1/SeaTalk1.kicad_sch | 52 +++++----- .../Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk | 7 +- 4 files changed, 126 insertions(+), 34 deletions(-) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb index 2b8ba102de..576bfadd2f 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb @@ -1,2 +1,99 @@ (kicad_pcb (version 20221018) (generator pcbnew) -) \ No newline at end of file + + (general + (thickness 1.6) + ) + + (paper "A4") + (title_block + (title "Seatalk1-Raspi Interface") + (date "2024-01-03") + (rev "1") + ) + + (layers + (0 "F.Cu" signal) + (31 "B.Cu" signal) + (32 "B.Adhes" user "B.Adhesive") + (33 "F.Adhes" user "F.Adhesive") + (34 "B.Paste" user) + (35 "F.Paste" user) + (36 "B.SilkS" user "B.Silkscreen") + (37 "F.SilkS" user "F.Silkscreen") + (38 "B.Mask" user) + (39 "F.Mask" user) + (40 "Dwgs.User" user "User.Drawings") + (41 "Cmts.User" user "User.Comments") + (42 "Eco1.User" user "User.Eco1") + (43 "Eco2.User" user "User.Eco2") + (44 "Edge.Cuts" user) + (45 "Margin" user) + (46 "B.CrtYd" user "B.Courtyard") + (47 "F.CrtYd" user "F.Courtyard") + (48 "B.Fab" user) + (49 "F.Fab" user) + (50 "User.1" user) + (51 "User.2" user) + (52 "User.3" user) + (53 "User.4" user) + (54 "User.5" user) + (55 "User.6" user) + (56 "User.7" user) + (57 "User.8" user) + (58 "User.9" user) + ) + + (setup + (stackup + (layer "F.SilkS" (type "Top Silk Screen")) + (layer "F.Paste" (type "Top Solder Paste")) + (layer "F.Mask" (type "Top Solder Mask") (thickness 0.01)) + (layer "F.Cu" (type "copper") (thickness 0.035)) + (layer "dielectric 1" (type "core") (thickness 1.51) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02)) + (layer "B.Cu" (type "copper") (thickness 0.035)) + (layer "B.Mask" (type "Bottom Solder Mask") (thickness 0.01)) + (layer "B.Paste" (type "Bottom Solder Paste")) + (layer "B.SilkS" (type "Bottom Silk Screen")) + (copper_finish "None") + (dielectric_constraints no) + ) + (pad_to_mask_clearance 0) + (pcbplotparams + (layerselection 0x00010fc_ffffffff) + (plot_on_all_layers_selection 0x0000000_00000000) + (disableapertmacros false) + (usegerberextensions false) + (usegerberattributes true) + (usegerberadvancedattributes true) + (creategerberjobfile true) + (dashed_line_dash_ratio 12.000000) + (dashed_line_gap_ratio 3.000000) + (svgprecision 4) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (dxfpolygonmode true) + (dxfimperialunits true) + (dxfusepcbnewfont true) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (sketchpadsonfab false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 1) + (scaleselection 1) + (outputdirectory "") + ) + ) + + (net 0 "") + +) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl index 30061e2286..86192ddcef 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl @@ -1,7 +1,7 @@ { "board": { "active_layer": 0, - "active_layer_preset": "", + "active_layer_preset": "All Layers", "auto_track_width": true, "hidden_netclasses": [], "hidden_nets": [], diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch index d522ba0690..8423747db8 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch @@ -1025,9 +1025,6 @@ (junction (at 78.74 91.44) (diameter 0) (color 0 0 0 0) (uuid 6fde8244-ba92-4977-b00e-d5e5037505c0) ) - (junction (at 55.88 67.31) (diameter 0) (color 0 0 0 0) - (uuid 71951e16-a954-4080-9836-02765d3bee3b) - ) (junction (at 104.14 91.44) (diameter 0) (color 0 0 0 0) (uuid 913843ae-a42d-4ec5-bc54-9bb74f618eb8) ) @@ -1191,6 +1188,10 @@ (stroke (width 0) (type default)) (uuid 3504c25b-c266-4edc-bf23-66089abff71a) ) + (wire (pts (xy 148.59 19.05) (xy 238.76 19.05)) + (stroke (width 0) (type default)) + (uuid 3d228b31-9238-40e1-b7b6-7063fa5d491e) + ) (wire (pts (xy 93.98 71.12) (xy 104.14 71.12)) (stroke (width 0) (type default)) (uuid 3d5ea4ae-a29c-4afc-99c6-4f313dfb4cab) @@ -1295,10 +1296,6 @@ (stroke (width 0) (type default)) (uuid 68eb80fe-cb1e-47ca-8f0f-51c4d30013c8) ) - (wire (pts (xy 134.62 91.44) (xy 148.59 91.44)) - (stroke (width 0) (type default)) - (uuid 6e4d9651-109b-4b8a-b523-e05257cdb63b) - ) (wire (pts (xy 233.68 22.86) (xy 233.68 25.4)) (stroke (width 0) (type default)) (uuid 6f7b28ef-1ebc-4e0e-a7ed-804c1ad2fe50) @@ -1307,6 +1304,10 @@ (stroke (width 0) (type default)) (uuid 70743eba-8649-4837-9280-0ed6ff392396) ) + (wire (pts (xy 134.62 91.44) (xy 148.59 91.44)) + (stroke (width 0) (type default)) + (uuid 70d03e07-ad24-4325-94e6-ef06c1bdc445) + ) (wire (pts (xy 134.62 58.42) (xy 134.62 91.44)) (stroke (width 0) (type default)) (uuid 73616a01-4faa-4ffd-8d94-19ab712113f5) @@ -1403,10 +1404,6 @@ (stroke (width 0) (type default)) (uuid acf4034f-3bba-4c21-a0fb-e57002a1e0f4) ) - (wire (pts (xy 46.99 67.31) (xy 55.88 67.31)) - (stroke (width 0) (type default)) - (uuid acf7adc9-995b-4c9a-b999-d816bf39474b) - ) (wire (pts (xy 262.89 140.97) (xy 262.89 161.29)) (stroke (width 0) (type default)) (uuid b1aaa67c-8dd8-4b91-b0aa-079a442b7051) @@ -1439,10 +1436,6 @@ (stroke (width 0) (type default)) (uuid bd458123-e665-4795-9ae8-450cb8a79e3a) ) - (wire (pts (xy 148.59 19.05) (xy 238.76 19.05)) - (stroke (width 0) (type default)) - (uuid bdab5554-e4c4-45de-ae0e-034832ab27a1) - ) (wire (pts (xy 78.74 64.77) (xy 78.74 91.44)) (stroke (width 0) (type default)) (uuid be0cb463-2824-4c93-a3e4-68c50010e20b) @@ -1578,10 +1571,10 @@ (effects (font (size 1.27 1.27)) (justify right) hide) ) ) - (global_label "SIM_BUS" (shape output) (at 224.79 116.84 90) (fields_autoplaced) + (global_label "SEATALK" (shape output) (at 224.79 116.84 90) (fields_autoplaced) (effects (font (size 1.27 1.27)) (justify left)) (uuid 29f71db3-7bff-4ff6-acaa-84fe0e08e66a) - (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 224.79 105.8115 90) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 224.79 106.0534 90) (effects (font (size 1.27 1.27)) (justify left) hide) ) ) @@ -1606,13 +1599,6 @@ (effects (font (size 1.27 1.27)) (justify right) hide) ) ) - (global_label "SIM_BUS" (shape input) (at 46.99 67.31 180) (fields_autoplaced) - (effects (font (size 1.27 1.27)) (justify right)) - (uuid 5121d1cc-153d-4518-b61d-4b58c488e25b) - (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 35.9615 67.31 0) - (effects (font (size 1.27 1.27)) (justify right) hide) - ) - ) (global_label "VCC_3.3" (shape passive) (at 236.22 118.11 90) (fields_autoplaced) (effects (font (size 1.27 1.27)) (justify left)) (uuid 7a64d7eb-50df-4fe0-9ac5-7878eacbbce8) @@ -1822,7 +1808,7 @@ ) (symbol (lib_id "Simulation_SPICE:VDC") (at 22.86 64.77 0) (unit 1) - (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (in_bom no) (on_board no) (dnp no) (fields_autoplaced) (uuid 27f6dfc4-6d11-4993-be5b-18f0ba52532f) (property "Reference" "V2" (at 26.67 63.3702 0) (effects (font (size 1.27 1.27)) (justify left)) @@ -1954,7 +1940,7 @@ (property "Sim.Device" "V" (at 224.79 142.24 0) (effects (font (size 1.27 1.27)) (justify left) hide) ) - (property "Sim.Params" "y1=12 y2=2 td=1m tr=2n tf=2n tw=1m per=2m np=3" (at 228.6 144.6502 0) + (property "Sim.Params" "y1=12 y2=2 td=1m tr=2n tf=2n tw=0.2m per=2m np=3" (at 228.6 144.6502 0) (effects (font (size 1.27 1.27)) (justify left)) ) (pin "1" (uuid 075f54ff-0140-4922-8631-014e613fcc3b)) @@ -2062,7 +2048,7 @@ ) (symbol (lib_id "Device:R") (at 57.15 30.48 270) (unit 1) - (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (in_bom no) (on_board no) (dnp no) (fields_autoplaced) (uuid 71be8ad0-bfd2-4f59-afd6-b1bb5fcc5604) (property "Reference" "R12" (at 57.15 24.13 90) (effects (font (size 1.27 1.27))) @@ -2295,10 +2281,16 @@ (property "Sim.Device" "D" (at 134.62 39.37 0) (effects (font (size 1.27 1.27)) hide) ) - (property "Sim.Pins" "1=A 2=K" (at 134.62 39.37 0) + (property "Sim.Pins" "1=K 2=A" (at 134.62 39.37 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Params" "is=259390a" (at 134.62 39.37 0) (effects (font (size 1.27 1.27)) hide) ) - (property "Sim.Params" "is=259.39f rs=0.24229 n=4.0113 ikf=0 eg=3 xtitun=25" (at 134.62 39.37 0) + (property "Sim.Library" "Leds.lib" (at 134.62 39.37 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Sim.Name" "DLED_Nichia" (at 134.62 39.37 0) (effects (font (size 1.27 1.27)) hide) ) (pin "2" (uuid 2a7e67eb-09da-4759-853a-db9309bb07cf)) @@ -2610,7 +2602,7 @@ ) (symbol (lib_id "Simulation_SPICE:VPULSE") (at 262.89 135.89 0) (unit 1) - (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (in_bom no) (on_board no) (dnp no) (fields_autoplaced) (uuid e7e16ff2-fd42-4d7f-b3c0-2d8d792d9503) (property "Reference" "V_TXD1" (at 266.7 133.2202 0) (effects (font (size 1.27 1.27)) (justify left)) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk index 96062ab5b3..26e14802b0 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk @@ -1,8 +1,11 @@ version 2 1 9 -.tran 100u 15m{return}{return}.kicad adjustpaths{return}.save all{return}.probe alli -4 +.tran 10u 20m{return}.kicad adjustpaths{return}.save all{return}.probe alli +5 +2 +I(D1) + 1 V(Net-_D1-K_) From 6bb711f24e71aa1873d4342b03825c40984e9dca Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 7 Jan 2024 19:18:15 +0100 Subject: [PATCH 24/31] Add some message translation between Seatalk and NMEA --- .../samples/NmeaSimulator/NmeaSimulator.cs | 3 +- .../Seatalk1/Messages/ApparentWindSpeed.cs | 82 +++++++++++++++++++ src/devices/Seatalk1/Seatalk1.csproj | 1 + src/devices/Seatalk1/Seatalk1Parser.cs | 1 + src/devices/Seatalk1/SeatalkInterface.cs | 2 +- .../Seatalk1/SeatalkToNmeaConverter.cs | 45 +++++++++- src/devices/Seatalk1/tests/MessageTests.cs | 16 ++++ 7 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 src/devices/Seatalk1/Messages/ApparentWindSpeed.cs diff --git a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs index 571393d798..b9fc9ff75d 100644 --- a/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs +++ b/src/devices/Nmea0183/samples/NmeaSimulator/NmeaSimulator.cs @@ -114,8 +114,7 @@ private void StartServer(string seatalk) { _seatalkInterface = new SeatalkToNmeaConverter("Seatalk1", seatalk); _seatalkInterface.OnNewSequence += SeatalkNewSequence; - _seatalkInterface.SentencesToTranslate.Add(HeadingAndTrackControlStatus.Id); - _seatalkInterface.SentencesToTranslate.Add(RudderSensorAngle.Id); + _seatalkInterface.SentencesToTranslate.Add(SentenceId.Any); _seatalkInterface.StartDecode(); } diff --git a/src/devices/Seatalk1/Messages/ApparentWindSpeed.cs b/src/devices/Seatalk1/Messages/ApparentWindSpeed.cs new file mode 100644 index 0000000000..fea9fc7965 --- /dev/null +++ b/src/devices/Seatalk1/Messages/ApparentWindSpeed.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Iot.Device.Common; +using UnitsNet; + +namespace Iot.Device.Seatalk1.Messages +{ + public record ApparentWindSpeed : SeatalkMessage + { + private readonly Speed _apparentSpeed; + + public ApparentWindSpeed() + { + ApparentSpeed = Speed.FromKnots(0); // Default unit is knots + } + + public ApparentWindSpeed(Speed apparentSpeed) + { + ApparentSpeed = apparentSpeed; + } + + public override byte CommandByte => 0x11; + public override byte ExpectedLength => 0x4; + + /// + /// Apparent wind angle, relative to bow. + /// Positive for right of bow (wind from starboard) + /// + public Speed ApparentSpeed + { + get + { + return _apparentSpeed; + } + init + { + if (value < Speed.Zero) + { + throw new ArgumentException("Speed cannot be negative"); + } + + _apparentSpeed = value; + } + } + + public override SeatalkMessage CreateNewMessage(IReadOnlyList data) + { + Speed spd = Speed.Zero; + if ((data[2] & 0x80) == 0x80) // Speed is given in m/s + { + spd = Speed.FromMetersPerSecond((data[2] & 0x7F) + (data[3] / 10.0)); + } + else // Speed is in knots + { + spd = Speed.FromKnots((data[2] & 0x7F) + (data[3] / 10.0)); + } + + return this with + { + ApparentSpeed = spd + }; + } + + public override byte[] CreateDatagram() + { + double rounded = Math.Round(ApparentSpeed.Knots, 1); + byte byte1 = (byte)rounded; + double remainder = Math.Round(Math.Abs(rounded - Math.Round(rounded)), 1); + byte byte2 = (byte)(remainder * 10.0); + return new byte[] + { + CommandByte, (byte)(ExpectedLength - 3), byte1, byte2 + }; + } + } +} diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index da8bf3f2b7..e699a72f83 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -16,6 +16,7 @@ + diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index 57996ab8ce..e552665f5d 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -62,6 +62,7 @@ public Seatalk1Parser(Stream inputStream) new SetLampIntensity(), new AutopilotCalibrationParameterMessage(), new ApparentWindAngle(), + new ApparentWindSpeed(), new NavigationToWaypoint(), new CourseComputerStatus(), }; diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index 1c6bcdf62a..e99e22620b 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -221,7 +221,7 @@ public virtual bool SendMessage(SeatalkMessage message) return SendDatagram(bytes); } - public Task SendMessageAsync(SeatalkMessage message) + public Task SendMessageAsync(SeatalkMessage message) { return Task.Factory.StartNew(() => SendMessage(message)); } diff --git a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs index 8570111388..c509cc959b 100644 --- a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs +++ b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs @@ -34,7 +34,9 @@ public SeatalkToNmeaConverter(string interfaceName, string portName) /// /// /// The following sentences are currently supported: - /// HTD (only Seatalk->Nmea) + /// HTD (Seatalk->Nmea) + /// RSA (Seatalk->Nmea) + /// MWV (Nmea->Seatalk) /// public List SentencesToTranslate => _sentencesToTranslate; @@ -43,9 +45,11 @@ private void SeatalkMessageReceived(SeatalkMessage stalk) var nmeaMsg = new SeatalkNmeaMessage(stalk.CreateDatagram(), DateTimeOffset.UtcNow); _logger.LogDebug($"Received Seatalk message: {stalk}"); DispatchSentenceEvents(nmeaMsg); + + // Translations Seatalk->Nmea if (stalk is CompassHeadingAutopilotCourse apStatus) { - if (SentencesToTranslate.Contains(HeadingAndTrackControlStatus.Id)) + if (SentencesToTranslate.Contains(HeadingAndTrackControlStatus.Id) || SentencesToTranslate.Contains(SentenceId.Any)) { string status = apStatus.AutopilotStatus switch { @@ -60,7 +64,7 @@ private void SeatalkMessageReceived(SeatalkMessage stalk) DispatchSentenceEvents(htd); } - if (SentencesToTranslate.Contains(RudderSensorAngle.Id)) + if (SentencesToTranslate.Contains(RudderSensorAngle.Id) || SentencesToTranslate.Contains(SentenceId.Any)) { var angle = apStatus.RudderPosition; var rsa = new RudderSensorAngle(angle, null); @@ -81,7 +85,12 @@ public override void StartDecode() public override void SendSentence(NmeaSinkAndSource source, NmeaSentence sentence) { - if (sentence.Valid && sentence.SentenceId == SeatalkNmeaMessage.Id) + if (sentence.Valid == false) + { + return; + } + + if (sentence.SentenceId == SeatalkNmeaMessage.Id) { // Since we get all commands we send out back on this interface, we must make sure we're not bouncing those again if (sentence is SeatalkNmeaMessage msg && source != this) @@ -90,6 +99,34 @@ public override void SendSentence(NmeaSinkAndSource source, NmeaSentence sentenc _seatalkInterface.SendDatagram(data); } } + + if (DoTranslate(sentence, out WindSpeedAndAngle? mwv) && mwv != null) + { + ApparentWindAngle awa = new ApparentWindAngle() + { + ApparentAngle = mwv.Angle + }; + _seatalkInterface.SendMessage(awa); + + ApparentWindSpeed aws = new ApparentWindSpeed() + { + ApparentSpeed = mwv.Speed, + }; + _seatalkInterface.SendMessage(aws); + } + } + + private bool DoTranslate(NmeaSentence sentence, out T? convertedSentence) + where T : NmeaSentence + { + if (sentence is T converted && (SentencesToTranslate.Contains(sentence.SentenceId) || SentencesToTranslate.Contains(SentenceId.Any))) + { + convertedSentence = converted; + return true; + } + + convertedSentence = default(T); + return false; } public override void StopDecode() diff --git a/src/devices/Seatalk1/tests/MessageTests.cs b/src/devices/Seatalk1/tests/MessageTests.cs index 4e8a217ca1..2ee4a71f21 100644 --- a/src/devices/Seatalk1/tests/MessageTests.cs +++ b/src/devices/Seatalk1/tests/MessageTests.cs @@ -31,6 +31,7 @@ public MessageTests() [InlineData("86 01 02 fd", typeof(Keystroke))] [InlineData("10 01 00 01", typeof(ApparentWindAngle))] [InlineData("85 06 00 00 C0 0D 1F 00 E0", typeof(NavigationToWaypoint))] + [InlineData("11 01 00 00", typeof(ApparentWindSpeed))] public void KnownMessageTypeDecode(string msg, Type expectedType) { msg = msg.Replace(" ", string.Empty); @@ -148,5 +149,20 @@ public void NavigationToWaypointMessage2() Assert.Equal(0x0F, data[6] & 0xF); // flags } + + [Fact] + public void WindSpeedMessage() + { + var windSpeed = new ApparentWindSpeed() + { + ApparentSpeed = Speed.FromKnots(12.212) + }; + + byte[] data = windSpeed.CreateDatagram(); + Assert.Equal(0x11, data[0]); + Assert.Equal(0x1, data[1]); + Assert.Equal(12, data[2]); + Assert.Equal(2, data[3]); + } } } From 95339ae16331d1fdf0cb5a7c49956005b067f98b Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 7 Jan 2024 21:21:27 +0100 Subject: [PATCH 25/31] Various tests added and NavigationToWaypoint reversed --- .../Seatalk1/Messages/NavigationToWaypoint.cs | 56 ++++++++++++++++++- src/devices/Seatalk1/tests/MessageTests.cs | 27 ++++++++- src/devices/Seatalk1/tests/Seatalk1Tests.cs | 27 +++++++++ 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs b/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs index edfa49f5a4..cc511befee 100644 --- a/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs +++ b/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs @@ -53,7 +53,56 @@ public Length? DistanceToDestination public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { - return new NavigationToWaypoint(); + byte flags = data[6]; + int vvv = ((data[1] & 0xF0) >> 4) | (data[2] << 4); + Length? crossTrackDistance = Length.FromNauticalMiles(vvv / 100.0); + if ((data[6] & 0x40) == 0x40) + { + crossTrackDistance = -crossTrackDistance; + } + + if ((flags & 1) == 0) + { + crossTrackDistance = null; + } + + bool bearingIsTrue = (data[3] & 0x8) == 0x8; + int u = data[3] & 0x3; + + int remainder = (data[4] & 0xF) << 4; + remainder |= (data[3] & 0xF0) >> 4; + + Angle? bearingToDestination = Angle.FromDegrees((u * 90) + (remainder / 2.0)); + + if ((flags & 2) == 0) + { + bearingToDestination = null; + } + + int dist = data[5] << 4; + dist |= (data[4] >> 4); + + Length? distance; + if ((flags & 4) == 0) + { + distance = null; + } + else if ((data[6] & 0x10) == 0x10) + { + distance = Length.FromNauticalMiles(dist / 100.0); + } + else + { + distance = Length.FromNauticalMiles(dist / 10.0); + } + + return new NavigationToWaypoint() + { + BearingIsTrue = bearingIsTrue, + BearingToDestination = bearingToDestination, + CrossTrackError = crossTrackDistance, + DistanceToDestination = distance, + }; } public override byte[] CreateDatagram() @@ -146,5 +195,10 @@ public override byte[] CreateDatagram() return data; } + + public override bool MatchesMessageType(IReadOnlyList data) + { + return base.MatchesMessageType(data) && data[6] == (byte)(~data[8]); + } } } diff --git a/src/devices/Seatalk1/tests/MessageTests.cs b/src/devices/Seatalk1/tests/MessageTests.cs index 2ee4a71f21..c49043f35a 100644 --- a/src/devices/Seatalk1/tests/MessageTests.cs +++ b/src/devices/Seatalk1/tests/MessageTests.cs @@ -119,6 +119,9 @@ public void NavigationToWaypointMessage1() Assert.Equal(0x06, data[4] & 0x0F); Assert.Equal(0x0F, data[6] & 0xF); // flags + + var reverse = n.CreateNewMessage(data); + Assert.Equal(n, reverse); } [Fact] @@ -148,6 +151,25 @@ public void NavigationToWaypointMessage2() Assert.Equal(0x00, data[4] & 0x0F); Assert.Equal(0x0F, data[6] & 0xF); // flags + + var reverse = n.CreateNewMessage(data); + Assert.Equal(n, reverse); + } + + [Fact] + public void NavigationToWaypointMessage3() + { + var n = new NavigationToWaypoint() + { + BearingToDestination = Angle.FromDegrees(299.5), + BearingIsTrue = true, + CrossTrackError = Length.FromNauticalMiles(-0.1), + DistanceToDestination = Length.FromNauticalMiles(5.3), + }; + + byte[] data = n.CreateDatagram(); + var reverse = n.CreateNewMessage(data); + Assert.Equal(n, reverse); } [Fact] @@ -155,7 +177,7 @@ public void WindSpeedMessage() { var windSpeed = new ApparentWindSpeed() { - ApparentSpeed = Speed.FromKnots(12.212) + ApparentSpeed = Speed.FromKnots(12.2) }; byte[] data = windSpeed.CreateDatagram(); @@ -163,6 +185,9 @@ public void WindSpeedMessage() Assert.Equal(0x1, data[1]); Assert.Equal(12, data[2]); Assert.Equal(2, data[3]); + + var reverse = windSpeed.CreateNewMessage(data); + Assert.Equal(windSpeed, reverse); } } } diff --git a/src/devices/Seatalk1/tests/Seatalk1Tests.cs b/src/devices/Seatalk1/tests/Seatalk1Tests.cs index c185ae5ed0..c5140b6eb3 100644 --- a/src/devices/Seatalk1/tests/Seatalk1Tests.cs +++ b/src/devices/Seatalk1/tests/Seatalk1Tests.cs @@ -173,6 +173,33 @@ public void CanBasicRoundTripMessages() } } + [Theory] + [InlineData("9c 01 12 00")] + [InlineData("84 06 12 00 00 00 00 00 08")] + [InlineData("86 01 02 fd")] + [InlineData("95 86 26 97 02 00 00 00 08")] + [InlineData("87 00 01")] + [InlineData("87 00 02")] + [InlineData("10 01 00 01")] + [InlineData("85 06 00 00 C0 0D 17 00 E8")] + [InlineData("11 01 12 04")] + public void ParseAndBack(string inputSentence) + { + var split = inputSentence.Split(new char[] { '\n', '\r', ' ' }, StringSplitOptions.RemoveEmptyEntries); + // FromHexString expects an uninterrupted sequence of two-char pairs + byte[] inputDatagram = Convert.FromHexString(string.Join(string.Empty, split)); + + MemoryStream ms = new MemoryStream(); + Seatalk1Parser parser = new Seatalk1Parser(ms); + + var msg = parser.GetTypeOfNextMessage(inputDatagram, out int bytesInMessage); + Assert.NotNull(msg); + Assert.NotEqual(0, bytesInMessage); + + byte[] roundTripped = msg.CreateDatagram(); + Assert.Equal(inputDatagram, roundTripped); + } + private static MemoryStream GetStreamFromInputString(string data) { var split = data.Split(new char[] { '\n', '\r', ' ' }, StringSplitOptions.RemoveEmptyEntries); From 9bbff7fc13a0d153e82e372fc6cebb41a2e365ae Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 8 Jan 2024 20:47:25 +0100 Subject: [PATCH 26/31] Minor cleanup, create empty PCB --- .../schematics/SeaTalk1/SeaTalk1.kicad_pcb | 2116 +++++++++++++++++ .../schematics/SeaTalk1/SeaTalk1.kicad_sch | 98 +- .../Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk | 12 +- 3 files changed, 2173 insertions(+), 53 deletions(-) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb index 576bfadd2f..3bb25f1513 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb @@ -95,5 +95,2121 @@ ) (net 0 "") + (net 1 "Net-(C1-Pad1)") + (net 2 "Net-(Q2-B)") + (net 3 "Net-(D1-K)") + (net 4 "Net-(D1-A)") + (net 5 "VCC_3.3") + (net 6 "VCC_5.0") + (net 7 "unconnected-(J1-SDA{slash}GPIO2-Pad3)") + (net 8 "unconnected-(J1-SCL{slash}GPIO3-Pad5)") + (net 9 "GND") + (net 10 "unconnected-(J1-GCLK0{slash}GPIO4-Pad7)") + (net 11 "TXD") + (net 12 "Net-(J1-GPIO15{slash}RXD)") + (net 13 "unconnected-(J1-GPIO17-Pad11)") + (net 14 "unconnected-(J1-GPIO18{slash}PWM0-Pad12)") + (net 15 "unconnected-(J1-GPIO27-Pad13)") + (net 16 "unconnected-(J1-GPIO22-Pad15)") + (net 17 "unconnected-(J1-GPIO23-Pad16)") + (net 18 "unconnected-(J1-GPIO24-Pad18)") + (net 19 "unconnected-(J1-MOSI0{slash}GPIO10-Pad19)") + (net 20 "unconnected-(J1-MISO0{slash}GPIO9-Pad21)") + (net 21 "unconnected-(J1-GPIO25-Pad22)") + (net 22 "unconnected-(J1-SCLK0{slash}GPIO11-Pad23)") + (net 23 "unconnected-(J1-~{CE0}{slash}GPIO8-Pad24)") + (net 24 "unconnected-(J1-~{CE1}{slash}GPIO7-Pad26)") + (net 25 "unconnected-(J1-ID_SD{slash}GPIO0-Pad27)") + (net 26 "unconnected-(J1-ID_SC{slash}GPIO1-Pad28)") + (net 27 "unconnected-(J1-GCLK1{slash}GPIO5-Pad29)") + (net 28 "unconnected-(J1-GCLK2{slash}GPIO6-Pad31)") + (net 29 "unconnected-(J1-PWM0{slash}GPIO12-Pad32)") + (net 30 "unconnected-(J1-PWM1{slash}GPIO13-Pad33)") + (net 31 "unconnected-(J1-GPIO19{slash}MISO1-Pad35)") + (net 32 "unconnected-(J1-GPIO16-Pad36)") + (net 33 "unconnected-(J1-GPIO26-Pad37)") + (net 34 "unconnected-(J1-GPIO20{slash}MOSI1-Pad38)") + (net 35 "unconnected-(J1-GPIO21{slash}SCLK1-Pad40)") + (net 36 "SEATALK") + (net 37 "Net-(J3-Pin_3)") + (net 38 "Net-(Q1-C)") + (net 39 "Net-(Q1-B)") + (net 40 "Net-(Q4-B)") + (net 41 "Net-(Q5-C)") + (net 42 "Net-(Q5-B)") + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp 143a716d-6648-4d65-9154-fb626eeef15e) + (at 53.40556 73.05) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "R") + (property "Sim.Pins" "1=+ 2=-") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/4f117a73-66ee-4224-8fe8-71a32870a260") + (attr through_hole) + (fp_text reference "R6" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 0b8f23ab-4bed-45be-b1ef-3b8d6c2182e3) + ) + (fp_text value "4.7k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp f77620d9-f581-491f-88a7-3a0e4e97ef30) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 5dbba380-31fa-4785-8c7d-40e13b8ad49d) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp aedd000d-a0aa-4717-9700-cc9c52617264)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c693a408-493f-4ffd-85a9-6dae84122bd5)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0a6085a2-5fa1-4935-92c3-7e1633e62abe)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fd8f0c47-e9e8-45a8-aa67-53ba0899b7e3)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b4c7eace-f233-4532-bcd5-af937cb90449)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 454807ae-09a8-4568-9f42-c8256966f765)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp da701bdd-623f-41ec-ad28-403258024061)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 68b12e79-7256-4750-84f8-a918ea13f7b4)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 576ea73f-5524-4dc6-b933-fe4211cf251a)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp fc6bcdf6-3c36-4216-9d0a-53286ffb494a)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6a95ef3d-2e53-457c-b2b1-6847a26fb786)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b8a42a6f-ad87-4dfe-a745-454433d81131)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6fcc09ad-4712-46f5-9460-8cff920febea)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 82d96c8a-2fe9-46ed-93ab-5a8313b4b0fc)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 86a1e5bc-4f6d-40a8-9a24-ebdff23bec31)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a067e0a1-84b8-44ca-841d-4f9a7e2755a0)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp bcfb35a3-00f4-4124-accd-c8b6f17f6129)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pintype "passive") (tstamp 118604ef-4780-427c-b7c6-ee44d5aceb8c)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") + (tstamp 1f42dcc5-eeaa-4e46-b2ae-97adbb29e215) + (at 79.35556 55.97) + (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") + (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "NPN") + (property "Sim.Library" "BC547_and_BC557.lib") + (property "Sim.Name" "bc547b") + (property "Sim.Pins" "1=C 2=B 3=E") + (property "Sim.Type" "GUMMELPOON") + (property "ki_description" "0.1A Ic, 45V Vce, Small Signal NPN Transistor, TO-92") + (property "ki_keywords" "NPN Transistor") + (path "/9fb6ea96-3606-4642-89c7-d6759aecd3a2") + (attr through_hole) + (fp_text reference "Q2" (at 1.27 -3.56) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 66d312a6-4601-4ca2-b42e-2b4a1bf91fee) + ) + (fp_text value "BC547" (at 1.27 2.79) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 6e837be2-9026-4534-8b37-de54e9c50939) + ) + (fp_text user "${REFERENCE}" (at 1.27 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 466143c4-0306-430b-9421-41f839349327) + ) + (fp_line (start -0.53 1.85) (end 3.07 1.85) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d1ffc7a8-6030-4c39-a136-fbd214514997)) + (fp_arc (start -0.568478 1.838478) (mid -1.132087 -0.994977) (end 1.27 -2.6) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 50c625e0-7977-4bdd-be2a-013ef50afdc7)) + (fp_arc (start 1.27 -2.6) (mid 3.672087 -0.994977) (end 3.108478 1.838478) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 563000a5-7b9c-498b-a21e-72933aa8e5b5)) + (fp_line (start -1.46 -2.73) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp cdf42ae7-59fb-4a6c-9038-c3b0bc565b78)) + (fp_line (start -1.46 -2.73) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp b752108e-36b7-4f34-b199-6b11d5c0d498)) + (fp_line (start 4 2.01) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c14ecd52-a16b-4a13-936a-a0708a903cbb)) + (fp_line (start 4 2.01) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6679d865-fef7-4ced-ac8c-6a9d74ffef62)) + (fp_line (start -0.5 1.75) (end 3 1.75) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 8c78d38a-68e4-47b7-8304-1a14b0fe5409)) + (fp_arc (start -0.483625 1.753625) (mid -1.021221 -0.949055) (end 1.27 -2.48) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp caa5b353-95dc-4588-b285-ea207c7061fb)) + (fp_arc (start 1.27 -2.48) (mid 3.561221 -0.949055) (end 3.023625 1.753625) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f1966e35-ff93-4ef8-b0a1-627c07ebf593)) + (pad "1" thru_hole rect (at 0 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 12 "Net-(J1-GPIO15{slash}RXD)") (pinfunction "C") (pintype "passive") (tstamp 886df849-4ba5-4146-9eda-70c6ec222944)) + (pad "2" thru_hole oval (at 1.27 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 2 "Net-(Q2-B)") (pinfunction "B") (pintype "input") (tstamp b7810ae4-9e2a-440d-9be8-8b5e7738d046)) + (pad "3" thru_hole oval (at 2.54 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "E") (pintype "passive") (tstamp 0d63f7b5-d5c7-4847-88cc-b282a427a401)) + (model "${KICAD6_3DMODEL_DIR}/Package_TO_SOT_THT.3dshapes/TO-92_Inline.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "LED_THT:LED_D3.0mm_Horizontal_O3.81mm_Z6.0mm" (layer "F.Cu") + (tstamp 25808193-2af6-4752-970c-26256f1fa393) + (at 85.65556 48.7) + (descr "LED, diameter 3.0mm z-position of LED center 2.0mm, 2 pins, diameter 3.0mm z-position of LED center 2.0mm, 2 pins, diameter 3.0mm z-position of LED center 2.0mm, 2 pins, diameter 3.0mm z-position of LED center 6.0mm, 2 pins, diameter 3.0mm z-position of LED center 6.0mm, 2 pins") + (tags "LED diameter 3.0mm z-position of LED center 2.0mm 2 pins diameter 3.0mm z-position of LED center 2.0mm 2 pins diameter 3.0mm z-position of LED center 2.0mm 2 pins diameter 3.0mm z-position of LED center 6.0mm 2 pins diameter 3.0mm z-position of LED center 6.0mm 2 pins") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "D") + (property "Sim.Library" "Leds.lib") + (property "Sim.Name" "DLED_Nichia") + (property "Sim.Params" "is=259390a") + (property "Sim.Pins" "1=K 2=A") + (property "ki_description" "Light emitting diode") + (property "ki_keywords" "LED diode") + (path "/88a72208-5af9-4097-94e1-8cb31aaadfea") + (attr through_hole) + (fp_text reference "D1" (at 1.27 -1.96) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp ed011d75-c95f-4703-87d4-4d2cc0e064f8) + ) + (fp_text value "LED" (at 1.27 10.17) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 8c3ad186-092d-40b5-a9ba-69a2a942b952) + ) + (fp_line (start -0.29 3.75) (end -0.29 7.61) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d57cb4e6-a45e-402c-89d9-f8dfb2108037)) + (fp_line (start -0.29 3.75) (end 2.83 3.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a878550b-ccee-416a-83e5-47469396e6fb)) + (fp_line (start 0 1.08) (end 0 1.08) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d3cc7ec9-2e84-4fed-a99e-424ce01300f7)) + (fp_line (start 0 1.08) (end 0 3.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9c4e3636-5ac8-4ad1-8941-d9d2c22dbdd4)) + (fp_line (start 0 3.75) (end 0 1.08) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e79c7d6d-8fb5-449b-bbf2-14e0777be246)) + (fp_line (start 0 3.75) (end 0 3.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f47b1f53-bf2d-4909-8006-e40c8f503f79)) + (fp_line (start 2.54 1.08) (end 2.54 1.08) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fed21792-e0bd-43c0-aa26-412aae97718f)) + (fp_line (start 2.54 1.08) (end 2.54 3.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 930c20cd-a7bf-4bd3-bd96-67fd20e18112)) + (fp_line (start 2.54 3.75) (end 2.54 1.08) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fe241723-e90c-48c7-a065-281bdf1b4bbd)) + (fp_line (start 2.54 3.75) (end 2.54 3.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c486d7e4-9598-47b2-a082-b64e8a9f9359)) + (fp_line (start 2.83 3.75) (end 2.83 7.61) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3d1adbb6-f7e9-4a18-ba47-bab71aeb634d)) + (fp_line (start 2.83 3.75) (end 3.23 3.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d8bdd4bb-cc3e-41be-833a-dbf8a97d6a02)) + (fp_line (start 2.83 4.87) (end 2.83 3.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 205b5bf0-2246-4288-a8b9-69e1382f351f)) + (fp_line (start 3.23 3.75) (end 3.23 4.87) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3906c52c-350f-4415-9d84-4bab78aef20a)) + (fp_line (start 3.23 4.87) (end 2.83 4.87) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ff3e0986-2e7f-400d-9368-6abd44161984)) + (fp_arc (start 2.83 7.61) (mid 1.27 9.17) (end -0.29 7.61) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2388aa19-8e87-485d-9a46-788f6b96da9d)) + (fp_line (start -1.25 -1.25) (end -1.25 9.45) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 98c2473b-692d-49c2-bdf2-e9a6f4e4e343)) + (fp_line (start -1.25 9.45) (end 3.75 9.45) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e1494dfa-b0c8-4ebd-98e6-036fb30ffa96)) + (fp_line (start 3.75 -1.25) (end -1.25 -1.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 8c4602fe-071d-4eb0-96ce-a18faa4ac34b)) + (fp_line (start 3.75 9.45) (end 3.75 -1.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp a8947a4d-dd09-4078-b30a-dacd3164a15e)) + (fp_line (start -0.23 3.81) (end -0.23 7.61) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 724f9769-fa89-43d1-9ee6-b8d9bbe6f464)) + (fp_line (start -0.23 3.81) (end 2.77 3.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 1f24f019-aedf-45d8-8088-f64f2fe614e4)) + (fp_line (start 0 0) (end 0 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 83ca193a-6519-493e-b492-6d394ca85c62)) + (fp_line (start 0 0) (end 0 3.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 72b245a0-bca3-4e1a-ae08-3d5255208d3c)) + (fp_line (start 0 3.81) (end 0 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c0eca2e3-995d-4b6a-a1a4-491471ccf6a9)) + (fp_line (start 0 3.81) (end 0 3.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 41577bb3-ca45-40b9-ae75-cb19f65a2557)) + (fp_line (start 2.54 0) (end 2.54 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 928ef726-01da-4cf4-9e63-502e32f73db2)) + (fp_line (start 2.54 0) (end 2.54 3.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7bc3cbec-7a1e-4ebb-92fd-0894d890a8ec)) + (fp_line (start 2.54 3.81) (end 2.54 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 89fb0f74-fc82-4645-879f-bc57093d973e)) + (fp_line (start 2.54 3.81) (end 2.54 3.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 120343bb-08f7-4ade-9f3a-80a7d757a563)) + (fp_line (start 2.77 3.81) (end 2.77 7.61) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 031bdd11-783e-41c5-91af-286dc21aff84)) + (fp_line (start 2.77 3.81) (end 3.17 3.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6d835b2f-d596-41a2-b234-94623c382ae7)) + (fp_line (start 2.77 4.81) (end 2.77 3.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 52648d6c-0bf3-41ec-8996-8c75763f676e)) + (fp_line (start 3.17 3.81) (end 3.17 4.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 1a29b7b9-03aa-4ad8-88c0-8073d7e9143d)) + (fp_line (start 3.17 4.81) (end 2.77 4.81) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f215b54a-e268-4cb1-883f-a0e53b3997a7)) + (fp_arc (start 2.77 7.61) (mid 1.27 9.11) (end -0.23 7.61) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 02437eff-3ebc-4d38-a406-d8d49792b90d)) + (pad "1" thru_hole rect (at 0 0) (size 1.8 1.8) (drill 0.9) (layers "*.Cu" "*.Mask") + (net 3 "Net-(D1-K)") (pinfunction "K") (pintype "passive") (tstamp 38d1529c-1927-40bb-8b71-b3cb495c564e)) + (pad "2" thru_hole circle (at 2.54 0) (size 1.8 1.8) (drill 0.9) (layers "*.Cu" "*.Mask") + (net 4 "Net-(D1-A)") (pinfunction "A") (pintype "passive") (tstamp 34bcf44b-3cdb-4640-96ae-73b5c0e836c4)) + (model "${KICAD6_3DMODEL_DIR}/LED_THT.3dshapes/LED_D3.0mm_Horizontal_O3.81mm_Z6.0mm.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp 265f818b-0fe1-4d04-b25c-6ae6c26e89a3) + (at 53.40556 101.55) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/8b0fd059-b19f-4565-852a-74e3223bfaf1") + (attr through_hole) + (fp_text reference "R14" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 9f1a862c-2580-42d4-bbbb-b9fbcfb18739) + ) + (fp_text value "2.2k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 7c4e277c-1380-40bd-9766-3c9b81dfde22) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 1232a4c2-27e3-4e01-9bc2-a439e9d52c61) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ebbd6d74-c3bb-4f6e-829f-1e245cf591cb)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ff8fc32c-4570-4591-bce7-667ffba0e70e)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8895f56f-e754-41de-8707-b25151e74bd7)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 90b10aa8-5279-4153-ae15-11b1a3fd14ff)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ec103252-80cb-43e0-9067-57c6d95b2d24)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 03d0a2ec-d331-486c-a22c-b70e325f9c5c)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1240405b-11b7-477c-9f95-8c6272645b70)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 01cf4b2c-b805-4391-b8d5-144b2bdba99a)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp dfce50b1-56ba-445a-b7d2-5aa17314fbde)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2075fd49-d6fd-4697-92f3-17b4c7a889cc)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2ad4005b-d7c4-4dea-bf61-fba0de563a11)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0284cf5d-bf95-4f80-8245-bab305023bdc)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0b7f3fc7-0522-458b-88a3-c8a838186700)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp bdecdb42-e448-4dc9-a29a-7beb3b893507)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b9001cc7-5715-4521-a7a3-a2bc25afaff7)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a6a5a203-39c0-4718-9ded-1eefdca82a60)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 40 "Net-(Q4-B)") (pintype "passive") (tstamp a18c8be9-d224-487b-a896-99004329def2)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pintype "passive") (tstamp 5f8a81d4-d0a2-4730-9a3d-043c376740b1)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp 29a518ee-ac44-4f07-bdf9-97bec75d2e31) + (at 53.40556 58.8) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "R") + (property "Sim.Pins" "1=+ 2=-") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/0512ba43-5f13-4592-bd94-7ec2752829fa") + (attr through_hole) + (fp_text reference "R3" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp af9c498c-8627-41cf-97a1-04471ddc2cbf) + ) + (fp_text value "2.2k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 931d2374-bd5d-42ee-8c09-e55dec719fcb) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp ac78ab7b-9493-4c33-abe1-fc6dc5202582) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e67008f8-a57d-4878-b07e-83d03f084db6)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 93a1c98d-dbae-42be-85f3-2691c4135ee9)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b48d49a4-b94a-4e5f-8a7b-7b70b827f2ad)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a53acdd2-a714-450b-8af6-dcf52139e12e)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fea01b30-a411-4e54-9e3a-ade9db9ab7b6)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4599e09f-455f-4f9d-afa9-bef14d28fb8a)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c6ac6064-9c69-4e57-92d8-74a0a2ac32b6)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e7b7b9f1-fe97-4282-a7fc-9515abd3712b)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 319083d1-cf10-4276-a207-56c9ba9c82bc)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 43300871-9fec-4968-ad60-18a2d0fe3e97)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 73ea93c8-ed59-4777-b54f-dcf8f73713b7)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 60da2fe0-a311-49c6-8119-b9e0c182f575)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 001ee6fb-2936-486c-9ad6-0c1a3e76a283)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b2790b0f-a280-41ec-a3f3-d2197c5211e5)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6b2e22d4-ac4e-40db-ac77-66e71518e7ae)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 730329f2-17bd-45c9-b965-d196287ba074)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 38 "Net-(Q1-C)") (pintype "passive") (tstamp 9dfb9a76-5c4d-4843-b279-ec635a4675c4)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp 00cd662e-ef9a-4cb7-b7c5-c5147c6adf9d)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Capacitor_THT:CP_Radial_D12.5mm_P7.50mm" (layer "F.Cu") + (tstamp 340a6af9-097e-4004-b71a-d4160aee262b) + (at 83.94 91.44) + (descr "CP, Radial series, Radial, pin pitch=7.50mm, , diameter=12.5mm, Electrolytic Capacitor") + (tags "CP Radial series Radial pin pitch 7.50mm diameter 12.5mm Electrolytic Capacitor") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "C") + (property "Sim.Pins" "1=+ 2=-") + (property "ki_description" "Polarized capacitor") + (property "ki_keywords" "cap capacitor") + (path "/ff3cc76a-1a65-43c7-a10c-c52bf541e8be") + (attr through_hole) + (fp_text reference "C1" (at 3.75 -7.5) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 4aabcb66-83c2-4552-bbe8-46e03c295130) + ) + (fp_text value "150u" (at 3.75 7.5) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 777ebd91-5d66-46a7-bd34-221264991f8a) + ) + (fp_text user "${REFERENCE}" (at 3.75 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp ee637a7e-42f8-4cd4-a1b0-7c49797e19d3) + ) + (fp_line (start -3.067082 -3.575) (end -1.817082 -3.575) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 82767668-99c5-481e-9234-70372e810e75)) + (fp_line (start -2.442082 -4.2) (end -2.442082 -2.95) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5ab7ec9f-bee5-46bc-93af-2f9449587fc1)) + (fp_line (start 3.75 -6.33) (end 3.75 6.33) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 956a9046-c259-4e05-a9ce-cced9afee24f)) + (fp_line (start 3.79 -6.33) (end 3.79 6.33) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c2fe83fe-c8c7-4fb9-b4b7-7b775661aade)) + (fp_line (start 3.83 -6.33) (end 3.83 6.33) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d2b37e33-fb2f-4be2-9df6-03a5fb70c04a)) + (fp_line (start 3.87 -6.329) (end 3.87 6.329) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7ef88d01-05cc-47a1-b4e3-a9d7a641e7df)) + (fp_line (start 3.91 -6.328) (end 3.91 6.328) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2cca9b5c-0af8-49c8-916a-a5ae5f223e66)) + (fp_line (start 3.95 -6.327) (end 3.95 6.327) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f9720154-61ea-4d2c-bae9-a57975584f07)) + (fp_line (start 3.99 -6.326) (end 3.99 6.326) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 76427781-0c85-4cf2-a074-1df8ed4162b4)) + (fp_line (start 4.03 -6.324) (end 4.03 6.324) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp be156fdb-44c3-45ef-8d88-5fa13e220797)) + (fp_line (start 4.07 -6.322) (end 4.07 6.322) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1fc6340e-a0c4-45b8-b291-fec71ab1b8c6)) + (fp_line (start 4.11 -6.32) (end 4.11 6.32) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3e4aeee0-7514-4db1-8655-05d41d6aa4ac)) + (fp_line (start 4.15 -6.318) (end 4.15 6.318) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1d4155e4-f2a2-4685-8baa-cb005f604180)) + (fp_line (start 4.19 -6.315) (end 4.19 6.315) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 03ba4508-1551-4d44-a170-0c466a1d9c58)) + (fp_line (start 4.23 -6.312) (end 4.23 6.312) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 82b3abe6-b904-409c-9622-c07c44a5f9e7)) + (fp_line (start 4.27 -6.309) (end 4.27 6.309) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 53f96142-c2d8-44b8-8072-c2c53a6e1fe7)) + (fp_line (start 4.31 -6.306) (end 4.31 6.306) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 18cca3af-c824-4e5e-a536-f83ed9d4c812)) + (fp_line (start 4.35 -6.302) (end 4.35 6.302) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0af26ac1-e24f-4cf8-96ca-2d3e4e348573)) + (fp_line (start 4.39 -6.298) (end 4.39 6.298) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9d32ece2-ea9f-4d7f-b872-719652b39682)) + (fp_line (start 4.43 -6.294) (end 4.43 6.294) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7e319ea5-6a76-408f-933d-849bc7fd87f5)) + (fp_line (start 4.471 -6.29) (end 4.471 6.29) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cb71da61-b6e9-4e62-871d-fb895f2ab243)) + (fp_line (start 4.511 -6.285) (end 4.511 6.285) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 90727ac6-87a0-48d7-9515-73ac5115809c)) + (fp_line (start 4.551 -6.28) (end 4.551 6.28) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c34e18e6-4924-4151-a997-923494cc77f2)) + (fp_line (start 4.591 -6.275) (end 4.591 6.275) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ef49d27c-5358-4e02-bdf4-b1d0c1f80199)) + (fp_line (start 4.631 -6.269) (end 4.631 6.269) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 355d343f-1da2-4e06-bcfe-e07a4ae47a92)) + (fp_line (start 4.671 -6.264) (end 4.671 6.264) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 54015540-4e55-43c0-8198-1c202b035af5)) + (fp_line (start 4.711 -6.258) (end 4.711 6.258) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1cc117df-9e88-4269-b98f-33dd07aed1f3)) + (fp_line (start 4.751 -6.252) (end 4.751 6.252) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5025e6d2-a7f9-417d-8dd4-793044cc87a7)) + (fp_line (start 4.791 -6.245) (end 4.791 6.245) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4b1dd6c4-159c-4743-b416-84dcee5304d5)) + (fp_line (start 4.831 -6.238) (end 4.831 6.238) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7f35451d-3112-4b68-ab56-26d695812557)) + (fp_line (start 4.871 -6.231) (end 4.871 6.231) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 73a0c15c-a250-4147-9aad-b75f5fefc033)) + (fp_line (start 4.911 -6.224) (end 4.911 6.224) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 78a343b7-9791-4523-bd9e-aea1839efce5)) + (fp_line (start 4.951 -6.216) (end 4.951 6.216) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1e83bad8-9133-4721-838f-dade80b0e36a)) + (fp_line (start 4.991 -6.209) (end 4.991 6.209) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 90cf4bf4-a4c1-4a7e-a780-f79055ef7f09)) + (fp_line (start 5.031 -6.201) (end 5.031 6.201) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5032015c-94df-4ce0-859d-0b9f675b1582)) + (fp_line (start 5.071 -6.192) (end 5.071 6.192) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a73554f1-06ff-4959-901c-66cca1603d3f)) + (fp_line (start 5.111 -6.184) (end 5.111 6.184) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp da823442-07a2-46ab-a34e-ad74d7067cac)) + (fp_line (start 5.151 -6.175) (end 5.151 6.175) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e76b1f11-90e1-4980-a44a-68cb54fa987b)) + (fp_line (start 5.191 -6.166) (end 5.191 6.166) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6693baf4-2466-44c1-b039-ce2dfc23bb0c)) + (fp_line (start 5.231 -6.156) (end 5.231 6.156) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f98eb426-0405-4bbd-bfbe-4d5c59ea04be)) + (fp_line (start 5.271 -6.146) (end 5.271 6.146) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6a32bcb9-c699-4a55-97ca-19de102f3f80)) + (fp_line (start 5.311 -6.137) (end 5.311 6.137) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ce974244-d287-4f7a-b171-4c11211e22f1)) + (fp_line (start 5.351 -6.126) (end 5.351 6.126) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bd1f2b8e-cfb0-4d5b-91af-ad888a549758)) + (fp_line (start 5.391 -6.116) (end 5.391 6.116) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 94c7c67d-7184-4f3f-813a-d6793e640b68)) + (fp_line (start 5.431 -6.105) (end 5.431 6.105) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0a9d4480-07a4-4a89-aa76-1df9367be0c6)) + (fp_line (start 5.471 -6.094) (end 5.471 6.094) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e6ba13fa-4910-4fec-a577-a378e34c6e07)) + (fp_line (start 5.511 -6.083) (end 5.511 6.083) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp aee6769c-2fc1-43d9-b54d-8522bfcd27b9)) + (fp_line (start 5.551 -6.071) (end 5.551 6.071) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8d58e4ce-c6e0-4933-9a99-82592d251598)) + (fp_line (start 5.591 -6.059) (end 5.591 6.059) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp eb8f47a2-90b4-44f6-9613-6738755e46f7)) + (fp_line (start 5.631 -6.047) (end 5.631 6.047) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9b4e9350-622e-41f0-ad71-2350d63e1a31)) + (fp_line (start 5.671 -6.034) (end 5.671 6.034) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 28c62b1d-7b38-4e1f-a219-6deda3b1ea95)) + (fp_line (start 5.711 -6.021) (end 5.711 6.021) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e57e4557-11da-48e5-a068-b01ed44ad230)) + (fp_line (start 5.751 -6.008) (end 5.751 6.008) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1c7383b9-dc57-4e20-abc0-b71c09361b40)) + (fp_line (start 5.791 -5.995) (end 5.791 5.995) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4ea2886f-eae0-4d9b-a369-a2e388779261)) + (fp_line (start 5.831 -5.981) (end 5.831 5.981) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4c8634ef-13b2-4789-b3df-6604e6ad1502)) + (fp_line (start 5.871 -5.967) (end 5.871 5.967) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0f421a4c-399e-490c-b1da-ed4d10e29cc9)) + (fp_line (start 5.911 -5.953) (end 5.911 5.953) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4de9e80a-98ea-4c4b-8bda-928a1be1f0a9)) + (fp_line (start 5.951 -5.939) (end 5.951 5.939) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp edd155ba-cf4f-47ba-93fe-55959fe5067b)) + (fp_line (start 5.991 -5.924) (end 5.991 5.924) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5212892c-894d-4eca-a43a-750b44e4e6f0)) + (fp_line (start 6.031 -5.908) (end 6.031 5.908) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b2a044d6-06d8-475a-8ba1-ff3e9bea8109)) + (fp_line (start 6.071 -5.893) (end 6.071 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4844b30d-aeb8-4264-873b-3004e39f56f9)) + (fp_line (start 6.071 1.44) (end 6.071 5.893) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0b53c68a-8174-4937-949d-2ef3e48e7f83)) + (fp_line (start 6.111 -5.877) (end 6.111 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 480d3029-f1ad-4ec0-afe7-c5ee480888c1)) + (fp_line (start 6.111 1.44) (end 6.111 5.877) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4f88ee6f-4d98-4d60-b72b-227aa98382cc)) + (fp_line (start 6.151 -5.861) (end 6.151 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 078f5d28-3004-4f83-9c9c-e9b878174492)) + (fp_line (start 6.151 1.44) (end 6.151 5.861) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 87b6d09f-48a9-42e9-ab38-1587f961295c)) + (fp_line (start 6.191 -5.845) (end 6.191 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1f3cefa0-0a88-4b31-90bb-a31cdd10ff32)) + (fp_line (start 6.191 1.44) (end 6.191 5.845) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 56d7419a-8aa8-4555-9825-5e584e48ec10)) + (fp_line (start 6.231 -5.828) (end 6.231 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1906fe27-36b4-4bcf-a57c-2d09e4724d79)) + (fp_line (start 6.231 1.44) (end 6.231 5.828) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 904af904-99b2-4d44-96aa-dbd0f226865c)) + (fp_line (start 6.271 -5.811) (end 6.271 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c11ab026-dce2-41c7-a15b-7edc77be366f)) + (fp_line (start 6.271 1.44) (end 6.271 5.811) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8c6b479d-14fa-4c98-a8f8-4c3afd3c3885)) + (fp_line (start 6.311 -5.793) (end 6.311 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 551b5b1c-b099-4e62-a418-00eb4a315a84)) + (fp_line (start 6.311 1.44) (end 6.311 5.793) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 10b60402-967b-4c0d-899e-64f708e8b6e5)) + (fp_line (start 6.351 -5.776) (end 6.351 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6efb8833-9f14-43c0-960c-2672026fba57)) + (fp_line (start 6.351 1.44) (end 6.351 5.776) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 934be11b-e1ea-435d-a001-0585d4e3c095)) + (fp_line (start 6.391 -5.758) (end 6.391 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 345d33a7-e2dd-46b5-b255-42e5725a79dd)) + (fp_line (start 6.391 1.44) (end 6.391 5.758) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 199d1996-0d55-48e8-8599-343f04e9dba9)) + (fp_line (start 6.431 -5.739) (end 6.431 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6fa94890-cf51-441c-80e2-bc4233e85608)) + (fp_line (start 6.431 1.44) (end 6.431 5.739) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6745b3af-45c7-45e1-ad98-41abd6a70ec3)) + (fp_line (start 6.471 -5.721) (end 6.471 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5f25046c-c5fc-4d07-8438-b2003c5804ea)) + (fp_line (start 6.471 1.44) (end 6.471 5.721) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bde99e9a-d945-4fa5-a023-510746c134df)) + (fp_line (start 6.511 -5.702) (end 6.511 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0d770d69-f2e4-404f-967d-e3a6fcd3059e)) + (fp_line (start 6.511 1.44) (end 6.511 5.702) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5a1c2a19-3fb3-42de-8024-668b2ced7250)) + (fp_line (start 6.551 -5.682) (end 6.551 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ad75d76f-1631-437f-9adc-7b7006d2a98a)) + (fp_line (start 6.551 1.44) (end 6.551 5.682) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 027b37e3-4bba-4402-80a1-bf1c49c63a93)) + (fp_line (start 6.591 -5.662) (end 6.591 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2b38e9fa-37e1-4bcb-8ffe-a5899705eace)) + (fp_line (start 6.591 1.44) (end 6.591 5.662) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5060c437-34a7-4f6c-a047-f452dfcb297d)) + (fp_line (start 6.631 -5.642) (end 6.631 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 62a74be7-17d7-4e39-be6a-6dcfe472fac0)) + (fp_line (start 6.631 1.44) (end 6.631 5.642) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7175e32d-06db-4e4f-a24f-1eb760970b52)) + (fp_line (start 6.671 -5.622) (end 6.671 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a9efdfd1-70ea-44c2-a2d4-d6bfffe730a0)) + (fp_line (start 6.671 1.44) (end 6.671 5.622) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 03ddf994-b175-4542-a8fd-3bd33792395e)) + (fp_line (start 6.711 -5.601) (end 6.711 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9f78d4fd-3b48-40a6-96f7-5a034da882c4)) + (fp_line (start 6.711 1.44) (end 6.711 5.601) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2fdc8188-7247-45c9-8c53-ba0e2e375634)) + (fp_line (start 6.751 -5.58) (end 6.751 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bf62727c-7aad-4e7f-bab1-3f2caea08a39)) + (fp_line (start 6.751 1.44) (end 6.751 5.58) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 18d6b958-8b39-41a6-8eb3-5e32651315dd)) + (fp_line (start 6.791 -5.558) (end 6.791 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c49141e5-173f-4e55-ab6c-0553413ecb71)) + (fp_line (start 6.791 1.44) (end 6.791 5.558) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f8594f0a-4a5c-4fca-86ec-d51b42e80427)) + (fp_line (start 6.831 -5.536) (end 6.831 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a97e9bb1-c6a4-415f-b18e-9cb6e1c5a6c6)) + (fp_line (start 6.831 1.44) (end 6.831 5.536) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a99ea0a3-251c-486c-9a15-7af9ae182522)) + (fp_line (start 6.871 -5.514) (end 6.871 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6c154e06-75d3-480c-b204-e72046dd8ee6)) + (fp_line (start 6.871 1.44) (end 6.871 5.514) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9be698bd-7223-48ba-ab7e-f5e3e4f8f035)) + (fp_line (start 6.911 -5.491) (end 6.911 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5dcc2bc7-9faa-425b-9891-4e70e05ff939)) + (fp_line (start 6.911 1.44) (end 6.911 5.491) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7615ce13-c2fb-4e67-97e8-c1e5b5691dc8)) + (fp_line (start 6.951 -5.468) (end 6.951 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 716e16a8-2c88-4e3e-878c-f60954e63717)) + (fp_line (start 6.951 1.44) (end 6.951 5.468) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2ae6ba25-3caa-438d-816e-00b6969cc402)) + (fp_line (start 6.991 -5.445) (end 6.991 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c37ee0bf-bfb9-4f6e-bc5e-4d82264936c4)) + (fp_line (start 6.991 1.44) (end 6.991 5.445) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e32cfc4a-92a4-48a4-9328-85b25fae1a3b)) + (fp_line (start 7.031 -5.421) (end 7.031 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6921743e-d92c-4718-b6ab-adabb50e15d6)) + (fp_line (start 7.031 1.44) (end 7.031 5.421) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2f9bf25c-6d80-4e23-9c0d-ca3db7f51b63)) + (fp_line (start 7.071 -5.397) (end 7.071 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f0e3cb57-f777-49f1-9bec-0da75807591d)) + (fp_line (start 7.071 1.44) (end 7.071 5.397) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 57410fa0-41aa-40fc-b4d5-0c696b696c43)) + (fp_line (start 7.111 -5.372) (end 7.111 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 48455bc3-27a6-4768-836a-99ed916b9afe)) + (fp_line (start 7.111 1.44) (end 7.111 5.372) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 156f04d7-dc30-44f8-8bbe-85d2f01f372d)) + (fp_line (start 7.151 -5.347) (end 7.151 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cf97ba62-20d2-4a2b-9b46-3547b6245d59)) + (fp_line (start 7.151 1.44) (end 7.151 5.347) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f3d440c0-d7bf-4f5f-b3a1-6e710bc03781)) + (fp_line (start 7.191 -5.322) (end 7.191 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3c805520-f4dc-45df-adcd-53e353a03f44)) + (fp_line (start 7.191 1.44) (end 7.191 5.322) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1963c1dd-054c-4865-b195-2f7a3837b3a5)) + (fp_line (start 7.231 -5.296) (end 7.231 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 56a7c36d-a100-47fd-86db-bc4addefb1a7)) + (fp_line (start 7.231 1.44) (end 7.231 5.296) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b2f260a3-d87a-42ba-b654-270c94fdf48b)) + (fp_line (start 7.271 -5.27) (end 7.271 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fa87bbd3-a47a-4acd-9465-5f396bb40952)) + (fp_line (start 7.271 1.44) (end 7.271 5.27) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4cf80c3d-6371-4ec9-bc23-4c73fa920bbc)) + (fp_line (start 7.311 -5.243) (end 7.311 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 69943be2-c60a-489a-a115-3583427c7027)) + (fp_line (start 7.311 1.44) (end 7.311 5.243) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e2ac8259-2779-42ba-8528-bcf293dd9ed9)) + (fp_line (start 7.351 -5.216) (end 7.351 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 26aaccab-aecc-4bd6-beac-8da341681a10)) + (fp_line (start 7.351 1.44) (end 7.351 5.216) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c5a4aef9-0d1e-44d2-a5a6-1f228db9cc16)) + (fp_line (start 7.391 -5.188) (end 7.391 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0599e333-2fcc-41c7-891c-511c567b35a4)) + (fp_line (start 7.391 1.44) (end 7.391 5.188) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 90599bf2-0cfd-4bbf-aa2b-ce86badc86d2)) + (fp_line (start 7.431 -5.16) (end 7.431 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 757b861c-4d25-4649-9172-84557ff8519d)) + (fp_line (start 7.431 1.44) (end 7.431 5.16) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5be68334-2b5e-4c63-9505-e0c3bdc280e2)) + (fp_line (start 7.471 -5.131) (end 7.471 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0c6141ed-ac6f-4bea-8cf9-a3f720009e5b)) + (fp_line (start 7.471 1.44) (end 7.471 5.131) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a00e8ae2-3da8-428a-868a-23f1ae58d113)) + (fp_line (start 7.511 -5.102) (end 7.511 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6c232b7d-cecb-4735-9493-7726564634c1)) + (fp_line (start 7.511 1.44) (end 7.511 5.102) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 99e832f3-865d-49ac-9e96-0834818cc069)) + (fp_line (start 7.551 -5.073) (end 7.551 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e238ec29-4830-4830-a887-84cd80adcc56)) + (fp_line (start 7.551 1.44) (end 7.551 5.073) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7e1495f3-7f7c-4209-a930-37d8cde99da6)) + (fp_line (start 7.591 -5.043) (end 7.591 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5254b827-5e9c-4a3c-a2f4-53615acb58da)) + (fp_line (start 7.591 1.44) (end 7.591 5.043) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 84737cb7-4502-42bb-93c5-d731f8deb367)) + (fp_line (start 7.631 -5.012) (end 7.631 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b058bfcf-82a8-461e-8f7c-a44bbc40ecf6)) + (fp_line (start 7.631 1.44) (end 7.631 5.012) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ba373796-20a1-4b8d-b3bd-59a084024c39)) + (fp_line (start 7.671 -4.982) (end 7.671 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9d14c0ef-6fdb-4d94-b590-95e79c57d052)) + (fp_line (start 7.671 1.44) (end 7.671 4.982) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6be18706-531e-4069-9d72-c240b7fdca4a)) + (fp_line (start 7.711 -4.95) (end 7.711 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cd930011-c757-4998-a2e9-1cc0f09cde1a)) + (fp_line (start 7.711 1.44) (end 7.711 4.95) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cc7a480b-1c36-4a75-a7c0-4d294776fa87)) + (fp_line (start 7.751 -4.918) (end 7.751 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c7f3debb-97c2-496d-8a5f-b13a18637ddc)) + (fp_line (start 7.751 1.44) (end 7.751 4.918) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 79714fe3-b670-4e07-a6b0-6f32e0f6a19e)) + (fp_line (start 7.791 -4.885) (end 7.791 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 469a7546-6d71-42c4-8b34-f738c83dbc5d)) + (fp_line (start 7.791 1.44) (end 7.791 4.885) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a3662e48-cd4e-4942-bdb2-1da3b4b758d7)) + (fp_line (start 7.831 -4.852) (end 7.831 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 58ceee12-5ac5-4a50-b234-4b2b86e0c4bf)) + (fp_line (start 7.831 1.44) (end 7.831 4.852) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0e676e50-997e-45b3-b333-7cfaad114b3a)) + (fp_line (start 7.871 -4.819) (end 7.871 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8995223e-97f3-43b7-b673-9df07247c83f)) + (fp_line (start 7.871 1.44) (end 7.871 4.819) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f6da67a3-0fe8-44c5-9531-a28bf7854064)) + (fp_line (start 7.911 -4.785) (end 7.911 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 46b3b17d-d03b-44ea-8afa-28345a7f092b)) + (fp_line (start 7.911 1.44) (end 7.911 4.785) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 10beb997-4fa1-45af-a933-038c07331f02)) + (fp_line (start 7.951 -4.75) (end 7.951 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 361130fe-4d9e-46e9-851c-359d8b39408f)) + (fp_line (start 7.951 1.44) (end 7.951 4.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 29b6a89a-f7cd-4bc1-a03d-eff9e3b33144)) + (fp_line (start 7.991 -4.714) (end 7.991 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 593cebd5-945f-410b-b430-39b739dfe34f)) + (fp_line (start 7.991 1.44) (end 7.991 4.714) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2ff4da54-f0c5-4b06-b0fb-0a4274f9d6dd)) + (fp_line (start 8.031 -4.678) (end 8.031 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 53c6d82c-68f5-4b7b-a033-deb16b8e26ac)) + (fp_line (start 8.031 1.44) (end 8.031 4.678) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b1a0e734-f2fa-4039-a0a4-9ffbaac429d6)) + (fp_line (start 8.071 -4.642) (end 8.071 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7d3d5a01-8270-41f0-a2d9-c5254e72997a)) + (fp_line (start 8.071 1.44) (end 8.071 4.642) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e04084c1-da3f-4998-9b39-fa1d016d906d)) + (fp_line (start 8.111 -4.605) (end 8.111 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d156eb07-befc-4859-aac4-10e96533aa06)) + (fp_line (start 8.111 1.44) (end 8.111 4.605) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 74fdecee-844d-4168-8e54-7bd2a142a078)) + (fp_line (start 8.151 -4.567) (end 8.151 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ce502cd7-7b51-487e-9870-2bfffbe76f48)) + (fp_line (start 8.151 1.44) (end 8.151 4.567) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7b8a0ed3-7b5a-4491-91d5-cfebe9ffc902)) + (fp_line (start 8.191 -4.528) (end 8.191 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 46e50693-cea1-4599-8dc5-491bbbd10fc5)) + (fp_line (start 8.191 1.44) (end 8.191 4.528) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cd64f394-e7c8-45ae-b20d-a8cf790f5d9e)) + (fp_line (start 8.231 -4.489) (end 8.231 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 01864512-53e8-4bb8-b17b-c299b1f5d8ea)) + (fp_line (start 8.231 1.44) (end 8.231 4.489) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ed5c1719-cc21-4c89-ac17-aa557ad82ca1)) + (fp_line (start 8.271 -4.449) (end 8.271 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ee2c6cae-c2ee-41a9-b27e-62828a45245c)) + (fp_line (start 8.271 1.44) (end 8.271 4.449) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7f961c9f-074f-4b19-9507-15029d30640c)) + (fp_line (start 8.311 -4.408) (end 8.311 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 32749002-9360-4157-bfac-4158e8782516)) + (fp_line (start 8.311 1.44) (end 8.311 4.408) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0795647e-19c7-4395-b485-87eaa296cb80)) + (fp_line (start 8.351 -4.367) (end 8.351 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp beb35982-1f6a-46e1-971a-5ebcf0dd3e6a)) + (fp_line (start 8.351 1.44) (end 8.351 4.367) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3bc0ba5c-0b11-4b9a-8696-0f4a457c1c2a)) + (fp_line (start 8.391 -4.325) (end 8.391 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 461e505f-ee10-4fd4-96bd-619bcfb2d5da)) + (fp_line (start 8.391 1.44) (end 8.391 4.325) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5bab45a4-79c3-44cd-b2a0-bc426e043eda)) + (fp_line (start 8.431 -4.282) (end 8.431 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 38e730bd-c70a-45ce-bfa7-87adfa52edca)) + (fp_line (start 8.431 1.44) (end 8.431 4.282) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d4c8d1fb-0ea1-4639-8bb8-fe06b28ec2e5)) + (fp_line (start 8.471 -4.238) (end 8.471 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9e012fc6-588a-43f3-b100-624626128e48)) + (fp_line (start 8.471 1.44) (end 8.471 4.238) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 04b9318b-79c0-4170-b6cc-2bec097092b1)) + (fp_line (start 8.511 -4.194) (end 8.511 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 97598b87-96fd-4be2-9784-036a394a4b9a)) + (fp_line (start 8.511 1.44) (end 8.511 4.194) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 450aecba-6b09-47cc-8ad7-dcb3aaa0b069)) + (fp_line (start 8.551 -4.148) (end 8.551 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 621a4e3c-4263-4e54-afa0-bba112c8cdeb)) + (fp_line (start 8.551 1.44) (end 8.551 4.148) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d2af1c98-ebf4-4532-9f5b-2a0df8bac69a)) + (fp_line (start 8.591 -4.102) (end 8.591 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2cddf167-7e6e-4b41-af88-a8375e38aaf9)) + (fp_line (start 8.591 1.44) (end 8.591 4.102) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 92531af7-f789-4365-bea7-4ca813e43bc1)) + (fp_line (start 8.631 -4.055) (end 8.631 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ad065f14-77b0-4046-a713-d4fa17a7cc64)) + (fp_line (start 8.631 1.44) (end 8.631 4.055) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3d3216df-594f-4a6e-81b8-89e29aaff1c0)) + (fp_line (start 8.671 -4.007) (end 8.671 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fa9538a8-2f79-41e1-8edc-9a90401b1d41)) + (fp_line (start 8.671 1.44) (end 8.671 4.007) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8310b711-8011-45dd-8a58-dbe51cace58e)) + (fp_line (start 8.711 -3.957) (end 8.711 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b9423b3a-c98b-4412-aa47-8f4cbb616e83)) + (fp_line (start 8.711 1.44) (end 8.711 3.957) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 774b78e8-7b3a-4b02-9040-7e5b48e33acf)) + (fp_line (start 8.751 -3.907) (end 8.751 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4d1cd6db-e27e-4436-ac93-97ea743fd416)) + (fp_line (start 8.751 1.44) (end 8.751 3.907) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp aaa3d9aa-3153-4b47-8614-143dff504a69)) + (fp_line (start 8.791 -3.856) (end 8.791 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp aebf617a-f5d3-4c90-afa9-f3a139c3b706)) + (fp_line (start 8.791 1.44) (end 8.791 3.856) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9797ee0d-4f4d-4bbf-a245-4bffdb2fed95)) + (fp_line (start 8.831 -3.804) (end 8.831 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b15f90ca-bb50-41ba-a9e7-ae22b7e905eb)) + (fp_line (start 8.831 1.44) (end 8.831 3.804) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e019de8c-d3b6-4cec-9364-521fab1a52dc)) + (fp_line (start 8.871 -3.75) (end 8.871 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 11c53d4d-3b39-4501-accb-c9eb9f84f1b1)) + (fp_line (start 8.871 1.44) (end 8.871 3.75) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp faa34a20-01e4-48cc-b7ea-e1d2ff307cd9)) + (fp_line (start 8.911 -3.696) (end 8.911 -1.44) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b327bb16-2f41-4102-a5d9-7aca05c8010d)) + (fp_line (start 8.911 1.44) (end 8.911 3.696) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f87be323-4662-4c55-8875-7e7d8eb2ef75)) + (fp_line (start 8.951 -3.64) (end 8.951 3.64) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4bb7711d-636f-4da0-89df-4909a2c0c5f0)) + (fp_line (start 8.991 -3.583) (end 8.991 3.583) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b3a66edf-3893-4390-9451-94d7c78cdae2)) + (fp_line (start 9.031 -3.524) (end 9.031 3.524) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5ba68b32-9801-4c2d-8012-621e86c504e7)) + (fp_line (start 9.071 -3.464) (end 9.071 3.464) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 36fb0ebd-dba5-4008-9ab9-627171bad6c5)) + (fp_line (start 9.111 -3.402) (end 9.111 3.402) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 34299e2b-3ddd-4dae-be5b-4b45234e4648)) + (fp_line (start 9.151 -3.339) (end 9.151 3.339) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3ab3b210-58c8-4894-b3ea-52e962f8f403)) + (fp_line (start 9.191 -3.275) (end 9.191 3.275) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9c245da5-6621-40b8-a475-41662c347865)) + (fp_line (start 9.231 -3.208) (end 9.231 3.208) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b9b1ca0a-3579-45b6-b0f9-3c392d038874)) + (fp_line (start 9.271 -3.14) (end 9.271 3.14) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ae70239b-7ef7-43d1-9998-23d2956a4cc3)) + (fp_line (start 9.311 -3.069) (end 9.311 3.069) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 106da3da-39f7-4114-8fde-1b4c0d9aad94)) + (fp_line (start 9.351 -2.996) (end 9.351 2.996) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a6b9a2ca-f8f0-4a74-b5b5-809d58672af6)) + (fp_line (start 9.391 -2.921) (end 9.391 2.921) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 025e23ff-c2a6-423b-b05b-fe5ea2d6cb33)) + (fp_line (start 9.431 -2.844) (end 9.431 2.844) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c14fb6bd-05f5-4fce-acf5-0fe794507859)) + (fp_line (start 9.471 -2.764) (end 9.471 2.764) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 429e73db-c941-4911-8dee-4dd5992007df)) + (fp_line (start 9.511 -2.681) (end 9.511 2.681) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 73b3129d-ef67-47c7-be5b-95b8b632ad88)) + (fp_line (start 9.551 -2.594) (end 9.551 2.594) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1609e0c5-b9bd-46fe-9e68-76111b1af24b)) + (fp_line (start 9.591 -2.504) (end 9.591 2.504) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 17fd6223-601c-414e-956f-f7ede26e57a2)) + (fp_line (start 9.631 -2.41) (end 9.631 2.41) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d9b23496-d4c2-4bc6-bde0-8c998f548e7f)) + (fp_line (start 9.671 -2.312) (end 9.671 2.312) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 10cb4b1a-abfb-4de6-bc14-039c07c53ad8)) + (fp_line (start 9.711 -2.209) (end 9.711 2.209) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 72274783-e48a-4abb-ba5f-4df264979cf2)) + (fp_line (start 9.751 -2.1) (end 9.751 2.1) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d8985808-e9f2-4ae5-828a-07499350683b)) + (fp_line (start 9.791 -1.984) (end 9.791 1.984) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 27ed6aed-0751-4683-9bd1-4855f6d01cd2)) + (fp_line (start 9.831 -1.861) (end 9.831 1.861) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8a2b413e-b1b4-4705-889b-c967db4e7410)) + (fp_line (start 9.871 -1.728) (end 9.871 1.728) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bed9f9c6-e3fe-4ac4-b4b4-6822adc57f68)) + (fp_line (start 9.911 -1.583) (end 9.911 1.583) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d4f9fac4-efde-4dc7-a668-72054280cd91)) + (fp_line (start 9.951 -1.422) (end 9.951 1.422) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 54cc8828-fb2a-4cb3-ab3b-9c77525ff28d)) + (fp_line (start 9.991 -1.241) (end 9.991 1.241) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ae890cfc-3a8e-4a92-9025-778eab9cf335)) + (fp_line (start 10.031 -1.028) (end 10.031 1.028) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1dccff06-9e7d-46c6-a179-044fb009d8db)) + (fp_line (start 10.071 -0.757) (end 10.071 0.757) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 753465a9-98bf-4a4d-a6f8-00b98dfacef1)) + (fp_line (start 10.111 -0.317) (end 10.111 0.317) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp dc5baac1-efbd-4766-a7fc-dc8ef58f5767)) + (fp_circle (center 3.75 0) (end 10.12 0) + (stroke (width 0.12) (type solid)) (fill none) (layer "F.SilkS") (tstamp f24b1ec6-35e2-4ffa-a6a7-17316978b2b8)) + (fp_circle (center 3.75 0) (end 10.25 0) + (stroke (width 0.05) (type solid)) (fill none) (layer "F.CrtYd") (tstamp 8563a1d1-1401-4208-9fbb-9e9177dcef13)) + (fp_line (start -1.616489 -2.7375) (end -0.366489 -2.7375) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4bf37ef0-fac9-415a-8915-bf4cb38e750c)) + (fp_line (start -0.991489 -3.3625) (end -0.991489 -2.1125) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 76cf51d8-2d0b-4738-b521-5bd5c779c6ba)) + (fp_circle (center 3.75 0) (end 10 0) + (stroke (width 0.1) (type solid)) (fill none) (layer "F.Fab") (tstamp 73a0589d-5a62-44c7-975d-dab1cc2448ec)) + (pad "1" thru_hole rect (at 0 0) (size 2.4 2.4) (drill 1.2) (layers "*.Cu" "*.Mask") + (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp fe6d4c10-4266-4dc9-9690-073bbde91ab8)) + (pad "2" thru_hole circle (at 7.5 0) (size 2.4 2.4) (drill 1.2) (layers "*.Cu" "*.Mask") + (net 2 "Net-(Q2-B)") (pintype "passive") (tstamp e3513430-3b66-4201-9984-03afb3da5a50)) + (model "${KICAD6_3DMODEL_DIR}/Capacitor_THT.3dshapes/CP_Radial_D12.5mm_P7.50mm.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") + (tstamp 3f52b951-fc4e-4791-8fd1-720ca73b3c85) + (at 79.35556 50.18) + (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") + (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "PNP") + (property "Sim.Library" "BC547_and_BC557.lib") + (property "Sim.Name" "BC557b") + (property "Sim.Pins" "1=C 2=B 3=E") + (property "Sim.Type" "GUMMELPOON") + (property "ki_description" "0.1A Ic, 45V Vce, PNP Small Signal Transistor, TO-92") + (property "ki_keywords" "PNP Transistor") + (path "/e18074c3-15bb-48dd-a644-780be992a99a") + (attr through_hole) + (fp_text reference "Q1" (at 1.27 -3.56) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 8daae1cd-5c1f-4d05-b13e-a4a097101afe) + ) + (fp_text value "BC557" (at 1.27 2.79) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp de84e890-b721-4014-8533-fa2ee8bf377b) + ) + (fp_text user "${REFERENCE}" (at 1.27 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp f3788bbd-e2a0-44f2-b8ac-6e9758e948e7) + ) + (fp_line (start -0.53 1.85) (end 3.07 1.85) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 49d93faf-5dbb-436d-999a-f7b17de5fb89)) + (fp_arc (start -0.568478 1.838478) (mid -1.132087 -0.994977) (end 1.27 -2.6) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 271144a7-e566-43d9-a5ff-304d834400ab)) + (fp_arc (start 1.27 -2.6) (mid 3.672087 -0.994977) (end 3.108478 1.838478) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4279778e-1e4d-4c54-bf92-ad31ec0bc2c6)) + (fp_line (start -1.46 -2.73) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp cd259a7a-a237-4c89-a3fb-e53ea146d34b)) + (fp_line (start -1.46 -2.73) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5314e6f2-9b9e-48f2-9660-c6ddd54c182c)) + (fp_line (start 4 2.01) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 129c391d-28e7-409d-811b-3bcc33871d8a)) + (fp_line (start 4 2.01) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d1f720a8-57d2-4be3-ba24-d21d6cdd6133)) + (fp_line (start -0.5 1.75) (end 3 1.75) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c2449067-60cb-40aa-a0a4-c8c808a1f477)) + (fp_arc (start -0.483625 1.753625) (mid -1.021221 -0.949055) (end 1.27 -2.48) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 32d1a9b4-7886-4e09-b649-3de0a25e5abe)) + (fp_arc (start 1.27 -2.48) (mid 3.561221 -0.949055) (end 3.023625 1.753625) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 1677d36d-e5c2-4c7f-8746-2fc557f700d0)) + (pad "1" thru_hole rect (at 0 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 38 "Net-(Q1-C)") (pinfunction "C") (pintype "passive") (tstamp 8ddc0d4c-e4c2-4b8f-8ea9-9fa49ce6277d)) + (pad "2" thru_hole oval (at 1.27 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 39 "Net-(Q1-B)") (pinfunction "B") (pintype "input") (tstamp a9fd507f-cdb2-4a28-bf52-f11b855bced1)) + (pad "3" thru_hole oval (at 2.54 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 6 "VCC_5.0") (pinfunction "E") (pintype "passive") (tstamp e854432b-06c7-4708-888d-385ba6334c4b)) + (model "${KICAD6_3DMODEL_DIR}/Package_TO_SOT_THT.3dshapes/TO-92_Inline.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp 3f7822ee-6283-474b-b37e-ff80c0af1726) + (at 53.40556 96.8) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/a88aec3a-89e0-4123-9d67-40bd4310a5ef") + (attr through_hole) + (fp_text reference "R13" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp cdc6b146-e229-4c54-ab2c-44beaa8a1515) + ) + (fp_text value "10k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 92733e8b-0e43-4160-aec6-99d8fa23bd6a) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 8d4db053-cdec-4062-ac10-5b5f0bd27630) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6c92436d-a108-49bb-af87-c1354a4e103f)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bbd4b519-20d3-4679-a52f-829990ea12e3)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 44f549f5-02a6-4952-9c70-69e2f44b0747)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a755e7d9-0445-4a31-a3e9-8f50c0a73446)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp da36b510-4a1a-489c-96ad-370da4d4a42e)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9912ac63-0522-4bc3-8f0a-6b3e96df484d)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp bb75e819-4ac9-4a82-81c1-3433866fd320)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0fc38fb9-4c9c-4786-af45-3e7095f0839a)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e5a71c9d-8b5f-4217-b01a-c45ee322e9c9)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 8ea94bb9-ec83-47dc-907c-328324db80a0)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e5ae438a-22a7-44ba-8e06-4fc7592cb14a)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp fc4a3769-114d-4084-ad24-aede7ae5db0e)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ff15b562-9d6c-4f5a-b498-316ccdd55957)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9404ab2f-e2cd-4f72-a27e-9d9a8e9f0758)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 8c50284c-eba6-40f8-aaa7-cd5d8df203c3)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp eeb173d8-0be1-4fb0-a6ea-3178b5a94454)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pintype "passive") (tstamp 4cd31f6a-8311-42e6-a7d4-ed9bb6944d56)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 11 "TXD") (pintype "passive") (tstamp 090a8cc6-6342-427a-9ce5-5607f5ff3931)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp 45cce9b3-3dbd-4d7c-b145-f372b61b3267) + (at 53.40556 106.3) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/94c334ed-1cb5-4404-a652-a5f07f1cffb8") + (attr through_hole) + (fp_text reference "R15" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp e38bd881-7a72-422e-800b-278a4d0b6f83) + ) + (fp_text value "10k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp ffc56232-7d5d-4b8b-93cb-1d19cf26d1bf) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp cd3acb43-6252-48fe-bed1-9da5b71b052a) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fed76ea4-fe98-417f-87e7-0e0984be9c25)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4cdf5b14-65dc-4716-b901-b1f3a72752fb)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c7d263db-be79-423d-9282-63e04436424a)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 258af670-1546-4f24-b975-1e1726d72297)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 30b4bddb-aa38-455f-b032-336ef257958c)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 70d7537f-8ec0-4055-8818-87fcd25d8c19)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6b63ab2a-8137-4967-9b3a-ab720277169f)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1db21bfd-fee1-4352-9aad-c49dd0dae24b)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 689c3c9b-7f5f-4a9b-9887-0e5cd0702738)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d575151a-864a-4e5e-95ef-574251d9f21d)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 90b8471a-c4b3-48b2-9efc-63c0d5a5b518)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 00e8fee1-fd13-4d20-ad94-2728c9f47699)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ba48af6d-46d1-431d-b54f-49f7010109a2)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 62a5b309-2015-4df9-a165-165a35fe5dd2)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9e07d14b-daa0-49e6-8b04-80b03fcee180)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6eb5a0f8-5a94-4220-8bb2-23ba39ebee4c)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pintype "passive") (tstamp 715169dc-c56f-4e1c-b9ed-1b9edb51091f)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 41 "Net-(Q5-C)") (pintype "passive") (tstamp 9c0b3468-19a8-4fb9-a654-c7a034c3583b)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp 845ccd1d-2298-4001-b687-cc6f145560b2) + (at 53.40556 82.55) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "R") + (property "Sim.Pins" "1=+ 2=-") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/05087989-f568-4ae5-b297-c298921fe111") + (attr through_hole) + (fp_text reference "R8" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp a2ca4617-074a-4efe-a0d5-8214a1026a9a) + ) + (fp_text value "2.2k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 15d16a67-c709-4470-be52-917b7d440f2b) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp cdb94f33-da34-454e-9031-5a1d7d470623) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a9c72b74-117f-48b2-9b4a-80866e49119e)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 56e4d213-a459-4367-baec-c7f6c094aab2)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 297b2d12-c3b0-4655-93a0-19d38db0e397)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b3f9e1b8-8ccf-4a5e-bcca-f18fd8b02892)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d30d6270-b7cd-45b1-889a-f27e97966e50)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp aa1d459c-b9b0-43da-a63f-48b070bc3fdd)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 581d0d1e-337d-4607-96d6-f4d5d0d580f8)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2f52cbff-7c88-4804-ac48-df8afff2e027)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0fa440f3-819f-4f80-b2f3-b3a4b9566628)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2ab23a9b-5b0d-415e-b951-6926395e1f5e)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp aff735f7-9d08-4334-b3fb-b2fa08f0d4a8)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 69224adf-c0b6-46bb-8449-1146e40dd9e2)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 05264557-5c9d-4259-b2b1-a7fc403daea5)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0193c69e-e526-4f9b-b1a8-6fa2ebb941d2)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp fb815bb0-7157-48e6-8b78-064f3696a8d3)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 679491bc-ae82-4b36-837b-99e479b44ade)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pintype "passive") (tstamp 0e78e12a-f27d-4a71-946c-a2e1f069feba)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 12 "Net-(J1-GPIO15{slash}RXD)") (pintype "passive") (tstamp ba7950b9-9511-488a-ba6b-860ca74efac3)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") + (tstamp 8a5f4c35-05cf-48db-b130-cef696223a71) + (at 79.35556 73.34) + (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") + (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "NPN") + (property "Sim.Library" "BC547_and_BC557.lib") + (property "Sim.Name" "bc547b") + (property "Sim.Pins" "1=C 2=B 3=E") + (property "Sim.Type" "GUMMELPOON") + (property "ki_description" "0.1A Ic, 45V Vce, Small Signal NPN Transistor, TO-92") + (property "ki_keywords" "NPN Transistor") + (path "/7a1d8624-75b3-40d9-8367-28b38d93d05c") + (attr through_hole) + (fp_text reference "Q5" (at 1.27 -3.56) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 36183255-0a80-4b4b-992d-adfb74936831) + ) + (fp_text value "BC547" (at 1.27 2.79) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 77961d15-7b32-4cfe-bdf1-ce5b537e6e5b) + ) + (fp_text user "${REFERENCE}" (at 1.27 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp ef45058c-a50e-458e-93a2-b01fd70e5dc5) + ) + (fp_line (start -0.53 1.85) (end 3.07 1.85) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 035463b4-9e74-4871-b7b2-139b5e2fe419)) + (fp_arc (start -0.568478 1.838478) (mid -1.132087 -0.994977) (end 1.27 -2.6) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9986ea23-33af-4a6d-8e3e-ec9b1fa0bdc3)) + (fp_arc (start 1.27 -2.6) (mid 3.672087 -0.994977) (end 3.108478 1.838478) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b8726f98-8ee4-4952-b15a-1dbcf72e5c0d)) + (fp_line (start -1.46 -2.73) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c918833e-faa8-43bb-913e-e85a9d44d117)) + (fp_line (start -1.46 -2.73) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 7a15506b-efae-410f-bb35-1a9e949d39d5)) + (fp_line (start 4 2.01) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 67190cbb-c04e-4c20-8e00-739b73d23650)) + (fp_line (start 4 2.01) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp f48d99c3-bd86-47e6-8187-0eaf876d1bc1)) + (fp_line (start -0.5 1.75) (end 3 1.75) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp dde95699-dbc6-4096-bda6-8d1f6b00785b)) + (fp_arc (start -0.483625 1.753625) (mid -1.021221 -0.949055) (end 1.27 -2.48) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 62f10716-cedb-4790-9fb8-38f24c2fea64)) + (fp_arc (start 1.27 -2.48) (mid 3.561221 -0.949055) (end 3.023625 1.753625) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2c951144-24d3-45ab-9cd0-583ea526095e)) + (pad "1" thru_hole rect (at 0 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 41 "Net-(Q5-C)") (pinfunction "C") (pintype "passive") (tstamp e45493d9-75c3-434b-b75b-9db95544055c)) + (pad "2" thru_hole oval (at 1.27 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 42 "Net-(Q5-B)") (pinfunction "B") (pintype "input") (tstamp c2c989ea-173b-4451-adbf-f71ac626bc5d)) + (pad "3" thru_hole oval (at 2.54 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "E") (pintype "passive") (tstamp da050428-f60a-40b8-8b59-2eed8db9f6dd)) + (model "${KICAD6_3DMODEL_DIR}/Package_TO_SOT_THT.3dshapes/TO-92_Inline.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp 8fc225f7-a8d9-414e-a7b3-9b9a85b6279a) + (at 53.40556 77.8) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/1e712663-9f97-4762-926c-2b4ce56e9875") + (attr through_hole) + (fp_text reference "R7" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 16ed253c-6bcc-4b77-937e-8f8e02e37b9a) + ) + (fp_text value "22k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 37e26409-2377-43a5-9d2c-921469eac87c) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp cd42b7f7-28cf-4814-9bd4-bc8350c2830e) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d28f3ef4-7a8d-4e86-af40-4d75a7cebd92)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a4c25ef4-f075-4320-ac73-cd12532b56ac)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5d06d985-7826-4ae5-99a1-3b029283f434)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1b3be610-573e-4eed-9563-552c32487b79)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 54eb83d7-a847-4813-925f-011454ade1b1)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8588f785-92b9-4329-aec4-fda29582bc4b)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 72bcc5f7-8972-4f8a-acfb-b86badb9cf97)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9c2899ec-17ba-4eed-af40-5fd3d794d25f)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp aa8ade3e-86b0-4750-bda5-ac204cb6e54a)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 7b143c23-bd56-4ec4-b9a6-b80484eeb2a1)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 462e1543-4418-49c9-8caa-beef5e500be0)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 098f74c7-b6b2-4e76-a6f1-f618b32e350c)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 89e2156c-f256-44ce-a8a0-77cd6f626214)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp de077ac3-e7cb-47f3-b734-23dee562c8b4)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e2ae2d88-d295-4afe-9d1a-64f7ada427cd)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d6e63721-399c-4bac-bfe6-c3f275a5e55d)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 2 "Net-(Q2-B)") (pintype "passive") (tstamp ebba090b-bd31-48d4-a384-d51aefc12ed0)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pintype "passive") (tstamp 96b63d0b-c941-449e-a440-3fb412c7cd3b)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") + (tstamp 94171681-d57e-4456-9703-3178e2780bdf) + (at 79.35556 67.55) + (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") + (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "NPN") + (property "Sim.Library" "BC547_and_BC557.lib") + (property "Sim.Name" "bc547b") + (property "Sim.Pins" "1=C 2=B 3=E") + (property "Sim.Type" "GUMMELPOON") + (property "ki_description" "0.1A Ic, 45V Vce, Small Signal NPN Transistor, TO-92") + (property "ki_keywords" "NPN Transistor") + (path "/4e0376b7-268d-4d3c-bc7b-c625228f33d1") + (attr through_hole) + (fp_text reference "Q4" (at 1.27 -3.56) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 44ef564e-a30c-4c75-b896-8062f9fccb31) + ) + (fp_text value "BC547" (at 1.27 2.79) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp efb7a986-9f64-44ba-9357-10cc5e45a2a5) + ) + (fp_text user "${REFERENCE}" (at 1.27 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp d22ca5f3-4e1a-4060-9171-20c8ca3246e5) + ) + (fp_line (start -0.53 1.85) (end 3.07 1.85) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d3dc99fb-bf71-462c-bb05-0a8efa171701)) + (fp_arc (start -0.568478 1.838478) (mid -1.132087 -0.994977) (end 1.27 -2.6) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cf04c351-8635-410a-adf5-393266205ed6)) + (fp_arc (start 1.27 -2.6) (mid 3.672087 -0.994977) (end 3.108478 1.838478) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0a55f91e-f921-491b-8625-af1f3557c7e7)) + (fp_line (start -1.46 -2.73) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c2eea5e1-6e48-4600-afe0-6c67f9bf7e80)) + (fp_line (start -1.46 -2.73) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 09f8dfef-1cb5-4b83-b276-3fad49e031d4)) + (fp_line (start 4 2.01) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3fa7ab0e-236c-4291-bee2-db04779cfd50)) + (fp_line (start 4 2.01) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp b1b08fe4-59ca-4291-9287-8be490399ab8)) + (fp_line (start -0.5 1.75) (end 3 1.75) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 74f8f097-364b-4aee-ab32-e158a6c68efe)) + (fp_arc (start -0.483625 1.753625) (mid -1.021221 -0.949055) (end 1.27 -2.48) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp bd1d6efd-a72b-4329-9d79-453718eb2a49)) + (fp_arc (start 1.27 -2.48) (mid 3.561221 -0.949055) (end 3.023625 1.753625) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3e5d25c0-5d6a-4767-820a-a5ec2445929a)) + (pad "1" thru_hole rect (at 0 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 36 "SEATALK") (pinfunction "C") (pintype "passive") (tstamp 6363770a-0a55-4594-9fb3-2bd8d38a95f1)) + (pad "2" thru_hole oval (at 1.27 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 40 "Net-(Q4-B)") (pinfunction "B") (pintype "input") (tstamp daf013b7-c57d-4db9-8d81-915d7ce98053)) + (pad "3" thru_hole oval (at 2.54 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "E") (pintype "passive") (tstamp 71928204-83a0-4841-8d80-f8d2b462f1e0)) + (model "${KICAD6_3DMODEL_DIR}/Package_TO_SOT_THT.3dshapes/TO-92_Inline.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp 96ab9178-579a-45a4-a68c-707fb33e88ed) + (at 53.40556 63.55) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "R") + (property "Sim.Pins" "1=+ 2=-") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/873fd484-3122-4533-8a3d-0b6694e5decf") + (attr through_hole) + (fp_text reference "R4" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 65aed444-b66b-4b96-9ec2-bf5dc9806d0f) + ) + (fp_text value "4.7k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 928eb78c-5a83-4ed6-9c07-00f9bf6e6b77) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 78dca79e-60b1-4c2c-8647-0f7b7c56b6c3) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1e4efc58-1aa9-4299-b44f-412afab24d0f)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6bdfb2dd-4341-4529-bda7-89b5aaf07fb0)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a789e6f6-f6db-463e-ba4b-4e91526c6cab)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 93e40aeb-71a6-4aea-a3f7-cab119ffee5e)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7002775c-c3d8-4a5b-af42-8a4a295fd926)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cee03ed3-2d1d-4288-abc3-805a19e152ab)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9c6c502d-1bed-42ec-9430-6d1e47d60582)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 08d80ac9-7188-402c-8205-e83f281cbc63)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9f6301b5-1aea-4d17-ba7c-3a4cd75f8c16)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5b5176ba-399d-4127-a636-231ab13f9d83)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 344776ac-5723-4dab-8be1-b7875a2afcae)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9fa5a4c2-9c59-4b98-96f5-204081c4d0ee)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 848748f5-8f74-4c49-95f7-713728afe545)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c9556c13-4c59-400b-88d3-1e240248bec1)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a3d94049-1660-407b-831c-f8f8de2dc50f)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f9a02d98-fc78-43a9-9bdd-7077eb9d2e67)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp 37055987-d40a-46ea-9358-a8f7c75accc4)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pintype "passive") (tstamp 47594406-e1a4-43d8-8805-5d6aa41b3f32)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical" (layer "F.Cu") + (tstamp 9b22d2a4-0ccb-47ea-90ce-737c81524990) + (at 40.64 86.36) + (descr "Through hole straight pin header, 1x03, 2.54mm pitch, single row") + (tags "Through hole pin header THT 1x03 2.54mm single row") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Enable" "0") + (property "ki_description" "Generic connector, single row, 01x03, script generated") + (property "ki_keywords" "connector") + (path "/8008b50a-ac2b-42d5-8e97-ecafe76dc831") + (attr through_hole) + (fp_text reference "J3" (at 0 -2.33) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp a071f763-581e-4a5e-b29c-e9f54513cd45) + ) + (fp_text value "Conn_01x03_Pin" (at 0 7.41) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 5dd83252-9051-4e64-96b4-503a15b3428b) + ) + (fp_text user "${REFERENCE}" (at 0 2.54 90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 475643e5-a312-40f3-880e-ed1b429bd938) + ) + (fp_line (start -1.33 -1.33) (end 0 -1.33) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 52671c20-b326-415c-8e1b-353a460e8484)) + (fp_line (start -1.33 0) (end -1.33 -1.33) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 119717db-aa05-4788-9a69-13bf9ed086e5)) + (fp_line (start -1.33 1.27) (end -1.33 6.41) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f8ca34b8-9d41-4a8f-a37a-f74ccaad493a)) + (fp_line (start -1.33 1.27) (end 1.33 1.27) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b2915d18-a840-434b-acc1-be54e9d7da21)) + (fp_line (start -1.33 6.41) (end 1.33 6.41) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3c629c98-4613-4a64-a798-d17372fddfdc)) + (fp_line (start 1.33 1.27) (end 1.33 6.41) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 848b6358-6f8c-4478-bdcd-26ecb2ff1055)) + (fp_line (start -1.8 -1.8) (end -1.8 6.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ccae0eae-d25d-4041-baf4-3d1c6fdd4b4e)) + (fp_line (start -1.8 6.85) (end 1.8 6.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 36546f7d-730a-4c7b-b5dd-bb318fd369cf)) + (fp_line (start 1.8 -1.8) (end -1.8 -1.8) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e8f6740c-7f54-4da3-b870-d236da815f49)) + (fp_line (start 1.8 6.85) (end 1.8 -1.8) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 74967ab3-71cf-42b2-b356-7aeb697fa057)) + (fp_line (start -1.27 -0.635) (end -0.635 -1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 937cff26-9f73-4d1b-9abd-525818dec708)) + (fp_line (start -1.27 6.35) (end -1.27 -0.635) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 03736a22-aa2c-4a21-a887-ff7542c6e3e8)) + (fp_line (start -0.635 -1.27) (end 1.27 -1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0ca9ebe4-9db4-48f2-afe7-d47671ed0b2c)) + (fp_line (start 1.27 -1.27) (end 1.27 6.35) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a4a8c9cd-e4d4-4113-ab60-c8bf63ff03b5)) + (fp_line (start 1.27 6.35) (end -1.27 6.35) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d202302b-a3d6-4fbe-b269-48c1ab594c86)) + (pad "1" thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "Pin_1") (pintype "passive") (tstamp cb60773a-e9bb-44b7-93cb-ae9b0dcd5076)) + (pad "2" thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 36 "SEATALK") (pinfunction "Pin_2") (pintype "passive") (tstamp 6c60ff97-7ab6-429d-b232-eafc637c7752)) + (pad "3" thru_hole oval (at 0 5.08) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 37 "Net-(J3-Pin_3)") (pinfunction "Pin_3") (pintype "passive") (tstamp 1f9dd82d-e5b9-41c3-9904-d00a230fe37e)) + (model "${KICAD6_3DMODEL_DIR}/Connector_PinHeader_2.54mm.3dshapes/PinHeader_1x03_P2.54mm_Vertical.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Connector_PinSocket_2.54mm:PinSocket_2x20_P2.54mm_Vertical" (layer "F.Cu") + (tstamp a553f4af-6beb-47ca-9bdf-3fe6bb347d97) + (at 132.08 48.26) + (descr "Through hole straight socket strip, 2x20, 2.54mm pitch, double cols (from Kicad 4.0.7), script generated") + (tags "Through hole socket strip THT 2x20 2.54mm double row") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Enable" "0") + (property "ki_description" "expansion header for Raspberry Pi 2 & 3") + (property "ki_keywords" "raspberrypi gpio") + (path "/58887779-90ab-4780-98be-8f57c4f8f78b") + (attr through_hole) + (fp_text reference "J1" (at -1.27 -2.77) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp b3f29cb6-f9aa-44cf-9081-ffcbfb4f1649) + ) + (fp_text value "Raspberry_Pi_2_3" (at -1.27 51.03) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 394f24f1-348c-4c70-bdb8-13e586c9ac2c) + ) + (fp_text user "${REFERENCE}" (at -1.27 24.13 90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp d9e5c979-0325-493f-be21-970ea4bbb3d3) + ) + (fp_line (start -3.87 -1.33) (end -3.87 49.59) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 56cffd37-418e-46ac-9c64-84b2a9514e88)) + (fp_line (start -3.87 -1.33) (end -1.27 -1.33) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4b871eca-318e-4884-b570-61a572b64fb5)) + (fp_line (start -3.87 49.59) (end 1.33 49.59) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp af2c957b-2870-4563-a15e-2556cb962ad6)) + (fp_line (start -1.27 -1.33) (end -1.27 1.27) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d28919b0-0eae-4809-8f8a-b4941c037682)) + (fp_line (start -1.27 1.27) (end 1.33 1.27) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 05e34ae7-f1c0-4266-b9d3-0154effc34d6)) + (fp_line (start 0 -1.33) (end 1.33 -1.33) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f0d18060-ef52-437a-9710-e1a8426e9c4f)) + (fp_line (start 1.33 -1.33) (end 1.33 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 81c2ef95-b8b4-4960-a45c-fef4a1644163)) + (fp_line (start 1.33 1.27) (end 1.33 49.59) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a3c00a0a-fbac-4131-ba74-405282c73d3c)) + (fp_line (start -4.34 -1.8) (end 1.76 -1.8) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e7312949-3522-466c-af68-79a4570c97bd)) + (fp_line (start -4.34 50) (end -4.34 -1.8) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp f6b05721-9d46-48ea-bf32-b049b07ee567)) + (fp_line (start 1.76 -1.8) (end 1.76 50) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6735c9f7-c892-4b6f-beaa-9c0b0f726e13)) + (fp_line (start 1.76 50) (end -4.34 50) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 8ccd6010-dc35-4777-9bd2-c04fa8cd87e2)) + (fp_line (start -3.81 -1.27) (end 0.27 -1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0a203383-1015-4339-93d2-9d9cb55c34e0)) + (fp_line (start -3.81 49.53) (end -3.81 -1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c540b7a3-bc12-47a5-8dbf-f964d52a6420)) + (fp_line (start 0.27 -1.27) (end 1.27 -0.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e2a144ec-1dd6-4308-b1bc-e10fc86d59b5)) + (fp_line (start 1.27 -0.27) (end 1.27 49.53) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6ea42a77-cf85-47a6-96bd-f7d5c7a95e31)) + (fp_line (start 1.27 49.53) (end -3.81 49.53) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp bf8f2e0e-bdf1-435f-844a-60daf93737b8)) + (pad "1" thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pinfunction "3V3") (pintype "power_in") (tstamp 58528890-541e-41c9-8553-ae0cee08e757)) + (pad "2" thru_hole oval (at -2.54 0) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 6 "VCC_5.0") (pinfunction "5V") (pintype "power_in") (tstamp 63fb603f-9f15-4680-964a-c1be50853204)) + (pad "3" thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 7 "unconnected-(J1-SDA{slash}GPIO2-Pad3)") (pinfunction "SDA/GPIO2") (pintype "bidirectional") (tstamp eab7008b-a1ff-47fe-950e-a4ff68d84b15)) + (pad "4" thru_hole oval (at -2.54 2.54) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 6 "VCC_5.0") (pinfunction "5V") (pintype "power_in") (tstamp 8976e579-c955-4688-817f-d3551b43996f)) + (pad "5" thru_hole oval (at 0 5.08) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 8 "unconnected-(J1-SCL{slash}GPIO3-Pad5)") (pinfunction "SCL/GPIO3") (pintype "bidirectional") (tstamp 62a149fc-80af-4fdd-a913-2bff78125909)) + (pad "6" thru_hole oval (at -2.54 5.08) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 01717d6d-6600-4cb3-8880-34ec125e8282)) + (pad "7" thru_hole oval (at 0 7.62) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 10 "unconnected-(J1-GCLK0{slash}GPIO4-Pad7)") (pinfunction "GCLK0/GPIO4") (pintype "bidirectional") (tstamp f11e0c36-845c-41bf-a710-ed95038758f1)) + (pad "8" thru_hole oval (at -2.54 7.62) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 11 "TXD") (pinfunction "GPIO14/TXD") (pintype "bidirectional") (tstamp fc31b1c5-4f3d-4ac7-a873-9fe5549d93b7)) + (pad "9" thru_hole oval (at 0 10.16) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp a982eb2e-9f2e-4815-9fb7-ea96cb3bf5fa)) + (pad "10" thru_hole oval (at -2.54 10.16) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 12 "Net-(J1-GPIO15{slash}RXD)") (pinfunction "GPIO15/RXD") (pintype "bidirectional") (tstamp b9b673ce-eeb3-4439-bd48-4db687e008c1)) + (pad "11" thru_hole oval (at 0 12.7) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 13 "unconnected-(J1-GPIO17-Pad11)") (pinfunction "GPIO17") (pintype "bidirectional") (tstamp 165ad222-842e-4a6e-86cc-91a0e51aaffa)) + (pad "12" thru_hole oval (at -2.54 12.7) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 14 "unconnected-(J1-GPIO18{slash}PWM0-Pad12)") (pinfunction "GPIO18/PWM0") (pintype "bidirectional") (tstamp 209fc722-fc6c-44c5-8161-5af70e08f5a9)) + (pad "13" thru_hole oval (at 0 15.24) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 15 "unconnected-(J1-GPIO27-Pad13)") (pinfunction "GPIO27") (pintype "bidirectional") (tstamp 23d032d4-dd1d-43f4-8d13-a79ba85ab3e6)) + (pad "14" thru_hole oval (at -2.54 15.24) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 43c6842c-1f58-4b5a-aa64-cc798e2a154e)) + (pad "15" thru_hole oval (at 0 17.78) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 16 "unconnected-(J1-GPIO22-Pad15)") (pinfunction "GPIO22") (pintype "bidirectional") (tstamp 38309d6e-81d3-4f76-a240-a11188452ec8)) + (pad "16" thru_hole oval (at -2.54 17.78) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 17 "unconnected-(J1-GPIO23-Pad16)") (pinfunction "GPIO23") (pintype "bidirectional") (tstamp 03e4b113-1537-43fa-92a9-d2a8443b2b9f)) + (pad "17" thru_hole oval (at 0 20.32) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pinfunction "3V3") (pintype "power_in") (tstamp 654f9ba5-310c-4d5a-af0b-ff5b85712b4d)) + (pad "18" thru_hole oval (at -2.54 20.32) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 18 "unconnected-(J1-GPIO24-Pad18)") (pinfunction "GPIO24") (pintype "bidirectional") (tstamp 86de948e-c5a2-4181-bdc8-05eb36367ff1)) + (pad "19" thru_hole oval (at 0 22.86) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 19 "unconnected-(J1-MOSI0{slash}GPIO10-Pad19)") (pinfunction "MOSI0/GPIO10") (pintype "bidirectional") (tstamp f6edaa64-a918-4f88-9892-6c995e9575f6)) + (pad "20" thru_hole oval (at -2.54 22.86) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 304e0b03-1cea-4d23-91a2-dc41d5ce210d)) + (pad "21" thru_hole oval (at 0 25.4) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 20 "unconnected-(J1-MISO0{slash}GPIO9-Pad21)") (pinfunction "MISO0/GPIO9") (pintype "bidirectional") (tstamp bfdca412-cdb9-48d0-92c5-752a4e949881)) + (pad "22" thru_hole oval (at -2.54 25.4) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 21 "unconnected-(J1-GPIO25-Pad22)") (pinfunction "GPIO25") (pintype "bidirectional") (tstamp 88589300-4c66-4f03-a5a1-6037ab7b21b6)) + (pad "23" thru_hole oval (at 0 27.94) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 22 "unconnected-(J1-SCLK0{slash}GPIO11-Pad23)") (pinfunction "SCLK0/GPIO11") (pintype "bidirectional") (tstamp c3d969d8-71fc-450e-bc8a-582f626baa6e)) + (pad "24" thru_hole oval (at -2.54 27.94) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 23 "unconnected-(J1-~{CE0}{slash}GPIO8-Pad24)") (pinfunction "~{CE0}/GPIO8") (pintype "bidirectional") (tstamp d14770f5-5058-4cb1-b720-1e6921d45332)) + (pad "25" thru_hole oval (at 0 30.48) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp fd272450-5023-45eb-b42b-9ce919739f26)) + (pad "26" thru_hole oval (at -2.54 30.48) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 24 "unconnected-(J1-~{CE1}{slash}GPIO7-Pad26)") (pinfunction "~{CE1}/GPIO7") (pintype "bidirectional") (tstamp 0eb56d41-2792-4c4e-82e3-fbbd68e1a0f2)) + (pad "27" thru_hole oval (at 0 33.02) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 25 "unconnected-(J1-ID_SD{slash}GPIO0-Pad27)") (pinfunction "ID_SD/GPIO0") (pintype "bidirectional") (tstamp c880e36d-41c2-4d06-af9d-2c7617a23133)) + (pad "28" thru_hole oval (at -2.54 33.02) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 26 "unconnected-(J1-ID_SC{slash}GPIO1-Pad28)") (pinfunction "ID_SC/GPIO1") (pintype "bidirectional") (tstamp ec5bd783-4334-460e-9233-0365f9ba4fa1)) + (pad "29" thru_hole oval (at 0 35.56) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 27 "unconnected-(J1-GCLK1{slash}GPIO5-Pad29)") (pinfunction "GCLK1/GPIO5") (pintype "bidirectional") (tstamp 53924c23-bf68-4cdb-af7e-3a7fc9cb34eb)) + (pad "30" thru_hole oval (at -2.54 35.56) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 41884a76-5a3d-4fec-97a3-f190dcb4359e)) + (pad "31" thru_hole oval (at 0 38.1) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 28 "unconnected-(J1-GCLK2{slash}GPIO6-Pad31)") (pinfunction "GCLK2/GPIO6") (pintype "bidirectional") (tstamp 5eb72e8e-9771-44a8-8bcc-b1a2670eb45b)) + (pad "32" thru_hole oval (at -2.54 38.1) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 29 "unconnected-(J1-PWM0{slash}GPIO12-Pad32)") (pinfunction "PWM0/GPIO12") (pintype "bidirectional") (tstamp f79ea345-cd02-4c42-b9ef-5e7c3ab6c734)) + (pad "33" thru_hole oval (at 0 40.64) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 30 "unconnected-(J1-PWM1{slash}GPIO13-Pad33)") (pinfunction "PWM1/GPIO13") (pintype "bidirectional") (tstamp ea4a1737-689c-42a6-8e2b-e05ba367f7f7)) + (pad "34" thru_hole oval (at -2.54 40.64) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp de446f11-bb46-40f4-b427-395e6936a157)) + (pad "35" thru_hole oval (at 0 43.18) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 31 "unconnected-(J1-GPIO19{slash}MISO1-Pad35)") (pinfunction "GPIO19/MISO1") (pintype "bidirectional") (tstamp bb0994d1-ce01-4d1b-a264-ae95e1726897)) + (pad "36" thru_hole oval (at -2.54 43.18) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 32 "unconnected-(J1-GPIO16-Pad36)") (pinfunction "GPIO16") (pintype "bidirectional") (tstamp 8fe78bff-e254-43d6-8919-7cdd28f5a1cd)) + (pad "37" thru_hole oval (at 0 45.72) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 33 "unconnected-(J1-GPIO26-Pad37)") (pinfunction "GPIO26") (pintype "bidirectional") (tstamp c4d72f46-e7e2-4e06-b30b-02c2ac3ed1a5)) + (pad "38" thru_hole oval (at -2.54 45.72) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 34 "unconnected-(J1-GPIO20{slash}MOSI1-Pad38)") (pinfunction "GPIO20/MOSI1") (pintype "bidirectional") (tstamp d9eb791d-5cde-4463-8dbb-c3f781f8687a)) + (pad "39" thru_hole oval (at 0 48.26) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 73b4246b-e0cc-4a08-a483-a5aba9f67139)) + (pad "40" thru_hole oval (at -2.54 48.26) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 35 "unconnected-(J1-GPIO21{slash}SCLK1-Pad40)") (pinfunction "GPIO21/SCLK1") (pintype "bidirectional") (tstamp d87de98a-8bcc-436b-8855-5fd9f42741e2)) + (model "${KICAD6_3DMODEL_DIR}/Connector_PinSocket_2.54mm.3dshapes/PinSocket_2x20_P2.54mm_Vertical.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp ca807d53-c77b-4bee-93c1-b656c3ae712c) + (at 53.40556 49.3) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/c3004251-8088-4827-aa14-0a4ce9cc2dcb") + (attr through_hole) + (fp_text reference "R1" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp fc678ea0-d98c-4352-a536-e0794ebceac1) + ) + (fp_text value "22k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp ccab0da9-6335-410d-9e6f-f448422a8eb8) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 5eb629ee-3e89-4b8a-b6c6-624a0d80ffca) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 300ecc94-3356-4b45-ac27-5d31acb45f2a)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 00399e6d-33ea-4005-9d56-9043352c9050)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d3d9d769-d24d-4a12-a31a-41d732976b47)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e1edf9a4-8588-45e6-8c8b-d2555ad51153)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e53cb279-6713-46d1-8c2d-a1a0372e1cf6)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 48628e68-cdc0-4555-a683-19a83c64e7d9)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp a5a84ca2-a104-4780-93c1-13ea5b7843e9)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 4d6633d4-85bc-4fe4-b142-6f3e24b1f24e)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1b6b945d-997b-4907-bb7e-178ae61d3c39)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d554f960-7418-402f-ac91-646c59822896)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4c2189af-4c52-4977-9357-79ef724beee4)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b453df1f-ee07-444a-8a44-618a66e573ec)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 94804a66-7975-4a04-b907-448fe742e21a)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ebf414ce-170a-4ad7-a32e-4a2db6678747)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4782de7d-26de-415d-9ae6-5b0c65ca7171)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d0e0bb1e-2048-4fe5-9f69-5ba72ba9a5dd)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pintype "passive") (tstamp 7f3e972e-45ed-4db9-bdc6-7c004dbe76c3)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 40 "Net-(Q4-B)") (pintype "passive") (tstamp 9ec23129-cff3-4cc1-945c-442628324a89)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp cbf39d8b-e581-487f-bb9f-5f9238d3e735) + (at 53.40556 68.3) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "R") + (property "Sim.Pins" "1=+ 2=-") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/e7236bba-1884-40d5-b2d5-3b06582681db") + (attr through_hole) + (fp_text reference "R5" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 46d1395c-5cd9-45e1-849d-6ff493bfc6e3) + ) + (fp_text value "4.7k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 15025776-2043-41d1-ba35-4c77df366fbe) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 86ae7193-fba1-4ef6-a01f-10c851c12db4) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0df10c54-95e9-4c87-84e3-7f547c96e29f)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f4fb4053-7669-43a8-b189-0a408226e61c)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5fa2eb73-c657-4a7f-a9c4-2da3024ac6f2)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7566461e-49c6-4ade-b3af-b740359021ec)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ee254e84-6f36-4a81-924f-7151bc9dfe72)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8dadabfe-a9c8-457a-8267-2e2285180914)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1d98e90b-18c6-41bf-9928-669811683b88)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d3a5ca73-3671-447c-a29a-7dcfb7e100c5)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ead40d08-9030-47db-a10a-dc22d9f8ae23)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5488e1f4-1d2b-4b42-82f1-e3d800b60542)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ed73877c-1fde-48e3-a2f4-721f2d9fe3d9)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4b07e009-4af4-435e-af27-bcf0cd6f50d0)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 1553dbe2-9633-4e5a-8ee0-f6b9fc20b50e)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 31b5bd6f-4b70-4c99-b7be-0871e6c7454f)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b9f24fb1-6052-4423-8950-3d83da0af056)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 02f7bbe1-9a75-4ba8-af46-a0fdac0fbab5)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 36 "SEATALK") (pintype "passive") (tstamp 2c8fa526-ed21-4f0b-9a10-d0d825bb3b35)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 39 "Net-(Q1-B)") (pintype "passive") (tstamp 39bb5522-a599-4339-91a4-2577e84e986a)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") + (tstamp d007f101-54a3-4c77-9bd7-a73cba8eb752) + (at 79.35556 79.13) + (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") + (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "NPN") + (property "Sim.Library" "BC547_and_BC557.lib") + (property "Sim.Name" "bc547b") + (property "Sim.Pins" "1=C 2=B 3=E") + (property "Sim.Type" "GUMMELPOON") + (property "ki_description" "0.1A Ic, 45V Vce, Small Signal NPN Transistor, TO-92") + (property "ki_keywords" "NPN Transistor") + (path "/aab4eea5-37eb-4106-bd44-0c724bfeaa6e") + (attr through_hole) + (fp_text reference "Q6" (at 1.27 -3.56) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp fbe91096-709f-4248-8b1b-715bef9b3e64) + ) + (fp_text value "BC547" (at 1.27 2.79) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 8436b44d-fa3f-4149-bc91-b0d6f0d80df0) + ) + (fp_text user "${REFERENCE}" (at 1.27 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp ea5c9eba-c3dc-4c5d-b5c5-84ba2ab2f0f7) + ) + (fp_line (start -0.53 1.85) (end 3.07 1.85) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp dbbbc7f0-2115-4264-a983-50a4941d3538)) + (fp_arc (start -0.568478 1.838478) (mid -1.132087 -0.994977) (end 1.27 -2.6) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ffd17c01-59e0-4766-9483-ae72e1c79461)) + (fp_arc (start 1.27 -2.6) (mid 3.672087 -0.994977) (end 3.108478 1.838478) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 24727389-f67c-4e3b-a95f-9c41f072f4cc)) + (fp_line (start -1.46 -2.73) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 7d78f865-c263-45dd-a8a7-62faedff3746)) + (fp_line (start -1.46 -2.73) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2568e5ce-2d5c-4f82-a494-0ce1429aef93)) + (fp_line (start 4 2.01) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1622989f-3f4d-4a2d-ab83-22f697b5ea79)) + (fp_line (start 4 2.01) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9f37abae-31f7-45cd-b3e0-b1654e97cb4d)) + (fp_line (start -0.5 1.75) (end 3 1.75) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e1666e34-8f15-4528-b610-cceec949be45)) + (fp_arc (start -0.483625 1.753625) (mid -1.021221 -0.949055) (end 1.27 -2.48) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d37cd9c0-9e63-40de-9f50-65c17bc76590)) + (fp_arc (start 1.27 -2.48) (mid 3.561221 -0.949055) (end 3.023625 1.753625) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d3fd33a0-08a6-4a10-9ae8-13d8910ce6a5)) + (pad "1" thru_hole rect (at 0 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pinfunction "C") (pintype "passive") (tstamp e6ce3118-7d40-4168-b720-5b7216bca586)) + (pad "2" thru_hole oval (at 1.27 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 41 "Net-(Q5-C)") (pinfunction "B") (pintype "input") (tstamp b88707f2-2a0b-46ee-ad8b-822fd40ab84f)) + (pad "3" thru_hole oval (at 2.54 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 40 "Net-(Q4-B)") (pinfunction "E") (pintype "passive") (tstamp 254e5d7e-331b-4859-b2cf-93b498418670)) + (model "${KICAD6_3DMODEL_DIR}/Package_TO_SOT_THT.3dshapes/TO-92_Inline.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") + (tstamp d1a4dee9-ad85-4d4b-bbe4-eac7c97c848b) + (at 79.35556 61.76) + (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") + (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "NPN") + (property "Sim.Library" "BC547_and_BC557.lib") + (property "Sim.Name" "bc547b") + (property "Sim.Params" "temp=20") + (property "Sim.Pins" "1=C 2=B 3=E") + (property "Sim.Type" "GUMMELPOON") + (property "ki_description" "0.1A Ic, 45V Vce, Small Signal NPN Transistor, TO-92") + (property "ki_keywords" "NPN Transistor") + (path "/7762f63f-936a-4d38-a129-b66d3e12b33b") + (attr through_hole) + (fp_text reference "Q3" (at 1.27 -3.56) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp d3daeabc-a004-4665-b170-8f24d16db1fd) + ) + (fp_text value "BC547" (at 1.27 2.79) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 7553e285-dc17-4ff6-ace6-339930caa096) + ) + (fp_text user "${REFERENCE}" (at 1.27 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 650572d1-576e-48e5-9e7f-8db38c0a6595) + ) + (fp_line (start -0.53 1.85) (end 3.07 1.85) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3053108d-a471-406a-b9ba-a160c4d01229)) + (fp_arc (start -0.568478 1.838478) (mid -1.132087 -0.994977) (end 1.27 -2.6) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a2a29989-8a99-410e-9121-67d6001d16cb)) + (fp_arc (start 1.27 -2.6) (mid 3.672087 -0.994977) (end 3.108478 1.838478) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5d767d9a-e587-40b3-86cd-f8d09e2834b6)) + (fp_line (start -1.46 -2.73) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5c35fbec-e148-411d-a1c0-84dd1bfa5108)) + (fp_line (start -1.46 -2.73) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 76102610-4faf-4b7d-8aa3-2511c81146fd)) + (fp_line (start 4 2.01) (end -1.46 2.01) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp efd5d6ec-6642-4bee-82cd-c24259b646b0)) + (fp_line (start 4 2.01) (end 4 -2.73) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 52ece934-29e9-44d9-b7c0-ef7b2343e66e)) + (fp_line (start -0.5 1.75) (end 3 1.75) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6a4137ab-7e92-4136-bfac-0efbe0ea0974)) + (fp_arc (start -0.483625 1.753625) (mid -1.021221 -0.949055) (end 1.27 -2.48) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 73552ca8-6e51-47a9-909c-9c5b076e8e19)) + (fp_arc (start 1.27 -2.48) (mid 3.561221 -0.949055) (end 3.023625 1.753625) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f0d6c94c-4075-4d78-a8ec-752fc693a814)) + (pad "1" thru_hole rect (at 0 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 3 "Net-(D1-K)") (pinfunction "C") (pintype "passive") (tstamp 1a33ecd8-093f-461a-833f-cba740935034)) + (pad "2" thru_hole oval (at 1.27 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 2 "Net-(Q2-B)") (pinfunction "B") (pintype "input") (tstamp fee31ae6-a29c-423b-8b10-9fc0cf917f3d)) + (pad "3" thru_hole oval (at 2.54 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "E") (pintype "passive") (tstamp db39512d-4ef4-4866-9b86-e4bc1499eb2c)) + (model "${KICAD6_3DMODEL_DIR}/Package_TO_SOT_THT.3dshapes/TO-92_Inline.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp dd9aba0a-3b67-450c-a7dc-b8136fb819d7) + (at 53.40556 54.05) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "R") + (property "Sim.Pins" "1=+ 2=-") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/efcaf01a-542f-4f53-800a-efe3e3979d0e") + (attr through_hole) + (fp_text reference "R2" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 101511fc-c112-4948-9d60-0b9211d18b99) + ) + (fp_text value "2.2k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp bcb5fde9-1877-46d5-99f4-b5ae9933fc0f) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 71ae167c-3184-4fd3-b2a0-9e3ae59e0dc2) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c1da7786-3511-467b-ba28-c6519535a520)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3a6ad5a2-c3d1-4d6e-8384-f6c7106bfdb3)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 08cf0112-48d0-46f2-9085-16d371f09e40)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6f5a3b91-bdc1-4361-8b96-7aa892f02a11)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 54704d09-332b-4496-ad0f-82bd6c01e307)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3016c42a-ab07-4ae3-a2eb-db67e167646d)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0e4cd44e-52a8-4c3a-91d0-503b42a7facc)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 08a96870-cf19-42c5-9b90-f53b1be5bf1a)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6661157b-8b81-4502-98b7-bb6f69dfe785)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3839b2ba-20b5-45ff-8dc6-cfacbd733524)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 630e4777-3097-43f7-a06b-8850fde11b6e)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 06ff254e-4ec0-4c16-bfb4-992c5f6824c2)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 85af1396-db6b-483f-8cb8-9706d8ec6e4f)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3a46dc99-4eed-4a66-84e5-6b65b0e0a238)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d7427ef3-29c0-4277-a307-638a83b6ff8e)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 33ec326c-b7df-4a88-849a-7c182fee6137)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 6 "VCC_5.0") (pintype "passive") (tstamp 0b5e7101-41db-48dd-b633-dc4274764213)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 39 "Net-(Q1-B)") (pintype "passive") (tstamp c2455b2c-b88d-4092-8b6a-7980f1d69c7a)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp debd4bf9-e187-48f4-b5b8-54f821e675b7) + (at 53.40556 87.3) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Device" "R") + (property "Sim.Params" "r=100") + (property "Sim.Pins" "1=+ 2=-") + (property "Sim.Type" "=") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/72ecdcab-4412-431f-ae1a-4d8a433bda34") + (attr through_hole) + (fp_text reference "R9" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 0b1bd8d1-a6a5-42a0-a54e-646497c8b89f) + ) + (fp_text value "100" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 21ce75d5-d431-4ecf-bd69-2af686a8b3c9) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp a07e3c44-b8c8-467e-afe1-ba2c197ecef5) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f4bc0a18-84bd-46fc-a499-c9bd944f1be9)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 400e2761-28af-4127-8df6-9443f40e3960)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1c6784e8-9c16-460c-b054-de32ae214032)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b07140a2-dc09-42a7-b87d-5c9f62163970)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7b4d96b9-5aee-4f74-9745-9cb80a7d5262)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 65279eec-5a57-4fa3-945e-c67790394350)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp bb0d9ccb-cd5a-4cbc-908e-76b27e1a95a4)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3d4f19d6-e6cb-4b96-8d58-10005d7164cb)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d75777ff-4abc-41e3-811a-02336fe9a4a6)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 64236c44-81e7-4eb3-876a-f64213221749)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 86e9dd7a-4b12-4104-936b-d0020d8040cd)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a1829c01-1947-4d4f-9d80-9db2cf2f5170)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ebedec27-5966-4f92-ab2f-3aa5e83e23ea)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3e00c740-5a26-432e-b0e7-b4b4852f7b3c)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ada0a556-e8c8-43da-afc9-4219f5440d70)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b5f83c8c-604a-4278-8fd1-8bcd827b9031)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pintype "passive") (tstamp 58090f3f-0b4e-443d-af49-5ab3873e9731)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 4 "Net-(D1-A)") (pintype "passive") (tstamp c81ec474-7e40-4e38-9ece-a20d074a96d7)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (tstamp e5a0b09f-5f1d-4dd5-97f0-ffb7f4370ea6) + (at 53.40556 92.05) + (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/579a3129-1551-4263-8c06-93d703fd61dd") + (attr through_hole) + (fp_text reference "R10" (at 7.62 -2.72) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 3f57e4b2-f8c6-49f6-a7f8-dbb4c017903a) + ) + (fp_text value "1.5k" (at 7.62 2.72) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp e7df3833-85ef-4683-9d5a-99133839ecec) + ) + (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp f5e0769f-cf38-4893-9b50-64776b0970d1) + ) + (fp_line (start 1.04 0) (end 3 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0e28f790-65bf-47d7-9172-498dbb2cd6a0)) + (fp_line (start 3 -1.72) (end 3 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cd6bc028-ab80-433b-ba4f-a6fb0f30026c)) + (fp_line (start 3 1.72) (end 12.24 1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 94924f74-db96-4a8d-b653-9d696c36ef71)) + (fp_line (start 12.24 -1.72) (end 3 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 414b4888-7032-4395-92d3-b6dcd89d338f)) + (fp_line (start 12.24 1.72) (end 12.24 -1.72) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 34503894-dcf0-4ce1-b19c-81b88fc3fdc0)) + (fp_line (start 14.2 0) (end 12.24 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e351b20a-b10a-4509-9ff3-991ec6d8e768)) + (fp_line (start -1.05 -1.85) (end -1.05 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp f6c49d66-cd58-4b69-bef2-3357beb0dbcb)) + (fp_line (start -1.05 1.85) (end 16.29 1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 4593944e-b1d6-4dfd-9759-348af6caef0e)) + (fp_line (start 16.29 -1.85) (end -1.05 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp f2e115a6-dd3f-4c14-97c9-b9e7f2f881e0)) + (fp_line (start 16.29 1.85) (end 16.29 -1.85) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ed1d84ed-18a4-4c3f-a418-f0a949b708da)) + (fp_line (start 0 0) (end 3.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f50195b8-d8ed-42e1-bf3c-2e8a740b0722)) + (fp_line (start 3.12 -1.6) (end 3.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 71b97826-719d-448e-9c4c-787d2cc9b278)) + (fp_line (start 3.12 1.6) (end 12.12 1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7a32c62d-9fd0-45f3-aa71-881ad058d3ca)) + (fp_line (start 12.12 -1.6) (end 3.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp da41fc17-9399-4b52-8189-5c3d531fa355)) + (fp_line (start 12.12 1.6) (end 12.12 -1.6) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c1a06b82-c594-4699-a65f-cb2621b16159)) + (fp_line (start 15.24 0) (end 12.12 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 25165936-a942-4d25-8b5d-b34ffdc8cd1e)) + (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 11 "TXD") (pintype "passive") (tstamp acd688f8-8d5f-4bd5-9c4d-6b0fe653d0d5)) + (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 42 "Net-(Q5-B)") (pintype "passive") (tstamp f81b0121-fe2b-4544-aadc-eb37401f332e)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) ) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch index 8423747db8..6c7bd9eb35 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch @@ -1040,12 +1040,18 @@ (junction (at 124.46 91.44) (diameter 0) (color 0 0 0 0) (uuid a7d268f7-32e9-4092-9d89-5d1361add476) ) + (junction (at 55.88 69.85) (diameter 0) (color 0 0 0 0) + (uuid af59d873-87f6-4b6b-9c63-7a90ce8852c2) + ) (junction (at 233.68 22.86) (diameter 0) (color 0 0 0 0) (uuid bb34be9b-b9cd-40cd-97fe-549557c0e323) ) (junction (at 238.76 91.44) (diameter 0) (color 0 0 0 0) (uuid bd060b68-f50f-4a4b-a001-e41b25bba6b6) ) + (junction (at 71.12 67.31) (diameter 0) (color 0 0 0 0) + (uuid c88283da-9c13-4284-836e-75cf6bab38a8) + ) (junction (at 262.89 161.29) (diameter 0) (color 0 0 0 0) (uuid cb75efd0-5091-475c-b9a4-a383ad8715b8) ) @@ -1180,6 +1186,10 @@ (stroke (width 0) (type default)) (uuid 2b9a13b7-2a69-42f5-920e-efd345e7e88c) ) + (wire (pts (xy 22.86 86.36) (xy 22.86 91.44)) + (stroke (width 0) (type default)) + (uuid 303cddc0-903a-48da-9011-3f8b8a6d39e2) + ) (wire (pts (xy 238.76 19.05) (xy 238.76 25.4)) (stroke (width 0) (type default)) (uuid 332c1d5f-cdf1-4103-9fe1-0e1d703602f2) @@ -1216,7 +1226,7 @@ (stroke (width 0) (type default)) (uuid 452060c5-3f97-48a1-b7a2-74ca2d0d8252) ) - (wire (pts (xy 71.12 30.48) (xy 71.12 53.34)) + (wire (pts (xy 71.12 69.85) (xy 71.12 67.31)) (stroke (width 0) (type default)) (uuid 45710f38-26a7-4688-85be-54a6e32b00b3) ) @@ -1284,7 +1294,7 @@ (stroke (width 0) (type default)) (uuid 6669daa5-08f0-4acc-9c79-01c1455e0f88) ) - (wire (pts (xy 22.86 30.48) (xy 22.86 59.69)) + (wire (pts (xy 22.86 69.85) (xy 22.86 76.2)) (stroke (width 0) (type default)) (uuid 668aaf4a-bf41-4c80-952f-ee5222a99d3b) ) @@ -1312,13 +1322,13 @@ (stroke (width 0) (type default)) (uuid 73616a01-4faa-4ffd-8d94-19ab712113f5) ) - (wire (pts (xy 248.92 118.11) (xy 248.92 130.81)) + (wire (pts (xy 22.86 69.85) (xy 55.88 69.85)) (stroke (width 0) (type default)) - (uuid 79063825-2d82-4234-a3b2-778ed97a0592) + (uuid 77da716c-6f64-47c0-96e4-1d7322095536) ) - (wire (pts (xy 22.86 69.85) (xy 22.86 91.44)) + (wire (pts (xy 248.92 118.11) (xy 248.92 130.81)) (stroke (width 0) (type default)) - (uuid 7b2f8535-2f2b-4780-aff5-9bf439d12c0a) + (uuid 79063825-2d82-4234-a3b2-778ed97a0592) ) (wire (pts (xy 93.98 81.28) (xy 93.98 91.44)) (stroke (width 0) (type default)) @@ -1392,6 +1402,10 @@ (stroke (width 0) (type default)) (uuid a208ba4c-b337-404e-b00f-fde003eb3019) ) + (wire (pts (xy 55.88 69.85) (xy 59.69 69.85)) + (stroke (width 0) (type default)) + (uuid a51c56f9-ec89-4bd0-ac27-7b9fdb1aec53) + ) (wire (pts (xy 129.54 125.73) (xy 113.03 125.73)) (stroke (width 0) (type default)) (uuid a96bd147-5b5e-437a-836e-3a7dd78175c8) @@ -1432,10 +1446,6 @@ (stroke (width 0) (type default)) (uuid b6edb122-0d4a-408b-a38f-95303db9b51c) ) - (wire (pts (xy 71.12 53.34) (xy 71.12 67.31)) - (stroke (width 0) (type default)) - (uuid bd458123-e665-4795-9ae8-450cb8a79e3a) - ) (wire (pts (xy 78.74 64.77) (xy 78.74 91.44)) (stroke (width 0) (type default)) (uuid be0cb463-2824-4c93-a3e4-68c50010e20b) @@ -1452,6 +1462,10 @@ (stroke (width 0) (type default)) (uuid bfb84e88-4141-45ae-954d-626ec12e011c) ) + (wire (pts (xy 71.12 67.31) (xy 71.12 53.34)) + (stroke (width 0) (type default)) + (uuid c0572784-d1df-4005-9ecf-d1883cfddb5b) + ) (wire (pts (xy 236.22 161.29) (xy 248.92 161.29)) (stroke (width 0) (type default)) (uuid c3065789-50d3-42bb-b0a3-807b4379f96b) @@ -1480,7 +1494,7 @@ (stroke (width 0) (type default)) (uuid d6e94bbc-4b7e-406e-a14d-dd9b76c1d3f5) ) - (wire (pts (xy 60.96 30.48) (xy 71.12 30.48)) + (wire (pts (xy 67.31 69.85) (xy 71.12 69.85)) (stroke (width 0) (type default)) (uuid d6f65a1f-1882-48da-b571-8c495f1ab874) ) @@ -1528,10 +1542,6 @@ (stroke (width 0) (type default)) (uuid efc38956-8ea5-409e-97d1-667213bb5655) ) - (wire (pts (xy 53.34 30.48) (xy 22.86 30.48)) - (stroke (width 0) (type default)) - (uuid f3936039-5ab9-45b6-8934-c7a9c8962258) - ) (wire (pts (xy 93.98 91.44) (xy 104.14 91.44)) (stroke (width 0) (type default)) (uuid f8293061-f56a-4bbc-91ed-4f1237ae0700) @@ -1672,7 +1682,7 @@ (property "Value" "2.2k" (at 151.13 33.02 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 146.812 31.75 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 146.812 31.75 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 148.59 31.75 0) @@ -1704,7 +1714,7 @@ (property "Value" "2.2k" (at 96.52 66.04 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 92.202 64.77 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 92.202 64.77 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 93.98 64.77 0) @@ -1761,7 +1771,7 @@ (property "Value" "22k" (at 127 81.28 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 122.682 80.01 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 122.682 80.01 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 124.46 80.01 0) @@ -1784,7 +1794,7 @@ (property "Reference" "R11" (at 227.33 127 0) (effects (font (size 1.27 1.27)) (justify right)) ) - (property "Value" "100" (at 227.33 129.54 0) + (property "Value" "200" (at 227.33 129.54 0) (effects (font (size 1.27 1.27)) (justify right)) ) (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 226.568 128.27 90) @@ -1807,28 +1817,28 @@ ) ) - (symbol (lib_id "Simulation_SPICE:VDC") (at 22.86 64.77 0) (unit 1) + (symbol (lib_id "Simulation_SPICE:VDC") (at 22.86 81.28 0) (unit 1) (in_bom no) (on_board no) (dnp no) (fields_autoplaced) (uuid 27f6dfc4-6d11-4993-be5b-18f0ba52532f) - (property "Reference" "V2" (at 26.67 63.3702 0) + (property "Reference" "V2" (at 26.67 79.8802 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Value" "12" (at 26.67 65.9102 0) + (property "Value" "12" (at 26.67 82.4202 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 22.86 64.77 0) + (property "Footprint" "" (at 22.86 81.28 0) (effects (font (size 1.27 1.27)) hide) ) - (property "Datasheet" "~" (at 22.86 64.77 0) + (property "Datasheet" "~" (at 22.86 81.28 0) (effects (font (size 1.27 1.27)) hide) ) - (property "Sim.Pins" "1=+ 2=-" (at 22.86 64.77 0) + (property "Sim.Pins" "1=+ 2=-" (at 22.86 81.28 0) (effects (font (size 1.27 1.27)) hide) ) - (property "Sim.Type" "DC" (at 22.86 64.77 0) + (property "Sim.Type" "DC" (at 22.86 81.28 0) (effects (font (size 1.27 1.27)) hide) ) - (property "Sim.Device" "V" (at 22.86 64.77 0) + (property "Sim.Device" "V" (at 22.86 81.28 0) (effects (font (size 1.27 1.27)) (justify left) hide) ) (pin "2" (uuid 22a64731-0d02-4297-846d-46b0f43ff1a9)) @@ -1893,7 +1903,7 @@ (property "Value" "4.7k" (at 106.68 78.74 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 102.362 77.47 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 102.362 77.47 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 104.14 77.47 0) @@ -1917,7 +1927,7 @@ ) (symbol (lib_id "Simulation_SPICE:VPULSE") (at 224.79 142.24 0) (unit 1) - (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) + (in_bom no) (on_board no) (dnp no) (fields_autoplaced) (uuid 520cf6fd-7c36-4222-967b-e5d1fe5a143a) (property "Reference" "V1" (at 228.6 139.5702 0) (effects (font (size 1.27 1.27)) (justify left)) @@ -2047,22 +2057,22 @@ ) ) - (symbol (lib_id "Device:R") (at 57.15 30.48 270) (unit 1) + (symbol (lib_id "Device:R") (at 63.5 69.85 270) (unit 1) (in_bom no) (on_board no) (dnp no) (fields_autoplaced) (uuid 71be8ad0-bfd2-4f59-afd6-b1bb5fcc5604) - (property "Reference" "R12" (at 57.15 24.13 90) + (property "Reference" "R12" (at 63.5 63.5 90) (effects (font (size 1.27 1.27))) ) - (property "Value" "10k" (at 57.15 26.67 90) + (property "Value" "10k" (at 63.5 66.04 90) (effects (font (size 1.27 1.27))) ) - (property "Footprint" "" (at 57.15 28.702 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 63.5 68.072 90) (effects (font (size 1.27 1.27)) hide) ) - (property "Datasheet" "~" (at 57.15 30.48 0) + (property "Datasheet" "~" (at 63.5 69.85 0) (effects (font (size 1.27 1.27)) hide) ) - (property "Remarks" "External pull-up from bus" (at 57.15 30.48 90) + (property "Remarks" "External pull-up from bus" (at 63.5 69.85 90) (effects (font (size 1.27 1.27)) hide) ) (pin "1" (uuid c7b42ef2-f5f0-4e97-a1ad-b69fd4fc0dba)) @@ -2085,7 +2095,7 @@ (property "Value" "100" (at 137.16 29.21 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0414_L11.9mm_D4.5mm_P15.24mm_Horizontal" (at 132.842 27.94 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 132.842 27.94 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 134.62 27.94 0) @@ -2240,7 +2250,7 @@ (property "Value" "4.7k" (at 96.52 78.74 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 92.202 77.47 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 92.202 77.47 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 93.98 77.47 0) @@ -2313,7 +2323,7 @@ (property "Value" "2.2k" (at 115.57 149.86 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 111.252 148.59 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 111.252 148.59 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 113.03 148.59 0) @@ -2374,7 +2384,7 @@ (property "Value" "10k" (at 151.13 110.49 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 146.812 109.22 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 146.812 109.22 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 148.59 109.22 0) @@ -2442,7 +2452,7 @@ (property "Value" "10k" (at 171.45 110.49 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 167.132 109.22 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 167.132 109.22 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 168.91 109.22 0) @@ -2510,7 +2520,7 @@ (property "Value" "22k" (at 115.57 110.49 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 111.252 109.22 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 111.252 109.22 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 113.03 109.22 0) @@ -2578,7 +2588,7 @@ (property "Value" "4.7k" (at 81.28 49.53 90) (effects (font (size 1.27 1.27))) ) - (property "Footprint" "" (at 81.28 55.118 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 81.28 55.118 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 81.28 53.34 0) @@ -2648,7 +2658,7 @@ (property "Value" "2.2k" (at 87.63 41.91 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "" (at 83.312 40.64 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 83.312 40.64 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 85.09 40.64 0) @@ -2715,7 +2725,7 @@ (property "Value" "150u" (at 113.411 66.04 90) (effects (font (size 1.27 1.27))) ) - (property "Footprint" "Capacitor_THT:CP_Radial_D10.0mm_P5.00mm" (at 118.11 70.1548 0) + (property "Footprint" "Capacitor_THT:CP_Radial_D12.5mm_P7.50mm" (at 118.11 70.1548 0) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 114.3 71.12 0) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk index 26e14802b0..713057609e 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.wbk @@ -2,19 +2,13 @@ version 2 1 9 .tran 10u 20m{return}.kicad adjustpaths{return}.save all{return}.probe alli -5 -2 -I(D1) - -1 -V(Net-_D1-K_) - +3 1 V(Net-_J1-GPIO15/RXD_) 1 -V(Net-_Q2-B_) +V(SEATALK) 1 -V(SEATALK) +V(TXD) From 7be59bdab926900b21ad79e5a979611dc41cdf3c Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sat, 13 Jan 2024 17:26:46 +0100 Subject: [PATCH 27/31] Schema updated, PCB drawn (unverified!) --- src/devices/Seatalk1/SeatalkInterface.png | Bin 0 -> 169339 bytes .../Seatalk1/schematics/SeaTalk1/SeaTalk1.csv | 13 + .../schematics/SeaTalk1/SeaTalk1.kicad_pcb | 5072 ++++++++++++++--- .../schematics/SeaTalk1/SeaTalk1.kicad_prl | 6 +- .../schematics/SeaTalk1/SeaTalk1.kicad_pro | 157 +- .../schematics/SeaTalk1/SeaTalk1.kicad_sch | 34 +- 6 files changed, 4408 insertions(+), 874 deletions(-) create mode 100644 src/devices/Seatalk1/SeatalkInterface.png create mode 100644 src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.csv diff --git a/src/devices/Seatalk1/SeatalkInterface.png b/src/devices/Seatalk1/SeatalkInterface.png new file mode 100644 index 0000000000000000000000000000000000000000..79956117d344002c04b9cf5d7bba78ddadbd73c8 GIT binary patch literal 169339 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

kuKxutIOZ5_0qY*%_QIykU1Njdf`BYP$q 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 aR^<+Kwe!mnlAD=E-Sm*f!9pYVxc>ur{|>SM literal 0 HcmV?d00001 diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.csv b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.csv new file mode 100644 index 0000000000..1d11e8554e --- /dev/null +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.csv @@ -0,0 +1,13 @@ +"#","Reference","Qty","Value","Footprint","DNP" +"1","C1","1","150u","Capacitor_THT:CP_Radial_D12.5mm_P7.50mm","" +"2","D1","1","blue","LED_THT:LED_D3.0mm_Horizontal_O3.81mm_Z6.0mm","" +"3","J1","1","Raspberry_Pi_2_3","Connector_PinSocket_2.54mm:PinSocket_2x20_P2.54mm_Vertical","" +"4","J3","1","Conn_01x03_Pin","Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical","" +"5","Q1","1","BC557","Package_TO_SOT_THT:TO-92_Inline","" +"6","Q2, Q3, Q4, Q5, Q6","5","BC547","Package_TO_SOT_THT:TO-92_Inline","" +"7","R1, R7","2","22k","Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal","" +"8","R2, R3, R8, R14","4","2.2k","Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal","" +"9","R4, R5, R6","3","4.7k","Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal","" +"10","R9","1","100","Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal","" +"11","R10","1","1.5k","Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal","" +"12","R12, R13, R15","3","10k","Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal","" diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb index 3bb25f1513..41cfaf5a7c 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb @@ -32,15 +32,6 @@ (47 "F.CrtYd" user "F.Courtyard") (48 "B.Fab" user) (49 "F.Fab" user) - (50 "User.1" user) - (51 "User.2" user) - (52 "User.3" user) - (53 "User.4" user) - (54 "User.5" user) - (55 "User.6" user) - (56 "User.7" user) - (57 "User.8" user) - (58 "User.9" user) ) (setup @@ -138,11 +129,11 @@ (net 41 "Net-(Q5-C)") (net 42 "Net-(Q5-B)") - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp 143a716d-6648-4d65-9154-fb626eeef15e) - (at 53.40556 73.05) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 87 66) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "Sim.Device" "R") @@ -151,55 +142,55 @@ (property "ki_keywords" "R res resistor") (path "/4f117a73-66ee-4224-8fe8-71a32870a260") (attr through_hole) - (fp_text reference "R6" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 0b8f23ab-4bed-45be-b1ef-3b8d6c2182e3) - ) - (fp_text value "4.7k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp f77620d9-f581-491f-88a7-3a0e4e97ef30) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 5dbba380-31fa-4785-8c7d-40e13b8ad49d) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp aedd000d-a0aa-4717-9700-cc9c52617264)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c693a408-493f-4ffd-85a9-6dae84122bd5)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0a6085a2-5fa1-4935-92c3-7e1633e62abe)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fd8f0c47-e9e8-45a8-aa67-53ba0899b7e3)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b4c7eace-f233-4532-bcd5-af937cb90449)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 454807ae-09a8-4568-9f42-c8256966f765)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp da701bdd-623f-41ec-ad28-403258024061)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 68b12e79-7256-4750-84f8-a918ea13f7b4)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 576ea73f-5524-4dc6-b933-fe4211cf251a)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp fc6bcdf6-3c36-4216-9d0a-53286ffb494a)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6a95ef3d-2e53-457c-b2b1-6847a26fb786)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b8a42a6f-ad87-4dfe-a745-454433d81131)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6fcc09ad-4712-46f5-9460-8cff920febea)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 82d96c8a-2fe9-46ed-93ab-5a8313b4b0fc)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 86a1e5bc-4f6d-40a8-9a24-ebdff23bec31)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a067e0a1-84b8-44ca-841d-4f9a7e2755a0)) + (fp_text reference "R6" (at 5.08 -2.37) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp df30d407-10fc-4865-9529-3c57fcf75ccb) + ) + (fp_text value "4.7k" (at 8 -2.5) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp a43b9c0f-d826-4ec4-894e-737d4f2cb7d3) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp b96df36c-6861-4e6d-a588-ea3f3cc72b6a) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 658d4661-3ba9-4556-9488-1880fe83bd80)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 59bb453e-1c08-4404-8324-c244dba71003)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4ba5ae23-e2ef-4a6c-aa41-f38097a799e3)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 678a0e4d-1472-4b59-8362-5403f42a51f5)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f761f3cb-049e-425f-b071-af2973ad67c7)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 416bb320-9fb0-48b8-9bcb-01170a38a0ce)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3f8e4a6e-f3c9-43fb-a8b8-0fef9fffbdae)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d338923c-36de-4b53-a8d6-68071084701f)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp a8ed4ea9-0e86-42de-b55f-413972beb4af)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c6986d1d-1a7c-4aa5-b044-0629a8c4c7bd)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d1500a86-34bd-4fe2-a738-de62666094fe)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 82e15b48-0cd0-4a5a-a1cd-32ce77d1728e)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0ea4c932-4090-49c9-8fa0-f89d2e397529)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a24d208b-5fdf-46ae-bf7f-585391db123d)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp cd795676-bd34-43b7-81ea-342530587815)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 136850c4-c28e-49aa-8bde-e54bbeaf07cb)) (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp bcfb35a3-00f4-4124-accd-c8b6f17f6129)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pintype "passive") (tstamp 118604ef-4780-427c-b7c6-ee44d5aceb8c)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp c8b618bd-cd4e-461c-97ab-8a4aa783dce5)) + (pad "2" thru_hole oval (at 10.16 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pintype "passive") (tstamp 13fd7acb-dba0-41b1-90d9-c06ab66880e7)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) @@ -208,7 +199,7 @@ (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") (tstamp 1f42dcc5-eeaa-4e46-b2ae-97adbb29e215) - (at 79.35556 55.97) + (at 117.96 60) (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -269,7 +260,7 @@ (footprint "LED_THT:LED_D3.0mm_Horizontal_O3.81mm_Z6.0mm" (layer "F.Cu") (tstamp 25808193-2af6-4752-970c-26256f1fa393) - (at 85.65556 48.7) + (at 115.75 93.9) (descr "LED, diameter 3.0mm z-position of LED center 2.0mm, 2 pins, diameter 3.0mm z-position of LED center 2.0mm, 2 pins, diameter 3.0mm z-position of LED center 2.0mm, 2 pins, diameter 3.0mm z-position of LED center 6.0mm, 2 pins, diameter 3.0mm z-position of LED center 6.0mm, 2 pins") (tags "LED diameter 3.0mm z-position of LED center 2.0mm 2 pins diameter 3.0mm z-position of LED center 2.0mm 2 pins diameter 3.0mm z-position of LED center 2.0mm 2 pins diameter 3.0mm z-position of LED center 6.0mm 2 pins diameter 3.0mm z-position of LED center 6.0mm 2 pins") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -287,7 +278,7 @@ (effects (font (size 1 1) (thickness 0.15))) (tstamp ed011d75-c95f-4703-87d4-4d2cc0e064f8) ) - (fp_text value "LED" (at 1.27 10.17) (layer "F.Fab") + (fp_text value "blue" (at 1.27 10.17) (layer "F.Fab") (effects (font (size 1 1) (thickness 0.15))) (tstamp 8c3ad186-092d-40b5-a9ba-69a2a942b952) ) @@ -374,77 +365,77 @@ ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp 265f818b-0fe1-4d04-b25c-6ae6c26e89a3) - (at 53.40556 101.55) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 107 73 -90) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "ki_description" "Resistor") (property "ki_keywords" "R res resistor") (path "/8b0fd059-b19f-4565-852a-74e3223bfaf1") (attr through_hole) - (fp_text reference "R14" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 9f1a862c-2580-42d4-bbbb-b9fbcfb18739) - ) - (fp_text value "2.2k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 7c4e277c-1380-40bd-9766-3c9b81dfde22) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 1232a4c2-27e3-4e01-9bc2-a439e9d52c61) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ebbd6d74-c3bb-4f6e-829f-1e245cf591cb)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ff8fc32c-4570-4591-bce7-667ffba0e70e)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8895f56f-e754-41de-8707-b25151e74bd7)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 90b10aa8-5279-4153-ae15-11b1a3fd14ff)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ec103252-80cb-43e0-9067-57c6d95b2d24)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 03d0a2ec-d331-486c-a22c-b70e325f9c5c)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1240405b-11b7-477c-9f95-8c6272645b70)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 01cf4b2c-b805-4391-b8d5-144b2bdba99a)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp dfce50b1-56ba-445a-b7d2-5aa17314fbde)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2075fd49-d6fd-4697-92f3-17b4c7a889cc)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2ad4005b-d7c4-4dea-bf61-fba0de563a11)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0284cf5d-bf95-4f80-8245-bab305023bdc)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0b7f3fc7-0522-458b-88a3-c8a838186700)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp bdecdb42-e448-4dc9-a29a-7beb3b893507)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b9001cc7-5715-4521-a7a3-a2bc25afaff7)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a6a5a203-39c0-4718-9ded-1eefdca82a60)) - (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 40 "Net-(Q4-B)") (pintype "passive") (tstamp a18c8be9-d224-487b-a896-99004329def2)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pintype "passive") (tstamp 5f8a81d4-d0a2-4730-9a3d-043c376740b1)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (fp_text reference "R14" (at 5.08 2 90) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 22237083-6bce-412a-8fb3-6230e8932fc1) + ) + (fp_text value "2.2k" (at 5 -2 90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 88876ffb-ef3a-4ea5-a2b6-f4c4d441e893) + ) + (fp_text user "${REFERENCE}" (at 5.08 0 90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 8e21ccc6-f740-4852-b114-0fe86e0e6b6e) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7b4586d3-a172-4c74-9a6e-82d8e9f8025f)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6667a83d-5221-45d7-8117-78c93a7f6305)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ab7d5819-51de-44e1-8094-84c2f547db52)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7d329e51-08f4-46a6-9aba-1fb4f39138e8)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 48565339-0824-41b1-afbd-4e96964dde10)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c05e8143-d5f5-4e80-859f-030a89048944)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 7d7f05e4-c1a4-4f12-b49b-9659ec65eb6d)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0840d53f-f617-43d4-9985-06309079b0b0)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp cafca424-b953-409a-a127-696ecb311f0c)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 60608954-3544-4d9a-a340-138c90ed598c)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e78bbb23-b21e-4b10-9bf9-b6b0bcb850f3)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a9510824-f628-462d-9cc1-68511dfab7be)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3befaf80-5650-4ff0-a70d-21404e44a12f)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 40021d1c-0136-4431-b26c-9db89f88b6f2)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7fd07db6-2ce4-4a40-9ad7-d7aa825d5657)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 49fe7696-67bc-4960-9154-df27dce643bc)) + (pad "1" thru_hole circle (at 0 0 270) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 40 "Net-(Q4-B)") (pintype "passive") (tstamp a5dcf8c0-219b-47d1-a73f-f15846313e79)) + (pad "2" thru_hole oval (at 10.16 0 270) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pintype "passive") (tstamp f6f17030-352a-4300-8470-5d847a453d80)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp 29a518ee-ac44-4f07-bdf9-97bec75d2e31) - (at 53.40556 58.8) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 113.08 51 180) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "Sim.Device" "R") @@ -453,55 +444,55 @@ (property "ki_keywords" "R res resistor") (path "/0512ba43-5f13-4592-bd94-7ec2752829fa") (attr through_hole) - (fp_text reference "R3" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp af9c498c-8627-41cf-97a1-04471ddc2cbf) - ) - (fp_text value "2.2k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 931d2374-bd5d-42ee-8c09-e55dec719fcb) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp ac78ab7b-9493-4c33-abe1-fc6dc5202582) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e67008f8-a57d-4878-b07e-83d03f084db6)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 93a1c98d-dbae-42be-85f3-2691c4135ee9)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b48d49a4-b94a-4e5f-8a7b-7b70b827f2ad)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a53acdd2-a714-450b-8af6-dcf52139e12e)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fea01b30-a411-4e54-9e3a-ade9db9ab7b6)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4599e09f-455f-4f9d-afa9-bef14d28fb8a)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c6ac6064-9c69-4e57-92d8-74a0a2ac32b6)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e7b7b9f1-fe97-4282-a7fc-9515abd3712b)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 319083d1-cf10-4276-a207-56c9ba9c82bc)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 43300871-9fec-4968-ad60-18a2d0fe3e97)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 73ea93c8-ed59-4777-b54f-dcf8f73713b7)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 60da2fe0-a311-49c6-8119-b9e0c182f575)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 001ee6fb-2936-486c-9ad6-0c1a3e76a283)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b2790b0f-a280-41ec-a3f3-d2197c5211e5)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6b2e22d4-ac4e-40db-ac77-66e71518e7ae)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 730329f2-17bd-45c9-b965-d196287ba074)) - (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 38 "Net-(Q1-C)") (pintype "passive") (tstamp 9dfb9a76-5c4d-4843-b279-ec635a4675c4)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp 00cd662e-ef9a-4cb7-b7c5-c5147c6adf9d)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (fp_text reference "R3" (at 5.08 2.5) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 933d0e2b-644e-429f-99bc-13b75f07731e) + ) + (fp_text value "2.2k" (at 3.58 -2.5) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp e854f44e-9902-4e4f-820d-fcafb9412abb) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 8374d805-ed07-4997-9df3-69d0bfe184f0) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 201c5d91-0381-46e4-bb8a-db78c72b1433)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c3e85da9-48a3-4341-8c8a-ddc03353235a)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 366ba58f-ad04-465f-8cbb-43295bcbf387)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4df76923-a19d-45bf-9cca-64846a009095)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 08b601ef-b072-4011-adb6-4c32bf806e43)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c718c598-9cea-45e7-a21d-681e78d8a686)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c7df78b4-1cf5-465d-a169-c89c08feb0ef)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 43164011-5727-4cd2-a920-25f95f2fed74)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5e1c57f0-c2c7-4a07-800a-d13834139cb3)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp b3fca45b-a15e-48de-83c9-f5f3b4e07cbd)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a2457a68-3280-4095-b8a7-d39ed77620fd)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e9f18d43-1703-4f1f-833f-60c3aa5b06f4)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2a9d1197-170d-4480-8282-798228413339)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b8deda03-0063-408b-8b9e-927af94e8b8f)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7d6632ca-7209-4eed-8165-b89691a1e012)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7731558a-b5a1-444d-af80-490bbaef261a)) + (pad "1" thru_hole circle (at 0 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 38 "Net-(Q1-C)") (pintype "passive") (tstamp 5dbb4394-f483-4dc2-8fc3-d3cb979d898d)) + (pad "2" thru_hole oval (at 10.16 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp 4e560953-458a-4e81-96d5-a5b8c5da9b6c)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) @@ -510,7 +501,7 @@ (footprint "Capacitor_THT:CP_Radial_D12.5mm_P7.50mm" (layer "F.Cu") (tstamp 340a6af9-097e-4004-b71a-d4160aee262b) - (at 83.94 91.44) + (at 101.5 60) (descr "CP, Radial series, Radial, pin pitch=7.50mm, , diameter=12.5mm, Electrolytic Capacitor") (tags "CP Radial series Radial pin pitch 7.50mm diameter 12.5mm Electrolytic Capacitor") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -521,7 +512,7 @@ (property "ki_keywords" "cap capacitor") (path "/ff3cc76a-1a65-43c7-a10c-c52bf541e8be") (attr through_hole) - (fp_text reference "C1" (at 3.75 -7.5) (layer "F.SilkS") + (fp_text reference "C1" (at -1 -6) (layer "F.SilkS") (effects (font (size 1 1) (thickness 0.15))) (tstamp 4aabcb66-83c2-4552-bbe8-46e03c295130) ) @@ -1024,7 +1015,7 @@ (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") (tstamp 3f52b951-fc4e-4791-8fd1-720ca73b3c85) - (at 79.35556 50.18) + (at 117.96 51) (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -1083,143 +1074,143 @@ ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp 3f7822ee-6283-474b-b37e-ff80c0af1726) - (at 53.40556 96.8) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 104 95 90) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "ki_description" "Resistor") (property "ki_keywords" "R res resistor") (path "/a88aec3a-89e0-4123-9d67-40bd4310a5ef") (attr through_hole) - (fp_text reference "R13" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp cdc6b146-e229-4c54-ab2c-44beaa8a1515) - ) - (fp_text value "10k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 92733e8b-0e43-4160-aec6-99d8fa23bd6a) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 8d4db053-cdec-4062-ac10-5b5f0bd27630) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6c92436d-a108-49bb-af87-c1354a4e103f)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bbd4b519-20d3-4679-a52f-829990ea12e3)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 44f549f5-02a6-4952-9c70-69e2f44b0747)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a755e7d9-0445-4a31-a3e9-8f50c0a73446)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp da36b510-4a1a-489c-96ad-370da4d4a42e)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9912ac63-0522-4bc3-8f0a-6b3e96df484d)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp bb75e819-4ac9-4a82-81c1-3433866fd320)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0fc38fb9-4c9c-4786-af45-3e7095f0839a)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e5a71c9d-8b5f-4217-b01a-c45ee322e9c9)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 8ea94bb9-ec83-47dc-907c-328324db80a0)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e5ae438a-22a7-44ba-8e06-4fc7592cb14a)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp fc4a3769-114d-4084-ad24-aede7ae5db0e)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ff15b562-9d6c-4f5a-b498-316ccdd55957)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9404ab2f-e2cd-4f72-a27e-9d9a8e9f0758)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 8c50284c-eba6-40f8-aaa7-cd5d8df203c3)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp eeb173d8-0be1-4fb0-a6ea-3178b5a94454)) - (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 5 "VCC_3.3") (pintype "passive") (tstamp 4cd31f6a-8311-42e6-a7d4-ed9bb6944d56)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 11 "TXD") (pintype "passive") (tstamp 090a8cc6-6342-427a-9ce5-5607f5ff3931)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (fp_text reference "R13" (at 5.08 -2.37 90) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 6df07662-a7a9-4889-936b-f2402ac188fa) + ) + (fp_text value "10k" (at 5.08 2.37 90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp c683178f-663f-4b0b-84d4-a160c678ec95) + ) + (fp_text user "${REFERENCE}" (at 5.08 0 90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 315f5b88-bc90-4e37-945c-1d59380e0909) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ea59be9d-ceba-4205-ad13-28ebce08a816)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 47d45d52-ea16-4b56-a1bc-18c31bdb1564)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6a74ba48-02f8-4db8-b416-15c3998d2582)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7449de72-977a-48b7-8017-e513f6583083)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1432726f-f5b8-4913-8503-f6d411281d1e)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 203ffaa4-1f13-4c34-9681-26f484b4706a)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 57e83331-bdeb-4c2d-9823-08c340b07938)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 12c909e5-bb34-4918-9c90-db7df6108601)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 4430c562-e685-4580-bc43-4c2a60cae786)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp bdfd57cb-ac33-435c-b961-311af1e69fe1)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f4c9faa5-38f9-4c38-b251-603da3a85606)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3c90a8ca-1ce9-4783-9732-71fc7c772bf3)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6bfe0278-1a56-4142-9f24-07ae0f8caa00)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7193c2e1-1883-4c4d-ae93-36a80c6fcc0a)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d2c419a8-ab4f-4b56-b784-53f4a4e5eaed)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f38500a2-ceb2-4bc8-987c-b83e0d49e3d9)) + (pad "1" thru_hole circle (at 0 0 90) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pintype "passive") (tstamp 7a99ae1f-3b52-4f2f-993d-fe39626cb96d)) + (pad "2" thru_hole oval (at 10.16 0 90) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 11 "TXD") (pintype "passive") (tstamp dbbc1296-ff8b-4c8c-ba25-2770b163e47d)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp 45cce9b3-3dbd-4d7c-b145-f372b61b3267) - (at 53.40556 106.3) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 88.92 89) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "ki_description" "Resistor") (property "ki_keywords" "R res resistor") (path "/94c334ed-1cb5-4404-a652-a5f07f1cffb8") (attr through_hole) - (fp_text reference "R15" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp e38bd881-7a72-422e-800b-278a4d0b6f83) - ) - (fp_text value "10k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp ffc56232-7d5d-4b8b-93cb-1d19cf26d1bf) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp cd3acb43-6252-48fe-bed1-9da5b71b052a) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fed76ea4-fe98-417f-87e7-0e0984be9c25)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4cdf5b14-65dc-4716-b901-b1f3a72752fb)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c7d263db-be79-423d-9282-63e04436424a)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 258af670-1546-4f24-b975-1e1726d72297)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 30b4bddb-aa38-455f-b032-336ef257958c)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 70d7537f-8ec0-4055-8818-87fcd25d8c19)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6b63ab2a-8137-4967-9b3a-ab720277169f)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1db21bfd-fee1-4352-9aad-c49dd0dae24b)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 689c3c9b-7f5f-4a9b-9887-0e5cd0702738)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d575151a-864a-4e5e-95ef-574251d9f21d)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 90b8471a-c4b3-48b2-9efc-63c0d5a5b518)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 00e8fee1-fd13-4d20-ad94-2728c9f47699)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ba48af6d-46d1-431d-b54f-49f7010109a2)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 62a5b309-2015-4df9-a165-165a35fe5dd2)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9e07d14b-daa0-49e6-8b04-80b03fcee180)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6eb5a0f8-5a94-4220-8bb2-23ba39ebee4c)) + (fp_text reference "R15" (at 5.08 -2.37) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp acfdbeff-51ac-4fb7-a44f-d88b2a15088b) + ) + (fp_text value "10k" (at 5.08 2.37) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 3bdfcc65-6c73-484b-852b-24e2c0d4846d) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp cde31ded-3b14-413e-b3f0-18d97e460b41) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 88e4df15-a9d3-40fd-a270-89e44ee7a879)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a4bdba37-0990-43c4-b162-3fcff9e6f722)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ccde9eb9-db6d-4323-9eaf-fb477578daa1)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b6397664-c439-499a-bffc-2022028eed3a)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bbc4086c-ef94-4492-9cc5-7d715c81effb)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c73fe885-965a-4ba1-9779-7a4318410ea0)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 7e9eff28-49a4-4ee6-9772-746f87c24cbe)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp fa42a1a1-8a7b-48ae-b104-498105639677)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp a69fa8bd-d0f5-419d-999b-7791060b5512)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 7017c73b-5267-40c4-84dc-19cfb60e6cfb)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 772f073e-80c2-4a2a-aaca-cfdef572bc02)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a5bd31eb-5d71-41db-8f95-4ad1f5e31e78)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b5cae3e3-95ea-453e-96de-65128cb6bf9d)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d9b64290-9540-4828-96c4-efa0469e5ac3)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 081cee40-b507-43ec-ae94-40210fe4b841)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 845e1edf-bef2-4420-9b9e-6890f4cde265)) (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 5 "VCC_3.3") (pintype "passive") (tstamp 715169dc-c56f-4e1c-b9ed-1b9edb51091f)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 41 "Net-(Q5-C)") (pintype "passive") (tstamp 9c0b3468-19a8-4fb9-a654-c7a034c3583b)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (net 5 "VCC_3.3") (pintype "passive") (tstamp 6eec3e49-1e98-4cce-8dd3-836ac2209b2f)) + (pad "2" thru_hole oval (at 10.16 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 41 "Net-(Q5-C)") (pintype "passive") (tstamp c9c58ef4-7a98-4424-bf3a-54206dad070a)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp 845ccd1d-2298-4001-b687-cc6f145560b2) - (at 53.40556 82.55) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 104 76 180) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "Sim.Device" "R") @@ -1228,55 +1219,55 @@ (property "ki_keywords" "R res resistor") (path "/05087989-f568-4ae5-b297-c298921fe111") (attr through_hole) - (fp_text reference "R8" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp a2ca4617-074a-4efe-a0d5-8214a1026a9a) - ) - (fp_text value "2.2k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 15d16a67-c709-4470-be52-917b7d440f2b) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp cdb94f33-da34-454e-9031-5a1d7d470623) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a9c72b74-117f-48b2-9b4a-80866e49119e)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 56e4d213-a459-4367-baec-c7f6c094aab2)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 297b2d12-c3b0-4655-93a0-19d38db0e397)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b3f9e1b8-8ccf-4a5e-bcca-f18fd8b02892)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d30d6270-b7cd-45b1-889a-f27e97966e50)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp aa1d459c-b9b0-43da-a63f-48b070bc3fdd)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 581d0d1e-337d-4607-96d6-f4d5d0d580f8)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2f52cbff-7c88-4804-ac48-df8afff2e027)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0fa440f3-819f-4f80-b2f3-b3a4b9566628)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2ab23a9b-5b0d-415e-b951-6926395e1f5e)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp aff735f7-9d08-4334-b3fb-b2fa08f0d4a8)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 69224adf-c0b6-46bb-8449-1146e40dd9e2)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 05264557-5c9d-4259-b2b1-a7fc403daea5)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0193c69e-e526-4f9b-b1a8-6fa2ebb941d2)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp fb815bb0-7157-48e6-8b78-064f3696a8d3)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 679491bc-ae82-4b36-837b-99e479b44ade)) - (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 5 "VCC_3.3") (pintype "passive") (tstamp 0e78e12a-f27d-4a71-946c-a2e1f069feba)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 12 "Net-(J1-GPIO15{slash}RXD)") (pintype "passive") (tstamp ba7950b9-9511-488a-ba6b-860ca74efac3)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (fp_text reference "R8" (at 5.08 -2.37) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 34f80fd9-e658-4a0c-9647-e66478be4923) + ) + (fp_text value "2.2k" (at 5.08 2.37) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp e63432aa-1f16-40b0-ac77-efd2e91ed895) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 6adb4ca8-f575-4097-be7f-0d96368cee97) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 35479412-f12b-413b-9168-fb92d7801c1a)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp fefbfbc6-1d8a-46d6-b2ec-1befb95d5648)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8f1ae895-0473-4eca-80d8-fd8acf8c8e78)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e2042a34-067f-4ee9-9b99-ab06b2980dda)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 245c30c6-a017-4976-b90c-f2702955af78)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bab2dd2a-5de1-4e2d-b558-5c998d4977e3)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 25a82f37-aff8-4855-bcae-a17b9a421d0c)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ace825f4-6a3b-42a7-9dbc-53734a9a7c0f)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1ea0646e-7751-4ac6-a9cb-80277b3d34ff)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 02bca96b-1387-417d-8842-38091fc34c1d)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e19401c8-422b-4d07-a14a-bf18eb908fe3)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4dba54c4-d827-4b01-801b-91014f6de41d)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c0472bef-d5c8-4a7b-9306-7b22258b9ae5)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6ad6fafd-4213-4212-ba98-f8c884978091)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3db05eb1-c332-4fe9-8d4c-16687436344a)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp cddcab99-f919-4652-8297-27933ff7b015)) + (pad "1" thru_hole circle (at 0 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pintype "passive") (tstamp 2a7ef9f0-87ba-4f11-880f-f85eb40e1feb)) + (pad "2" thru_hole oval (at 10.16 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 12 "Net-(J1-GPIO15{slash}RXD)") (pintype "passive") (tstamp 5a91186c-99a7-4c81-98a8-102cf0ed0200)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) @@ -1285,7 +1276,7 @@ (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") (tstamp 8a5f4c35-05cf-48db-b130-cef696223a71) - (at 79.35556 73.34) + (at 108.46 89) (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -1344,66 +1335,66 @@ ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp 8fc225f7-a8d9-414e-a7b3-9b9a85b6279a) - (at 53.40556 77.8) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 111 72.92 -90) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "ki_description" "Resistor") (property "ki_keywords" "R res resistor") (path "/1e712663-9f97-4762-926c-2b4ce56e9875") (attr through_hole) - (fp_text reference "R7" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 16ed253c-6bcc-4b77-937e-8f8e02e37b9a) - ) - (fp_text value "22k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 37e26409-2377-43a5-9d2c-921469eac87c) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp cd42b7f7-28cf-4814-9bd4-bc8350c2830e) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d28f3ef4-7a8d-4e86-af40-4d75a7cebd92)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a4c25ef4-f075-4320-ac73-cd12532b56ac)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5d06d985-7826-4ae5-99a1-3b029283f434)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1b3be610-573e-4eed-9563-552c32487b79)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 54eb83d7-a847-4813-925f-011454ade1b1)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8588f785-92b9-4329-aec4-fda29582bc4b)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 72bcc5f7-8972-4f8a-acfb-b86badb9cf97)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9c2899ec-17ba-4eed-af40-5fd3d794d25f)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp aa8ade3e-86b0-4750-bda5-ac204cb6e54a)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 7b143c23-bd56-4ec4-b9a6-b80484eeb2a1)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 462e1543-4418-49c9-8caa-beef5e500be0)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 098f74c7-b6b2-4e76-a6f1-f618b32e350c)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 89e2156c-f256-44ce-a8a0-77cd6f626214)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp de077ac3-e7cb-47f3-b734-23dee562c8b4)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e2ae2d88-d295-4afe-9d1a-64f7ada427cd)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d6e63721-399c-4bac-bfe6-c3f275a5e55d)) - (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 2 "Net-(Q2-B)") (pintype "passive") (tstamp ebba090b-bd31-48d4-a384-d51aefc12ed0)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pintype "passive") (tstamp 96b63d0b-c941-449e-a440-3fb412c7cd3b)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (fp_text reference "R7" (at 6.58 -2.5 90) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp bb8e6e05-5642-468d-9f21-21b408aadd2a) + ) + (fp_text value "22k" (at 4.08 -2.5 90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp ce47c9f8-9e8e-42ca-880b-7e73f4c98285) + ) + (fp_text user "${REFERENCE}" (at 5.08 0 90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp dbf08de9-4d8f-403e-a8a2-a390ffd407fc) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7eea2dda-54e8-4a59-8820-9310d743f569)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7f9a0325-abbc-4bd9-89ee-f5b453307081)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a46a75ee-c28d-4cea-a181-b143d7e0ccfc)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e7367653-5e67-4311-9de3-b6594e028d51)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d953e37c-9abf-41a3-9fc7-1b1dc542b311)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 062fa0b6-b2b6-427a-bdab-dec8720c0dcc)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c93675e3-fe42-4c5e-ba4a-06e6adfc4860)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6971d6ef-96ac-411f-8c19-9dac3b27a3a2)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0fc472ee-0474-4244-836a-4c0a56530099)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 8efc70dd-c1b0-495c-9beb-c3bc2d2295ae)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 46db18a5-79ca-4ca1-be07-8428ea21b640)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7f5f07bf-91c3-483c-bf53-30c46397d9fb)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp bb09eae9-0f5c-4d22-a624-7136fef766e4)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ea761013-3614-4f2d-b862-2854a498b856)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b2c6d1c2-42c1-4393-a2f1-0e4c59e9ff49)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ff412aaa-cecb-40c5-b6d0-15c6c08fb2d7)) + (pad "1" thru_hole circle (at 0 0 270) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 2 "Net-(Q2-B)") (pintype "passive") (tstamp 99ed30be-e172-4f42-9356-4cf818a0cccf)) + (pad "2" thru_hole oval (at 10.16 0 270) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pintype "passive") (tstamp 7e2907e8-57b3-4148-9f87-19a0fece99d0)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) @@ -1412,7 +1403,7 @@ (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") (tstamp 94171681-d57e-4456-9703-3178e2780bdf) - (at 79.35556 67.55) + (at 117.73 81) (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -1471,11 +1462,11 @@ ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp 96ab9178-579a-45a4-a68c-707fb33e88ed) - (at 53.40556 63.55) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 86.92 71) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "Sim.Device" "R") @@ -1484,55 +1475,55 @@ (property "ki_keywords" "R res resistor") (path "/873fd484-3122-4533-8a3d-0b6694e5decf") (attr through_hole) - (fp_text reference "R4" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 65aed444-b66b-4b96-9ec2-bf5dc9806d0f) - ) - (fp_text value "4.7k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 928eb78c-5a83-4ed6-9c07-00f9bf6e6b77) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 78dca79e-60b1-4c2c-8647-0f7b7c56b6c3) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1e4efc58-1aa9-4299-b44f-412afab24d0f)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6bdfb2dd-4341-4529-bda7-89b5aaf07fb0)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a789e6f6-f6db-463e-ba4b-4e91526c6cab)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 93e40aeb-71a6-4aea-a3f7-cab119ffee5e)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7002775c-c3d8-4a5b-af42-8a4a295fd926)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cee03ed3-2d1d-4288-abc3-805a19e152ab)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9c6c502d-1bed-42ec-9430-6d1e47d60582)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 08d80ac9-7188-402c-8205-e83f281cbc63)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9f6301b5-1aea-4d17-ba7c-3a4cd75f8c16)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5b5176ba-399d-4127-a636-231ab13f9d83)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 344776ac-5723-4dab-8be1-b7875a2afcae)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9fa5a4c2-9c59-4b98-96f5-204081c4d0ee)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 848748f5-8f74-4c49-95f7-713728afe545)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c9556c13-4c59-400b-88d3-1e240248bec1)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a3d94049-1660-407b-831c-f8f8de2dc50f)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f9a02d98-fc78-43a9-9bdd-7077eb9d2e67)) + (fp_text reference "R4" (at 5.08 -2) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 37fb503a-080f-462a-9b22-f394e88f0df4) + ) + (fp_text value "4.7k" (at 5.08 2.37) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp d7858332-0a89-43bd-843c-c4019c2ef22e) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp bedfe455-bd6f-46c0-9300-8842f1cb3ffd) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 01e02490-7388-4d67-975e-899e21b38702)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 08b523e2-c93b-49b7-b009-22ae5f12b25e)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a0832920-26df-44d4-ab46-c094438af8f9)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 85f5c5f8-5424-4ee3-98d0-83c2472d10fb)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0555e233-54a8-4542-a84f-1b642bab3557)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f25e5076-aee2-4b32-a531-fa5c611d02e9)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5c684b52-6187-401f-a1ca-bae88832c7c6)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 11258aa9-841f-415b-8190-ee003a6d5c3a)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 176a5eac-bccd-4785-9223-164eadc9abbe)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 089bbf21-c349-4415-a9c2-87bee252dd3b)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f218a2a2-5403-444d-90fd-8bb21efc0b7f)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 560d47ea-221e-4fa7-acfc-e132fac5f0ba)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 1d724313-af71-4eea-81b3-cbce565a2c8a)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ee0045f3-8ff0-4f53-9e3b-2990a066c97f)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e8ec7e56-85b1-4ad2-a4c8-17a130210003)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ce7ca2e2-da3d-41df-b0a0-d25f7350d386)) (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp 37055987-d40a-46ea-9358-a8f7c75accc4)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pintype "passive") (tstamp 47594406-e1a4-43d8-8805-5d6aa41b3f32)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (net 1 "Net-(C1-Pad1)") (pintype "passive") (tstamp d94bd03d-a033-4d12-98a3-695286a85a34)) + (pad "2" thru_hole oval (at 10.16 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pintype "passive") (tstamp 075bd117-6a16-454e-8d6c-359b01d22aaa)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) @@ -1541,7 +1532,7 @@ (footprint "Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical" (layer "F.Cu") (tstamp 9b22d2a4-0ccb-47ea-90ce-737c81524990) - (at 40.64 86.36) + (at 84 90.46) (descr "Through hole straight pin header, 1x03, 2.54mm pitch, single row") (tags "Through hole pin header THT 1x03 2.54mm single row") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -1555,7 +1546,7 @@ (effects (font (size 1 1) (thickness 0.15))) (tstamp a071f763-581e-4a5e-b29c-e9f54513cd45) ) - (fp_text value "Conn_01x03_Pin" (at 0 7.41) (layer "F.Fab") + (fp_text value "Conn_01x03_Pin" (at 2 8.04) (layer "F.Fab") (effects (font (size 1 1) (thickness 0.15))) (tstamp 5dd83252-9051-4e64-96b4-503a15b3428b) ) @@ -1606,222 +1597,77 @@ ) ) - (footprint "Connector_PinSocket_2.54mm:PinSocket_2x20_P2.54mm_Vertical" (layer "F.Cu") - (tstamp a553f4af-6beb-47ca-9bdf-3fe6bb347d97) - (at 132.08 48.26) - (descr "Through hole straight socket strip, 2x20, 2.54mm pitch, double cols (from Kicad 4.0.7), script generated") - (tags "Through hole socket strip THT 2x20 2.54mm double row") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") + (tstamp ca807d53-c77b-4bee-93c1-b656c3ae712c) + (at 114.5 74.16 90) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") - (property "Sim.Enable" "0") - (property "ki_description" "expansion header for Raspberry Pi 2 & 3") - (property "ki_keywords" "raspberrypi gpio") - (path "/58887779-90ab-4780-98be-8f57c4f8f78b") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/c3004251-8088-4827-aa14-0a4ce9cc2dcb") (attr through_hole) - (fp_text reference "J1" (at -1.27 -2.77) (layer "F.SilkS") + (fp_text reference "R1" (at 3 -2 90) (layer "F.SilkS") (effects (font (size 1 1) (thickness 0.15))) - (tstamp b3f29cb6-f9aa-44cf-9081-ffcbfb4f1649) + (tstamp d2f0c015-24aa-438a-9541-9cc61ef62126) ) - (fp_text value "Raspberry_Pi_2_3" (at -1.27 51.03) (layer "F.Fab") + (fp_text value "22k" (at 5.08 2.37 90) (layer "F.Fab") (effects (font (size 1 1) (thickness 0.15))) - (tstamp 394f24f1-348c-4c70-bdb8-13e586c9ac2c) + (tstamp a129d50f-f57a-4002-963c-256e93292c48) ) - (fp_text user "${REFERENCE}" (at -1.27 24.13 90) (layer "F.Fab") + (fp_text user "${REFERENCE}" (at 5.08 0 90) (layer "F.Fab") (effects (font (size 1 1) (thickness 0.15))) - (tstamp d9e5c979-0325-493f-be21-970ea4bbb3d3) + (tstamp f251dce7-d4af-4a97-9ae8-335df770d910) ) - (fp_line (start -3.87 -1.33) (end -3.87 49.59) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 56cffd37-418e-46ac-9c64-84b2a9514e88)) - (fp_line (start -3.87 -1.33) (end -1.27 -1.33) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4b871eca-318e-4884-b570-61a572b64fb5)) - (fp_line (start -3.87 49.59) (end 1.33 49.59) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp af2c957b-2870-4563-a15e-2556cb962ad6)) - (fp_line (start -1.27 -1.33) (end -1.27 1.27) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d28919b0-0eae-4809-8f8a-b4941c037682)) - (fp_line (start -1.27 1.27) (end 1.33 1.27) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 05e34ae7-f1c0-4266-b9d3-0154effc34d6)) - (fp_line (start 0 -1.33) (end 1.33 -1.33) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f0d18060-ef52-437a-9710-e1a8426e9c4f)) - (fp_line (start 1.33 -1.33) (end 1.33 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 81c2ef95-b8b4-4960-a45c-fef4a1644163)) - (fp_line (start 1.33 1.27) (end 1.33 49.59) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp a3c00a0a-fbac-4131-ba74-405282c73d3c)) - (fp_line (start -4.34 -1.8) (end 1.76 -1.8) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e7312949-3522-466c-af68-79a4570c97bd)) - (fp_line (start -4.34 50) (end -4.34 -1.8) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp f6b05721-9d46-48ea-bf32-b049b07ee567)) - (fp_line (start 1.76 -1.8) (end 1.76 50) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6735c9f7-c892-4b6f-beaa-9c0b0f726e13)) - (fp_line (start 1.76 50) (end -4.34 50) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 8ccd6010-dc35-4777-9bd2-c04fa8cd87e2)) - (fp_line (start -3.81 -1.27) (end 0.27 -1.27) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 0a203383-1015-4339-93d2-9d9cb55c34e0)) - (fp_line (start -3.81 49.53) (end -3.81 -1.27) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c540b7a3-bc12-47a5-8dbf-f964d52a6420)) - (fp_line (start 0.27 -1.27) (end 1.27 -0.27) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e2a144ec-1dd6-4308-b1bc-e10fc86d59b5)) - (fp_line (start 1.27 -0.27) (end 1.27 49.53) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6ea42a77-cf85-47a6-96bd-f7d5c7a95e31)) - (fp_line (start 1.27 49.53) (end -3.81 49.53) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp bf8f2e0e-bdf1-435f-844a-60daf93737b8)) - (pad "1" thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 5 "VCC_3.3") (pinfunction "3V3") (pintype "power_in") (tstamp 58528890-541e-41c9-8553-ae0cee08e757)) - (pad "2" thru_hole oval (at -2.54 0) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 6 "VCC_5.0") (pinfunction "5V") (pintype "power_in") (tstamp 63fb603f-9f15-4680-964a-c1be50853204)) - (pad "3" thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 7 "unconnected-(J1-SDA{slash}GPIO2-Pad3)") (pinfunction "SDA/GPIO2") (pintype "bidirectional") (tstamp eab7008b-a1ff-47fe-950e-a4ff68d84b15)) - (pad "4" thru_hole oval (at -2.54 2.54) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 6 "VCC_5.0") (pinfunction "5V") (pintype "power_in") (tstamp 8976e579-c955-4688-817f-d3551b43996f)) - (pad "5" thru_hole oval (at 0 5.08) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 8 "unconnected-(J1-SCL{slash}GPIO3-Pad5)") (pinfunction "SCL/GPIO3") (pintype "bidirectional") (tstamp 62a149fc-80af-4fdd-a913-2bff78125909)) - (pad "6" thru_hole oval (at -2.54 5.08) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 01717d6d-6600-4cb3-8880-34ec125e8282)) - (pad "7" thru_hole oval (at 0 7.62) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 10 "unconnected-(J1-GCLK0{slash}GPIO4-Pad7)") (pinfunction "GCLK0/GPIO4") (pintype "bidirectional") (tstamp f11e0c36-845c-41bf-a710-ed95038758f1)) - (pad "8" thru_hole oval (at -2.54 7.62) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 11 "TXD") (pinfunction "GPIO14/TXD") (pintype "bidirectional") (tstamp fc31b1c5-4f3d-4ac7-a873-9fe5549d93b7)) - (pad "9" thru_hole oval (at 0 10.16) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp a982eb2e-9f2e-4815-9fb7-ea96cb3bf5fa)) - (pad "10" thru_hole oval (at -2.54 10.16) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 12 "Net-(J1-GPIO15{slash}RXD)") (pinfunction "GPIO15/RXD") (pintype "bidirectional") (tstamp b9b673ce-eeb3-4439-bd48-4db687e008c1)) - (pad "11" thru_hole oval (at 0 12.7) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 13 "unconnected-(J1-GPIO17-Pad11)") (pinfunction "GPIO17") (pintype "bidirectional") (tstamp 165ad222-842e-4a6e-86cc-91a0e51aaffa)) - (pad "12" thru_hole oval (at -2.54 12.7) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 14 "unconnected-(J1-GPIO18{slash}PWM0-Pad12)") (pinfunction "GPIO18/PWM0") (pintype "bidirectional") (tstamp 209fc722-fc6c-44c5-8161-5af70e08f5a9)) - (pad "13" thru_hole oval (at 0 15.24) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 15 "unconnected-(J1-GPIO27-Pad13)") (pinfunction "GPIO27") (pintype "bidirectional") (tstamp 23d032d4-dd1d-43f4-8d13-a79ba85ab3e6)) - (pad "14" thru_hole oval (at -2.54 15.24) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 43c6842c-1f58-4b5a-aa64-cc798e2a154e)) - (pad "15" thru_hole oval (at 0 17.78) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 16 "unconnected-(J1-GPIO22-Pad15)") (pinfunction "GPIO22") (pintype "bidirectional") (tstamp 38309d6e-81d3-4f76-a240-a11188452ec8)) - (pad "16" thru_hole oval (at -2.54 17.78) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 17 "unconnected-(J1-GPIO23-Pad16)") (pinfunction "GPIO23") (pintype "bidirectional") (tstamp 03e4b113-1537-43fa-92a9-d2a8443b2b9f)) - (pad "17" thru_hole oval (at 0 20.32) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 5 "VCC_3.3") (pinfunction "3V3") (pintype "power_in") (tstamp 654f9ba5-310c-4d5a-af0b-ff5b85712b4d)) - (pad "18" thru_hole oval (at -2.54 20.32) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 18 "unconnected-(J1-GPIO24-Pad18)") (pinfunction "GPIO24") (pintype "bidirectional") (tstamp 86de948e-c5a2-4181-bdc8-05eb36367ff1)) - (pad "19" thru_hole oval (at 0 22.86) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 19 "unconnected-(J1-MOSI0{slash}GPIO10-Pad19)") (pinfunction "MOSI0/GPIO10") (pintype "bidirectional") (tstamp f6edaa64-a918-4f88-9892-6c995e9575f6)) - (pad "20" thru_hole oval (at -2.54 22.86) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 304e0b03-1cea-4d23-91a2-dc41d5ce210d)) - (pad "21" thru_hole oval (at 0 25.4) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 20 "unconnected-(J1-MISO0{slash}GPIO9-Pad21)") (pinfunction "MISO0/GPIO9") (pintype "bidirectional") (tstamp bfdca412-cdb9-48d0-92c5-752a4e949881)) - (pad "22" thru_hole oval (at -2.54 25.4) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 21 "unconnected-(J1-GPIO25-Pad22)") (pinfunction "GPIO25") (pintype "bidirectional") (tstamp 88589300-4c66-4f03-a5a1-6037ab7b21b6)) - (pad "23" thru_hole oval (at 0 27.94) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 22 "unconnected-(J1-SCLK0{slash}GPIO11-Pad23)") (pinfunction "SCLK0/GPIO11") (pintype "bidirectional") (tstamp c3d969d8-71fc-450e-bc8a-582f626baa6e)) - (pad "24" thru_hole oval (at -2.54 27.94) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 23 "unconnected-(J1-~{CE0}{slash}GPIO8-Pad24)") (pinfunction "~{CE0}/GPIO8") (pintype "bidirectional") (tstamp d14770f5-5058-4cb1-b720-1e6921d45332)) - (pad "25" thru_hole oval (at 0 30.48) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp fd272450-5023-45eb-b42b-9ce919739f26)) - (pad "26" thru_hole oval (at -2.54 30.48) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 24 "unconnected-(J1-~{CE1}{slash}GPIO7-Pad26)") (pinfunction "~{CE1}/GPIO7") (pintype "bidirectional") (tstamp 0eb56d41-2792-4c4e-82e3-fbbd68e1a0f2)) - (pad "27" thru_hole oval (at 0 33.02) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 25 "unconnected-(J1-ID_SD{slash}GPIO0-Pad27)") (pinfunction "ID_SD/GPIO0") (pintype "bidirectional") (tstamp c880e36d-41c2-4d06-af9d-2c7617a23133)) - (pad "28" thru_hole oval (at -2.54 33.02) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 26 "unconnected-(J1-ID_SC{slash}GPIO1-Pad28)") (pinfunction "ID_SC/GPIO1") (pintype "bidirectional") (tstamp ec5bd783-4334-460e-9233-0365f9ba4fa1)) - (pad "29" thru_hole oval (at 0 35.56) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 27 "unconnected-(J1-GCLK1{slash}GPIO5-Pad29)") (pinfunction "GCLK1/GPIO5") (pintype "bidirectional") (tstamp 53924c23-bf68-4cdb-af7e-3a7fc9cb34eb)) - (pad "30" thru_hole oval (at -2.54 35.56) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 41884a76-5a3d-4fec-97a3-f190dcb4359e)) - (pad "31" thru_hole oval (at 0 38.1) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 28 "unconnected-(J1-GCLK2{slash}GPIO6-Pad31)") (pinfunction "GCLK2/GPIO6") (pintype "bidirectional") (tstamp 5eb72e8e-9771-44a8-8bcc-b1a2670eb45b)) - (pad "32" thru_hole oval (at -2.54 38.1) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 29 "unconnected-(J1-PWM0{slash}GPIO12-Pad32)") (pinfunction "PWM0/GPIO12") (pintype "bidirectional") (tstamp f79ea345-cd02-4c42-b9ef-5e7c3ab6c734)) - (pad "33" thru_hole oval (at 0 40.64) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 30 "unconnected-(J1-PWM1{slash}GPIO13-Pad33)") (pinfunction "PWM1/GPIO13") (pintype "bidirectional") (tstamp ea4a1737-689c-42a6-8e2b-e05ba367f7f7)) - (pad "34" thru_hole oval (at -2.54 40.64) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp de446f11-bb46-40f4-b427-395e6936a157)) - (pad "35" thru_hole oval (at 0 43.18) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 31 "unconnected-(J1-GPIO19{slash}MISO1-Pad35)") (pinfunction "GPIO19/MISO1") (pintype "bidirectional") (tstamp bb0994d1-ce01-4d1b-a264-ae95e1726897)) - (pad "36" thru_hole oval (at -2.54 43.18) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 32 "unconnected-(J1-GPIO16-Pad36)") (pinfunction "GPIO16") (pintype "bidirectional") (tstamp 8fe78bff-e254-43d6-8919-7cdd28f5a1cd)) - (pad "37" thru_hole oval (at 0 45.72) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 33 "unconnected-(J1-GPIO26-Pad37)") (pinfunction "GPIO26") (pintype "bidirectional") (tstamp c4d72f46-e7e2-4e06-b30b-02c2ac3ed1a5)) - (pad "38" thru_hole oval (at -2.54 45.72) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 34 "unconnected-(J1-GPIO20{slash}MOSI1-Pad38)") (pinfunction "GPIO20/MOSI1") (pintype "bidirectional") (tstamp d9eb791d-5cde-4463-8dbb-c3f781f8687a)) - (pad "39" thru_hole oval (at 0 48.26) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 73b4246b-e0cc-4a08-a483-a5aba9f67139)) - (pad "40" thru_hole oval (at -2.54 48.26) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 35 "unconnected-(J1-GPIO21{slash}SCLK1-Pad40)") (pinfunction "GPIO21/SCLK1") (pintype "bidirectional") (tstamp d87de98a-8bcc-436b-8855-5fd9f42741e2)) - (model "${KICAD6_3DMODEL_DIR}/Connector_PinSocket_2.54mm.3dshapes/PinSocket_2x20_P2.54mm_Vertical.wrl" - (offset (xyz 0 0 0)) - (scale (xyz 1 1 1)) - (rotate (xyz 0 0 0)) - ) - ) - - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") - (tstamp ca807d53-c77b-4bee-93c1-b656c3ae712c) - (at 53.40556 49.3) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") - (property "Sheetfile" "SeaTalk1.kicad_sch") - (property "Sheetname" "") - (property "ki_description" "Resistor") - (property "ki_keywords" "R res resistor") - (path "/c3004251-8088-4827-aa14-0a4ce9cc2dcb") - (attr through_hole) - (fp_text reference "R1" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp fc678ea0-d98c-4352-a536-e0794ebceac1) - ) - (fp_text value "22k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp ccab0da9-6335-410d-9e6f-f448422a8eb8) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 5eb629ee-3e89-4b8a-b6c6-624a0d80ffca) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 300ecc94-3356-4b45-ac27-5d31acb45f2a)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 00399e6d-33ea-4005-9d56-9043352c9050)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d3d9d769-d24d-4a12-a31a-41d732976b47)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e1edf9a4-8588-45e6-8c8b-d2555ad51153)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e53cb279-6713-46d1-8c2d-a1a0372e1cf6)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 48628e68-cdc0-4555-a683-19a83c64e7d9)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp a5a84ca2-a104-4780-93c1-13ea5b7843e9)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 4d6633d4-85bc-4fe4-b142-6f3e24b1f24e)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1b6b945d-997b-4907-bb7e-178ae61d3c39)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d554f960-7418-402f-ac91-646c59822896)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4c2189af-4c52-4977-9357-79ef724beee4)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b453df1f-ee07-444a-8a44-618a66e573ec)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 94804a66-7975-4a04-b907-448fe742e21a)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ebf414ce-170a-4ad7-a32e-4a2db6678747)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4782de7d-26de-415d-9ae6-5b0c65ca7171)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d0e0bb1e-2048-4fe5-9f69-5ba72ba9a5dd)) - (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 5 "VCC_3.3") (pintype "passive") (tstamp 7f3e972e-45ed-4db9-bdc6-7c004dbe76c3)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 40 "Net-(Q4-B)") (pintype "passive") (tstamp 9ec23129-cff3-4cc1-945c-442628324a89)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 17689c9a-9787-4abb-8312-a43c8b895918)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 841a3b36-59b2-49b3-9286-1839d4e42b90)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4aed7759-2b42-42ac-b8f8-14afbccaee53)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 60d997b2-12e1-4497-a592-79958ce07ac8)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c2f22d5e-8fee-473c-ac04-31823111c414)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8a8181b0-54fc-48eb-9bfa-2e2584ba7654)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 19ce634a-a228-40fd-ad39-369f1bb53f04)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ec1fedd7-5df3-4ac5-8dab-4d3a63e0010e)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 38f0e664-91bf-4fc7-bd1a-bbf057d11656)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 64f3e11d-5464-4204-8da5-58525b1c95c5)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 07806d8f-f312-4b54-ab38-c722c47398b0)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 00c984c0-5619-42aa-84c2-c3ad0136745c)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 678a38f4-95c4-40cc-8116-656bc2867d59)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ed294fe9-76d2-47ae-89a7-3687c84d9183)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7ed972ca-f723-4f93-bfbf-4224d5cf6d66)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c1d30e4c-ccd9-4bcd-9ab1-31bd6437f6a5)) + (pad "1" thru_hole circle (at 0 0 90) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pintype "passive") (tstamp aae05436-5a92-4ac5-81d6-35647d420303)) + (pad "2" thru_hole oval (at 10.16 0 90) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 40 "Net-(Q4-B)") (pintype "passive") (tstamp 54377306-d198-440c-a267-ffb6da1890ec)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp cbf39d8b-e581-487f-bb9f-5f9238d3e735) - (at 53.40556 68.3) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 98.08 55 180) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "Sim.Device" "R") @@ -1830,55 +1676,55 @@ (property "ki_keywords" "R res resistor") (path "/e7236bba-1884-40d5-b2d5-3b06582681db") (attr through_hole) - (fp_text reference "R5" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 46d1395c-5cd9-45e1-849d-6ff493bfc6e3) - ) - (fp_text value "4.7k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 15025776-2043-41d1-ba35-4c77df366fbe) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 86ae7193-fba1-4ef6-a01f-10c851c12db4) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0df10c54-95e9-4c87-84e3-7f547c96e29f)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f4fb4053-7669-43a8-b189-0a408226e61c)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5fa2eb73-c657-4a7f-a9c4-2da3024ac6f2)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7566461e-49c6-4ade-b3af-b740359021ec)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ee254e84-6f36-4a81-924f-7151bc9dfe72)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8dadabfe-a9c8-457a-8267-2e2285180914)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1d98e90b-18c6-41bf-9928-669811683b88)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d3a5ca73-3671-447c-a29a-7dcfb7e100c5)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ead40d08-9030-47db-a10a-dc22d9f8ae23)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5488e1f4-1d2b-4b42-82f1-e3d800b60542)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ed73877c-1fde-48e3-a2f4-721f2d9fe3d9)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4b07e009-4af4-435e-af27-bcf0cd6f50d0)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 1553dbe2-9633-4e5a-8ee0-f6b9fc20b50e)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 31b5bd6f-4b70-4c99-b7be-0871e6c7454f)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b9f24fb1-6052-4423-8950-3d83da0af056)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 02f7bbe1-9a75-4ba8-af46-a0fdac0fbab5)) - (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 36 "SEATALK") (pintype "passive") (tstamp 2c8fa526-ed21-4f0b-9a10-d0d825bb3b35)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 39 "Net-(Q1-B)") (pintype "passive") (tstamp 39bb5522-a599-4339-91a4-2577e84e986a)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (fp_text reference "R5" (at 5.08 -2.37) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp e58af2fa-639d-477d-ab8d-6ca61ec63873) + ) + (fp_text value "4.7k" (at 2.08 -2.5) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 7de15450-5c23-4c36-b039-b102b71bc0fc) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 9f949ff3-b6b7-44fe-a379-755b38e97ef9) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e4b6dd23-fa53-4b1e-ba32-6d74bb36da13)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7e590205-ff8a-4a42-aacb-dc118e8cf381)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b22d6a2c-255f-4d6d-8009-c27fd3458084)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp efe33c1d-1076-46db-9bd9-2301f0d31cfd)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1d9e83de-cd31-427a-ade3-6fb6b2deab8b)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp af2bfda5-69e3-49d0-9b29-5aab45f26f62)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 896ee8c3-d9d0-4489-bade-5b21131a6df1)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 42f215b6-5ed0-4450-94ca-095e523caf0b)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp aec1e736-bd69-4f28-aa51-df10d996dcc9)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c130b929-0faf-4200-9693-c6f6cbc6609e)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4f0af603-2261-42b5-9fa2-f1dc33db9ce5)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2963daf5-25bf-4642-bce5-ccce45f2221c)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d53ae629-db2a-428a-b58e-634cadb6448c)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 59446e49-4352-4d70-bf15-f6ac86165a67)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b184d40c-1e8a-4c38-a7a0-552f75f6e5c3)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 70f899cf-b17c-410e-9ab1-7def94bba7e4)) + (pad "1" thru_hole circle (at 0 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 36 "SEATALK") (pintype "passive") (tstamp 81c93291-cb6c-4014-bcc2-1bc2bf37137e)) + (pad "2" thru_hole oval (at 10.16 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 39 "Net-(Q1-B)") (pintype "passive") (tstamp 0001be7b-18ae-4367-a0ce-059e0485753f)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) @@ -1887,7 +1733,7 @@ (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") (tstamp d007f101-54a3-4c77-9bd7-a73cba8eb752) - (at 79.35556 79.13) + (at 118 68.36) (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -1948,7 +1794,7 @@ (footprint "Package_TO_SOT_THT:TO-92_Inline" (layer "F.Cu") (tstamp d1a4dee9-ad85-4d4b-bbe4-eac7c97c848b) - (at 79.35556 61.76) + (at 117.73 89.36) (descr "TO-92 leads in-line, narrow, oval pads, drill 0.75mm (see NXP sot054_po.pdf)") (tags "to-92 sc-43 sc-43a sot54 PA33 transistor") (property "Sheetfile" "SeaTalk1.kicad_sch") @@ -2008,11 +1854,11 @@ ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp dd9aba0a-3b67-450c-a7dc-b8136fb819d7) - (at 53.40556 54.05) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 98 51 180) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "Sim.Device" "R") @@ -2021,66 +1867,66 @@ (property "ki_keywords" "R res resistor") (path "/efcaf01a-542f-4f53-800a-efe3e3979d0e") (attr through_hole) - (fp_text reference "R2" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 101511fc-c112-4948-9d60-0b9211d18b99) - ) - (fp_text value "2.2k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp bcb5fde9-1877-46d5-99f4-b5ae9933fc0f) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 71ae167c-3184-4fd3-b2a0-9e3ae59e0dc2) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c1da7786-3511-467b-ba28-c6519535a520)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3a6ad5a2-c3d1-4d6e-8384-f6c7106bfdb3)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 08cf0112-48d0-46f2-9085-16d371f09e40)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6f5a3b91-bdc1-4361-8b96-7aa892f02a11)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 54704d09-332b-4496-ad0f-82bd6c01e307)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3016c42a-ab07-4ae3-a2eb-db67e167646d)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0e4cd44e-52a8-4c3a-91d0-503b42a7facc)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 08a96870-cf19-42c5-9b90-f53b1be5bf1a)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6661157b-8b81-4502-98b7-bb6f69dfe785)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3839b2ba-20b5-45ff-8dc6-cfacbd733524)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 630e4777-3097-43f7-a06b-8850fde11b6e)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 06ff254e-4ec0-4c16-bfb4-992c5f6824c2)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 85af1396-db6b-483f-8cb8-9706d8ec6e4f)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3a46dc99-4eed-4a66-84e5-6b65b0e0a238)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp d7427ef3-29c0-4277-a307-638a83b6ff8e)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 33ec326c-b7df-4a88-849a-7c182fee6137)) - (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 6 "VCC_5.0") (pintype "passive") (tstamp 0b5e7101-41db-48dd-b633-dc4274764213)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 39 "Net-(Q1-B)") (pintype "passive") (tstamp c2455b2c-b88d-4092-8b6a-7980f1d69c7a)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (fp_text reference "R2" (at 5 2) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp d72b0214-4aad-4e72-a81b-b9a3de380ff5) + ) + (fp_text value "2.2k" (at 2 2) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp cad4da24-0a5f-4bb7-9f64-fc9b37045294) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 9d3c7c9f-44c1-4dc0-9d2e-790944136204) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d1e84b1c-5e68-4e83-831f-7d27a516cfbf)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp c3f554ed-c65b-42aa-9a03-22d2d0468061)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 35c02950-e87b-4b07-b4fe-75f736fce361)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8e4318fc-55d3-41c0-a916-c0ef0badc9db)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 76cb7daf-4a38-41cb-9dd7-6794788db8a1)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 38650a1f-dc94-4217-846b-9939037fc45b)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 78265606-1e82-42c6-b341-ff5a1c9a4ce4)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp de625a4f-6be8-4055-8dc6-7fced765d719)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp bc18d339-84d3-4e72-85f5-83fa5519f68e)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 47f86db8-3099-4ce9-a450-af33a514d2fd)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 660f5c02-25a7-4192-babb-a177225229d6)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2af31c30-b0e6-4b29-9053-5f78b0bd5408)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7152c385-5534-4e4b-946e-42bfeae5bd23)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ca30de16-9515-447d-b8dd-59fc8b039eba)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6b88b136-479d-4a4c-9412-bb5f9bca0c9f)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 8b5dd965-7956-4e35-81fa-c3edb88367d4)) + (pad "1" thru_hole circle (at 0 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 6 "VCC_5.0") (pintype "passive") (tstamp 0cabe27b-b3ec-45c4-9037-78d2fed33197)) + (pad "2" thru_hole oval (at 10.16 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 39 "Net-(Q1-B)") (pintype "passive") (tstamp 8432737e-8005-434c-8366-107a432f3b9e)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp debd4bf9-e187-48f4-b5b8-54f821e675b7) - (at 53.40556 87.3) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 102.92 99) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "Sim.Device" "R") @@ -2091,125 +1937,3655 @@ (property "ki_keywords" "R res resistor") (path "/72ecdcab-4412-431f-ae1a-4d8a433bda34") (attr through_hole) - (fp_text reference "R9" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 0b1bd8d1-a6a5-42a0-a54e-646497c8b89f) - ) - (fp_text value "100" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 21ce75d5-d431-4ecf-bd69-2af686a8b3c9) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp a07e3c44-b8c8-467e-afe1-ba2c197ecef5) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f4bc0a18-84bd-46fc-a499-c9bd944f1be9)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 400e2761-28af-4127-8df6-9443f40e3960)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1c6784e8-9c16-460c-b054-de32ae214032)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b07140a2-dc09-42a7-b87d-5c9f62163970)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7b4d96b9-5aee-4f74-9745-9cb80a7d5262)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 65279eec-5a57-4fa3-945e-c67790394350)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp bb0d9ccb-cd5a-4cbc-908e-76b27e1a95a4)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3d4f19d6-e6cb-4b96-8d58-10005d7164cb)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d75777ff-4abc-41e3-811a-02336fe9a4a6)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 64236c44-81e7-4eb3-876a-f64213221749)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 86e9dd7a-4b12-4104-936b-d0020d8040cd)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a1829c01-1947-4d4f-9d80-9db2cf2f5170)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ebedec27-5966-4f92-ab2f-3aa5e83e23ea)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3e00c740-5a26-432e-b0e7-b4b4852f7b3c)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ada0a556-e8c8-43da-afc9-4219f5440d70)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b5f83c8c-604a-4278-8fd1-8bcd827b9031)) + (fp_text reference "R9" (at 5.08 -2.37) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 1adabb0b-2f3b-4e44-a211-439fe984c34c) + ) + (fp_text value "100" (at 5.08 2.37) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 6f4d2614-be84-491c-bab5-2d4f6a044f06) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 6eeaf29c-ffb0-4ce6-8578-3fb206625640) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 04052e68-808b-4b0e-8bd4-278782906382)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7757df2c-386b-42c2-96da-7bd64007fcae)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 55efcd37-6330-46f5-8e2e-51159ca94120)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp dbd18270-a9d9-4b04-b0c3-9cc94baa075d)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f78df423-7713-4c0b-b799-71f8988c0a6e)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 32e49050-5eaa-4cf2-91a1-7eb8474d38b2)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3b801b06-a4ad-4cb8-8aa5-f9c5b10ad98a)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 985b7bd0-5feb-4b79-b18e-18e57d3e996e)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e70eedb8-6c79-426d-8142-c7b85c1e8e1b)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e6cae90a-9a4a-4ee1-8a0f-55652d53c694)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 61042d46-1928-4348-9503-e08ee3e5695c)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 63243ee3-b640-4eec-8288-aa7ff9fe8eb2)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp da5397b2-c999-48b1-b0ab-4d9f0f834557)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6ee6c2a2-5ca8-48c2-9e89-91cd15ea9e04)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp dc3e0402-6f45-419e-8214-69f657768375)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9f04a8db-01c1-48d5-91f1-e5c12b5b63ae)) (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 5 "VCC_3.3") (pintype "passive") (tstamp 58090f3f-0b4e-443d-af49-5ab3873e9731)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 4 "Net-(D1-A)") (pintype "passive") (tstamp c81ec474-7e40-4e38-9ece-a20d074a96d7)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (net 5 "VCC_3.3") (pintype "passive") (tstamp 4594b6e2-6d08-4072-b84a-254175f3a113)) + (pad "2" thru_hole oval (at 10.16 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 4 "Net-(D1-A)") (pintype "passive") (tstamp d3a1db46-f007-4acb-93b3-a53b2620b384)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) ) ) - (footprint "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (layer "F.Cu") + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") (tstamp e5a0b09f-5f1d-4dd5-97f0-ffb7f4370ea6) - (at 53.40556 92.05) - (descr "Resistor, Axial_DIN0309 series, Axial, Horizontal, pin pitch=15.24mm, 0.5W = 1/2W, length*diameter=9*3.2mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") - (tags "Resistor Axial_DIN0309 series Axial Horizontal pin pitch 15.24mm 0.5W = 1/2W length 9mm diameter 3.2mm") + (at 93.42 81.5) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") (property "Sheetfile" "SeaTalk1.kicad_sch") (property "Sheetname" "") (property "ki_description" "Resistor") (property "ki_keywords" "R res resistor") (path "/579a3129-1551-4263-8c06-93d703fd61dd") (attr through_hole) - (fp_text reference "R10" (at 7.62 -2.72) (layer "F.SilkS") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp 3f57e4b2-f8c6-49f6-a7f8-dbb4c017903a) - ) - (fp_text value "1.5k" (at 7.62 2.72) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp e7df3833-85ef-4683-9d5a-99133839ecec) - ) - (fp_text user "${REFERENCE}" (at 7.62 0) (layer "F.Fab") - (effects (font (size 1 1) (thickness 0.15))) - (tstamp f5e0769f-cf38-4893-9b50-64776b0970d1) - ) - (fp_line (start 1.04 0) (end 3 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0e28f790-65bf-47d7-9172-498dbb2cd6a0)) - (fp_line (start 3 -1.72) (end 3 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp cd6bc028-ab80-433b-ba4f-a6fb0f30026c)) - (fp_line (start 3 1.72) (end 12.24 1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 94924f74-db96-4a8d-b653-9d696c36ef71)) - (fp_line (start 12.24 -1.72) (end 3 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 414b4888-7032-4395-92d3-b6dcd89d338f)) - (fp_line (start 12.24 1.72) (end 12.24 -1.72) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 34503894-dcf0-4ce1-b19c-81b88fc3fdc0)) - (fp_line (start 14.2 0) (end 12.24 0) - (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e351b20a-b10a-4509-9ff3-991ec6d8e768)) - (fp_line (start -1.05 -1.85) (end -1.05 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp f6c49d66-cd58-4b69-bef2-3357beb0dbcb)) - (fp_line (start -1.05 1.85) (end 16.29 1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 4593944e-b1d6-4dfd-9759-348af6caef0e)) - (fp_line (start 16.29 -1.85) (end -1.05 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp f2e115a6-dd3f-4c14-97c9-b9e7f2f881e0)) - (fp_line (start 16.29 1.85) (end 16.29 -1.85) - (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ed1d84ed-18a4-4c3f-a418-f0a949b708da)) - (fp_line (start 0 0) (end 3.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f50195b8-d8ed-42e1-bf3c-2e8a740b0722)) - (fp_line (start 3.12 -1.6) (end 3.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 71b97826-719d-448e-9c4c-787d2cc9b278)) - (fp_line (start 3.12 1.6) (end 12.12 1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7a32c62d-9fd0-45f3-aa71-881ad058d3ca)) - (fp_line (start 12.12 -1.6) (end 3.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp da41fc17-9399-4b52-8189-5c3d531fa355)) - (fp_line (start 12.12 1.6) (end 12.12 -1.6) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c1a06b82-c594-4699-a65f-cb2621b16159)) - (fp_line (start 15.24 0) (end 12.12 0) - (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 25165936-a942-4d25-8b5d-b34ffdc8cd1e)) + (fp_text reference "R10" (at 7.58 -2) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp c42c07ac-5c85-4daa-9d9d-a7d024817d5d) + ) + (fp_text value "1.5k" (at 5.08 2.37) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp b0677b47-47a4-4e1f-8e44-362da38f6c9e) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 1fbb7735-2f08-47c9-a35e-842978183958) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e1dc2511-0130-415c-a2a9-5122c7636424)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5bb189b6-5b7f-4733-8857-ceb9d5ae6041)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ea660d08-c466-4f39-ae9f-470853c8b1da)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp acd51042-f84f-4777-95ed-cf08e95daa07)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6f70a6c0-d26d-4dbf-affd-804bb4c867e4)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2520c0f1-ade0-4bfb-a435-32c31dae3b5f)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp f56e1675-50ba-48a8-ba84-97b760e876a2)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ed446b59-8a71-46c0-81ea-a1c991b3bd21)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 0f861356-1f5a-4801-9714-3b27d5c11792)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp cd93bac7-9b45-4ca1-8c1b-6073b4f7f7b6)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9b77d67e-1c42-4405-86b6-bc64d6927477)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 84bf1246-58af-411d-9deb-6fa2a1c47f11)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 79b3c894-83e5-4758-b4f6-66b7b65193f5)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 8684cb2c-5d8e-41fb-852b-665da25b12e7)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ff42be25-4dec-455e-aede-73bb030a8964)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f7a61194-bbda-470e-a973-831ca9c8452f)) (pad "1" thru_hole circle (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 11 "TXD") (pintype "passive") (tstamp acd688f8-8d5f-4bd5-9c4d-6b0fe653d0d5)) - (pad "2" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 42 "Net-(Q5-B)") (pintype "passive") (tstamp f81b0121-fe2b-4544-aadc-eb37401f332e)) - (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal.wrl" + (net 11 "TXD") (pintype "passive") (tstamp fb6cf04f-3b77-496c-b9f5-f42a4efb1189)) + (pad "2" thru_hole oval (at 10.16 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 42 "Net-(Q5-B)") (pintype "passive") (tstamp 293d8404-bb2c-4a79-a7cb-8680b72cc5e0)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (footprint "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (layer "F.Cu") + (tstamp e7703e6d-9a49-4d76-9f0b-65a55ef858aa) + (at 99 96 180) + (descr "Resistor, Axial_DIN0207 series, Axial, Horizontal, pin pitch=10.16mm, 0.25W = 1/4W, length*diameter=6.3*2.5mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf") + (tags "Resistor Axial_DIN0207 series Axial Horizontal pin pitch 10.16mm 0.25W = 1/4W length 6.3mm diameter 2.5mm") + (property "Remarks" "External pull-up from bus") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/71be8ad0-bfd2-4f59-afd6-b1bb5fcc5604") + (attr through_hole) + (fp_text reference "R12" (at 5.08 -2.37) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp f9ea6408-2cce-4ff2-9411-b63169638446) + ) + (fp_text value "10k" (at 5.08 2.37) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 014f932c-954f-4dac-a637-fdb2be919266) + ) + (fp_text user "${REFERENCE}" (at 5.08 0) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 7ff6333d-7837-4683-b9b9-36831c69bec2) + ) + (fp_line (start 1.04 0) (end 1.81 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 1affa843-829b-423e-95d9-25618d982d88)) + (fp_line (start 1.81 -1.37) (end 1.81 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d8bf1cf6-9361-48bc-bd0c-c972d2199006)) + (fp_line (start 1.81 1.37) (end 8.35 1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b80e9e2f-72be-4ee6-b523-641b000a997f)) + (fp_line (start 8.35 -1.37) (end 1.81 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp b7a7bd87-9853-4892-a032-efbb5d108b4d)) + (fp_line (start 8.35 1.37) (end 8.35 -1.37) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d69065e7-c866-4dae-9811-5ad0a278902b)) + (fp_line (start 9.12 0) (end 8.35 0) + (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 821a318d-50c5-41ca-b6ac-8fb327d69504)) + (fp_line (start -1.05 -1.5) (end -1.05 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6ec2a0d0-9097-4280-b5b1-961832eb4190)) + (fp_line (start -1.05 1.5) (end 11.21 1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3b6e4a2a-8ab0-42d0-bc26-1831bd9ef990)) + (fp_line (start 11.21 -1.5) (end -1.05 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 220559d4-b3d5-4dc9-9376-b1f8262337f9)) + (fp_line (start 11.21 1.5) (end 11.21 -1.5) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp b59ece0b-0ecd-4f0e-99ae-12a3c26f62fc)) + (fp_line (start 0 0) (end 1.93 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 6ed78fbe-bf71-4e3f-a39e-50399bc0d5ed)) + (fp_line (start 1.93 -1.25) (end 1.93 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 86b7abaf-922c-47b1-8d76-ee6b1a1eb326)) + (fp_line (start 1.93 1.25) (end 8.23 1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ef968bb6-d89a-45e6-8fa1-a988f47a66d2)) + (fp_line (start 8.23 -1.25) (end 1.93 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 86206d43-2f19-4330-8a69-1bd5174742a2)) + (fp_line (start 8.23 1.25) (end 8.23 -1.25) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e9a2518d-c96c-4b42-aa46-925156fa741f)) + (fp_line (start 10.16 0) (end 8.23 0) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp beadf34b-9923-4eb4-9d7a-425866995c3a)) + (pad "1" thru_hole circle (at 0 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 36 "SEATALK") (pintype "passive") (tstamp e5add682-4bcf-4215-a641-107af43037d0)) + (pad "2" thru_hole oval (at 10.16 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") + (net 37 "Net-(J3-Pin_3)") (pintype "passive") (tstamp 0b1ca68b-aa53-4a8c-8ac4-a295c8a00861)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) (rotate (xyz 0 0 0)) ) ) + (footprint "Connector_PinSocket_2.54mm:PinSocket_2x20_P2.54mm_Vertical" (layer "B.Cu") + (tstamp a553f4af-6beb-47ca-9bdf-3fe6bb347d97) + (at 130 48.5 180) + (descr "Through hole straight socket strip, 2x20, 2.54mm pitch, double cols (from Kicad 4.0.7), script generated") + (tags "Through hole socket strip THT 2x20 2.54mm double row") + (property "Sheetfile" "SeaTalk1.kicad_sch") + (property "Sheetname" "") + (property "Sim.Enable" "0") + (property "ki_description" "expansion header for Raspberry Pi 2 & 3") + (property "ki_keywords" "raspberrypi gpio") + (path "/58887779-90ab-4780-98be-8f57c4f8f78b") + (attr through_hole) + (fp_text reference "J1" (at -1.27 2.77) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp b3f29cb6-f9aa-44cf-9081-ffcbfb4f1649) + ) + (fp_text value "Raspberry_Pi_2_3" (at -1.27 -51.03) (layer "B.Fab") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 394f24f1-348c-4c70-bdb8-13e586c9ac2c) + ) + (fp_text user "${REFERENCE}" (at -1.27 -24.13 90) (layer "B.Fab") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp d9e5c979-0325-493f-be21-970ea4bbb3d3) + ) + (fp_line (start -3.87 -49.59) (end 1.33 -49.59) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp af2c957b-2870-4563-a15e-2556cb962ad6)) + (fp_line (start -3.87 1.33) (end -3.87 -49.59) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp 56cffd37-418e-46ac-9c64-84b2a9514e88)) + (fp_line (start -3.87 1.33) (end -1.27 1.33) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp 4b871eca-318e-4884-b570-61a572b64fb5)) + (fp_line (start -1.27 -1.27) (end 1.33 -1.27) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp 05e34ae7-f1c0-4266-b9d3-0154effc34d6)) + (fp_line (start -1.27 1.33) (end -1.27 -1.27) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp d28919b0-0eae-4809-8f8a-b4941c037682)) + (fp_line (start 0 1.33) (end 1.33 1.33) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp f0d18060-ef52-437a-9710-e1a8426e9c4f)) + (fp_line (start 1.33 -1.27) (end 1.33 -49.59) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp a3c00a0a-fbac-4131-ba74-405282c73d3c)) + (fp_line (start 1.33 1.33) (end 1.33 0) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp 81c2ef95-b8b4-4960-a45c-fef4a1644163)) + (fp_line (start -4.34 -50) (end -4.34 1.8) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp f6b05721-9d46-48ea-bf32-b049b07ee567)) + (fp_line (start -4.34 1.8) (end 1.76 1.8) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp e7312949-3522-466c-af68-79a4570c97bd)) + (fp_line (start 1.76 -50) (end -4.34 -50) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp 8ccd6010-dc35-4777-9bd2-c04fa8cd87e2)) + (fp_line (start 1.76 1.8) (end 1.76 -50) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp 6735c9f7-c892-4b6f-beaa-9c0b0f726e13)) + (fp_line (start -3.81 -49.53) (end -3.81 1.27) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp c540b7a3-bc12-47a5-8dbf-f964d52a6420)) + (fp_line (start -3.81 1.27) (end 0.27 1.27) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 0a203383-1015-4339-93d2-9d9cb55c34e0)) + (fp_line (start 0.27 1.27) (end 1.27 0.27) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp e2a144ec-1dd6-4308-b1bc-e10fc86d59b5)) + (fp_line (start 1.27 -49.53) (end -3.81 -49.53) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp bf8f2e0e-bdf1-435f-844a-60daf93737b8)) + (fp_line (start 1.27 0.27) (end 1.27 -49.53) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 6ea42a77-cf85-47a6-96bd-f7d5c7a95e31)) + (pad "1" thru_hole rect (at 0 0 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pinfunction "3V3") (pintype "power_in") (tstamp 58528890-541e-41c9-8553-ae0cee08e757)) + (pad "2" thru_hole oval (at -2.54 0 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 6 "VCC_5.0") (pinfunction "5V") (pintype "power_in") (tstamp 63fb603f-9f15-4680-964a-c1be50853204)) + (pad "3" thru_hole oval (at 0 -2.54 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 7 "unconnected-(J1-SDA{slash}GPIO2-Pad3)") (pinfunction "SDA/GPIO2") (pintype "bidirectional") (tstamp eab7008b-a1ff-47fe-950e-a4ff68d84b15)) + (pad "4" thru_hole oval (at -2.54 -2.54 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 6 "VCC_5.0") (pinfunction "5V") (pintype "power_in") (tstamp 8976e579-c955-4688-817f-d3551b43996f)) + (pad "5" thru_hole oval (at 0 -5.08 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 8 "unconnected-(J1-SCL{slash}GPIO3-Pad5)") (pinfunction "SCL/GPIO3") (pintype "bidirectional") (tstamp 62a149fc-80af-4fdd-a913-2bff78125909)) + (pad "6" thru_hole oval (at -2.54 -5.08 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 01717d6d-6600-4cb3-8880-34ec125e8282)) + (pad "7" thru_hole oval (at 0 -7.62 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 10 "unconnected-(J1-GCLK0{slash}GPIO4-Pad7)") (pinfunction "GCLK0/GPIO4") (pintype "bidirectional") (tstamp f11e0c36-845c-41bf-a710-ed95038758f1)) + (pad "8" thru_hole oval (at -2.54 -7.62 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 11 "TXD") (pinfunction "GPIO14/TXD") (pintype "bidirectional") (tstamp fc31b1c5-4f3d-4ac7-a873-9fe5549d93b7)) + (pad "9" thru_hole oval (at 0 -10.16 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp a982eb2e-9f2e-4815-9fb7-ea96cb3bf5fa)) + (pad "10" thru_hole oval (at -2.54 -10.16 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 12 "Net-(J1-GPIO15{slash}RXD)") (pinfunction "GPIO15/RXD") (pintype "bidirectional") (tstamp b9b673ce-eeb3-4439-bd48-4db687e008c1)) + (pad "11" thru_hole oval (at 0 -12.7 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 13 "unconnected-(J1-GPIO17-Pad11)") (pinfunction "GPIO17") (pintype "bidirectional") (tstamp 165ad222-842e-4a6e-86cc-91a0e51aaffa)) + (pad "12" thru_hole oval (at -2.54 -12.7 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 14 "unconnected-(J1-GPIO18{slash}PWM0-Pad12)") (pinfunction "GPIO18/PWM0") (pintype "bidirectional") (tstamp 209fc722-fc6c-44c5-8161-5af70e08f5a9)) + (pad "13" thru_hole oval (at 0 -15.24 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 15 "unconnected-(J1-GPIO27-Pad13)") (pinfunction "GPIO27") (pintype "bidirectional") (tstamp 23d032d4-dd1d-43f4-8d13-a79ba85ab3e6)) + (pad "14" thru_hole oval (at -2.54 -15.24 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 43c6842c-1f58-4b5a-aa64-cc798e2a154e)) + (pad "15" thru_hole oval (at 0 -17.78 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 16 "unconnected-(J1-GPIO22-Pad15)") (pinfunction "GPIO22") (pintype "bidirectional") (tstamp 38309d6e-81d3-4f76-a240-a11188452ec8)) + (pad "16" thru_hole oval (at -2.54 -17.78 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 17 "unconnected-(J1-GPIO23-Pad16)") (pinfunction "GPIO23") (pintype "bidirectional") (tstamp 03e4b113-1537-43fa-92a9-d2a8443b2b9f)) + (pad "17" thru_hole oval (at 0 -20.32 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 5 "VCC_3.3") (pinfunction "3V3") (pintype "power_in") (tstamp 654f9ba5-310c-4d5a-af0b-ff5b85712b4d)) + (pad "18" thru_hole oval (at -2.54 -20.32 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 18 "unconnected-(J1-GPIO24-Pad18)") (pinfunction "GPIO24") (pintype "bidirectional") (tstamp 86de948e-c5a2-4181-bdc8-05eb36367ff1)) + (pad "19" thru_hole oval (at 0 -22.86 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 19 "unconnected-(J1-MOSI0{slash}GPIO10-Pad19)") (pinfunction "MOSI0/GPIO10") (pintype "bidirectional") (tstamp f6edaa64-a918-4f88-9892-6c995e9575f6)) + (pad "20" thru_hole oval (at -2.54 -22.86 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 304e0b03-1cea-4d23-91a2-dc41d5ce210d)) + (pad "21" thru_hole oval (at 0 -25.4 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 20 "unconnected-(J1-MISO0{slash}GPIO9-Pad21)") (pinfunction "MISO0/GPIO9") (pintype "bidirectional") (tstamp bfdca412-cdb9-48d0-92c5-752a4e949881)) + (pad "22" thru_hole oval (at -2.54 -25.4 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 21 "unconnected-(J1-GPIO25-Pad22)") (pinfunction "GPIO25") (pintype "bidirectional") (tstamp 88589300-4c66-4f03-a5a1-6037ab7b21b6)) + (pad "23" thru_hole oval (at 0 -27.94 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 22 "unconnected-(J1-SCLK0{slash}GPIO11-Pad23)") (pinfunction "SCLK0/GPIO11") (pintype "bidirectional") (tstamp c3d969d8-71fc-450e-bc8a-582f626baa6e)) + (pad "24" thru_hole oval (at -2.54 -27.94 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 23 "unconnected-(J1-~{CE0}{slash}GPIO8-Pad24)") (pinfunction "~{CE0}/GPIO8") (pintype "bidirectional") (tstamp d14770f5-5058-4cb1-b720-1e6921d45332)) + (pad "25" thru_hole oval (at 0 -30.48 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp fd272450-5023-45eb-b42b-9ce919739f26)) + (pad "26" thru_hole oval (at -2.54 -30.48 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 24 "unconnected-(J1-~{CE1}{slash}GPIO7-Pad26)") (pinfunction "~{CE1}/GPIO7") (pintype "bidirectional") (tstamp 0eb56d41-2792-4c4e-82e3-fbbd68e1a0f2)) + (pad "27" thru_hole oval (at 0 -33.02 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 25 "unconnected-(J1-ID_SD{slash}GPIO0-Pad27)") (pinfunction "ID_SD/GPIO0") (pintype "bidirectional") (tstamp c880e36d-41c2-4d06-af9d-2c7617a23133)) + (pad "28" thru_hole oval (at -2.54 -33.02 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 26 "unconnected-(J1-ID_SC{slash}GPIO1-Pad28)") (pinfunction "ID_SC/GPIO1") (pintype "bidirectional") (tstamp ec5bd783-4334-460e-9233-0365f9ba4fa1)) + (pad "29" thru_hole oval (at 0 -35.56 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 27 "unconnected-(J1-GCLK1{slash}GPIO5-Pad29)") (pinfunction "GCLK1/GPIO5") (pintype "bidirectional") (tstamp 53924c23-bf68-4cdb-af7e-3a7fc9cb34eb)) + (pad "30" thru_hole oval (at -2.54 -35.56 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 41884a76-5a3d-4fec-97a3-f190dcb4359e)) + (pad "31" thru_hole oval (at 0 -38.1 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 28 "unconnected-(J1-GCLK2{slash}GPIO6-Pad31)") (pinfunction "GCLK2/GPIO6") (pintype "bidirectional") (tstamp 5eb72e8e-9771-44a8-8bcc-b1a2670eb45b)) + (pad "32" thru_hole oval (at -2.54 -38.1 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 29 "unconnected-(J1-PWM0{slash}GPIO12-Pad32)") (pinfunction "PWM0/GPIO12") (pintype "bidirectional") (tstamp f79ea345-cd02-4c42-b9ef-5e7c3ab6c734)) + (pad "33" thru_hole oval (at 0 -40.64 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 30 "unconnected-(J1-PWM1{slash}GPIO13-Pad33)") (pinfunction "PWM1/GPIO13") (pintype "bidirectional") (tstamp ea4a1737-689c-42a6-8e2b-e05ba367f7f7)) + (pad "34" thru_hole oval (at -2.54 -40.64 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp de446f11-bb46-40f4-b427-395e6936a157)) + (pad "35" thru_hole oval (at 0 -43.18 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 31 "unconnected-(J1-GPIO19{slash}MISO1-Pad35)") (pinfunction "GPIO19/MISO1") (pintype "bidirectional") (tstamp bb0994d1-ce01-4d1b-a264-ae95e1726897)) + (pad "36" thru_hole oval (at -2.54 -43.18 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 32 "unconnected-(J1-GPIO16-Pad36)") (pinfunction "GPIO16") (pintype "bidirectional") (tstamp 8fe78bff-e254-43d6-8919-7cdd28f5a1cd)) + (pad "37" thru_hole oval (at 0 -45.72 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 33 "unconnected-(J1-GPIO26-Pad37)") (pinfunction "GPIO26") (pintype "bidirectional") (tstamp c4d72f46-e7e2-4e06-b30b-02c2ac3ed1a5)) + (pad "38" thru_hole oval (at -2.54 -45.72 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 34 "unconnected-(J1-GPIO20{slash}MOSI1-Pad38)") (pinfunction "GPIO20/MOSI1") (pintype "bidirectional") (tstamp d9eb791d-5cde-4463-8dbb-c3f781f8687a)) + (pad "39" thru_hole oval (at 0 -48.26 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 73b4246b-e0cc-4a08-a483-a5aba9f67139)) + (pad "40" thru_hole oval (at -2.54 -48.26 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") + (net 35 "unconnected-(J1-GPIO21{slash}SCLK1-Pad40)") (pinfunction "GPIO21/SCLK1") (pintype "bidirectional") (tstamp d87de98a-8bcc-436b-8855-5fd9f42741e2)) + (model "${KICAD6_3DMODEL_DIR}/Connector_PinSocket_2.54mm.3dshapes/PinSocket_2x20_P2.54mm_Vertical.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (gr_arc (start 135.87868 101.87868) (mid 135 104) (end 132.87868 104.87868) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 006b697e-cb9f-47bf-9b08-fa272db3abbc)) + (gr_line (start 117 40) (end 133 40) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 0651e6f3-a8ef-4f5b-81b7-46a9174573f4)) + (gr_line (start 117 45) (end 117 40) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 1c3a603d-274b-478b-8330-c3c77c097754)) + (gr_circle (center 82.5 101.6) (end 83.875 101.6) + (stroke (width 0.1) (type default)) (fill none) (layer "Edge.Cuts") (tstamp 1e27e95c-9b16-4076-b6a3-91f2f93e4dfd)) + (gr_arc (start 80 43) (mid 80.87868 40.87868) (end 83 40) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 2712933c-bdf1-45f2-9125-54ad4f20f7d8)) + (gr_line (start 136 43) (end 135.87868 101.87868) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 29941149-35ba-4e98-9236-92c4a3d1b05a)) + (gr_line (start 83 40) (end 98 40) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 35eabd1e-ce48-4d1b-b4c5-f9b672087f1c)) + (gr_arc (start 133 40) (mid 135.12132 40.87868) (end 136 43) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 513ae3a3-7c34-4694-b07a-38501e038067)) + (gr_line (start 98 40) (end 98 45) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 799345f8-d4d6-43db-9095-0c8383f55faa)) + (gr_arc (start 83 105) (mid 80.87868 104.12132) (end 80 102) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 90c4a468-59f6-4d4c-a54e-29aa7b58ed59)) + (gr_line (start 80 102) (end 80 43) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp 9593da5c-79ca-4d03-8106-9b3f2f218924)) + (gr_circle (center 131.5 43.6) (end 132.875 43.6) + (stroke (width 0.1) (type default)) (fill none) (layer "Edge.Cuts") (tstamp bf777d3a-4f8c-41a4-a310-edcd8b120e56)) + (gr_circle (center 131.5 101.6) (end 132.875 101.6) + (stroke (width 0.1) (type default)) (fill none) (layer "Edge.Cuts") (tstamp e8bd6918-8800-41e6-8041-2ea427ebf530)) + (gr_line (start 132.87868 104.87868) (end 83 105) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp eb3ec9ba-383e-4c14-8005-68029166ea09)) + (gr_circle (center 82.5 43.6) (end 83.875 43.6) + (stroke (width 0.1) (type default)) (fill none) (layer "Edge.Cuts") (tstamp eff26a51-47e0-42f5-8359-64aa1452d4e7)) + (gr_line (start 98 45) (end 117 45) + (stroke (width 0.1) (type default)) (layer "Edge.Cuts") (tstamp ff024263-f8c0-49a5-9121-7b62352dc469)) + (dimension (type aligned) (layer "Cmts.User") (tstamp 6705364b-1522-4cc6-a81a-55388acff2d3) + (pts (xy 131.5 43.6) (xy 82.5 43.6)) + (height 5.1) + (gr_text "49.0000 mm" (at 107 37.35) (layer "Cmts.User") (tstamp 6705364b-1522-4cc6-a81a-55388acff2d3) + (effects (font (size 1 1) (thickness 0.15))) + ) + (format (prefix "") (suffix "") (units 3) (units_format 1) (precision 4)) + (style (thickness 0.1) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0.5) keep_text_aligned) + ) + (dimension (type aligned) (layer "Cmts.User") (tstamp 7442e083-5fd6-4509-a29a-b2f83c8fc427) + (pts (xy 80 43) (xy 98 43)) + (height -10) + (gr_text "18.0000 mm" (at 89 31.85) (layer "Cmts.User") (tstamp 7442e083-5fd6-4509-a29a-b2f83c8fc427) + (effects (font (size 1 1) (thickness 0.15))) + ) + (format (prefix "") (suffix "") (units 3) (units_format 1) (precision 4)) + (style (thickness 0.1) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0.5) keep_text_aligned) + ) + (dimension (type aligned) (layer "Cmts.User") (tstamp 7d43cf37-f314-440b-99d4-17d21e3030b1) + (pts (xy 136.25 105) (xy 136.25 40)) + (height 5.75) + (gr_text "65.0000 mm" (at 140.85 72.5 90) (layer "Cmts.User") (tstamp 7d43cf37-f314-440b-99d4-17d21e3030b1) + (effects (font (size 1 1) (thickness 0.15))) + ) + (format (prefix "") (suffix "") (units 3) (units_format 1) (precision 4)) + (style (thickness 0.1) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0.5) keep_text_aligned) + ) + (dimension (type aligned) (layer "Cmts.User") (tstamp 853abeed-4063-4eb0-975e-a091b30e18f8) + (pts (xy 131.5 101.6) (xy 131.5 43.6)) + (height -6.5) + (gr_text "58.0000 mm" (at 123.85 72.6 90) (layer "Cmts.User") (tstamp 853abeed-4063-4eb0-975e-a091b30e18f8) + (effects (font (size 1 1) (thickness 0.15))) + ) + (format (prefix "") (suffix "") (units 3) (units_format 1) (precision 4)) + (style (thickness 0.1) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0.5) keep_text_aligned) + ) + (dimension (type aligned) (layer "Cmts.User") (tstamp cf31d3d2-7034-4942-8991-bc5c07196fb2) + (pts (xy 80 100) (xy 136 100)) + (height 9) + (gr_text "56.0000 mm" (at 108 107.85) (layer "Cmts.User") (tstamp cf31d3d2-7034-4942-8991-bc5c07196fb2) + (effects (font (size 1 1) (thickness 0.15))) + ) + (format (prefix "") (suffix "") (units 3) (units_format 1) (precision 4)) + (style (thickness 0.1) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0.5) keep_text_aligned) + ) + (dimension (type aligned) (layer "Cmts.User") (tstamp e4441770-feb8-4a15-be6c-7a546dc5154e) + (pts (xy 131.29 72.6) (xy 131.5 43.6)) + (height 5.554449) + (gr_text "29.0008 mm" (at 135.799333 58.131894 89.58510678) (layer "Cmts.User") (tstamp e4441770-feb8-4a15-be6c-7a546dc5154e) + (effects (font (size 1 1) (thickness 0.15))) + ) + (format (prefix "") (suffix "") (units 3) (units_format 1) (precision 4)) + (style (thickness 0.1) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0.5) keep_text_aligned) + ) + + (segment (start 87 66) (end 87 70.92) (width 0.25) (layer "F.Cu") (net 1) (tstamp 12de7299-d5bb-46fd-af29-e1851f91feda)) + (segment (start 102.92 52.1269) (end 101.5 53.5469) (width 0.25) (layer "F.Cu") (net 1) (tstamp 669a2170-2cce-4c71-8d88-0555a0258298)) + (segment (start 87 70.92) (end 86.92 71) (width 0.25) (layer "F.Cu") (net 1) (tstamp 932c0858-377b-4fb2-af97-f2586912fe28)) + (segment (start 102.92 51) (end 102.92 52.1269) (width 0.25) (layer "F.Cu") (net 1) (tstamp a7337225-4c21-4d70-9f38-47564f584e87)) + (segment (start 101.5 53.5469) (end 101.5 60) (width 0.25) (layer "F.Cu") (net 1) (tstamp b9e6424d-c285-41c2-9b6c-800b3e41043d)) + (segment (start 99.9731 60) (end 93.9731 66) (width 0.25) (layer "B.Cu") (net 1) (tstamp 135035c0-9d69-4562-8e0a-d991158265d9)) + (segment (start 93.9731 66) (end 87 66) (width 0.25) (layer "B.Cu") (net 1) (tstamp 652efb54-6c84-44be-800e-c1aef8e3cb99)) + (segment (start 101.5 60) (end 99.9731 60) (width 0.25) (layer "B.Cu") (net 1) (tstamp 86a3a902-beff-4f84-a3c5-abbaa0d1864e)) + (segment (start 119 86.6345) (end 119 89.36) (width 0.25) (layer "F.Cu") (net 2) (tstamp 46b6c6b6-be99-4c32-9203-d532cb5ae1cd)) + (segment (start 111 74.1639) (end 111 78.6345) (width 0.25) (layer "F.Cu") (net 2) (tstamp 681d89b9-903b-44d3-9ab8-f84db39722c9)) + (segment (start 109 70.92) (end 109 60) (width 0.25) (layer "F.Cu") (net 2) (tstamp 72979bee-e5ee-404a-9be5-46a26902f1da)) + (segment (start 111 72.92) (end 109 70.92) (width 0.25) (layer "F.Cu") (net 2) (tstamp 773a2291-2ca3-412e-978d-3f0d082f3695)) + (segment (start 111 74.1639) (end 111 72.92) (width 0.25) (layer "F.Cu") (net 2) (tstamp b46460b9-ce42-4c49-ae92-a4cac368ad97)) + (segment (start 111 78.6345) (end 119 86.6345) (width 0.25) (layer "F.Cu") (net 2) (tstamp fa0b1faf-bfde-4e3d-b79d-582368ee2bd4)) + (segment (start 117.3 58.9231) (end 117.298 58.9246) (width 0.25) (layer "B.Cu") (net 2) (tstamp b4ec3c22-5c9d-4ead-b077-5caac6b3c8a2)) + (segment (start 119.23 58.9231) (end 117.3 58.9231) (width 0.25) (layer "B.Cu") (net 2) (tstamp c5981127-fc52-4754-8351-e5cf589641ea)) + (segment (start 119.23 60) (end 119.23 58.9231) (width 0.25) (layer "B.Cu") (net 2) (tstamp e137e365-ddb0-4226-9577-adb814a4c162)) + (segment (start 110.076 58.9246) (end 109 60) (width 0.25) (layer "B.Cu") (net 2) (tstamp e71bf624-54bf-4664-bc64-084e3363e160)) + (segment (start 117.298 58.9246) (end 110.076 58.9246) (width 0.25) (layer "B.Cu") (net 2) (tstamp f45770d1-3e24-4728-862d-d97c79c30275)) + (segment (start 117.73 89.36) (end 116.8781 89.36) (width 0.25) (layer "F.Cu") (net 3) (tstamp 214ff578-63cb-4388-9dde-227d2c854de7)) + (segment (start 115.75 90.4881) (end 116.8781 89.36) (width 0.25) (layer "F.Cu") (net 3) (tstamp c4810feb-b248-4d4a-ae51-7f5da5940cf0)) + (segment (start 115.75 93.9) (end 115.75 90.4881) (width 0.25) (layer "F.Cu") (net 3) (tstamp f9211cbe-c226-4fd3-85f5-f37a0ca11e6c)) + (segment (start 114.207 99) (end 114.207 97.9831) (width 0.25) (layer "B.Cu") (net 4) (tstamp 3f700287-caff-4804-8740-1632b11da9b7)) + (segment (start 114.207 97.9831) (end 118.29 93.9) (width 0.25) (layer "B.Cu") (net 4) (tstamp af87ae71-9e1b-49ec-bd4d-319b146ee1d5)) + (segment (start 113.08 99) (end 114.207 99) (width 0.25) (layer "B.Cu") (net 4) (tstamp e30fdff4-de5f-4c6d-ba80-dd6bb63ff193)) + (segment (start 129.634 67.6431) (end 128.806 66.8149) (width 0.25) (layer "F.Cu") (net 5) (tstamp 000a9cd6-8d22-4b01-9c66-b4ef0bacba7b)) + (segment (start 102.92 99) (end 102.92 96.08) (width 0.25) (layer "F.Cu") (net 5) (tstamp 21b66ff9-ce6d-41f2-90c3-19611ee9deb2)) + (segment (start 129.632 49.6769) (end 130 49.6769) (width 0.25) (layer "F.Cu") (net 5) (tstamp 5f2e5dbc-b6d5-4679-b172-cc7584cecb2d)) + (segment (start 102 78) (end 102 93) (width 0.25) (layer "F.Cu") (net 5) (tstamp 72f02a8d-a0e6-463e-916b-442aacbd65b6)) + (segment (start 130 49.6769) (end 130 48.5) (width 0.25) (layer "F.Cu") (net 5) (tstamp 7d7e2c71-47b6-4a0a-a024-935642a6bec7)) + (segment (start 104 76) (end 102 78) (width 0.25) (layer "F.Cu") (net 5) (tstamp 993df407-53ca-442c-8c37-93531b24641e)) + (segment (start 102 93) (end 104 95) (width 0.25) (layer "F.Cu") (net 5) (tstamp aeb50686-be30-41d2-a6ab-eafbb9189dac)) + (segment (start 130 67.6431) (end 129.634 67.6431) (width 0.25) (layer "F.Cu") (net 5) (tstamp b0559386-dd8d-49a0-b9a4-64aa58cf7d04)) + (segment (start 102.92 96.08) (end 104 95) (width 0.25) (layer "F.Cu") (net 5) (tstamp b930af55-bc63-4587-beac-0ed9cc135c6d)) + (segment (start 130 68.82) (end 130 67.6431) (width 0.25) (layer "F.Cu") (net 5) (tstamp da0d60c6-e9e3-4622-a2e7-e758a990e4f1)) + (segment (start 128.806 50.5031) (end 129.632 49.6769) (width 0.25) (layer "F.Cu") (net 5) (tstamp f1d14b7b-d184-47b7-8b7e-b823085e73d2)) + (segment (start 128.806 66.8149) (end 128.806 50.5031) (width 0.25) (layer "F.Cu") (net 5) (tstamp fd1a7f4d-1d77-41ca-8e84-351c344d7711)) + (segment (start 117.998 70) (end 123.5 70) (width 0.25) (layer "B.Cu") (net 5) (tstamp 0ae8ae0d-3b50-4a40-9e48-ded2a036f9bf)) + (segment (start 117.46 69.4615) (end 117.998 70) (width 0.25) (layer "B.Cu") (net 5) (tstamp 0d0ae462-6f71-41cb-a659-d3d8e56bf847)) + (segment (start 112.175 70.8268) (end 113.54 69.4615) (width 0.25) (layer "B.Cu") (net 5) (tstamp 13d33456-669b-4c11-b534-7c605171e849)) + (segment (start 105.607 76) (end 110.78 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp 2f1eda7f-c6a3-45f0-ae2b-1c2b774a65fa)) + (segment (start 114.5 74.16) (end 114.5 73.1521) (width 0.25) (layer "B.Cu") (net 5) (tstamp 304a3970-f98a-4342-bdc7-592b627e254d)) + (segment (start 117.46 69.4615) (end 118.102 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp 415ead74-eba7-42d0-929d-f7bdcd713f03)) + (segment (start 123.5 70) (end 124.68 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp 4223a899-c365-458f-bcfb-bf1d34f43b3e)) + (segment (start 104 76) (end 105.607 76) (width 0.25) (layer "B.Cu") (net 5) (tstamp 4347d8e3-d621-4312-8bdb-cd0b0e528d26)) + (segment (start 113.54 69.4615) (end 117.46 69.4615) (width 0.25) (layer "B.Cu") (net 5) (tstamp 579ab2f1-9dfb-4765-8cc0-1b105bc4fa7c)) + (segment (start 110.78 70.8268) (end 112.175 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp 8c57fb34-9606-4fc5-a551-96bfbafc9c22)) + (segment (start 89 92) (end 88.92 91.92) (width 0.25) (layer "B.Cu") (net 5) (tstamp a4425cbb-e868-4ba0-a9d1-dddeb619f248)) + (segment (start 101 92) (end 89 92) (width 0.25) (layer "B.Cu") (net 5) (tstamp abd3312e-d1ba-4a3b-94fa-8184c404367c)) + (segment (start 118.102 68.462) (end 118 68.36) (width 0.25) (layer "B.Cu") (net 5) (tstamp b4a18b60-603e-4939-a8cf-0d643631416d)) + (segment (start 114.5 73.1521) (end 112.175 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp beb520f3-38b4-486b-98c0-5457d63fa639)) + (segment (start 104 95) (end 101 92) (width 0.25) (layer "B.Cu") (net 5) (tstamp c105c5db-c2ab-4e2a-b3d9-4a0e50a9b405)) + (segment (start 124.68 68.82) (end 130 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp c222c1cc-e69c-460f-9966-e83aeb1c6eb5)) + (segment (start 88.92 91.92) (end 88.92 89) (width 0.25) (layer "B.Cu") (net 5) (tstamp e2f70e35-b847-4ac9-930f-6ff66e76225c)) + (segment (start 118.102 68.82) (end 118.102 68.462) (width 0.25) (layer "B.Cu") (net 5) (tstamp e6bece4a-bde5-44ea-b625-4714828c80dd)) + (segment (start 132.54 51.04) (end 132.54 48.5) (width 0.25) (layer "F.Cu") (net 6) (tstamp b1bb8fa4-5e4b-4784-b61e-59372a3074d8)) + (segment (start 99.1435 49.8565) (end 98 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 1d48b1b5-0713-4b3e-ad9a-b4064231b803)) + (segment (start 131.363 51.04) (end 131.363 51.4078) (width 0.25) (layer "B.Cu") (net 6) (tstamp 296dfc89-0a81-429f-92c5-8c00e61ef51f)) + (segment (start 126.078 51) (end 120.676 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 37f283a2-4103-440e-b19f-993d05402ab3)) + (segment (start 120.5 51) (end 120.676 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 536fd090-895b-4d2e-9a33-f3e9fff9e87e)) + (segment (start 130.66 52.1103) (end 130.66 52.1104) (width 0.25) (layer "B.Cu") (net 6) (tstamp 577b8187-8ae4-4d70-a461-59643b37ff0e)) + (segment (start 130.66 52.1103) (end 130.54 52.2306) (width 0.25) (layer "B.Cu") (net 6) (tstamp 651f5aef-f1ee-4d32-97b1-0bbd64e3f6c9)) + (segment (start 130.461 52.31) (end 127.388 52.31) (width 0.25) (layer "B.Cu") (net 6) (tstamp 8d70dc4f-c843-4e49-9fcd-977f16f10b21)) + (segment (start 119.532 49.8565) (end 99.1435 49.8565) (width 0.25) (layer "B.Cu") (net 6) (tstamp 9116f3ea-f62e-4555-8523-2487df84ebb2)) + (segment (start 130.66 52.1104) (end 130.461 52.31) (width 0.25) (layer "B.Cu") (net 6) (tstamp 9e14b3bd-4ac2-4a90-91bc-414727e78565)) + (segment (start 127.388 52.31) (end 126.078 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp bdbb3d65-a15c-4e0e-a5c5-a31287edad20)) + (segment (start 120.676 51) (end 119.532 49.8565) (width 0.25) (layer "B.Cu") (net 6) (tstamp c248b53e-3202-4c32-bc80-5bbb06acc8b4)) + (segment (start 131.363 51.4078) (end 130.66 52.1103) (width 0.25) (layer "B.Cu") (net 6) (tstamp e5936714-5c9f-42ce-900d-eaa9a8ce353e)) + (segment (start 132.54 51.04) (end 131.363 51.04) (width 0.25) (layer "B.Cu") (net 6) (tstamp f6530600-0257-4fc5-8db4-260b31eceb59)) + (segment (start 131.349 69.3583) (end 131.349 65.7397) (width 0.25) (layer "F.Cu") (net 9) (tstamp 015d5d70-ad28-486a-affd-1ccb889446a1)) + (segment (start 132.174 82.8831) (end 131.177 81.8858) (width 0.25) (layer "F.Cu") (net 9) (tstamp 01e1e3da-69bf-4092-bc0d-2ddb405b0628)) + (segment (start 132.172 85.2369) (end 132.54 85.2369) (width 0.25) (layer "F.Cu") (net 9) (tstamp 0450cd28-2b63-4b2c-9bfc-ea172a3c502d)) + (segment (start 130 58.66) (end 130 59.2484) (width 0.25) (layer "F.Cu") (net 9) (tstamp 111b30e5-030f-4154-bc17-0072c902a082)) + (segment (start 132.172 64.9169) (end 132.54 64.9169) (width 0.25) (layer "F.Cu") (net 9) (tstamp 178a5ee7-2545-458d-a3f2-5d01dbc18b07)) + (segment (start 131.349 65.7397) (end 132.172 64.9169) (width 0.25) (layer "F.Cu") (net 9) (tstamp 1a3ac35c-d7de-4cc6-ba0f-0435231f5a4f)) + (segment (start 130 59.8369) (end 130 59.2484) (width 0.25) (layer "F.Cu") (net 9) (tstamp 1cb2c6fe-3b67-4ca1-a01e-690c315fc20a)) + (segment (start 132.54 63.74) (end 132.54 62.5631) (width 0.25) (layer "F.Cu") (net 9) (tstamp 1d77abb7-8287-4441-8daf-eea764b830fd)) + (segment (start 132.54 64.9169) (end 132.54 63.74) (width 0.25) (layer "F.Cu") (net 9) (tstamp 2791a470-c6b5-42d2-9d4a-409c7675fc4f)) + (segment (start 132.54 62.5631) (end 132.174 62.5631) (width 0.25) (layer "F.Cu") (net 9) (tstamp 2bdfa8fd-7ea8-4d50-86a6-e83be73dfb43)) + (segment (start 132.174 70.1831) (end 131.349 69.3583) (width 0.25) (layer "F.Cu") (net 9) (tstamp 2c4bacf8-4c15-4c02-b020-5c97a546d1b6)) + (segment (start 131.35 87.1389) (end 131.35 86.0591) (width 0.25) (layer "F.Cu") (net 9) (tstamp 36b23fe4-d023-4e40-8b79-f7dc8ad3f903)) + (segment (start 132.54 53.58) (end 132.54 54.7569) (width 0.25) (layer "F.Cu") (net 9) (tstamp 3a7cbdab-b813-4db7-b288-05711d3813ff)) + (segment (start 130 80.1569) (end 130 78.98) (width 0.25) (layer "F.Cu") (net 9) (tstamp 3d79828a-ae4f-4f94-9ecc-e37e44709f33)) + (segment (start 132.54 85.2369) (end 132.54 84.06) (width 0.25) (layer "F.Cu") (net 9) (tstamp 45241f53-575d-490c-b36c-2b0c31fb6aaf)) + (segment (start 132.54 82.8831) (end 132.174 82.8831) (width 0.25) (layer "F.Cu") (net 9) (tstamp 463917a6-a822-43cc-a9fb-f56614037679)) + (segment (start 132.54 54.7569) (end 132.174 54.7569) (width 0.25) (layer "F.Cu") (net 9) (tstamp 4c69ca62-d215-4b92-917a-114269249a49)) + (segment (start 131.35 86.0591) (end 132.172 85.2369) (width 0.25) (layer "F.Cu") (net 9) (tstamp 4f6dbb33-f713-4f5a-90c1-d17cc6d3df20)) + (segment (start 131.27 57.9784) (end 130 59.2484) (width 0.25) (layer "F.Cu") (net 9) (tstamp 542ca533-a7e2-4be1-a319-dd3cae691b87)) + (segment (start 131.177 61.5658) (end 131.177 60.6459) (width 0.25) (layer "F.Cu") (net 9) (tstamp 65ee1135-93f8-4edc-b3af-a0f87b32abad)) + (segment (start 130.368 59.8369) (end 130 59.8369) (width 0.25) (layer "F.Cu") (net 9) (tstamp 6c88593b-940f-492b-aefc-110b4f41bb96)) + (segment (start 132.174 62.5631) (end 131.177 61.5658) (width 0.25) (layer "F.Cu") (net 9) (tstamp 74bb7a96-850e-4001-8091-fe45ef8694fb)) + (segment (start 132.174 54.7569) (end 131.27 55.6611) (width 0.25) (layer "F.Cu") (net 9) (tstamp 9c033c6f-2945-471d-916e-3569ad2e7976)) + (segment (start 132.54 84.06) (end 132.54 82.8831) (width 0.25) (layer "F.Cu") (net 9) (tstamp 9dbe77dd-9f99-42fc-9407-c953f6d502e6)) + (segment (start 132.54 89.14) (end 132.54 87.9631) (width 0.25) (layer "F.Cu") (net 9) (tstamp c1549742-20ed-46d4-a5b0-cda02bd51367)) + (segment (start 132.54 70.1831) (end 132.174 70.1831) (width 0.25) (layer "F.Cu") (net 9) (tstamp c2008f27-52eb-4e19-959c-e5aa1e0e0226)) + (segment (start 130.368 80.1569) (end 130 80.1569) (width 0.25) (layer "F.Cu") (net 9) (tstamp c6892cb1-32be-471d-9e4e-15a91f719a1a)) + (segment (start 132.174 87.9631) (end 131.35 87.1389) (width 0.25) (layer "F.Cu") (net 9) (tstamp cc28b2c9-2ef4-4fec-b657-36206be2c294)) + (segment (start 131.177 80.9659) (end 130.368 80.1569) (width 0.25) (layer "F.Cu") (net 9) (tstamp e044c3ac-cc65-4258-97f2-cfef39ea1bcc)) + (segment (start 132.54 87.9631) (end 132.174 87.9631) (width 0.25) (layer "F.Cu") (net 9) (tstamp e9df421e-17f3-48b2-9f8a-a43aa531d0fb)) + (segment (start 131.177 81.8858) (end 131.177 80.9659) (width 0.25) (layer "F.Cu") (net 9) (tstamp ecaafa16-adf0-4d59-b6b6-683fa7596d8d)) + (segment (start 131.27 55.6611) (end 131.27 57.9784) (width 0.25) (layer "F.Cu") (net 9) (tstamp f89bc0cc-961e-4306-bed1-5d79f9b37e36)) + (segment (start 131.177 60.6459) (end 130.368 59.8369) (width 0.25) (layer "F.Cu") (net 9) (tstamp fd5ed285-e053-40ab-b553-aa28c66a8d74)) + (segment (start 132.54 71.36) (end 132.54 70.1831) (width 0.25) (layer "F.Cu") (net 9) (tstamp fe1aa7d9-9a24-4c3a-b284-cac114130df3)) + (segment (start 130 96.76) (end 128.823 96.76) (width 0.25) (layer "B.Cu") (net 9) (tstamp 074943c8-ea7d-4e5c-a237-e2426bf73dc3)) + (segment (start 128.823 58.66) (end 128.504 58.3409) (width 0.25) (layer "B.Cu") (net 9) (tstamp 0b4c38ea-a800-4fb8-9a1a-d170bcfb7c6d)) + (segment (start 107 84.2914) (end 107 83.16) (width 0.25) (layer "B.Cu") (net 9) (tstamp 2d6b5396-75eb-4f01-9ccc-3f1639e82ef7)) + (segment (start 128.823 78.98) (end 128.263 78.42) (width 0.25) (layer "B.Cu") (net 9) (tstamp 2e57a579-a598-4019-8e97-97311cf98b26)) + (segment (start 104.291 87) (end 107 84.2914) (width 0.25) (layer "B.Cu") (net 9) (tstamp 378ee728-d507-4070-b4b0-2ad5ae48d5f1)) + (segment (start 121.3626 78.42) (end 128.263 78.42) (width 0.25) (layer "B.Cu") (net 9) (tstamp 4180254c-95a8-4d79-876a-57242821beb0)) + (segment (start 130 58.66) (end 128.823 58.66) (width 0.25) (layer "B.Cu") (net 9) (tstamp 57679316-d8d5-4ca8-9e86-ca11039775bc)) + (segment (start 128.423 96.36) (end 120.9 96.36) (width 0.25) (layer "B.Cu") (net 9) (tstamp 74f680d6-bb6f-4f64-9565-5d3901bd4a64)) + (segment (start 87.46 87) (end 104.291 87) (width 0.25) (layer "B.Cu") (net 9) (tstamp 7616ea0a-24e0-42ef-b5ec-54a6ab87053e)) + (segment (start 84 90.46) (end 87.46 87) (width 0.25) (layer "B.Cu") (net 9) (tstamp 7ff22eab-721c-437a-8946-edbadb95f38d)) + (segment (start 111 83) (end 111 83.08) (width 0.25) (layer "B.Cu") (net 9) (tstamp b59138c2-7e22-4ecb-84be-a17e476467d3)) + (segment (start 130 78.98) (end 128.823 78.98) (width 0.25) (layer "B.Cu") (net 9) (tstamp bd30812b-4b82-466a-821a-3fb6026bd65b)) + (segment (start 128.823 96.76) (end 128.423 96.36) (width 0.25) (layer "B.Cu") (net 9) (tstamp f021be97-82b3-4788-8919-507b810bad35)) + (segment (start 128.504 58.3409) (end 121.228 58.3409) (width 0.25) (layer "B.Cu") (net 9) (tstamp f5f9a00a-488f-4d92-9bc4-d0fe03d04371)) + (segment (start 111 89) (end 111 83.08) (width 0.25) (layer "B.Cu") (net 9) (tstamp fa638c11-e51e-44c9-9a90-770a63a58d1c)) + (segment (start 94.46 80.46) (end 93.42 81.5) (width 0.25) (layer "B.Cu") (net 11) (tstamp 01733c9c-0d5c-40b6-9bd8-30709222c85f)) + (segment (start 93.42 84.1) (end 94.16 84.84) (width 0.25) (layer "B.Cu") (net 11) (tstamp 04132aa3-fbdb-4c6d-9fda-72d3a8a98154)) + (segment (start 133.776 59.0995) (end 133.039 59.8369) (width 0.25) (layer "B.Cu") (net 11) (tstamp 18d46a4c-23ed-4db7-b389-e7d4bfe4a0cb)) + (segment (start 132.54 57.2969) (end 132.908 57.2969) (width 0.25) (layer "B.Cu") (net 11) (tstamp 1b524de6-a4b3-4e2a-a2ba-a36ad5dc0988)) + (segment (start 130.344 62.557) (end 112.363 62.557) (width 0.25) (layer "B.Cu") (net 11) (tstamp 1efba9fa-edf9-4e0b-aa72-ea2c89d61ec7)) + (segment (start 133.039 59.8369) (end 132.224 59.8369) (width 0.25) (layer "B.Cu") (net 11) (tstamp 383dded2-5852-4f3d-b54f-11124872fd4c)) + (segment (start 131.27 61.6309) (end 130.344 62.557) (width 0.25) (layer "B.Cu") (net 11) (tstamp 3b3098d9-d7ae-430c-8e23-aca1a8e971a3)) + (segment (start 131.27 60.791) (end 131.27 61.6309) (width 0.25) (layer "B.Cu") (net 11) (tstamp 4da0dcb0-feb6-4b2f-877a-f899796a14b7)) + (segment (start 94.46 80.46) (end 93.92 81) (width 0.25) (layer "B.Cu") (net 11) (tstamp 56692325-45c4-46cc-b8f8-dc76c18ba661)) + (segment (start 104 84.84) (end 94.16 84.84) (width 0.25) (layer "B.Cu") (net 11) (tstamp 84285f7b-2b92-4b9c-a805-c85805b8f764)) + (segment (start 132.54 56.12) (end 132.54 57.2969) (width 0.25) (layer "B.Cu") (net 11) (tstamp 90e6a160-29a3-4503-bfcd-0fdeb49fcde7)) + (segment (start 112.363 62.557) (end 94.46 80.46) (width 0.25) (layer "B.Cu") (net 11) (tstamp 9ab701d9-3312-4afd-8f75-2c09eb622c3f)) + (segment (start 133.776 58.1653) (end 133.776 59.0995) (width 0.25) (layer "B.Cu") (net 11) (tstamp a1dd10ed-b3f8-49d8-8521-96d5a3d97d7f)) + (segment (start 132.224 59.8369) (end 131.27 60.791) (width 0.25) (layer "B.Cu") (net 11) (tstamp c76c8697-c39c-4007-89ec-a05cfaee27d7)) + (segment (start 132.908 57.2969) (end 133.776 58.1653) (width 0.25) (layer "B.Cu") (net 11) (tstamp d35b49da-e779-4d34-a77e-a595fe1ceded)) + (segment (start 93.92 81) (end 93.92 82) (width 0.25) (layer "B.Cu") (net 11) (tstamp e5c16329-a17f-4d7c-9e1c-9d6d677c354a)) + (segment (start 93.42 81.5) (end 93.42 84.1) (width 0.25) (layer "B.Cu") (net 11) (tstamp e8d78740-11e9-4cac-b149-2f97b7cfad5e)) + (segment (start 118.006 61.0843) (end 122.111 61.0843) (width 0.25) (layer "B.Cu") (net 12) (tstamp 0a2f789c-e685-4c35-9bf7-4bda9120be89)) + (segment (start 130.554 59.8369) (end 131.363 59.0279) (width 0.25) (layer "B.Cu") (net 12) (tstamp 26bcd68d-c0f2-4f8a-91b6-48c0cd23ecb3)) + (segment (start 117.46 60.2692) (end 117.46 60.5384) (width 0.25) (layer "B.Cu") (net 12) (tstamp 2a2635c9-82b7-44df-93fa-2098f4b6c779)) + (segment (start 123.358 59.8369) (end 130.554 59.8369) (width 0.25) (layer "B.Cu") (net 12) (tstamp 3995de97-fed8-49af-9675-2f9484dce630)) + (segment (start 131.363 58.66) (end 132.54 58.66) (width 0.25) (layer "B.Cu") (net 12) (tstamp 5774f9f6-5f53-4929-b1f6-fb6c8fb5f58c)) + (segment (start 117.46 60.2692) (end 117.691 60.2692) (width 0.25) (layer "B.Cu") (net 12) (tstamp 5c6a91cf-bdc8-4115-ba42-9d55d36c83d8)) + (segment (start 117.46 60) (end 117.46 60.2692) (width 0.25) (layer "B.Cu") (net 12) (tstamp 83c81229-cc6c-421f-924d-3c7b962af46b)) + (segment (start 96.5137 76) (end 111.975 60.5384) (width 0.25) (layer "B.Cu") (net 12) (tstamp 84daa2bf-3a4d-41f5-9aa8-9db5ff931586)) + (segment (start 117.691 60.2692) (end 117.96 60) (width 0.25) (layer "B.Cu") (net 12) (tstamp 8dc752de-0bf6-4019-be85-12312fea1983)) + (segment (start 111.975 60.5384) (end 117.46 60.5384) (width 0.25) (layer "B.Cu") (net 12) (tstamp 945e5762-7f6d-4189-92e7-06dcff46d3e7)) + (segment (start 131.363 59.0279) (end 131.363 58.66) (width 0.25) (layer "B.Cu") (net 12) (tstamp 9f65880f-f285-44c8-b06a-d781948e6e09)) + (segment (start 122.111 61.0843) (end 123.358 59.8369) (width 0.25) (layer "B.Cu") (net 12) (tstamp bdb565dd-d031-4978-a774-9722d30fb140)) + (segment (start 93.84 76) (end 96.5137 76) (width 0.25) (layer "B.Cu") (net 12) (tstamp d741666e-5a34-4d4b-a9fe-e636c6bb3f77)) + (segment (start 117.46 60.5384) (end 118.006 61.0843) (width 0.25) (layer "B.Cu") (net 12) (tstamp f76e1fb2-b32c-4dc3-b41e-4077d1986ebc)) + (segment (start 101 94) (end 99 96) (width 0.25) (layer "F.Cu") (net 36) (tstamp 39e36e71-341f-40b4-a8c9-063647e9354c)) + (segment (start 99.6748 56.5948) (end 99.6748 85.6748) (width 0.25) (layer "F.Cu") (net 36) (tstamp 78ef3220-d731-4c99-ab89-273e98604dd7)) + (segment (start 98.08 55) (end 99.6748 56.5948) (width 0.25) (layer "F.Cu") (net 36) (tstamp c951465e-49f3-4013-8e2f-aea6ecf9fe69)) + (segment (start 101 87) (end 101 94) (width 0.25) (layer "F.Cu") (net 36) (tstamp cbb2e4e1-17ab-4fc9-981e-b0295b340175)) + (segment (start 99.6748 85.6748) (end 101 87) (width 0.25) (layer "F.Cu") (net 36) (tstamp dd36e835-146a-4797-85d1-dc7f1d562859)) + (segment (start 99 96) (end 99.1973 96.1973) (width 0.25) (layer "B.Cu") (net 36) (tstamp 6aeccbc8-68fa-4f53-8483-15d7530a52e1)) + (segment (start 99.1973 96.1973) (end 107.3027 96.1973) (width 0.25) (layer "B.Cu") (net 36) (tstamp 83bccfac-675e-44b8-944f-f96fae70b791)) + (segment (start 84 93) (end 85.1769 93) (width 0.25) (layer "B.Cu") (net 36) (tstamp 96736583-c06e-4882-9a0e-30062fe247e8)) + (segment (start 85.1769 93) (end 85.1784 93.0015) (width 0.25) (layer "B.Cu") (net 36) (tstamp b1dcc291-0653-4234-90b6-dd7f59aff230)) + (segment (start 107.3027 96.1973) (end 117.73 85.77) (width 0.25) (layer "B.Cu") (net 36) (tstamp c7fa1d27-c602-4b81-979d-3c90538432c7)) + (segment (start 85.1784 93.0015) (end 96.0015 93.0015) (width 0.25) (layer "B.Cu") (net 36) (tstamp d25c8750-b5b5-44b0-8a33-0ef2f82cd8fa)) + (segment (start 117.73 85.77) (end 117.73 81) (width 0.25) (layer "B.Cu") (net 36) (tstamp dd529443-f598-475e-b43f-9e30ec21e1c7)) + (segment (start 96.0015 93.0015) (end 99 96) (width 0.25) (layer "B.Cu") (net 36) (tstamp eb11030d-e0a0-4f2e-a1f8-e5a74a7d3c79)) + (segment (start 87.2531 95.54) (end 84 95.54) (width 0.25) (layer "B.Cu") (net 37) (tstamp 4e3041b3-2e86-4764-876d-b671564d9448)) + (segment (start 88.84 96) (end 87.7131 96) (width 0.25) (layer "B.Cu") (net 37) (tstamp 5f5b7574-4170-488e-b9ac-3c33a3d44a3b)) + (segment (start 87.7131 96) (end 87.2531 95.54) (width 0.25) (layer "B.Cu") (net 37) (tstamp ab1b15f1-2238-48e2-9bfc-4851c7a94ea1)) + (segment (start 113.08 51) (end 117.96 51) (width 0.25) (layer "B.Cu") (net 38) (tstamp 05473841-1cf1-4ad7-a6ab-c99e45477171)) + (segment (start 87.84 51) (end 87.84 52.1269) (width 0.25) (layer "F.Cu") (net 39) (tstamp 12fea319-949f-4551-b905-7c78de52c57f)) + (segment (start 87.92 52.2069) (end 87.92 55) (width 0.25) (layer "F.Cu") (net 39) (tstamp 184a30f5-b071-4b8f-b113-f9458d4bf1a7)) + (segment (start 87.84 52.1269) (end 87.92 52.2069) (width 0.25) (layer "F.Cu") (net 39) (tstamp d74e3c5e-00cc-46fd-8e64-48af99eb63fa)) + (segment (start 119.23 52.0769) (end 119.165 52.1419) (width 0.25) (layer "B.Cu") (net 39) (tstamp 365f03ee-43af-4610-9c23-4dc654230482)) + (segment (start 119.165 52.1419) (end 90.1088 52.1419) (width 0.25) (layer "B.Cu") (net 39) (tstamp 43ad19ca-5a57-49e6-92e1-c91d35d7f9bc)) + (segment (start 90.1088 52.1419) (end 88.9669 51) (width 0.25) (layer "B.Cu") (net 39) (tstamp 81ed1a3c-d903-4318-b8bd-c002887f8c23)) + (segment (start 119.23 51) (end 119.23 52.0769) (width 0.25) (layer "B.Cu") (net 39) (tstamp 982e8d46-3493-4d04-a5d8-3b94f41341e5)) + (segment (start 88.9669 51) (end 87.84 51) (width 0.25) (layer "B.Cu") (net 39) (tstamp a2dbcbd8-197f-42ec-bd23-ced41d018f77)) + (segment (start 120.659 68.7623) (end 120.659 65.5634) (width 0.25) (layer "F.Cu") (net 40) (tstamp 0904e793-3c42-489b-b607-e91780981713)) + (segment (start 115.627 62.8732) (end 116.798 61.7022) (width 0.25) (layer "F.Cu") (net 40) (tstamp 1ae8792e-e390-4325-a55f-0ad68268702f)) + (segment (start 119 76.5) (end 119 81) (width 0.25) (layer "F.Cu") (net 40) (tstamp 3be305e0-e8c3-46dd-99e9-88beb45ada93)) + (segment (start 108.343 58.4731) (end 107 59.8161) (width 0.25) (layer "F.Cu") (net 40) (tstamp 3df34c56-ab63-4071-acee-83d81190c479)) + (segment (start 120.54 72.0804) (end 120.659 71.9613) (width 0.25) (layer "F.Cu") (net 40) (tstamp 4a47f56b-356b-48c4-b282-24d9ee80eace)) + (segment (start 120.54 74.96) (end 120.54 72.0804) (width 0.25) (layer "F.Cu") (net 40) (tstamp 55d71abe-1345-47c6-8988-3ca9a07aa985)) + (segment (start 120.659 71.9613) (end 120.659 68.7623) (width 0.25) (layer "F.Cu") (net 40) (tstamp 6d944b5d-e173-4bd7-840c-efc1cee12fbb)) + (segment (start 119 76.5) (end 120.54 74.96) (width 0.25) (layer "F.Cu") (net 40) (tstamp 9e45a6f4-1a14-4500-b6b5-1f027a4721df)) + (segment (start 115.627 64) (end 115.627 62.8732) (width 0.25) (layer "F.Cu") (net 40) (tstamp ac43a70e-5bec-43cd-a86d-c71ed780dbde)) + (segment (start 113.569 58.4731) (end 108.343 58.4731) (width 0.25) (layer "F.Cu") (net 40) (tstamp ae3cb963-5995-49fe-80f8-d75c184db4c4)) + (segment (start 114.5 64) (end 115.627 64) (width 0.25) (layer "F.Cu") (net 40) (tstamp af2a4461-7189-4dd6-93e3-756ba0aa73d1)) + (segment (start 116.798 61.7022) (end 113.569 58.4731) (width 0.25) (layer "F.Cu") (net 40) (tstamp cbe3133f-c1af-4cb3-9ae5-9e4390e033f6)) + (segment (start 107 59.8161) (end 107 73) (width 0.25) (layer "F.Cu") (net 40) (tstamp d6d7bd3b-6518-479c-b871-3942dff9ef21)) + (segment (start 120.659 68.7623) (end 120.54 68.6433) (width 0.25) (layer "F.Cu") (net 40) (tstamp e5471a8d-15c1-4d44-89eb-83d1bf2fcceb)) + (segment (start 120.54 68.6433) (end 120.54 68.36) (width 0.25) (layer "F.Cu") (net 40) (tstamp fae59cf4-133d-4b0c-a632-f10821800187)) + (segment (start 120.659 65.5634) (end 116.798 61.7022) (width 0.25) (layer "F.Cu") (net 40) (tstamp ff1d352a-b2b8-4e4f-a9e7-30f3c9de6acc)) + (segment (start 107 72.4487) (end 107 73) (width 0.25) (layer "B.Cu") (net 40) (tstamp 71e514c3-d67f-4e54-a104-1c1e0f50e2d8)) + (segment (start 99.08 89) (end 100.207 89) (width 0.25) (layer "B.Cu") (net 41) (tstamp 4550b75b-9c2e-424f-8fde-6e37b4aa6c47)) + (segment (start 102.824 75.5627) (end 102.824 77.192) (width 0.25) (layer "B.Cu") (net 41) (tstamp 4ae7ab7c-2340-4bff-9595-48ec06db68f9)) + (segment (start 102.824 77.192) (end 108.46 82.828) (width 0.25) (layer "B.Cu") (net 41) (tstamp 668d8dcd-dd4c-40a0-ac79-9ceb16e23643)) + (segment (start 108.46 82.828) (end 108.46 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp 6a668c91-cbad-4416-8dab-1e054354f1fc)) + (segment (start 101.094 88.1125) (end 108.46 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp 6f8ce3e2-1717-4a44-b9d7-e61d98aeba6a)) + (segment (start 108.46 88.1125) (end 108.46 89) (width 0.25) (layer "B.Cu") (net 41) (tstamp 7fc9d907-0924-4566-8c99-b2b2c366936e)) + (segment (start 100.207 89) (end 101.094 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp 810d8137-f0b1-46aa-bfc5-c4f480afb4d1)) + (segment (start 111.104 67.2831) (end 102.824 75.5627) (width 0.25) (layer "B.Cu") (net 41) (tstamp b7c52624-cbb9-409e-b774-e85e765108ac)) + (segment (start 119.27 68.36) (end 119.27 67.2831) (width 0.25) (layer "B.Cu") (net 41) (tstamp cbc4bf54-e3a1-4652-93ee-6603ff767c47)) + (segment (start 119.27 67.2831) (end 111.104 67.2831) (width 0.25) (layer "B.Cu") (net 41) (tstamp ccb3a081-fe9a-4abe-9f86-e399bea2d90d)) + (segment (start 109.73 87) (end 108.805 87) (width 0.25) (layer "F.Cu") (net 42) (tstamp 01e61a23-b173-4cfe-b055-fd79a5e70654)) + (segment (start 104.932 83.1269) (end 104.08 83.1269) (width 0.25) (layer "F.Cu") (net 42) (tstamp 5fce7aec-561a-4b69-b758-477e9a68c72d)) + (segment (start 109.73 89) (end 109.73 87) (width 0.25) (layer "F.Cu") (net 42) (tstamp 62b4e8fb-e83a-4b56-9e46-2481ccc01753)) + (segment (start 108.805 87) (end 104.932 83.1269) (width 0.25) (layer "F.Cu") (net 42) (tstamp 7b67057a-6f03-4b84-90b4-4fb4a422a5ee)) + (segment (start 104.08 83.1269) (end 104.08 82) (width 0.25) (layer "F.Cu") (net 42) (tstamp feaea463-c235-4a46-8f64-a934b08bf957)) + + (zone (net 9) (net_name "GND") (layer "B.Cu") (tstamp 0439734c-1f86-4b67-9c14-36cdfe2e2799) (name "GND") (hatch edge 0.5) + (connect_pads (clearance 0.5)) + (min_thickness 0.25) (filled_areas_thickness no) + (fill yes (thermal_gap 0.5) (thermal_bridge_width 0.5)) + (polygon + (pts + (xy 83 47) + (xy 123 47) + (xy 123 102) + (xy 88 102) + (xy 88 84) + (xy 83 84) + ) + ) + (filled_polygon + (layer "B.Cu") + (pts + (xy 122.943039 47.019685) + (xy 122.988794 47.072489) + (xy 123 47.124) + (xy 123 50.2505) + (xy 122.980315 50.317539) + (xy 122.927511 50.363294) + (xy 122.876 50.3745) + (xy 121.523054 50.3745) + (xy 121.456015 50.354815) + (xy 121.413696 50.308953) + (xy 121.356801 50.202511) + (xy 121.356799 50.202509) + (xy 121.356798 50.202506) + (xy 121.317824 50.155016) + (xy 121.228647 50.046352) + (xy 121.072495 49.918203) + (xy 121.072488 49.918198) + (xy 120.894345 49.822978) + (xy 120.701031 49.764337) + (xy 120.521962 49.746701) + (xy 120.5 49.744538) + (xy 120.499999 49.744538) + (xy 120.380631 49.756294) + (xy 120.311985 49.743275) + (xy 120.280816 49.720591) + (xy 120.032777 49.47266) + (xy 120.022989 49.460444) + (xy 120.02276 49.460634) + (xy 120.017789 49.454625) + (xy 119.967316 49.407228) + (xy 119.946369 49.386289) + (xy 119.943506 49.38407) + (xy 119.940943 49.382082) + (xy 119.936494 49.378283) + (xy 119.902583 49.346439) + (xy 119.902584 49.346439) + (xy 119.884949 49.336744) + (xy 119.86871 49.326079) + (xy 119.852819 49.313758) + (xy 119.810117 49.295289) + (xy 119.80486 49.292714) + (xy 119.764092 49.270303) + (xy 119.764089 49.270302) + (xy 119.744606 49.265299) + (xy 119.726231 49.25901) + (xy 119.707762 49.251023) + (xy 119.661809 49.243755) + (xy 119.656074 49.242568) + (xy 119.64075 49.238633) + (xy 119.611019 49.231) + (xy 119.611017 49.231) + (xy 119.590902 49.231) + (xy 119.571534 49.229478) + (xy 119.551669 49.226336) + (xy 119.55166 49.226336) + (xy 119.505362 49.230723) + (xy 119.49951 49.231) + (xy 99.226237 49.231) + (xy 99.21062 49.229276) + (xy 99.210593 49.229562) + (xy 99.202831 49.228827) + (xy 99.133703 49.231) + (xy 99.10415 49.231) + (xy 99.103429 49.23109) + (xy 99.097257 49.231869) + (xy 99.091445 49.232326) + (xy 99.044873 49.23379) + (xy 99.044872 49.23379) + (xy 99.025629 49.239381) + (xy 99.006579 49.243325) + (xy 98.986711 49.245834) + (xy 98.986709 49.245835) + (xy 98.943384 49.262988) + (xy 98.937857 49.26488) + (xy 98.89311 49.277881) + (xy 98.893109 49.277882) + (xy 98.875867 49.288079) + (xy 98.858399 49.296637) + (xy 98.839769 49.304013) + (xy 98.839767 49.304014) + (xy 98.802076 49.331398) + (xy 98.797194 49.334605) + (xy 98.757079 49.35833) + (xy 98.742908 49.3725) + (xy 98.728123 49.385128) + (xy 98.711912 49.396907) + (xy 98.682209 49.43281) + (xy 98.678277 49.437131) + (xy 98.414821 49.700586) + (xy 98.353498 49.734071) + (xy 98.295048 49.73268) + (xy 98.226697 49.714366) + (xy 98.226693 49.714365) + (xy 98.226692 49.714365) + (xy 98.113346 49.704448) + (xy 98.000001 49.694532) + (xy 97.999998 49.694532) + (xy 97.773313 49.714364) + (xy 97.773302 49.714366) + (xy 97.553511 49.773258) + (xy 97.553502 49.773261) + (xy 97.347267 49.869431) + (xy 97.347265 49.869432) + (xy 97.160858 49.999954) + (xy 96.999954 50.160858) + (xy 96.869432 50.347265) + (xy 96.869431 50.347267) + (xy 96.773261 50.553502) + (xy 96.773258 50.553511) + (xy 96.714366 50.773302) + (xy 96.714364 50.773313) + (xy 96.694532 50.999998) + (xy 96.694532 51.000001) + (xy 96.714364 51.226686) + (xy 96.714366 51.226696) + (xy 96.750167 51.360307) + (xy 96.748504 51.430156) + (xy 96.709341 51.488019) + (xy 96.645113 51.515523) + (xy 96.630392 51.5164) + (xy 90.419253 51.5164) + (xy 90.352214 51.496715) + (xy 90.331572 51.480081) + (xy 89.467703 50.616212) + (xy 89.45788 50.60395) + (xy 89.457659 50.604134) + (xy 89.452686 50.598123) + (xy 89.420867 50.568243) + (xy 89.402264 50.550773) + (xy 89.391819 50.540328) + (xy 89.381375 50.529883) + (xy 89.375886 50.525625) + (xy 89.371461 50.521847) + (xy 89.337482 50.489938) + (xy 89.33748 50.489936) + (xy 89.337477 50.489935) + (xy 89.319929 50.480288) + (xy 89.303663 50.469604) + (xy 89.287833 50.457325) + (xy 89.245068 50.438818) + (xy 89.239822 50.436248) + (xy 89.198993 50.413803) + (xy 89.198992 50.413802) + (xy 89.179593 50.408822) + (xy 89.161181 50.402518) + (xy 89.142798 50.394562) + (xy 89.142792 50.39456) + (xy 89.096774 50.387272) + (xy 89.091052 50.386087) + (xy 89.045915 50.374499) + (xy 89.038689 50.373586) + (xy 88.974646 50.345653) + (xy 88.952659 50.321689) + (xy 88.840047 50.160861) + (xy 88.840045 50.160858) + (xy 88.679141 49.999954) + (xy 88.492734 49.869432) + (xy 88.492732 49.869431) + (xy 88.286497 49.773261) + (xy 88.286488 49.773258) + (xy 88.066697 49.714366) + (xy 88.066693 49.714365) + (xy 88.066692 49.714365) + (xy 88.066691 49.714364) + (xy 88.066686 49.714364) + (xy 87.840002 49.694532) + (xy 87.839998 49.694532) + (xy 87.613313 49.714364) + (xy 87.613302 49.714366) + (xy 87.393511 49.773258) + (xy 87.393502 49.773261) + (xy 87.187267 49.869431) + (xy 87.187265 49.869432) + (xy 87.000858 49.999954) + (xy 86.839954 50.160858) + (xy 86.709432 50.347265) + (xy 86.709431 50.347267) + (xy 86.613261 50.553502) + (xy 86.613258 50.553511) + (xy 86.554366 50.773302) + (xy 86.554364 50.773313) + (xy 86.534532 50.999998) + (xy 86.534532 51.000001) + (xy 86.554364 51.226686) + (xy 86.554366 51.226697) + (xy 86.613258 51.446488) + (xy 86.613261 51.446497) + (xy 86.709431 51.652732) + (xy 86.709432 51.652734) + (xy 86.839954 51.839141) + (xy 87.000858 52.000045) + (xy 87.000861 52.000047) + (xy 87.187266 52.130568) + (xy 87.393504 52.226739) + (xy 87.613308 52.285635) + (xy 87.77523 52.299801) + (xy 87.839998 52.305468) + (xy 87.84 52.305468) + (xy 87.840002 52.305468) + (xy 87.896673 52.300509) + (xy 88.066692 52.285635) + (xy 88.286496 52.226739) + (xy 88.492734 52.130568) + (xy 88.679139 52.000047) + (xy 88.793068 51.886117) + (xy 88.854389 51.852634) + (xy 88.924081 51.857618) + (xy 88.968428 51.886118) + (xy 89.304185 52.221876) + (xy 89.607997 52.525688) + (xy 89.617822 52.537951) + (xy 89.618043 52.537769) + (xy 89.623014 52.543778) + (xy 89.643143 52.56268) + (xy 89.673435 52.591126) + (xy 89.694329 52.61202) + (xy 89.699811 52.616273) + (xy 89.704243 52.620057) + (xy 89.738218 52.651962) + (xy 89.755776 52.661614) + (xy 89.772035 52.672295) + (xy 89.787864 52.684573) + (xy 89.830638 52.703082) + (xy 89.835856 52.705638) + (xy 89.876708 52.728097) + (xy 89.896116 52.73308) + (xy 89.914517 52.73938) + (xy 89.932904 52.747337) + (xy 89.976288 52.754208) + (xy 89.978919 52.754625) + (xy 89.984639 52.755809) + (xy 90.029781 52.7674) + (xy 90.049816 52.7674) + (xy 90.069214 52.768926) + (xy 90.088994 52.772059) + (xy 90.088995 52.77206) + (xy 90.088995 52.772059) + (xy 90.088996 52.77206) + (xy 90.135384 52.767675) + (xy 90.141222 52.7674) + (xy 119.082257 52.7674) + (xy 119.097877 52.769124) + (xy 119.097904 52.768839) + (xy 119.10566 52.769571) + (xy 119.105667 52.769573) + (xy 119.174814 52.7674) + (xy 119.20435 52.7674) + (xy 119.211228 52.76653) + (xy 119.217041 52.766072) + (xy 119.263627 52.764609) + (xy 119.282869 52.759017) + (xy 119.301912 52.755074) + (xy 119.321792 52.752564) + (xy 119.365122 52.735407) + (xy 119.370646 52.733517) + (xy 119.374396 52.732427) + (xy 119.41539 52.720518) + (xy 119.432629 52.710322) + (xy 119.450103 52.701762) + (xy 119.468729 52.694387) + (xy 119.468728 52.694387) + (xy 119.468732 52.694386) + (xy 119.506439 52.666989) + (xy 119.511305 52.663792) + (xy 119.55142 52.64007) + (xy 119.565583 52.625907) + (xy 119.580371 52.613275) + (xy 119.596587 52.601494) + (xy 119.614311 52.580067) + (xy 119.630831 52.56355) + (xy 119.631867 52.562692) + (xy 119.631877 52.562686) + (xy 119.679228 52.512262) + (xy 119.70012 52.491371) + (xy 119.704379 52.485878) + (xy 119.708152 52.481461) + (xy 119.740062 52.447482) + (xy 119.749715 52.42992) + (xy 119.760389 52.41367) + (xy 119.772673 52.397836) + (xy 119.79118 52.355067) + (xy 119.793749 52.349824) + (xy 119.816196 52.308993) + (xy 119.816197 52.308992) + (xy 119.821177 52.289591) + (xy 119.827478 52.271188) + (xy 119.835438 52.252796) + (xy 119.840335 52.221872) + (xy 119.870261 52.15874) + (xy 119.929571 52.121806) + (xy 119.999434 52.122801) + (xy 120.021255 52.131908) + (xy 120.105659 52.177023) + (xy 120.298967 52.235662) + (xy 120.5 52.255462) + (xy 120.701033 52.235662) + (xy 120.894341 52.177023) + (xy 121.072494 52.081798) + (xy 121.228647 51.953647) + (xy 121.356798 51.797494) + (xy 121.369611 51.773521) + (xy 121.413696 51.691047) + (xy 121.462658 51.641203) + (xy 121.523054 51.6255) + (xy 122.876 51.6255) + (xy 122.943039 51.645185) + (xy 122.988794 51.697989) + (xy 123 51.7495) + (xy 123 59.258931) + (xy 122.980315 59.32597) + (xy 122.963688 59.346605) + (xy 122.957372 59.352922) + (xy 122.942573 59.365563) + (xy 122.926416 59.377302) + (xy 122.926413 59.377304) + (xy 122.896674 59.413252) + (xy 122.892749 59.417567) + (xy 121.888172 60.422467) + (xy 121.826855 60.455962) + (xy 121.800477 60.4588) + (xy 121.643746 60.4588) + (xy 121.576707 60.439115) + (xy 121.530952 60.386311) + (xy 121.520343 60.322647) + (xy 121.525 60.275358) + (xy 121.525 60.25) + (xy 120.77956 60.25) + (xy 120.818278 60.207941) + (xy 120.868551 60.09333) + (xy 120.878886 59.968605) + (xy 120.848163 59.847281) + (xy 120.784606 59.75) + (xy 121.525 59.75) + (xy 121.525 59.724642) + (xy 121.51017 59.574067) + (xy 121.451556 59.380845) + (xy 121.356384 59.20279) + (xy 121.356379 59.202784) + (xy 121.228292 59.046707) + (xy 121.072215 58.91862) + (xy 121.072209 58.918615) + (xy 120.89415 58.823441) + (xy 120.75 58.779712) + (xy 120.75 59.719382) + (xy 120.680948 59.665637) + (xy 120.562576 59.625) + (xy 120.468927 59.625) + (xy 120.376554 59.640414) + (xy 120.266486 59.699981) + (xy 120.254369 59.713142) + (xy 120.250299 59.671808) + (xy 120.25 59.665728) + (xy 120.25 58.779712) + (xy 120.105851 58.82344) + (xy 120.023091 58.867676) + (xy 119.954688 58.881917) + (xy 119.889445 58.856916) + (xy 119.848075 58.800611) + (xy 119.841617 58.773858) + (xy 119.840664 58.766308) + (xy 119.81952 58.712906) + (xy 119.818211 58.70927) + (xy 119.800467 58.654659) + (xy 119.796089 58.647761) + (xy 119.785495 58.626968) + (xy 119.782486 58.619368) + (xy 119.748736 58.572915) + (xy 119.746545 58.569692) + (xy 119.715786 58.521223) + (xy 119.709833 58.515633) + (xy 119.694398 58.498125) + (xy 119.689594 58.491513) + (xy 119.689591 58.491511) + (xy 119.689591 58.49151) + (xy 119.645361 58.45492) + (xy 119.642438 58.452343) + (xy 119.600585 58.41304) + (xy 119.600577 58.413034) + (xy 119.593415 58.409097) + (xy 119.574114 58.39598) + (xy 119.567824 58.390776) + (xy 119.515878 58.366332) + (xy 119.512417 58.364569) + (xy 119.462092 58.336903) + (xy 119.462089 58.336902) + (xy 119.462085 58.3369) + (xy 119.454174 58.334869) + (xy 119.432222 58.326966) + (xy 119.424825 58.323485) + (xy 119.424821 58.323484) + (xy 119.368444 58.31273) + (xy 119.364644 58.31188) + (xy 119.309023 58.2976) + (xy 119.309019 58.2976) + (xy 119.300847 58.2976) + (xy 119.277615 58.295404) + (xy 119.269588 58.293873) + (xy 119.269586 58.293873) + (xy 119.260633 58.294436) + (xy 119.212275 58.297478) + (xy 119.208403 58.2976) + (xy 117.338019 58.2976) + (xy 117.331181 58.297222) + (xy 117.314793 58.295404) + (xy 117.290431 58.292701) + (xy 117.290424 58.292701) + (xy 117.249632 58.298485) + (xy 117.240918 58.2991) + (xy 110.158847 58.2991) + (xy 110.143299 58.297381) + (xy 110.143271 58.29768) + (xy 110.135508 58.296943) + (xy 110.066274 58.2991) + (xy 110.03665 58.2991) + (xy 110.036646 58.2991) + (xy 110.036635 58.299101) + (xy 110.029858 58.299957) + (xy 110.024023 58.300415) + (xy 109.977545 58.301863) + (xy 109.958206 58.307476) + (xy 109.939188 58.311411) + (xy 109.936863 58.311705) + (xy 109.919211 58.313935) + (xy 109.9192 58.313938) + (xy 109.875977 58.331052) + (xy 109.870432 58.33295) + (xy 109.825774 58.34591) + (xy 109.808432 58.35616) + (xy 109.790992 58.3647) + (xy 109.772268 58.372113) + (xy 109.738678 58.396517) + (xy 109.672871 58.419995) + (xy 109.6278 58.412799) + (xy 109.627437 58.413979) + (xy 109.623007 58.412612) + (xy 109.623004 58.412611) + (xy 109.472971 58.366332) + (xy 109.379466 58.337489) + (xy 109.379462 58.337488) + (xy 109.379458 58.337487) + (xy 109.258231 58.319214) + (xy 109.12744 58.2995) + (xy 109.127435 58.2995) + (xy 108.872565 58.2995) + (xy 108.872559 58.2995) + (xy 108.715609 58.323157) + (xy 108.620542 58.337487) + (xy 108.620539 58.337488) + (xy 108.620533 58.337489) + (xy 108.376992 58.412612) + (xy 108.147373 58.52319) + (xy 108.147372 58.523191) + (xy 107.936782 58.666768) + (xy 107.749952 58.840121) + (xy 107.74995 58.840123) + (xy 107.591041 59.039388) + (xy 107.463608 59.260109) + (xy 107.370492 59.497362) + (xy 107.37049 59.497369) + (xy 107.313777 59.745845) + (xy 107.294732 59.999995) + (xy 107.294732 60.000004) + (xy 107.313777 60.254154) + (xy 107.359838 60.455962) + (xy 107.370492 60.502637) + (xy 107.463607 60.739888) + (xy 107.591041 60.960612) + (xy 107.74995 61.159877) + (xy 107.936783 61.333232) + (xy 108.147366 61.476805) + (xy 108.147371 61.476807) + (xy 108.147372 61.476808) + (xy 108.147373 61.476809) + (xy 108.261373 61.531708) + (xy 108.376992 61.587387) + (xy 108.376993 61.587387) + (xy 108.376996 61.587389) + (xy 108.620542 61.662513) + (xy 108.872565 61.7005) + (xy 109.127435 61.7005) + (xy 109.379458 61.662513) + (xy 109.623004 61.587389) + (xy 109.77262 61.515337) + (xy 109.841558 61.503986) + (xy 109.905693 61.531708) + (xy 109.944659 61.589703) + (xy 109.946084 61.659558) + (xy 109.914101 61.714738) + (xy 96.290925 75.33818) + (xy 96.229602 75.371666) + (xy 96.203243 75.3745) + (xy 95.054188 75.3745) + (xy 94.987149 75.354815) + (xy 94.952613 75.321623) + (xy 94.840045 75.160858) + (xy 94.679141 74.999954) + (xy 94.492734 74.869432) + (xy 94.492732 74.869431) + (xy 94.286497 74.773261) + (xy 94.286488 74.773258) + (xy 94.066697 74.714366) + (xy 94.066693 74.714365) + (xy 94.066692 74.714365) + (xy 94.066691 74.714364) + (xy 94.066686 74.714364) + (xy 93.840002 74.694532) + (xy 93.839998 74.694532) + (xy 93.613313 74.714364) + (xy 93.613302 74.714366) + (xy 93.393511 74.773258) + (xy 93.393502 74.773261) + (xy 93.187267 74.869431) + (xy 93.187265 74.869432) + (xy 93.000858 74.999954) + (xy 92.839954 75.160858) + (xy 92.709432 75.347265) + (xy 92.709431 75.347267) + (xy 92.613261 75.553502) + (xy 92.613258 75.553511) + (xy 92.554366 75.773302) + (xy 92.554364 75.773313) + (xy 92.534532 75.999998) + (xy 92.534532 76.000001) + (xy 92.554364 76.226686) + (xy 92.554366 76.226697) + (xy 92.613258 76.446488) + (xy 92.613261 76.446497) + (xy 92.709431 76.652732) + (xy 92.709432 76.652734) + (xy 92.839954 76.839141) + (xy 93.000858 77.000045) + (xy 93.000861 77.000047) + (xy 93.187266 77.130568) + (xy 93.393504 77.226739) + (xy 93.393509 77.22674) + (xy 93.393511 77.226741) + (xy 93.41075 77.23136) + (xy 93.613308 77.285635) + (xy 93.77523 77.299801) + (xy 93.839998 77.305468) + (xy 93.84 77.305468) + (xy 93.840002 77.305468) + (xy 93.896673 77.300509) + (xy 94.066692 77.285635) + (xy 94.286496 77.226739) + (xy 94.492734 77.130568) + (xy 94.679139 77.000047) + (xy 94.840047 76.839139) + (xy 94.952613 76.678377) + (xy 95.007189 76.634752) + (xy 95.054188 76.6255) + (xy 96.430961 76.6255) + (xy 96.446578 76.627224) + (xy 96.446605 76.626939) + (xy 96.454366 76.627671) + (xy 96.454373 76.627673) + (xy 96.523506 76.6255) + (xy 96.55305 76.6255) + (xy 96.553051 76.6255) + (xy 96.553051 76.625499) + (xy 96.55855 76.624804) + (xy 96.559925 76.624631) + (xy 96.565757 76.624171) + (xy 96.612333 76.622708) + (xy 96.631569 76.617118) + (xy 96.650614 76.613174) + (xy 96.670492 76.610664) + (xy 96.71383 76.593504) + (xy 96.719348 76.591615) + (xy 96.764096 76.578615) + (xy 96.78133 76.568422) + (xy 96.798805 76.55986) + (xy 96.817432 76.552486) + (xy 96.855149 76.525081) + (xy 96.859988 76.521902) + (xy 96.900125 76.498166) + (xy 96.914287 76.484002) + (xy 96.929083 76.471366) + (xy 96.93061 76.470256) + (xy 96.945287 76.459594) + (xy 96.975013 76.42366) + (xy 96.978904 76.419384) + (xy 110.381436 63.016594) + (xy 112.197775 61.20022) + (xy 112.259098 61.166734) + (xy 112.285457 61.1639) + (xy 117.111461 61.1639) + (xy 117.1785 61.183585) + (xy 117.185771 61.188633) + (xy 117.192664 61.193793) + (xy 117.192671 61.193797) + (xy 117.22829 61.207082) + (xy 117.272628 61.235573) + (xy 117.505214 61.468115) + (xy 117.515017 61.480353) + (xy 117.515242 61.480168) + (xy 117.520212 61.486175) + (xy 117.520213 61.486176) + (xy 117.520214 61.486177) + (xy 117.543401 61.507951) + (xy 117.570654 61.533544) + (xy 117.591571 61.554458) + (xy 117.597029 61.558691) + (xy 117.601478 61.56249) + (xy 117.635418 61.594362) + (xy 117.635419 61.594363) + (xy 117.643514 61.598812) + (xy 117.653 61.604028) + (xy 117.669252 61.614701) + (xy 117.685114 61.627003) + (xy 117.723933 61.643797) + (xy 117.727853 61.645493) + (xy 117.733096 61.64806) + (xy 117.773908 61.670497) + (xy 117.793345 61.675487) + (xy 117.811733 61.681782) + (xy 117.83016 61.689754) + (xy 117.837323 61.692853) + (xy 117.836281 61.69526) + (xy 117.884458 61.726023) + (xy 117.91367 61.789493) + (xy 117.903929 61.858681) + (xy 117.858329 61.911618) + (xy 117.791348 61.931499) + (xy 117.790984 61.9315) + (xy 112.445737 61.9315) + (xy 112.43012 61.929776) + (xy 112.430093 61.930062) + (xy 112.422331 61.929327) + (xy 112.353203 61.9315) + (xy 112.32365 61.9315) + (xy 112.322929 61.93159) + (xy 112.316757 61.932369) + (xy 112.310945 61.932826) + (xy 112.264372 61.93429) + (xy 112.264369 61.934291) + (xy 112.245126 61.939881) + (xy 112.226083 61.943825) + (xy 112.206204 61.946336) + (xy 112.206203 61.946337) + (xy 112.162878 61.96349) + (xy 112.157352 61.965382) + (xy 112.112608 61.978383) + (xy 112.112604 61.978385) + (xy 112.095365 61.98858) + (xy 112.077898 61.997137) + (xy 112.059269 62.004512) + (xy 112.059267 62.004513) + (xy 112.021564 62.031906) + (xy 112.016682 62.035112) + (xy 111.97658 62.058828) + (xy 111.962408 62.073) + (xy 111.947623 62.085628) + (xy 111.931412 62.097407) + (xy 111.901709 62.13331) + (xy 111.897777 62.137631) + (xy 94.073579 79.96183) + (xy 93.834821 80.200587) + (xy 93.773498 80.234071) + (xy 93.715048 80.23268) + (xy 93.646697 80.214366) + (xy 93.646693 80.214365) + (xy 93.646692 80.214365) + (xy 93.506811 80.202127) + (xy 93.420001 80.194532) + (xy 93.419998 80.194532) + (xy 93.193313 80.214364) + (xy 93.193302 80.214366) + (xy 92.973511 80.273258) + (xy 92.973502 80.273261) + (xy 92.767267 80.369431) + (xy 92.767265 80.369432) + (xy 92.580858 80.499954) + (xy 92.419954 80.660858) + (xy 92.289432 80.847265) + (xy 92.289431 80.847267) + (xy 92.193261 81.053502) + (xy 92.193258 81.053511) + (xy 92.134366 81.273302) + (xy 92.134364 81.273313) + (xy 92.114532 81.499998) + (xy 92.114532 81.500001) + (xy 92.134364 81.726686) + (xy 92.134366 81.726697) + (xy 92.193258 81.946488) + (xy 92.193261 81.946497) + (xy 92.289431 82.152732) + (xy 92.289432 82.152734) + (xy 92.419954 82.339141) + (xy 92.580858 82.500045) + (xy 92.741623 82.612613) + (xy 92.785248 82.667189) + (xy 92.7945 82.714188) + (xy 92.7945 84.017255) + (xy 92.792775 84.032872) + (xy 92.793061 84.032899) + (xy 92.792326 84.040665) + (xy 92.7945 84.109814) + (xy 92.7945 84.139343) + (xy 92.794501 84.13936) + (xy 92.795368 84.146231) + (xy 92.795826 84.15205) + (xy 92.79729 84.198624) + (xy 92.797291 84.198627) + (xy 92.80288 84.217867) + (xy 92.806824 84.236911) + (xy 92.809336 84.256791) + (xy 92.82649 84.300119) + (xy 92.828382 84.305647) + (xy 92.841382 84.35039) + (xy 92.846397 84.358871) + (xy 92.85158 84.367634) + (xy 92.860136 84.3851) + (xy 92.863464 84.393504) + (xy 92.867514 84.403732) + (xy 92.894898 84.441423) + (xy 92.898106 84.446307) + (xy 92.921827 84.486416) + (xy 92.921833 84.486424) + (xy 92.93599 84.50058) + (xy 92.948628 84.515376) + (xy 92.960405 84.531586) + (xy 92.960406 84.531587) + (xy 92.996309 84.561288) + (xy 93.00062 84.56521) + (xy 93.275408 84.839998) + (xy 93.659197 85.223788) + (xy 93.669022 85.236051) + (xy 93.669243 85.235869) + (xy 93.674214 85.241878) + (xy 93.700217 85.266295) + (xy 93.724635 85.289226) + (xy 93.745529 85.31012) + (xy 93.751011 85.314373) + (xy 93.755443 85.318157) + (xy 93.789418 85.350062) + (xy 93.806976 85.359714) + (xy 93.823233 85.370393) + (xy 93.839064 85.382673) + (xy 93.858737 85.391186) + (xy 93.881833 85.401182) + (xy 93.887077 85.40375) + (xy 93.927908 85.426197) + (xy 93.940523 85.429435) + (xy 93.947305 85.431177) + (xy 93.965719 85.437481) + (xy 93.984104 85.445438) + (xy 94.030157 85.452732) + (xy 94.035826 85.453906) + (xy 94.080981 85.4655) + (xy 94.101016 85.4655) + (xy 94.120413 85.467026) + (xy 94.140196 85.47016) + (xy 94.186584 85.465775) + (xy 94.192422 85.4655) + (xy 102.785812 85.4655) + (xy 102.852851 85.485185) + (xy 102.887387 85.518377) + (xy 102.999954 85.679141) + (xy 103.160858 85.840045) + (xy 103.160861 85.840047) + (xy 103.347266 85.970568) + (xy 103.553504 86.066739) + (xy 103.773308 86.125635) + (xy 103.93523 86.139801) + (xy 103.999998 86.145468) + (xy 104 86.145468) + (xy 104.000002 86.145468) + (xy 104.056673 86.140509) + (xy 104.226692 86.125635) + (xy 104.446496 86.066739) + (xy 104.652734 85.970568) + (xy 104.839139 85.840047) + (xy 105.000047 85.679139) + (xy 105.130568 85.492734) + (xy 105.226739 85.286496) + (xy 105.285635 85.066692) + (xy 105.305468 84.84) + (xy 105.285635 84.613308) + (xy 105.226739 84.393504) + (xy 105.130568 84.187266) + (xy 105.000047 84.000861) + (xy 105.000045 84.000858) + (xy 104.839141 83.839954) + (xy 104.652734 83.709432) + (xy 104.652732 83.709431) + (xy 104.446497 83.613261) + (xy 104.446488 83.613258) + (xy 104.226697 83.554366) + (xy 104.226693 83.554365) + (xy 104.226692 83.554365) + (xy 104.226691 83.554364) + (xy 104.226686 83.554364) + (xy 104.000002 83.534532) + (xy 103.999998 83.534532) + (xy 103.773313 83.554364) + (xy 103.773302 83.554366) + (xy 103.553511 83.613258) + (xy 103.553502 83.613261) + (xy 103.347267 83.709431) + (xy 103.347265 83.709432) + (xy 103.160858 83.839954) + (xy 102.999954 84.000858) + (xy 102.887387 84.161623) + (xy 102.832811 84.205248) + (xy 102.785812 84.2145) + (xy 94.470452 84.2145) + (xy 94.403413 84.194815) + (xy 94.382771 84.178181) + (xy 94.081819 83.877228) + (xy 94.048334 83.815905) + (xy 94.0455 83.789547) + (xy 94.0455 82.714187) + (xy 94.065185 82.647148) + (xy 94.098379 82.612611) + (xy 94.117527 82.599204) + (xy 94.150328 82.58285) + (xy 94.188441 82.570467) + (xy 94.321877 82.485786) + (xy 94.430062 82.370582) + (xy 94.506197 82.232092) + (xy 94.507074 82.228673) + (xy 94.525605 82.188383) + (xy 94.550568 82.152734) + (xy 94.646739 81.946496) + (xy 94.705635 81.726692) + (xy 94.725468 81.500001) + (xy 102.274532 81.500001) + (xy 102.294364 81.726686) + (xy 102.294366 81.726697) + (xy 102.353258 81.946488) + (xy 102.353261 81.946497) + (xy 102.449431 82.152732) + (xy 102.449432 82.152734) + (xy 102.579954 82.339141) + (xy 102.740858 82.500045) + (xy 102.740861 82.500047) + (xy 102.927266 82.630568) + (xy 103.133504 82.726739) + (xy 103.133509 82.72674) + (xy 103.133511 82.726741) + (xy 103.143334 82.729373) + (xy 103.353308 82.785635) + (xy 103.51523 82.799801) + (xy 103.579998 82.805468) + (xy 103.58 82.805468) + (xy 103.580002 82.805468) + (xy 103.636673 82.800509) + (xy 103.806692 82.785635) + (xy 104.026496 82.726739) + (xy 104.232734 82.630568) + (xy 104.419139 82.500047) + (xy 104.580047 82.339139) + (xy 104.710568 82.152734) + (xy 104.806739 81.946496) + (xy 104.865635 81.726692) + (xy 104.885468 81.5) + (xy 104.865635 81.273308) + (xy 104.806739 81.053504) + (xy 104.710568 80.847266) + (xy 104.580047 80.660861) + (xy 104.580045 80.660858) + (xy 104.419141 80.499954) + (xy 104.232734 80.369432) + (xy 104.232732 80.369431) + (xy 104.026497 80.273261) + (xy 104.026488 80.273258) + (xy 103.806697 80.214366) + (xy 103.806693 80.214365) + (xy 103.806692 80.214365) + (xy 103.806691 80.214364) + (xy 103.806686 80.214364) + (xy 103.580002 80.194532) + (xy 103.579998 80.194532) + (xy 103.353313 80.214364) + (xy 103.353302 80.214366) + (xy 103.133511 80.273258) + (xy 103.133502 80.273261) + (xy 102.927267 80.369431) + (xy 102.927265 80.369432) + (xy 102.740858 80.499954) + (xy 102.579954 80.660858) + (xy 102.449432 80.847265) + (xy 102.449431 80.847267) + (xy 102.353261 81.053502) + (xy 102.353258 81.053511) + (xy 102.294366 81.273302) + (xy 102.294364 81.273313) + (xy 102.274532 81.499998) + (xy 102.274532 81.500001) + (xy 94.725468 81.500001) + (xy 94.725468 81.5) + (xy 94.705635 81.273308) + (xy 94.687318 81.204948) + (xy 94.688981 81.135103) + (xy 94.719408 81.085181) + (xy 94.93012 80.874471) + (xy 94.930121 80.874468) + (xy 94.93549 80.8691) + (xy 94.935498 80.86909) + (xy 112.585772 63.218819) + (xy 112.647095 63.185334) + (xy 112.673453 63.1825) + (xy 113.251623 63.1825) + (xy 113.318662 63.202185) + (xy 113.364417 63.254989) + (xy 113.374361 63.324147) + (xy 113.364005 63.358905) + (xy 113.273261 63.553502) + (xy 113.273258 63.553511) + (xy 113.214366 63.773302) + (xy 113.214364 63.773313) + (xy 113.194532 63.999998) + (xy 113.194532 64.000001) + (xy 113.214364 64.226686) + (xy 113.214366 64.226697) + (xy 113.273258 64.446488) + (xy 113.273261 64.446497) + (xy 113.369431 64.652732) + (xy 113.369432 64.652734) + (xy 113.499954 64.839141) + (xy 113.660858 65.000045) + (xy 113.660861 65.000047) + (xy 113.847266 65.130568) + (xy 114.053504 65.226739) + (xy 114.273308 65.285635) + (xy 114.43523 65.299801) + (xy 114.499998 65.305468) + (xy 114.5 65.305468) + (xy 114.500002 65.305468) + (xy 114.556673 65.300509) + (xy 114.726692 65.285635) + (xy 114.946496 65.226739) + (xy 115.152734 65.130568) + (xy 115.339139 65.000047) + (xy 115.500047 64.839139) + (xy 115.630568 64.652734) + (xy 115.726739 64.446496) + (xy 115.785635 64.226692) + (xy 115.805468 64) + (xy 115.785635 63.773308) + (xy 115.726739 63.553504) + (xy 115.635994 63.358903) + (xy 115.625503 63.289828) + (xy 115.654023 63.226044) + (xy 115.712499 63.187804) + (xy 115.748377 63.1825) + (xy 122.876 63.1825) + (xy 122.943039 63.202185) + (xy 122.988794 63.254989) + (xy 123 63.3065) + (xy 123 69.2505) + (xy 122.980315 69.317539) + (xy 122.927511 69.363294) + (xy 122.876 69.3745) + (xy 121.480882 69.3745) + (xy 121.413843 69.354815) + (xy 121.368088 69.302011) + (xy 121.358144 69.232853) + (xy 121.385029 69.171835) + (xy 121.396797 69.157495) + (xy 121.396801 69.157488) + (xy 121.492021 68.979345) + (xy 121.492021 68.979344) + (xy 121.492023 68.979341) + (xy 121.550662 68.786033) + (xy 121.5655 68.63538) + (xy 121.5655 68.08462) + (xy 121.550662 67.933967) + (xy 121.492023 67.740659) + (xy 121.492021 67.740656) + (xy 121.492021 67.740654) + (xy 121.396801 67.562511) + (xy 121.396799 67.562509) + (xy 121.396798 67.562506) + (xy 121.357824 67.515016) + (xy 121.268647 67.406352) + (xy 121.112495 67.278203) + (xy 121.112488 67.278198) + (xy 120.934345 67.182978) + (xy 120.741031 67.124337) + (xy 120.54 67.104538) + (xy 120.338968 67.124337) + (xy 120.145655 67.182978) + (xy 120.063024 67.227145) + (xy 119.994621 67.241386) + (xy 119.929378 67.216385) + (xy 119.888008 67.16008) + (xy 119.88155 67.133326) + (xy 119.880664 67.126308) + (xy 119.85952 67.072906) + (xy 119.858211 67.06927) + (xy 119.840467 67.014659) + (xy 119.836089 67.007761) + (xy 119.825495 66.986968) + (xy 119.822486 66.979368) + (xy 119.788736 66.932915) + (xy 119.786545 66.929692) + (xy 119.755785 66.881222) + (xy 119.749834 66.875634) + (xy 119.734398 66.858125) + (xy 119.729594 66.851513) + (xy 119.729591 66.851511) + (xy 119.729591 66.85151) + (xy 119.685361 66.81492) + (xy 119.682438 66.812343) + (xy 119.640585 66.77304) + (xy 119.640577 66.773034) + (xy 119.633415 66.769097) + (xy 119.614114 66.75598) + (xy 119.607824 66.750776) + (xy 119.555878 66.726332) + (xy 119.552417 66.724569) + (xy 119.502092 66.696903) + (xy 119.502089 66.696902) + (xy 119.502085 66.6969) + (xy 119.494174 66.694869) + (xy 119.472222 66.686966) + (xy 119.464825 66.683485) + (xy 119.464821 66.683484) + (xy 119.408444 66.67273) + (xy 119.404644 66.67188) + (xy 119.349023 66.6576) + (xy 119.349019 66.6576) + (xy 119.340847 66.6576) + (xy 119.317615 66.655404) + (xy 119.309588 66.653873) + (xy 119.309586 66.653873) + (xy 119.300633 66.654436) + (xy 119.252275 66.657478) + (xy 119.248403 66.6576) + (xy 111.18675 66.6576) + (xy 111.17114 66.655876) + (xy 111.171113 66.656163) + (xy 111.163349 66.655428) + (xy 111.098093 66.657478) + (xy 111.094208 66.6576) + (xy 111.064639 66.6576) + (xy 111.057764 66.658469) + (xy 111.051944 66.658926) + (xy 111.005387 66.660389) + (xy 111.005385 66.660389) + (xy 110.98614 66.665979) + (xy 110.967103 66.669921) + (xy 110.947217 66.672434) + (xy 110.947211 66.672435) + (xy 110.947208 66.672436) + (xy 110.932202 66.678377) + (xy 110.903879 66.68959) + (xy 110.898352 66.691482) + (xy 110.853624 66.704476) + (xy 110.853618 66.704479) + (xy 110.836367 66.71468) + (xy 110.818907 66.723233) + (xy 110.80027 66.730612) + (xy 110.762574 66.757998) + (xy 110.757692 66.761205) + (xy 110.717589 66.784922) + (xy 110.703413 66.799096) + (xy 110.688634 66.811719) + (xy 110.672412 66.823506) + (xy 110.642713 66.859406) + (xy 110.63878 66.863727) + (xy 110.197019 67.305468) + (xy 102.440214 75.061896) + (xy 102.427944 75.071729) + (xy 102.428126 75.071948) + (xy 102.422121 75.076914) + (xy 102.374773 75.127334) + (xy 102.353884 75.148223) + (xy 102.349624 75.153714) + (xy 102.345838 75.158146) + (xy 102.313939 75.192115) + (xy 102.313938 75.192116) + (xy 102.304289 75.209668) + (xy 102.293608 75.225927) + (xy 102.281335 75.241747) + (xy 102.281334 75.241751) + (xy 102.262822 75.284525) + (xy 102.260253 75.289769) + (xy 102.237803 75.330607) + (xy 102.237803 75.330608) + (xy 102.232821 75.350008) + (xy 102.226521 75.368408) + (xy 102.218567 75.386787) + (xy 102.218567 75.38679) + (xy 102.211272 75.43283) + (xy 102.210091 75.438533) + (xy 102.1985 75.483678) + (xy 102.1985 75.503701) + (xy 102.196973 75.523102) + (xy 102.193839 75.542879) + (xy 102.198225 75.589275) + (xy 102.1985 75.595112) + (xy 102.1985 77.109255) + (xy 102.196775 77.124872) + (xy 102.197061 77.124899) + (xy 102.196326 77.132665) + (xy 102.1985 77.201814) + (xy 102.1985 77.231343) + (xy 102.198501 77.23136) + (xy 102.199368 77.238231) + (xy 102.199826 77.24405) + (xy 102.20129 77.290624) + (xy 102.201291 77.290627) + (xy 102.20688 77.309867) + (xy 102.210824 77.328911) + (xy 102.213336 77.348791) + (xy 102.23049 77.392119) + (xy 102.232382 77.397647) + (xy 102.245382 77.44239) + (xy 102.247808 77.446493) + (xy 102.25558 77.459634) + (xy 102.264136 77.4771) + (xy 102.271514 77.495732) + (xy 102.280293 77.507816) + (xy 102.298898 77.533423) + (xy 102.302106 77.538307) + (xy 102.325827 77.578416) + (xy 102.325833 77.578424) + (xy 102.33999 77.59258) + (xy 102.352628 77.607376) + (xy 102.364405 77.623586) + (xy 102.364406 77.623587) + (xy 102.400309 77.653288) + (xy 102.40462 77.65721) + (xy 104.491948 79.744538) + (xy 106.515384 81.767974) + (xy 106.548869 81.829297) + (xy 106.543885 81.898989) + (xy 106.502013 81.954922) + (xy 106.480108 81.968037) + (xy 106.347517 82.029865) + (xy 106.161179 82.160342) + (xy 106.000342 82.321179) + (xy 105.869865 82.507517) + (xy 105.773734 82.713673) + (xy 105.77373 82.713682) + (xy 105.721127 82.909999) + (xy 105.721128 82.91) + (xy 106.684314 82.91) + (xy 106.672359 82.921955) + (xy 106.614835 83.034852) + (xy 106.595014 83.16) + (xy 106.614835 83.285148) + (xy 106.672359 83.398045) + (xy 106.684314 83.41) + (xy 105.721128 83.41) + (xy 105.77373 83.606317) + (xy 105.773734 83.606326) + (xy 105.869865 83.812482) + (xy 106.000342 83.99882) + (xy 106.161179 84.159657) + (xy 106.347517 84.290134) + (xy 106.553673 84.386265) + (xy 106.553682 84.386269) + (xy 106.749999 84.438872) + (xy 106.75 84.438871) + (xy 106.75 83.475686) + (xy 106.761955 83.487641) + (xy 106.874852 83.545165) + (xy 106.968519 83.56) + (xy 107.031481 83.56) + (xy 107.125148 83.545165) + (xy 107.238045 83.487641) + (xy 107.25 83.475686) + (xy 107.25 84.438872) + (xy 107.446317 84.386269) + (xy 107.446326 84.386265) + (xy 107.657389 84.287846) + (xy 107.658411 84.290039) + (xy 107.716349 84.275958) + (xy 107.782385 84.298783) + (xy 107.825598 84.353686) + (xy 107.8345 84.39982) + (xy 107.8345 87.363) + (xy 107.814815 87.430039) + (xy 107.762011 87.475794) + (xy 107.7105 87.487) + (xy 101.176634 87.487) + (xy 101.160947 87.48527) + (xy 101.160922 87.485543) + (xy 101.153156 87.484811) + (xy 101.084098 87.487) + (xy 101.05465 87.487) + (xy 101.054647 87.487) + (xy 101.054635 87.487001) + (xy 101.047668 87.487881) + (xy 101.041867 87.488337) + (xy 100.995197 87.489817) + (xy 100.976061 87.495383) + (xy 100.95698 87.499337) + (xy 100.94691 87.50061) + (xy 100.937207 87.501836) + (xy 100.893782 87.519028) + (xy 100.888273 87.520915) + (xy 100.843447 87.533952) + (xy 100.843446 87.533953) + (xy 100.826291 87.544104) + (xy 100.808798 87.552676) + (xy 100.790273 87.560011) + (xy 100.790266 87.560015) + (xy 100.752487 87.587461) + (xy 100.747621 87.590659) + (xy 100.70744 87.614437) + (xy 100.707439 87.614438) + (xy 100.693351 87.628534) + (xy 100.678536 87.641191) + (xy 100.662413 87.652905) + (xy 100.632645 87.688886) + (xy 100.628726 87.693195) + (xy 100.208378 88.11378) + (xy 100.147064 88.147283) + (xy 100.077371 88.142318) + (xy 100.032992 88.113806) + (xy 99.919139 87.999953) + (xy 99.919138 87.999952) + (xy 99.919137 87.999951) + (xy 99.732734 87.869432) + (xy 99.732732 87.869431) + (xy 99.526497 87.773261) + (xy 99.526488 87.773258) + (xy 99.306697 87.714366) + (xy 99.306693 87.714365) + (xy 99.306692 87.714365) + (xy 99.306691 87.714364) + (xy 99.306686 87.714364) + (xy 99.080002 87.694532) + (xy 99.079998 87.694532) + (xy 98.853313 87.714364) + (xy 98.853302 87.714366) + (xy 98.633511 87.773258) + (xy 98.633502 87.773261) + (xy 98.427267 87.869431) + (xy 98.427265 87.869432) + (xy 98.240858 87.999954) + (xy 98.079954 88.160858) + (xy 97.949432 88.347265) + (xy 97.949431 88.347267) + (xy 97.853261 88.553502) + (xy 97.853258 88.553511) + (xy 97.794366 88.773302) + (xy 97.794364 88.773313) + (xy 97.774532 88.999998) + (xy 97.774532 89.000001) + (xy 97.794364 89.226686) + (xy 97.794366 89.226697) + (xy 97.853258 89.446488) + (xy 97.853261 89.446497) + (xy 97.949431 89.652732) + (xy 97.949432 89.652734) + (xy 98.079954 89.839141) + (xy 98.240858 90.000045) + (xy 98.240861 90.000047) + (xy 98.427266 90.130568) + (xy 98.633504 90.226739) + (xy 98.633509 90.22674) + (xy 98.633511 90.226741) + (xy 98.666805 90.235662) + (xy 98.853308 90.285635) + (xy 99.01523 90.299801) + (xy 99.079998 90.305468) + (xy 99.08 90.305468) + (xy 99.080002 90.305468) + (xy 99.136673 90.300509) + (xy 99.306692 90.285635) + (xy 99.526496 90.226739) + (xy 99.732734 90.130568) + (xy 99.919139 90.000047) + (xy 100.080047 89.839139) + (xy 100.194323 89.675933) + (xy 100.248898 89.63231) + (xy 100.291971 89.62312) + (xy 100.305803 89.622682) + (xy 100.324939 89.617116) + (xy 100.344024 89.61316) + (xy 100.363792 89.610664) + (xy 100.407222 89.593467) + (xy 100.412712 89.591587) + (xy 100.457553 89.578547) + (xy 100.474706 89.568395) + (xy 100.492196 89.559824) + (xy 100.510732 89.552486) + (xy 100.548521 89.525029) + (xy 100.553375 89.521841) + (xy 100.56879 89.512719) + (xy 100.593561 89.498061) + (xy 100.60765 89.483962) + (xy 100.622465 89.471306) + (xy 100.638587 89.459594) + (xy 100.668352 89.423612) + (xy 100.672256 89.41932) + (xy 101.316871 88.774342) + (xy 101.378185 88.740841) + (xy 101.404577 88.738) + (xy 107.3105 88.738) + (xy 107.377539 88.757685) + (xy 107.423294 88.810489) + (xy 107.4345 88.862) + (xy 107.4345 89.79787) + (xy 107.434501 89.797876) + (xy 107.440908 89.857483) + (xy 107.491202 89.992328) + (xy 107.491206 89.992335) + (xy 107.577452 90.107544) + (xy 107.577455 90.107547) + (xy 107.692664 90.193793) + (xy 107.692671 90.193797) + (xy 107.827517 90.244091) + (xy 107.827516 90.244091) + (xy 107.834444 90.244835) + (xy 107.887127 90.2505) + (xy 109.032872 90.250499) + (xy 109.092483 90.244091) + (xy 109.227331 90.193796) + (xy 109.227335 90.193792) + (xy 109.235118 90.189544) + (xy 109.236252 90.191621) + (xy 109.289715 90.171671) + (xy 109.334576 90.176694) + (xy 109.335656 90.177021) + (xy 109.335659 90.177023) + (xy 109.528967 90.235662) + (xy 109.73 90.255462) + (xy 109.931033 90.235662) + (xy 110.124341 90.177023) + (xy 110.134354 90.171671) + (xy 110.307078 90.079348) + (xy 110.37548 90.065106) + (xy 110.423985 90.079348) + (xy 110.605848 90.176557) + (xy 110.75 90.220285) + (xy 110.75 89.33427) + (xy 110.750299 89.32819) + (xy 110.754629 89.28422) + (xy 110.819052 89.334363) + (xy 110.937424 89.375) + (xy 111.031073 89.375) + (xy 111.123446 89.359586) + (xy 111.233514 89.300019) + (xy 111.25 89.28211) + (xy 111.25 90.220285) + (xy 111.394153 90.176557) + (xy 111.572209 90.081384) + (xy 111.572215 90.081379) + (xy 111.728292 89.953292) + (xy 111.856379 89.797215) + (xy 111.856384 89.797209) + (xy 111.951556 89.619154) + (xy 112.01017 89.425932) + (xy 112.025 89.275357) + (xy 112.025 89.25) + (xy 111.27956 89.25) + (xy 111.318278 89.207941) + (xy 111.368551 89.09333) + (xy 111.378886 88.968605) + (xy 111.348163 88.847281) + (xy 111.284606 88.75) + (xy 112.025 88.75) + (xy 112.025 88.724642) + (xy 112.01017 88.574067) + (xy 111.951556 88.380845) + (xy 111.856384 88.20279) + (xy 111.856379 88.202784) + (xy 111.728292 88.046707) + (xy 111.572215 87.91862) + (xy 111.572209 87.918615) + (xy 111.39415 87.823441) + (xy 111.25 87.779712) + (xy 111.25 88.719382) + (xy 111.180948 88.665637) + (xy 111.062576 88.625) + (xy 110.968927 88.625) + (xy 110.876554 88.640414) + (xy 110.766486 88.699981) + (xy 110.754369 88.713142) + (xy 110.750299 88.671808) + (xy 110.75 88.665728) + (xy 110.75 87.779712) + (xy 110.605849 87.823441) + (xy 110.423983 87.920651) + (xy 110.35558 87.934893) + (xy 110.307077 87.920651) + (xy 110.124345 87.822978) + (xy 109.931031 87.764337) + (xy 109.73 87.744538) + (xy 109.528968 87.764337) + (xy 109.390959 87.806202) + (xy 109.335659 87.822977) + (xy 109.335658 87.822977) + (xy 109.334575 87.823306) + (xy 109.264708 87.823929) + (xy 109.235618 87.809529) + (xy 109.235114 87.810454) + (xy 109.227328 87.806202) + (xy 109.166167 87.783391) + (xy 109.110233 87.74152) + (xy 109.085816 87.676056) + (xy 109.0855 87.667209) + (xy 109.0855 82.910742) + (xy 109.087224 82.895122) + (xy 109.086939 82.895095) + (xy 109.087673 82.887333) + (xy 109.085872 82.829999) + (xy 109.721127 82.829999) + (xy 109.721128 82.83) + (xy 110.684314 82.83) + (xy 110.672359 82.841955) + (xy 110.614835 82.954852) + (xy 110.595014 83.08) + (xy 110.614835 83.205148) + (xy 110.672359 83.318045) + (xy 110.684314 83.33) + (xy 109.721128 83.33) + (xy 109.77373 83.526317) + (xy 109.773734 83.526326) + (xy 109.869865 83.732482) + (xy 110.000342 83.91882) + (xy 110.161179 84.079657) + (xy 110.347517 84.210134) + (xy 110.553673 84.306265) + (xy 110.553682 84.306269) + (xy 110.749999 84.358872) + (xy 110.75 84.358871) + (xy 110.75 83.395686) + (xy 110.761955 83.407641) + (xy 110.874852 83.465165) + (xy 110.968519 83.48) + (xy 111.031481 83.48) + (xy 111.125148 83.465165) + (xy 111.238045 83.407641) + (xy 111.25 83.395686) + (xy 111.25 84.358872) + (xy 111.446317 84.306269) + (xy 111.446326 84.306265) + (xy 111.652482 84.210134) + (xy 111.83882 84.079657) + (xy 111.999657 83.91882) + (xy 112.130134 83.732482) + (xy 112.226265 83.526326) + (xy 112.226269 83.526317) + (xy 112.278872 83.33) + (xy 111.315686 83.33) + (xy 111.327641 83.318045) + (xy 111.385165 83.205148) + (xy 111.404986 83.08) + (xy 111.385165 82.954852) + (xy 111.327641 82.841955) + (xy 111.315686 82.83) + (xy 112.278872 82.83) + (xy 112.278872 82.829999) + (xy 112.226269 82.633682) + (xy 112.226265 82.633673) + (xy 112.130134 82.427517) + (xy 111.999657 82.241179) + (xy 111.83882 82.080342) + (xy 111.652482 81.949865) + (xy 111.446328 81.853734) + (xy 111.25 81.801127) + (xy 111.25 82.764314) + (xy 111.238045 82.752359) + (xy 111.125148 82.694835) + (xy 111.031481 82.68) + (xy 110.968519 82.68) + (xy 110.874852 82.694835) + (xy 110.761955 82.752359) + (xy 110.75 82.764314) + (xy 110.75 81.801127) + (xy 110.553671 81.853734) + (xy 110.347517 81.949865) + (xy 110.161179 82.080342) + (xy 110.000342 82.241179) + (xy 109.869865 82.427517) + (xy 109.773734 82.633673) + (xy 109.77373 82.633682) + (xy 109.721127 82.829999) + (xy 109.085872 82.829999) + (xy 109.0855 82.818172) + (xy 109.0855 82.788656) + (xy 109.0855 82.78865) + (xy 109.084631 82.781779) + (xy 109.084173 82.775952) + (xy 109.083672 82.76) + (xy 109.08271 82.729373) + (xy 109.077119 82.71013) + (xy 109.073173 82.691078) + (xy 109.070664 82.671208) + (xy 109.053504 82.627867) + (xy 109.051624 82.622379) + (xy 109.038618 82.57761) + (xy 109.028422 82.56037) + (xy 109.019861 82.542894) + (xy 109.012487 82.52427) + (xy 109.012486 82.524268) + (xy 108.985079 82.486545) + (xy 108.981888 82.481686) + (xy 108.958172 82.441583) + (xy 108.958165 82.441574) + (xy 108.944006 82.427415) + (xy 108.931368 82.412619) + (xy 108.919594 82.396413) + (xy 108.888369 82.370582) + (xy 108.883688 82.366709) + (xy 108.879376 82.362786) + (xy 104.024407 77.507816) + (xy 103.990922 77.446493) + (xy 103.995906 77.376801) + (xy 104.037778 77.320868) + (xy 104.10128 77.296607) + (xy 104.226692 77.285635) + (xy 104.446496 77.226739) + (xy 104.652734 77.130568) + (xy 104.839139 77.000047) + (xy 105.000047 76.839139) + (xy 105.112613 76.678377) + (xy 105.167189 76.634752) + (xy 105.214188 76.6255) + (xy 105.524265 76.6255) + (xy 105.539887 76.627224) + (xy 105.539914 76.62694) + (xy 105.547672 76.627672) + (xy 105.54768 76.627674) + (xy 105.616817 76.6255) + (xy 105.64635 76.6255) + (xy 105.653229 76.62463) + (xy 105.659052 76.624171) + (xy 105.705639 76.622707) + (xy 105.724871 76.617118) + (xy 105.743916 76.613174) + (xy 105.763792 76.610664) + (xy 105.807119 76.593509) + (xy 105.807127 76.593506) + (xy 105.812643 76.591616) + (xy 105.857401 76.578613) + (xy 105.874636 76.568419) + (xy 105.892106 76.55986) + (xy 105.910732 76.552486) + (xy 105.948437 76.52509) + (xy 105.953302 76.521894) + (xy 105.99343 76.498163) + (xy 106.007595 76.483996) + (xy 106.022388 76.471362) + (xy 106.038587 76.459594) + (xy 106.068295 76.423681) + (xy 106.072207 76.419381) + (xy 109.496597 72.994858) + (xy 109.557918 72.961374) + (xy 109.627609 72.966357) + (xy 109.683544 73.008228) + (xy 109.707806 73.071731) + (xy 109.714364 73.146687) + (xy 109.714366 73.146697) + (xy 109.773258 73.366488) + (xy 109.773261 73.366497) + (xy 109.869431 73.572732) + (xy 109.869432 73.572734) + (xy 109.999954 73.759141) + (xy 110.160858 73.920045) + (xy 110.160861 73.920047) + (xy 110.347266 74.050568) + (xy 110.553504 74.146739) + (xy 110.553509 74.14674) + (xy 110.553511 74.146741) + (xy 110.602995 74.16) + (xy 110.773308 74.205635) + (xy 110.93523 74.219801) + (xy 110.999998 74.225468) + (xy 111 74.225468) + (xy 111.000002 74.225468) + (xy 111.056673 74.220509) + (xy 111.226692 74.205635) + (xy 111.446496 74.146739) + (xy 111.652734 74.050568) + (xy 111.839139 73.920047) + (xy 112.000047 73.759139) + (xy 112.130568 73.572734) + (xy 112.226739 73.366496) + (xy 112.285635 73.146692) + (xy 112.305468 72.92) + (xy 112.285635 72.693308) + (xy 112.226739 72.473504) + (xy 112.130568 72.267266) + (xy 112.000047 72.080861) + (xy 112.000045 72.080858) + (xy 111.839141 71.919954) + (xy 111.652734 71.789432) + (xy 111.652732 71.789431) + (xy 111.57072 71.751188) + (xy 111.446496 71.693261) + (xy 111.446493 71.69326) + (xy 111.445282 71.692819) + (xy 111.444823 71.692481) + (xy 111.441589 71.690973) + (xy 111.441892 71.690322) + (xy 111.389021 71.651388) + (xy 111.36409 71.586118) + (xy 111.378405 71.51773) + (xy 111.427421 71.467938) + (xy 111.487701 71.4523) + (xy 111.864518 71.4523) + (xy 111.931557 71.471985) + (xy 111.952205 71.488624) + (xy 113.554417 73.091043) + (xy 113.587898 73.152369) + (xy 113.582909 73.22206) + (xy 113.554413 73.266399) + (xy 113.499952 73.320861) + (xy 113.369432 73.507265) + (xy 113.369431 73.507267) + (xy 113.273261 73.713502) + (xy 113.273258 73.713511) + (xy 113.214366 73.933302) + (xy 113.214364 73.933313) + (xy 113.194532 74.159998) + (xy 113.194532 74.160001) + (xy 113.214364 74.386686) + (xy 113.214366 74.386697) + (xy 113.273258 74.606488) + (xy 113.273261 74.606497) + (xy 113.369431 74.812732) + (xy 113.369432 74.812734) + (xy 113.499954 74.999141) + (xy 113.660858 75.160045) + (xy 113.706659 75.192115) + (xy 113.847266 75.290568) + (xy 114.053504 75.386739) + (xy 114.273308 75.445635) + (xy 114.43523 75.459801) + (xy 114.499998 75.465468) + (xy 114.5 75.465468) + (xy 114.500002 75.465468) + (xy 114.556673 75.460509) + (xy 114.726692 75.445635) + (xy 114.946496 75.386739) + (xy 115.152734 75.290568) + (xy 115.339139 75.160047) + (xy 115.500047 74.999139) + (xy 115.630568 74.812734) + (xy 115.726739 74.606496) + (xy 115.785635 74.386692) + (xy 115.805468 74.16) + (xy 115.803148 74.133488) + (xy 115.791474 74.000047) + (xy 115.785635 73.933308) + (xy 115.726739 73.713504) + (xy 115.630568 73.507266) + (xy 115.500047 73.320861) + (xy 115.500045 73.320858) + (xy 115.339141 73.159954) + (xy 115.213144 73.071731) + (xy 115.152734 73.029432) + (xy 115.152732 73.029431) + (xy 115.148299 73.026327) + (xy 115.148992 73.025337) + (xy 115.104884 72.979066) + (xy 115.09982 72.96792) + (xy 115.093517 72.952001) + (xy 115.091623 72.946467) + (xy 115.08751 72.932309) + (xy 115.078634 72.901748) + (xy 115.068426 72.884484) + (xy 115.059869 72.867015) + (xy 115.052487 72.848369) + (xy 115.02511 72.810688) + (xy 115.021899 72.8058) + (xy 114.998195 72.765712) + (xy 114.984016 72.751532) + (xy 114.971381 72.736737) + (xy 114.959596 72.720515) + (xy 114.9267 72.693302) + (xy 114.92371 72.690828) + (xy 114.919385 72.686893) + (xy 113.147172 70.91445) + (xy 113.113692 70.853126) + (xy 113.118681 70.783435) + (xy 113.147167 70.739106) + (xy 113.762811 70.123328) + (xy 113.824131 70.089837) + (xy 113.850502 70.087) + (xy 117.149343 70.087) + (xy 117.216382 70.106685) + (xy 117.237065 70.12336) + (xy 117.497144 70.383681) + (xy 117.507038 70.396036) + (xy 117.507242 70.395868) + (xy 117.512212 70.401876) + (xy 117.562524 70.449123) + (xy 117.572986 70.459594) + (xy 117.583311 70.469928) + (xy 117.588924 70.474286) + (xy 117.593332 70.478052) + (xy 117.607586 70.491438) + (xy 117.627416 70.510061) + (xy 117.627421 70.510064) + (xy 117.644813 70.519625) + (xy 117.66112 70.530342) + (xy 117.676812 70.542525) + (xy 117.689723 70.548119) + (xy 117.719719 70.561116) + (xy 117.724942 70.563676) + (xy 117.752122 70.578618) + (xy 117.765908 70.586197) + (xy 117.785142 70.591135) + (xy 117.803603 70.597461) + (xy 117.821818 70.605354) + (xy 117.82182 70.605354) + (xy 117.821824 70.605356) + (xy 117.868008 70.612692) + (xy 117.873685 70.613869) + (xy 117.918981 70.6255) + (xy 117.938841 70.6255) + (xy 117.958295 70.627035) + (xy 117.977904 70.630151) + (xy 118.013547 70.626798) + (xy 118.02445 70.625773) + (xy 118.03026 70.6255) + (xy 122.876 70.6255) + (xy 122.943039 70.645185) + (xy 122.988794 70.697989) + (xy 123 70.7495) + (xy 123 101.876) + (xy 122.980315 101.943039) + (xy 122.927511 101.988794) + (xy 122.876 102) + (xy 88.124 102) + (xy 88.056961 101.980315) + (xy 88.011206 101.927511) + (xy 88 101.876) + (xy 88 99.000001) + (xy 101.614532 99.000001) + (xy 101.634364 99.226686) + (xy 101.634366 99.226697) + (xy 101.693258 99.446488) + (xy 101.693261 99.446497) + (xy 101.789431 99.652732) + (xy 101.789432 99.652734) + (xy 101.919954 99.839141) + (xy 102.080858 100.000045) + (xy 102.080861 100.000047) + (xy 102.267266 100.130568) + (xy 102.473504 100.226739) + (xy 102.693308 100.285635) + (xy 102.85523 100.299801) + (xy 102.919998 100.305468) + (xy 102.92 100.305468) + (xy 102.920002 100.305468) + (xy 102.976673 100.300509) + (xy 103.146692 100.285635) + (xy 103.366496 100.226739) + (xy 103.572734 100.130568) + (xy 103.759139 100.000047) + (xy 103.920047 99.839139) + (xy 104.050568 99.652734) + (xy 104.146739 99.446496) + (xy 104.205635 99.226692) + (xy 104.225468 99.000001) + (xy 111.774532 99.000001) + (xy 111.794364 99.226686) + (xy 111.794366 99.226697) + (xy 111.853258 99.446488) + (xy 111.853261 99.446497) + (xy 111.949431 99.652732) + (xy 111.949432 99.652734) + (xy 112.079954 99.839141) + (xy 112.240858 100.000045) + (xy 112.240861 100.000047) + (xy 112.427266 100.130568) + (xy 112.633504 100.226739) + (xy 112.853308 100.285635) + (xy 113.01523 100.299801) + (xy 113.079998 100.305468) + (xy 113.08 100.305468) + (xy 113.080002 100.305468) + (xy 113.136673 100.300509) + (xy 113.306692 100.285635) + (xy 113.526496 100.226739) + (xy 113.732734 100.130568) + (xy 113.919139 100.000047) + (xy 114.080047 99.839139) + (xy 114.195546 99.674188) + (xy 114.250122 99.630563) + (xy 114.289333 99.621556) + (xy 114.325138 99.619304) + (xy 114.332905 99.61678) + (xy 114.35568 99.611688) + (xy 114.363792 99.610664) + (xy 114.417195 99.589519) + (xy 114.420835 99.588209) + (xy 114.475441 99.570467) + (xy 114.482337 99.56609) + (xy 114.503133 99.555494) + (xy 114.510732 99.552486) + (xy 114.557191 99.51873) + (xy 114.56039 99.516555) + (xy 114.608877 99.485786) + (xy 114.614466 99.479833) + (xy 114.631979 99.464394) + (xy 114.638587 99.459594) + (xy 114.67519 99.415347) + (xy 114.677736 99.412457) + (xy 114.717062 99.370582) + (xy 114.720998 99.363421) + (xy 114.734119 99.344114) + (xy 114.739324 99.337823) + (xy 114.763769 99.285874) + (xy 114.765528 99.282419) + (xy 114.793197 99.232092) + (xy 114.795227 99.224181) + (xy 114.803135 99.202218) + (xy 114.806614 99.194826) + (xy 114.817377 99.138401) + (xy 114.81821 99.13467) + (xy 114.8325 99.079019) + (xy 114.8325 99.070844) + (xy 114.834697 99.047606) + (xy 114.836227 99.039588) + (xy 114.832621 98.982275) + (xy 114.8325 98.978403) + (xy 114.8325 98.293547) + (xy 114.852185 98.226508) + (xy 114.868818 98.205867) + (xy 115.367057 97.707616) + (xy 117.791495 95.283117) + (xy 117.852817 95.249632) + (xy 117.919441 95.253517) + (xy 117.945018 95.262298) + (xy 118.059485 95.281399) + (xy 118.173951 95.3005) + (xy 118.173952 95.3005) + (xy 118.406048 95.3005) + (xy 118.406049 95.3005) + (xy 118.634981 95.262298) + (xy 118.854503 95.186936) + (xy 119.058626 95.07647) + (xy 119.241784 94.933913) + (xy 119.398979 94.763153) + (xy 119.525924 94.568849) + (xy 119.619157 94.3563) + (xy 119.676134 94.131305) + (xy 119.676135 94.131297) + (xy 119.6953 93.900006) + (xy 119.6953 93.899993) + (xy 119.676135 93.668702) + (xy 119.676133 93.668691) + (xy 119.619157 93.443699) + (xy 119.525924 93.231151) + (xy 119.398983 93.036852) + (xy 119.39898 93.036849) + (xy 119.398979 93.036847) + (xy 119.241784 92.866087) + (xy 119.241779 92.866083) + (xy 119.241777 92.866081) + (xy 119.058634 92.723535) + (xy 119.058628 92.723531) + (xy 118.854504 92.613064) + (xy 118.854495 92.613061) + (xy 118.634984 92.537702) + (xy 118.44445 92.505908) + (xy 118.406049 92.4995) + (xy 118.173951 92.4995) + (xy 118.13555 92.505908) + (xy 117.945015 92.537702) + (xy 117.725504 92.613061) + (xy 117.725495 92.613064) + (xy 117.521371 92.723531) + (xy 117.521365 92.723535) + (xy 117.338222 92.866081) + (xy 117.338218 92.866085) + (xy 117.329866 92.875158) + (xy 117.269979 92.911148) + (xy 117.200141 92.909047) + (xy 117.142525 92.869522) + (xy 117.122455 92.834507) + (xy 117.093797 92.757671) + (xy 117.093793 92.757664) + (xy 117.007547 92.642455) + (xy 117.007544 92.642452) + (xy 116.892335 92.556206) + (xy 116.892328 92.556202) + (xy 116.757482 92.505908) + (xy 116.757483 92.505908) + (xy 116.697883 92.499501) + (xy 116.697881 92.4995) + (xy 116.697873 92.4995) + (xy 116.697864 92.4995) + (xy 114.802129 92.4995) + (xy 114.802123 92.499501) + (xy 114.742516 92.505908) + (xy 114.607671 92.556202) + (xy 114.607664 92.556206) + (xy 114.492455 92.642452) + (xy 114.492452 92.642455) + (xy 114.406206 92.757664) + (xy 114.406202 92.757671) + (xy 114.355908 92.892517) + (xy 114.349501 92.952116) + (xy 114.3495 92.952135) + (xy 114.3495 94.84787) + (xy 114.349501 94.847876) + (xy 114.355908 94.907483) + (xy 114.406202 95.042328) + (xy 114.406206 95.042335) + (xy 114.492452 95.157544) + (xy 114.492455 95.157547) + (xy 114.607664 95.243793) + (xy 114.607671 95.243797) + (xy 114.742517 95.294091) + (xy 114.742516 95.294091) + (xy 114.749444 95.294835) + (xy 114.802127 95.3005) + (xy 115.705597 95.300499) + (xy 115.772636 95.320183) + (xy 115.818391 95.372987) + (xy 115.828335 95.442146) + (xy 115.79931 95.505702) + (xy 115.793279 95.512179) + (xy 113.823206 97.482299) + (xy 113.810949 97.492123) + (xy 113.811131 97.492343) + (xy 113.805122 97.497313) + (xy 113.773879 97.530584) + (xy 113.757766 97.547743) + (xy 113.74732 97.558189) + (xy 113.736873 97.568636) + (xy 113.736866 97.568644) + (xy 113.732617 97.57412) + (xy 113.72883 97.578554) + (xy 113.696939 97.612515) + (xy 113.687283 97.63008) + (xy 113.676605 97.646336) + (xy 113.664322 97.662171) + (xy 113.649432 97.696581) + (xy 113.604741 97.750289) + (xy 113.538109 97.771309) + (xy 113.503538 97.767109) + (xy 113.306697 97.714366) + (xy 113.306693 97.714365) + (xy 113.306692 97.714365) + (xy 113.306691 97.714364) + (xy 113.306686 97.714364) + (xy 113.080002 97.694532) + (xy 113.079998 97.694532) + (xy 112.853313 97.714364) + (xy 112.853302 97.714366) + (xy 112.633511 97.773258) + (xy 112.633502 97.773261) + (xy 112.427267 97.869431) + (xy 112.427265 97.869432) + (xy 112.240858 97.999954) + (xy 112.079954 98.160858) + (xy 111.949432 98.347265) + (xy 111.949431 98.347267) + (xy 111.853261 98.553502) + (xy 111.853258 98.553511) + (xy 111.794366 98.773302) + (xy 111.794364 98.773313) + (xy 111.774532 98.999998) + (xy 111.774532 99.000001) + (xy 104.225468 99.000001) + (xy 104.225468 99) + (xy 104.205635 98.773308) + (xy 104.146739 98.553504) + (xy 104.050568 98.347266) + (xy 103.920047 98.160861) + (xy 103.920045 98.160858) + (xy 103.759141 97.999954) + (xy 103.572734 97.869432) + (xy 103.572732 97.869431) + (xy 103.366497 97.773261) + (xy 103.366488 97.773258) + (xy 103.146697 97.714366) + (xy 103.146693 97.714365) + (xy 103.146692 97.714365) + (xy 103.146691 97.714364) + (xy 103.146686 97.714364) + (xy 102.920002 97.694532) + (xy 102.919998 97.694532) + (xy 102.693313 97.714364) + (xy 102.693302 97.714366) + (xy 102.473511 97.773258) + (xy 102.473502 97.773261) + (xy 102.267267 97.869431) + (xy 102.267265 97.869432) + (xy 102.080858 97.999954) + (xy 101.919954 98.160858) + (xy 101.789432 98.347265) + (xy 101.789431 98.347267) + (xy 101.693261 98.553502) + (xy 101.693258 98.553511) + (xy 101.634366 98.773302) + (xy 101.634364 98.773313) + (xy 101.614532 98.999998) + (xy 101.614532 99.000001) + (xy 88 99.000001) + (xy 88 97.237223) + (xy 88.019685 97.170184) + (xy 88.072489 97.124429) + (xy 88.141647 97.114485) + (xy 88.18224 97.128537) + (xy 88.18236 97.12828) + (xy 88.184846 97.129439) + (xy 88.186012 97.129843) + (xy 88.187255 97.13056) + (xy 88.187266 97.130568) + (xy 88.393504 97.226739) + (xy 88.613308 97.285635) + (xy 88.77523 97.299801) + (xy 88.839998 97.305468) + (xy 88.84 97.305468) + (xy 88.840002 97.305468) + (xy 88.896673 97.300509) + (xy 89.066692 97.285635) + (xy 89.286496 97.226739) + (xy 89.492734 97.130568) + (xy 89.679139 97.000047) + (xy 89.840047 96.839139) + (xy 89.970568 96.652734) + (xy 90.066739 96.446496) + (xy 90.125635 96.226692) + (xy 90.145468 96) + (xy 90.125635 95.773308) + (xy 90.066739 95.553504) + (xy 89.970568 95.347266) + (xy 89.840047 95.160861) + (xy 89.840045 95.160858) + (xy 89.679141 94.999954) + (xy 89.492734 94.869432) + (xy 89.492732 94.869431) + (xy 89.286497 94.773261) + (xy 89.286488 94.773258) + (xy 89.066697 94.714366) + (xy 89.066693 94.714365) + (xy 89.066692 94.714365) + (xy 89.066691 94.714364) + (xy 89.066686 94.714364) + (xy 88.840002 94.694532) + (xy 88.839998 94.694532) + (xy 88.613313 94.714364) + (xy 88.613302 94.714366) + (xy 88.393511 94.773258) + (xy 88.393502 94.773261) + (xy 88.187263 94.869433) + (xy 88.185998 94.870164) + (xy 88.18537 94.870316) + (xy 88.18236 94.87172) + (xy 88.182077 94.871114) + (xy 88.118098 94.886635) + (xy 88.052071 94.863782) + (xy 88.008882 94.80886) + (xy 88 94.762776) + (xy 88 93.751) + (xy 88.019685 93.683961) + (xy 88.072489 93.638206) + (xy 88.124 93.627) + (xy 95.691048 93.627) + (xy 95.758087 93.646685) + (xy 95.778729 93.663319) + (xy 97.700586 95.585177) + (xy 97.734071 95.6465) + (xy 97.73268 95.704949) + (xy 97.714367 95.773296) + (xy 97.714364 95.773313) + (xy 97.694532 95.999999) + (xy 97.694532 96.000001) + (xy 97.714364 96.226686) + (xy 97.714366 96.226697) + (xy 97.773258 96.446488) + (xy 97.773261 96.446497) + (xy 97.869431 96.652732) + (xy 97.869432 96.652734) + (xy 97.999954 96.839141) + (xy 98.160858 97.000045) + (xy 98.160861 97.000047) + (xy 98.347266 97.130568) + (xy 98.553504 97.226739) + (xy 98.773308 97.285635) + (xy 98.93523 97.299801) + (xy 98.999998 97.305468) + (xy 99 97.305468) + (xy 99.000002 97.305468) + (xy 99.056673 97.300509) + (xy 99.226692 97.285635) + (xy 99.446496 97.226739) + (xy 99.652734 97.130568) + (xy 99.839139 97.000047) + (xy 99.980068 96.859117) + (xy 100.041389 96.825634) + (xy 100.067748 96.8228) + (xy 107.219957 96.8228) + (xy 107.235577 96.824524) + (xy 107.235604 96.824239) + (xy 107.24336 96.824971) + (xy 107.243367 96.824973) + (xy 107.312514 96.8228) + (xy 107.34205 96.8228) + (xy 107.348928 96.82193) + (xy 107.354741 96.821472) + (xy 107.401327 96.820009) + (xy 107.420569 96.814417) + (xy 107.439612 96.810474) + (xy 107.459492 96.807964) + (xy 107.502822 96.790807) + (xy 107.508346 96.788917) + (xy 107.512096 96.787827) + (xy 107.55309 96.775918) + (xy 107.570329 96.765722) + (xy 107.587803 96.757162) + (xy 107.606427 96.749788) + (xy 107.606427 96.749787) + (xy 107.606432 96.749786) + (xy 107.644149 96.722382) + (xy 107.649005 96.719192) + (xy 107.68912 96.69547) + (xy 107.703289 96.681299) + (xy 107.718079 96.668668) + (xy 107.734287 96.656894) + (xy 107.763999 96.620976) + (xy 107.767912 96.616676) + (xy 114.226719 90.15787) + (xy 116.7045 90.15787) + (xy 116.704501 90.157876) + (xy 116.710908 90.217483) + (xy 116.761202 90.352328) + (xy 116.761206 90.352335) + (xy 116.847452 90.467544) + (xy 116.847455 90.467547) + (xy 116.962664 90.553793) + (xy 116.962671 90.553797) + (xy 117.097517 90.604091) + (xy 117.097516 90.604091) + (xy 117.104444 90.604835) + (xy 117.157127 90.6105) + (xy 118.302872 90.610499) + (xy 118.362483 90.604091) + (xy 118.497331 90.553796) + (xy 118.497335 90.553792) + (xy 118.505118 90.549544) + (xy 118.506252 90.551621) + (xy 118.559715 90.531671) + (xy 118.604576 90.536694) + (xy 118.605656 90.537021) + (xy 118.605659 90.537023) + (xy 118.798967 90.595662) + (xy 119 90.615462) + (xy 119.201033 90.595662) + (xy 119.394341 90.537023) + (xy 119.572494 90.441798) + (xy 119.572493 90.441798) + (xy 119.577078 90.439348) + (xy 119.64548 90.425106) + (xy 119.693985 90.439348) + (xy 119.875848 90.536557) + (xy 120.02 90.580285) + (xy 120.02 89.69427) + (xy 120.020299 89.68819) + (xy 120.024629 89.64422) + (xy 120.089052 89.694363) + (xy 120.207424 89.735) + (xy 120.301073 89.735) + (xy 120.393446 89.719586) + (xy 120.503514 89.660019) + (xy 120.52 89.64211) + (xy 120.52 90.580285) + (xy 120.664153 90.536557) + (xy 120.842209 90.441384) + (xy 120.842215 90.441379) + (xy 120.998292 90.313292) + (xy 121.126379 90.157215) + (xy 121.126384 90.157209) + (xy 121.221556 89.979154) + (xy 121.28017 89.785932) + (xy 121.295 89.635357) + (xy 121.295 89.61) + (xy 120.54956 89.61) + (xy 120.588278 89.567941) + (xy 120.638551 89.45333) + (xy 120.648886 89.328605) + (xy 120.618163 89.207281) + (xy 120.554606 89.11) + (xy 121.295 89.11) + (xy 121.295 89.084642) + (xy 121.28017 88.934067) + (xy 121.221556 88.740845) + (xy 121.126384 88.56279) + (xy 121.126379 88.562784) + (xy 120.998292 88.406707) + (xy 120.842215 88.27862) + (xy 120.842209 88.278615) + (xy 120.66415 88.183441) + (xy 120.52 88.139712) + (xy 120.52 89.079382) + (xy 120.450948 89.025637) + (xy 120.332576 88.985) + (xy 120.238927 88.985) + (xy 120.146554 89.000414) + (xy 120.036486 89.059981) + (xy 120.024369 89.073142) + (xy 120.020299 89.031808) + (xy 120.02 89.025728) + (xy 120.02 88.139712) + (xy 119.875849 88.183441) + (xy 119.693983 88.280651) + (xy 119.62558 88.294893) + (xy 119.577077 88.280651) + (xy 119.394345 88.182978) + (xy 119.201031 88.124337) + (xy 119 88.104538) + (xy 118.798968 88.124337) + (xy 118.678566 88.160861) + (xy 118.605659 88.182977) + (xy 118.605658 88.182977) + (xy 118.604575 88.183306) + (xy 118.534708 88.183929) + (xy 118.505618 88.169529) + (xy 118.505114 88.170454) + (xy 118.497328 88.166202) + (xy 118.362482 88.115908) + (xy 118.362483 88.115908) + (xy 118.302883 88.109501) + (xy 118.302881 88.1095) + (xy 118.302873 88.1095) + (xy 118.302864 88.1095) + (xy 117.157129 88.1095) + (xy 117.157123 88.109501) + (xy 117.097516 88.115908) + (xy 116.962671 88.166202) + (xy 116.962664 88.166206) + (xy 116.847455 88.252452) + (xy 116.847452 88.252455) + (xy 116.761206 88.367664) + (xy 116.761202 88.367671) + (xy 116.710908 88.502517) + (xy 116.704501 88.562116) + (xy 116.7045 88.562135) + (xy 116.7045 90.15787) + (xy 114.226719 90.15787) + (xy 118.113788 86.270801) + (xy 118.126042 86.260986) + (xy 118.125859 86.260764) + (xy 118.131866 86.255792) + (xy 118.131877 86.255786) + (xy 118.162775 86.222882) + (xy 118.179227 86.205364) + (xy 118.189671 86.194918) + (xy 118.20012 86.184471) + (xy 118.204379 86.178978) + (xy 118.208152 86.174561) + (xy 118.240062 86.140582) + (xy 118.249713 86.123024) + (xy 118.260396 86.106761) + (xy 118.272673 86.090936) + (xy 118.291185 86.048153) + (xy 118.293738 86.042941) + (xy 118.316197 86.002092) + (xy 118.32118 85.98268) + (xy 118.327481 85.96428) + (xy 118.335437 85.945896) + (xy 118.342729 85.899852) + (xy 118.343906 85.894171) + (xy 118.3555 85.849019) + (xy 118.3555 85.828983) + (xy 118.357027 85.809582) + (xy 118.36016 85.789804) + (xy 118.355775 85.743415) + (xy 118.3555 85.737577) + (xy 118.3555 82.33279) + (xy 118.375185 82.265751) + (xy 118.427989 82.219996) + (xy 118.43615 82.216614) + (xy 118.497331 82.193796) + (xy 118.497335 82.193792) + (xy 118.505118 82.189544) + (xy 118.506252 82.191621) + (xy 118.559715 82.171671) + (xy 118.604576 82.176694) + (xy 118.605656 82.177021) + (xy 118.605659 82.177023) + (xy 118.798967 82.235662) + (xy 119 82.255462) + (xy 119.201033 82.235662) + (xy 119.394341 82.177023) + (xy 119.425549 82.160342) + (xy 119.577078 82.079348) + (xy 119.64548 82.065106) + (xy 119.693985 82.079348) + (xy 119.875848 82.176557) + (xy 120.02 82.220285) + (xy 120.02 81.33427) + (xy 120.020299 81.32819) + (xy 120.024629 81.28422) + (xy 120.089052 81.334363) + (xy 120.207424 81.375) + (xy 120.301073 81.375) + (xy 120.393446 81.359586) + (xy 120.503514 81.300019) + (xy 120.52 81.28211) + (xy 120.52 82.220285) + (xy 120.664153 82.176557) + (xy 120.842209 82.081384) + (xy 120.842215 82.081379) + (xy 120.998292 81.953292) + (xy 121.126379 81.797215) + (xy 121.126384 81.797209) + (xy 121.221556 81.619154) + (xy 121.28017 81.425932) + (xy 121.295 81.275357) + (xy 121.295 81.25) + (xy 120.54956 81.25) + (xy 120.588278 81.207941) + (xy 120.638551 81.09333) + (xy 120.648886 80.968605) + (xy 120.618163 80.847281) + (xy 120.554606 80.75) + (xy 121.295 80.75) + (xy 121.295 80.724642) + (xy 121.28017 80.574067) + (xy 121.221556 80.380845) + (xy 121.126384 80.20279) + (xy 121.126379 80.202784) + (xy 120.998292 80.046707) + (xy 120.842215 79.91862) + (xy 120.842209 79.918615) + (xy 120.66415 79.823441) + (xy 120.52 79.779712) + (xy 120.52 80.719382) + (xy 120.450948 80.665637) + (xy 120.332576 80.625) + (xy 120.238927 80.625) + (xy 120.146554 80.640414) + (xy 120.036486 80.699981) + (xy 120.024369 80.713142) + (xy 120.020299 80.671808) + (xy 120.02 80.665728) + (xy 120.02 79.779712) + (xy 119.875849 79.823441) + (xy 119.693983 79.920651) + (xy 119.62558 79.934893) + (xy 119.577077 79.920651) + (xy 119.394345 79.822978) + (xy 119.201031 79.764337) + (xy 119 79.744538) + (xy 118.798968 79.764337) + (xy 118.660959 79.806202) + (xy 118.605659 79.822977) + (xy 118.605658 79.822977) + (xy 118.604575 79.823306) + (xy 118.534708 79.823929) + (xy 118.505618 79.809529) + (xy 118.505114 79.810454) + (xy 118.497328 79.806202) + (xy 118.362482 79.755908) + (xy 118.362483 79.755908) + (xy 118.302883 79.749501) + (xy 118.302881 79.7495) + (xy 118.302873 79.7495) + (xy 118.302864 79.7495) + (xy 117.157129 79.7495) + (xy 117.157123 79.749501) + (xy 117.097516 79.755908) + (xy 116.962671 79.806202) + (xy 116.962664 79.806206) + (xy 116.847455 79.892452) + (xy 116.847452 79.892455) + (xy 116.761206 80.007664) + (xy 116.761202 80.007671) + (xy 116.710908 80.142517) + (xy 116.704501 80.202116) + (xy 116.7045 80.202135) + (xy 116.7045 81.79787) + (xy 116.704501 81.797876) + (xy 116.710908 81.857483) + (xy 116.761202 81.992328) + (xy 116.761206 81.992335) + (xy 116.847452 82.107544) + (xy 116.847455 82.107547) + (xy 116.962664 82.193793) + (xy 116.962666 82.193794) + (xy 116.962669 82.193796) + (xy 117.023833 82.216608) + (xy 117.079766 82.258478) + (xy 117.104184 82.323942) + (xy 117.1045 82.33279) + (xy 117.1045 85.459547) + (xy 117.084815 85.526586) + (xy 117.068181 85.547228) + (xy 107.079928 95.535481) + (xy 107.018605 95.568966) + (xy 106.992247 95.5718) + (xy 105.354764 95.5718) + (xy 105.287725 95.552115) + (xy 105.24197 95.499311) + (xy 105.232026 95.430153) + (xy 105.234989 95.415707) + (xy 105.265858 95.3005) + (xy 105.285635 95.226692) + (xy 105.302849 95.029938) + (xy 105.305468 95.000001) + (xy 105.305468 94.999998) + (xy 105.29355 94.863782) + (xy 105.285635 94.773308) + (xy 105.226739 94.553504) + (xy 105.130568 94.347266) + (xy 105.032839 94.207693) + (xy 105.000045 94.160858) + (xy 104.839141 93.999954) + (xy 104.652734 93.869432) + (xy 104.652732 93.869431) + (xy 104.446497 93.773261) + (xy 104.446488 93.773258) + (xy 104.226697 93.714366) + (xy 104.226693 93.714365) + (xy 104.226692 93.714365) + (xy 104.226691 93.714364) + (xy 104.226686 93.714364) + (xy 104.000002 93.694532) + (xy 103.999999 93.694532) + (xy 103.773313 93.714364) + (xy 103.773296 93.714367) + (xy 103.704949 93.73268) + (xy 103.635099 93.731016) + (xy 103.585177 93.700586) + (xy 101.500803 91.616212) + (xy 101.49098 91.60395) + (xy 101.490759 91.604134) + (xy 101.485786 91.598123) + (xy 101.435364 91.550773) + (xy 101.424919 91.540328) + (xy 101.414475 91.529883) + (xy 101.408986 91.525625) + (xy 101.404561 91.521847) + (xy 101.370582 91.489938) + (xy 101.37058 91.489936) + (xy 101.370577 91.489935) + (xy 101.353029 91.480288) + (xy 101.336763 91.469604) + (xy 101.320933 91.457325) + (xy 101.278168 91.438818) + (xy 101.272922 91.436248) + (xy 101.232093 91.413803) + (xy 101.232092 91.413802) + (xy 101.212693 91.408822) + (xy 101.194281 91.402518) + (xy 101.175898 91.394562) + (xy 101.175892 91.39456) + (xy 101.129874 91.387272) + (xy 101.124152 91.386087) + (xy 101.079021 91.3745) + (xy 101.079019 91.3745) + (xy 101.058984 91.3745) + (xy 101.039586 91.372973) + (xy 101.032162 91.371797) + (xy 101.019805 91.36984) + (xy 101.019804 91.36984) + (xy 100.973416 91.374225) + (xy 100.967578 91.3745) + (xy 89.6695 91.3745) + (xy 89.602461 91.354815) + (xy 89.556706 91.302011) + (xy 89.5455 91.2505) + (xy 89.5455 90.214188) + (xy 89.565185 90.147149) + (xy 89.598377 90.112613) + (xy 89.675102 90.05889) + (xy 89.759139 90.000047) + (xy 89.920047 89.839139) + (xy 90.050568 89.652734) + (xy 90.146739 89.446496) + (xy 90.205635 89.226692) + (xy 90.225468 89) + (xy 90.205635 88.773308) + (xy 90.146739 88.553504) + (xy 90.050568 88.347266) + (xy 89.920047 88.160861) + (xy 89.920045 88.160858) + (xy 89.759141 87.999954) + (xy 89.572734 87.869432) + (xy 89.572732 87.869431) + (xy 89.366497 87.773261) + (xy 89.366488 87.773258) + (xy 89.146697 87.714366) + (xy 89.146693 87.714365) + (xy 89.146692 87.714365) + (xy 89.146691 87.714364) + (xy 89.146686 87.714364) + (xy 88.920002 87.694532) + (xy 88.919998 87.694532) + (xy 88.693313 87.714364) + (xy 88.693302 87.714366) + (xy 88.473511 87.773258) + (xy 88.473502 87.773261) + (xy 88.267267 87.869431) + (xy 88.195122 87.919947) + (xy 88.128916 87.942274) + (xy 88.061149 87.925262) + (xy 88.013336 87.874313) + (xy 88 87.818371) + (xy 88 84) + (xy 83.124 84) + (xy 83.056961 83.980315) + (xy 83.011206 83.927511) + (xy 83 83.876) + (xy 83 71.000001) + (xy 85.614532 71.000001) + (xy 85.634364 71.226686) + (xy 85.634366 71.226697) + (xy 85.693258 71.446488) + (xy 85.693261 71.446497) + (xy 85.789431 71.652732) + (xy 85.789432 71.652734) + (xy 85.919954 71.839141) + (xy 86.080858 72.000045) + (xy 86.080861 72.000047) + (xy 86.267266 72.130568) + (xy 86.473504 72.226739) + (xy 86.693308 72.285635) + (xy 86.85523 72.299801) + (xy 86.919998 72.305468) + (xy 86.92 72.305468) + (xy 86.920002 72.305468) + (xy 86.976673 72.300509) + (xy 87.146692 72.285635) + (xy 87.366496 72.226739) + (xy 87.572734 72.130568) + (xy 87.759139 72.000047) + (xy 87.920047 71.839139) + (xy 88.050568 71.652734) + (xy 88.146739 71.446496) + (xy 88.205635 71.226692) + (xy 88.225468 71) + (xy 88.205635 70.773308) + (xy 88.199389 70.749999) + (xy 95.801127 70.749999) + (xy 95.801128 70.75) + (xy 96.764314 70.75) + (xy 96.752359 70.761955) + (xy 96.694835 70.874852) + (xy 96.675014 71) + (xy 96.694835 71.125148) + (xy 96.752359 71.238045) + (xy 96.764314 71.25) + (xy 95.801128 71.25) + (xy 95.85373 71.446317) + (xy 95.853734 71.446326) + (xy 95.949865 71.652482) + (xy 96.080342 71.83882) + (xy 96.241179 71.999657) + (xy 96.427517 72.130134) + (xy 96.633673 72.226265) + (xy 96.633682 72.226269) + (xy 96.829999 72.278872) + (xy 96.83 72.278871) + (xy 96.83 71.315686) + (xy 96.841955 71.327641) + (xy 96.954852 71.385165) + (xy 97.048519 71.4) + (xy 97.111481 71.4) + (xy 97.205148 71.385165) + (xy 97.318045 71.327641) + (xy 97.33 71.315686) + (xy 97.33 72.278872) + (xy 97.526317 72.226269) + (xy 97.526326 72.226265) + (xy 97.732482 72.130134) + (xy 97.91882 71.999657) + (xy 98.079657 71.83882) + (xy 98.210134 71.652482) + (xy 98.306265 71.446326) + (xy 98.306269 71.446317) + (xy 98.358872 71.25) + (xy 97.395686 71.25) + (xy 97.407641 71.238045) + (xy 97.465165 71.125148) + (xy 97.484986 71) + (xy 97.465165 70.874852) + (xy 97.407641 70.761955) + (xy 97.395686 70.75) + (xy 98.358872 70.75) + (xy 98.358872 70.749999) + (xy 98.306269 70.553682) + (xy 98.306265 70.553673) + (xy 98.210134 70.347517) + (xy 98.079657 70.161179) + (xy 97.91882 70.000342) + (xy 97.732482 69.869865) + (xy 97.526328 69.773734) + (xy 97.33 69.721127) + (xy 97.33 70.684314) + (xy 97.318045 70.672359) + (xy 97.205148 70.614835) + (xy 97.111481 70.6) + (xy 97.048519 70.6) + (xy 96.954852 70.614835) + (xy 96.841955 70.672359) + (xy 96.83 70.684314) + (xy 96.83 69.721127) + (xy 96.633671 69.773734) + (xy 96.427517 69.869865) + (xy 96.241179 70.000342) + (xy 96.080342 70.161179) + (xy 95.949865 70.347517) + (xy 95.853734 70.553673) + (xy 95.85373 70.553682) + (xy 95.801127 70.749999) + (xy 88.199389 70.749999) + (xy 88.146739 70.553504) + (xy 88.050568 70.347266) + (xy 87.920047 70.160861) + (xy 87.920045 70.160858) + (xy 87.759141 69.999954) + (xy 87.572734 69.869432) + (xy 87.572732 69.869431) + (xy 87.366497 69.773261) + (xy 87.366488 69.773258) + (xy 87.146697 69.714366) + (xy 87.146693 69.714365) + (xy 87.146692 69.714365) + (xy 87.146691 69.714364) + (xy 87.146686 69.714364) + (xy 86.920002 69.694532) + (xy 86.919998 69.694532) + (xy 86.693313 69.714364) + (xy 86.693302 69.714366) + (xy 86.473511 69.773258) + (xy 86.473502 69.773261) + (xy 86.267267 69.869431) + (xy 86.267265 69.869432) + (xy 86.080858 69.999954) + (xy 85.919954 70.160858) + (xy 85.789432 70.347265) + (xy 85.789431 70.347267) + (xy 85.693261 70.553502) + (xy 85.693258 70.553511) + (xy 85.634366 70.773302) + (xy 85.634364 70.773313) + (xy 85.614532 70.999998) + (xy 85.614532 71.000001) + (xy 83 71.000001) + (xy 83 66.000001) + (xy 85.694532 66.000001) + (xy 85.714364 66.226686) + (xy 85.714366 66.226697) + (xy 85.773258 66.446488) + (xy 85.773261 66.446497) + (xy 85.869431 66.652732) + (xy 85.869432 66.652734) + (xy 85.999954 66.839141) + (xy 86.160858 67.000045) + (xy 86.181729 67.014659) + (xy 86.347266 67.130568) + (xy 86.553504 67.226739) + (xy 86.773308 67.285635) + (xy 86.93523 67.299801) + (xy 86.999998 67.305468) + (xy 87 67.305468) + (xy 87.000002 67.305468) + (xy 87.056673 67.300509) + (xy 87.226692 67.285635) + (xy 87.446496 67.226739) + (xy 87.652734 67.130568) + (xy 87.839139 67.000047) + (xy 88.000047 66.839139) + (xy 88.094336 66.704479) + (xy 88.112613 66.678377) + (xy 88.167189 66.634752) + (xy 88.214188 66.6255) + (xy 93.890357 66.6255) + (xy 93.905977 66.627224) + (xy 93.906004 66.626939) + (xy 93.91376 66.627671) + (xy 93.913767 66.627673) + (xy 93.982914 66.6255) + (xy 94.01245 66.6255) + (xy 94.019328 66.62463) + (xy 94.025141 66.624172) + (xy 94.071727 66.622709) + (xy 94.090969 66.617117) + (xy 94.110012 66.613174) + (xy 94.129892 66.610664) + (xy 94.173222 66.593507) + (xy 94.178746 66.591617) + (xy 94.182496 66.590527) + (xy 94.22349 66.578618) + (xy 94.240729 66.568422) + (xy 94.258203 66.559862) + (xy 94.276827 66.552488) + (xy 94.276827 66.552487) + (xy 94.276832 66.552486) + (xy 94.314549 66.525082) + (xy 94.319405 66.521892) + (xy 94.35952 66.49817) + (xy 94.373689 66.483999) + (xy 94.388479 66.471368) + (xy 94.404687 66.459594) + (xy 94.434399 66.423676) + (xy 94.438312 66.419376) + (xy 95.107689 65.749999) + (xy 95.881127 65.749999) + (xy 95.881128 65.75) + (xy 96.844314 65.75) + (xy 96.832359 65.761955) + (xy 96.774835 65.874852) + (xy 96.755014 66) + (xy 96.774835 66.125148) + (xy 96.832359 66.238045) + (xy 96.844314 66.25) + (xy 95.881128 66.25) + (xy 95.93373 66.446317) + (xy 95.933734 66.446326) + (xy 96.029865 66.652482) + (xy 96.160342 66.83882) + (xy 96.321179 66.999657) + (xy 96.507517 67.130134) + (xy 96.713673 67.226265) + (xy 96.713682 67.226269) + (xy 96.909999 67.278872) + (xy 96.91 67.278871) + (xy 96.91 66.315686) + (xy 96.921955 66.327641) + (xy 97.034852 66.385165) + (xy 97.128519 66.4) + (xy 97.191481 66.4) + (xy 97.285148 66.385165) + (xy 97.398045 66.327641) + (xy 97.41 66.315686) + (xy 97.41 67.278872) + (xy 97.606317 67.226269) + (xy 97.606326 67.226265) + (xy 97.812482 67.130134) + (xy 97.99882 66.999657) + (xy 98.159657 66.83882) + (xy 98.290134 66.652482) + (xy 98.386265 66.446326) + (xy 98.386269 66.446317) + (xy 98.438872 66.25) + (xy 97.475686 66.25) + (xy 97.487641 66.238045) + (xy 97.545165 66.125148) + (xy 97.564986 66) + (xy 97.545165 65.874852) + (xy 97.487641 65.761955) + (xy 97.475686 65.75) + (xy 98.438872 65.75) + (xy 98.438872 65.749999) + (xy 98.386269 65.553682) + (xy 98.386265 65.553673) + (xy 98.290134 65.347517) + (xy 98.159657 65.161179) + (xy 97.99882 65.000342) + (xy 97.812482 64.869865) + (xy 97.606328 64.773734) + (xy 97.41 64.721127) + (xy 97.41 65.684314) + (xy 97.398045 65.672359) + (xy 97.285148 65.614835) + (xy 97.191481 65.6) + (xy 97.128519 65.6) + (xy 97.034852 65.614835) + (xy 96.921955 65.672359) + (xy 96.91 65.684314) + (xy 96.91 64.721127) + (xy 96.713671 64.773734) + (xy 96.507517 64.869865) + (xy 96.321179 65.000342) + (xy 96.160342 65.161179) + (xy 96.029865 65.347517) + (xy 95.933734 65.553673) + (xy 95.93373 65.553682) + (xy 95.881127 65.749999) + (xy 95.107689 65.749999) + (xy 99.600012 61.257676) + (xy 99.661333 61.224193) + (xy 99.731025 61.229177) + (xy 99.786958 61.271049) + (xy 99.803873 61.302026) + (xy 99.856202 61.442328) + (xy 99.856206 61.442335) + (xy 99.942452 61.557544) + (xy 99.942455 61.557547) + (xy 100.057664 61.643793) + (xy 100.057671 61.643797) + (xy 100.192517 61.694091) + (xy 100.192516 61.694091) + (xy 100.199444 61.694835) + (xy 100.252127 61.7005) + (xy 102.747872 61.700499) + (xy 102.807483 61.694091) + (xy 102.942331 61.643796) + (xy 103.057546 61.557546) + (xy 103.143796 61.442331) + (xy 103.194091 61.307483) + (xy 103.2005 61.247873) + (xy 103.200499 58.752128) + (xy 103.194091 58.692517) + (xy 103.184487 58.666768) + (xy 103.143797 58.557671) + (xy 103.143793 58.557664) + (xy 103.057547 58.442455) + (xy 103.057544 58.442452) + (xy 102.942335 58.356206) + (xy 102.942328 58.356202) + (xy 102.807482 58.305908) + (xy 102.807483 58.305908) + (xy 102.747883 58.299501) + (xy 102.747881 58.2995) + (xy 102.747873 58.2995) + (xy 102.747864 58.2995) + (xy 100.252129 58.2995) + (xy 100.252123 58.299501) + (xy 100.192516 58.305908) + (xy 100.057671 58.356202) + (xy 100.057664 58.356206) + (xy 99.942455 58.442452) + (xy 99.942452 58.442455) + (xy 99.856206 58.557664) + (xy 99.856202 58.557671) + (xy 99.805908 58.692517) + (xy 99.80391 58.711107) + (xy 99.799501 58.752123) + (xy 99.7995 58.752135) + (xy 99.7995 59.3067) + (xy 99.779815 59.373739) + (xy 99.729418 59.417407) + (xy 99.729422 59.417413) + (xy 99.729392 59.41743) + (xy 99.727011 59.419494) + (xy 99.724746 59.420502) + (xy 99.722704 59.421385) + (xy 99.705465 59.43158) + (xy 99.687998 59.440137) + (xy 99.669369 59.447512) + (xy 99.669367 59.447513) + (xy 99.631664 59.474906) + (xy 99.626782 59.478112) + (xy 99.58668 59.501828) + (xy 99.572508 59.516) + (xy 99.557723 59.528628) + (xy 99.541512 59.540407) + (xy 99.511809 59.57631) + (xy 99.507877 59.580631) + (xy 93.750328 65.338181) + (xy 93.689005 65.371666) + (xy 93.662647 65.3745) + (xy 88.214188 65.3745) + (xy 88.147149 65.354815) + (xy 88.112613 65.321623) + (xy 88.000045 65.160858) + (xy 87.839141 64.999954) + (xy 87.652734 64.869432) + (xy 87.652732 64.869431) + (xy 87.446497 64.773261) + (xy 87.446488 64.773258) + (xy 87.226697 64.714366) + (xy 87.226693 64.714365) + (xy 87.226692 64.714365) + (xy 87.226691 64.714364) + (xy 87.226686 64.714364) + (xy 87.000002 64.694532) + (xy 86.999998 64.694532) + (xy 86.773313 64.714364) + (xy 86.773302 64.714366) + (xy 86.553511 64.773258) + (xy 86.553502 64.773261) + (xy 86.347267 64.869431) + (xy 86.347265 64.869432) + (xy 86.160858 64.999954) + (xy 85.999954 65.160858) + (xy 85.869432 65.347265) + (xy 85.869431 65.347267) + (xy 85.773261 65.553502) + (xy 85.773258 65.553511) + (xy 85.714366 65.773302) + (xy 85.714364 65.773313) + (xy 85.694532 65.999998) + (xy 85.694532 66.000001) + (xy 83 66.000001) + (xy 83 55.000001) + (xy 86.614532 55.000001) + (xy 86.634364 55.226686) + (xy 86.634366 55.226697) + (xy 86.693258 55.446488) + (xy 86.693261 55.446497) + (xy 86.789431 55.652732) + (xy 86.789432 55.652734) + (xy 86.919954 55.839141) + (xy 87.080858 56.000045) + (xy 87.080861 56.000047) + (xy 87.267266 56.130568) + (xy 87.473504 56.226739) + (xy 87.693308 56.285635) + (xy 87.85523 56.299801) + (xy 87.919998 56.305468) + (xy 87.92 56.305468) + (xy 87.920002 56.305468) + (xy 87.976673 56.300509) + (xy 88.146692 56.285635) + (xy 88.366496 56.226739) + (xy 88.572734 56.130568) + (xy 88.759139 56.000047) + (xy 88.920047 55.839139) + (xy 89.050568 55.652734) + (xy 89.146739 55.446496) + (xy 89.205635 55.226692) + (xy 89.225468 55.000001) + (xy 96.774532 55.000001) + (xy 96.794364 55.226686) + (xy 96.794366 55.226697) + (xy 96.853258 55.446488) + (xy 96.853261 55.446497) + (xy 96.949431 55.652732) + (xy 96.949432 55.652734) + (xy 97.079954 55.839141) + (xy 97.240858 56.000045) + (xy 97.240861 56.000047) + (xy 97.427266 56.130568) + (xy 97.633504 56.226739) + (xy 97.853308 56.285635) + (xy 98.01523 56.299801) + (xy 98.079998 56.305468) + (xy 98.08 56.305468) + (xy 98.080002 56.305468) + (xy 98.136673 56.300509) + (xy 98.306692 56.285635) + (xy 98.526496 56.226739) + (xy 98.732734 56.130568) + (xy 98.919139 56.000047) + (xy 99.080047 55.839139) + (xy 99.210568 55.652734) + (xy 99.306739 55.446496) + (xy 99.365635 55.226692) + (xy 99.385468 55) + (xy 99.365635 54.773308) + (xy 99.306739 54.553504) + (xy 99.210568 54.347266) + (xy 99.080047 54.160861) + (xy 99.080045 54.160858) + (xy 98.919141 53.999954) + (xy 98.732734 53.869432) + (xy 98.732732 53.869431) + (xy 98.526497 53.773261) + (xy 98.526488 53.773258) + (xy 98.306697 53.714366) + (xy 98.306693 53.714365) + (xy 98.306692 53.714365) + (xy 98.306691 53.714364) + (xy 98.306686 53.714364) + (xy 98.080002 53.694532) + (xy 98.079998 53.694532) + (xy 97.853313 53.714364) + (xy 97.853302 53.714366) + (xy 97.633511 53.773258) + (xy 97.633502 53.773261) + (xy 97.427267 53.869431) + (xy 97.427265 53.869432) + (xy 97.240858 53.999954) + (xy 97.079954 54.160858) + (xy 96.949432 54.347265) + (xy 96.949431 54.347267) + (xy 96.853261 54.553502) + (xy 96.853258 54.553511) + (xy 96.794366 54.773302) + (xy 96.794364 54.773313) + (xy 96.774532 54.999998) + (xy 96.774532 55.000001) + (xy 89.225468 55.000001) + (xy 89.225468 55) + (xy 89.205635 54.773308) + (xy 89.146739 54.553504) + (xy 89.050568 54.347266) + (xy 88.920047 54.160861) + (xy 88.920045 54.160858) + (xy 88.759141 53.999954) + (xy 88.572734 53.869432) + (xy 88.572732 53.869431) + (xy 88.366497 53.773261) + (xy 88.366488 53.773258) + (xy 88.146697 53.714366) + (xy 88.146693 53.714365) + (xy 88.146692 53.714365) + (xy 88.146691 53.714364) + (xy 88.146686 53.714364) + (xy 87.920002 53.694532) + (xy 87.919998 53.694532) + (xy 87.693313 53.714364) + (xy 87.693302 53.714366) + (xy 87.473511 53.773258) + (xy 87.473502 53.773261) + (xy 87.267267 53.869431) + (xy 87.267265 53.869432) + (xy 87.080858 53.999954) + (xy 86.919954 54.160858) + (xy 86.789432 54.347265) + (xy 86.789431 54.347267) + (xy 86.693261 54.553502) + (xy 86.693258 54.553511) + (xy 86.634366 54.773302) + (xy 86.634364 54.773313) + (xy 86.614532 54.999998) + (xy 86.614532 55.000001) + (xy 83 55.000001) + (xy 83 47.124) + (xy 83.019685 47.056961) + (xy 83.072489 47.011206) + (xy 83.124 47) + (xy 122.876 47) + ) + ) + ) ) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl index 86192ddcef..c328dcb49c 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl @@ -2,7 +2,7 @@ "board": { "active_layer": 0, "active_layer_preset": "All Layers", - "auto_track_width": true, + "auto_track_width": false, "hidden_netclasses": [], "hidden_nets": [], "high_contrast_mode": 0, @@ -10,7 +10,7 @@ "opacity": { "images": 0.6, "pads": 1.0, - "tracks": 1.0, + "tracks": 0.800000011920929, "vias": 1.0, "zones": 0.6 }, @@ -65,7 +65,7 @@ 40 ], "visible_layers": "fffffff_ffffffff", - "zone_display_mode": 0 + "zone_display_mode": 1 }, "meta": { "filename": "SeaTalk1.kicad_prl", diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro index a89b285be6..003f68f8f4 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro @@ -3,26 +3,171 @@ "3dviewports": [], "design_settings": { "defaults": { - "board_outline_line_width": 0.1, - "copper_line_width": 0.2, + "board_outline_line_width": 0.09999999999999999, + "copper_line_width": 0.19999999999999998, + "copper_text_italic": false, "copper_text_size_h": 1.5, "copper_text_size_v": 1.5, "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": false, + "text_position": 0, + "units_format": 1 + }, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, "other_line_width": 0.15, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.762, + "height": 1.524, + "width": 1.524 + }, "silk_line_width": 0.15, + "silk_text_italic": false, "silk_text_size_h": 1.0, "silk_text_size_v": 1.0, - "silk_text_thickness": 0.15 + "silk_text_thickness": 0.15, + "silk_text_upright": false, + "zones": { + "min_clearance": 0.5 + } }, "diff_pair_dimensions": [], "drc_exclusions": [], + "meta": { + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "connection_width": "warning", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "footprint": "error", + "footprint_type_mismatch": "ignore", + "hole_clearance": "error", + "hole_near_hole": "error", + "invalid_outline": "error", + "isolated_copper": "warning", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "warning", + "lib_footprint_mismatch": "warning", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "warning", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_edge_clearance": "warning", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_thickness": "warning", + "through_hole_pad_without_hole": "error", + "too_many_vias": "error", + "track_dangling": "warning", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zones_intersect": "error" + }, "rules": { - "min_copper_edge_clearance": 0.0, + "max_error": 0.005, + "min_clearance": 0.19999999999999998, + "min_connection": 0.19999999999999998, + "min_copper_edge_clearance": 1.0, + "min_hole_clearance": 0.25, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.19999999999999998, + "min_microvia_drill": 0.09999999999999999, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.7999999999999999, + "min_text_thickness": 0.08, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.19999999999999998, + "min_via_annular_width": 0.09999999999999999, + "min_via_diameter": 0.5, "solder_mask_clearance": 0.0, - "solder_mask_min_width": 0.0 + "solder_mask_min_width": 0.0, + "solder_mask_to_copper_clearance": 0.0, + "use_height_for_length_calcs": true }, + "teardrop_options": [ + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 5, + "td_on_pad_in_zone": false, + "td_onpadsmd": true, + "td_onroundshapesonly": false, + "td_ontrackend": false, + "td_onviapad": true + } + ], + "teardrop_parameters": [ + { + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_target_name": "td_round_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_target_name": "td_rect_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_target_name": "td_track_end", + "td_width_to_size_filter_ratio": 0.9 + } + ], "track_widths": [], - "via_dimensions": [] + "via_dimensions": [], + "zones_allow_external_fillets": false }, "layer_presets": [], "viewports": [] diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch index 6c7bd9eb35..56d245dc79 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch @@ -1682,7 +1682,7 @@ (property "Value" "2.2k" (at 151.13 33.02 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 146.812 31.75 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 146.812 31.75 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 148.59 31.75 0) @@ -1714,7 +1714,7 @@ (property "Value" "2.2k" (at 96.52 66.04 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 92.202 64.77 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 92.202 64.77 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 93.98 64.77 0) @@ -1771,7 +1771,7 @@ (property "Value" "22k" (at 127 81.28 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 122.682 80.01 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 122.682 80.01 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 124.46 80.01 0) @@ -1797,7 +1797,7 @@ (property "Value" "200" (at 227.33 129.54 0) (effects (font (size 1.27 1.27)) (justify right)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 226.568 128.27 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 226.568 128.27 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 224.79 128.27 0) @@ -1903,7 +1903,7 @@ (property "Value" "4.7k" (at 106.68 78.74 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 102.362 77.47 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 102.362 77.47 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 104.14 77.47 0) @@ -1973,7 +1973,7 @@ (property "Value" "1.5k" (at 171.45 124.46 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 167.132 123.19 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 167.132 123.19 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 168.91 123.19 0) @@ -2058,7 +2058,7 @@ ) (symbol (lib_id "Device:R") (at 63.5 69.85 270) (unit 1) - (in_bom no) (on_board no) (dnp no) (fields_autoplaced) + (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) (uuid 71be8ad0-bfd2-4f59-afd6-b1bb5fcc5604) (property "Reference" "R12" (at 63.5 63.5 90) (effects (font (size 1.27 1.27))) @@ -2066,7 +2066,7 @@ (property "Value" "10k" (at 63.5 66.04 90) (effects (font (size 1.27 1.27))) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 63.5 68.072 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 63.5 68.072 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 63.5 69.85 0) @@ -2095,7 +2095,7 @@ (property "Value" "100" (at 137.16 29.21 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 132.842 27.94 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 132.842 27.94 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 134.62 27.94 0) @@ -2250,7 +2250,7 @@ (property "Value" "4.7k" (at 96.52 78.74 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 92.202 77.47 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 92.202 77.47 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 93.98 77.47 0) @@ -2279,7 +2279,7 @@ (property "Reference" "D1" (at 138.43 39.6875 90) (effects (font (size 1.27 1.27)) (justify right)) ) - (property "Value" "LED" (at 138.43 42.2275 90) + (property "Value" "blue" (at 138.43 42.2275 90) (effects (font (size 1.27 1.27)) (justify right)) ) (property "Footprint" "LED_THT:LED_D3.0mm_Horizontal_O3.81mm_Z6.0mm" (at 134.62 39.37 0) @@ -2323,7 +2323,7 @@ (property "Value" "2.2k" (at 115.57 149.86 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 111.252 148.59 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 111.252 148.59 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 113.03 148.59 0) @@ -2384,7 +2384,7 @@ (property "Value" "10k" (at 151.13 110.49 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 146.812 109.22 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 146.812 109.22 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 148.59 109.22 0) @@ -2452,7 +2452,7 @@ (property "Value" "10k" (at 171.45 110.49 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 167.132 109.22 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 167.132 109.22 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 168.91 109.22 0) @@ -2520,7 +2520,7 @@ (property "Value" "22k" (at 115.57 110.49 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 111.252 109.22 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 111.252 109.22 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 113.03 109.22 0) @@ -2588,7 +2588,7 @@ (property "Value" "4.7k" (at 81.28 49.53 90) (effects (font (size 1.27 1.27))) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 81.28 55.118 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 81.28 55.118 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 81.28 53.34 0) @@ -2658,7 +2658,7 @@ (property "Value" "2.2k" (at 87.63 41.91 0) (effects (font (size 1.27 1.27)) (justify left)) ) - (property "Footprint" "Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P15.24mm_Horizontal" (at 83.312 40.64 90) + (property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" (at 83.312 40.64 90) (effects (font (size 1.27 1.27)) hide) ) (property "Datasheet" "~" (at 85.09 40.64 0) From 38c42251d3ec6bff35dc2ce02142069fa5a665b3 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sat, 13 Jan 2024 20:43:37 +0100 Subject: [PATCH 28/31] Documentation started --- .../Seatalk1/AutoPilotRemoteController.cs | 105 +- src/devices/Seatalk1/README.md | 61 +- src/devices/Seatalk1/Seatalk1.csproj | 2 - src/devices/Seatalk1/SeatalkInterface.png | Bin 169339 -> 108709 bytes .../Seatalk1/SeatalkToNmeaConverter.cs | 8 + .../schematics/SeaTalk1/SeaTalk1.kicad_pcb | 2914 ++++++++++++----- .../schematics/SeaTalk1/SeaTalk1.kicad_prl | 4 +- .../schematics/SeaTalk1/SeaTalk1.kicad_pro | 8 +- .../schematics/SeaTalk1/SeaTalk1.kicad_sch | 44 +- 9 files changed, 2249 insertions(+), 897 deletions(-) diff --git a/src/devices/Seatalk1/AutoPilotRemoteController.cs b/src/devices/Seatalk1/AutoPilotRemoteController.cs index 4a3633ac69..f6ad1ad39e 100644 --- a/src/devices/Seatalk1/AutoPilotRemoteController.cs +++ b/src/devices/Seatalk1/AutoPilotRemoteController.cs @@ -18,7 +18,7 @@ namespace Iot.Device.Seatalk1 { ///

- /// Remote controller for an autopilot connected via Seatalk1 + /// Remote controller for an autopilot connected via Seatalk1. To get an instance of this class, call . /// /// /// Type is not disposable, to prevent accidental disposal by clients. They don't get ownership of the instance. @@ -35,6 +35,10 @@ public class AutoPilotRemoteController : MarshalByRefObject private DateTime _lastUpdateTime = new DateTime(0); private bool _buttonOnApPressed = false; + /// + /// Internal constructor, used by the owning instance of + /// + /// The owner internal AutoPilotRemoteController(SeatalkInterface parentInterface) { _logger = this.GetCurrentClassLogger(); @@ -48,32 +52,79 @@ internal AutoPilotRemoteController(SeatalkInterface parentInterface) DefaultTimeout = TimeSpan.FromSeconds(3); } + /// + /// Current value of the heading sensor internal to the autopilot (if present). + /// When the autopilot controller has such a sensor, this value is always available, however it is + /// useless on tiler pilots such as ST2000 in standby mode, because that one needs to be removed from the tiller for manual steering and thus + /// will read random values. + /// public Angle? AutopilotHeading { get; private set; } + /// + /// Desired heading of the autopilot. + /// This value is only valid when the autopilot is active (not standby) + /// public Angle? AutopilotDesiredHeading { get; private set; } + /// + /// Current rudder angle. Positive for turning to starboard. + /// This value is only available when a rudder position sensor is fitted. + /// public Angle? RudderAngle { get; private set; } + /// + /// True when the rudder angle is valid. This stays false when either no rudder sensor is fitted or the reported values are apparently wrong. + /// public bool RudderAngleAvailable { get; private set; } + /// + /// Current status of the autopilot + /// public AutopilotStatus Status { get; private set; } + /// + /// Active autopilot alarms + /// public AutopilotAlarms Alarms { get; private set; } + /// + /// Current deadband mode. The value is only meaningful in auto mode + /// public DeadbandMode DeadbandMode { get; private set; } + /// + /// Type of autopilot controller. Known values: 05 for 150G type, 08 for most other types + /// public int AutopilotType { get; private set; } + /// + /// Timeout for changing the status + /// public TimeSpan DefaultTimeout { get; set; } + /// + /// Current turning direction of the boat. Depending on the type, this may be derived from heading changes and therefore not really reliable. + /// public TurnDirection TurnDirection { get; private set; } + /// + /// True if the autopilot is active + /// public bool IsOperating => Status is AutopilotStatus.Auto or AutopilotStatus.Track or AutopilotStatus.Wind; + /// + /// True if the autopilot is in Standby + /// public bool IsStandby => Status is AutopilotStatus.Standby or AutopilotStatus.InactiveTrack or AutopilotStatus.InactiveWind; + /// + /// Warning flags from the course computer + /// public CourseComputerWarnings CourseComputerStatus { get; private set; } + /// + /// This event is fired when keys on the controller are pressed. + /// public event Action? AutopilotKeysPressed; private void AutopilotMessageInterpretation(SeatalkMessage obj) @@ -156,6 +207,17 @@ private void AutopilotMessageInterpretation(SeatalkMessage obj) } } + /// + /// Change the autopilot status. + /// + /// The new desired status + /// When changing to track mode, confirm a turn in this direction. + /// True if the desired mode was reached, false if not. Reasons that this could fail are: Operation cancelled by user + /// (user pressed standby while remote control was trying to switch to auto); No data available for change to wind or track mode + /// + /// should initially be set to null. When requesting a change to track mode, it will return a value + /// indicating the required direction change to return to the track. Then call the method again with that value to confirm the change. + /// public bool SetStatus(AutopilotStatus status, ref TurnDirection? directionConfirmation) { return SetStatus(status, DefaultTimeout, ref directionConfirmation); @@ -251,6 +313,11 @@ public bool SetStatus(AutopilotStatus newStatus, TimeSpan timeout, ref TurnDirec return ret; } + /// + /// Change deadband mode + /// + /// The new mode + /// True if the value was set, false otherwise. This method fails if the autopilot is in standby mode public bool SetDeadbandMode(DeadbandMode mode) { if (Status == AutopilotStatus.Offline || IsStandby) @@ -284,21 +351,50 @@ public bool SetDeadbandMode(DeadbandMode mode) return SendMessageAndVerifyStatus(ks, DefaultTimeout, () => DeadbandMode == mode); } + /// + /// Turns to the desired heading + /// + /// New desired heading + /// Desired turn direction. Pass null for taking the default (shorter) turn. + /// True on success, false otherwise + /// This operation can take a significant time public bool TurnTo(Angle degrees, TurnDirection? direction) { return TurnTo(degrees, direction, CancellationToken.None); } + /// + /// Same as , except in async mode + /// + /// New desired heading + /// Desired turn direction + /// Cancellation token + /// True on success, false otherwise public Task TurnToAsync(Angle degrees, TurnDirection? direction, CancellationToken token) { return Task.Factory.StartNew(() => TurnTo(degrees, direction, token)); } + /// + /// Turn by a certain value + /// + /// Degrees to turn, unsigned + /// Direction to turn + /// Cancellation token + /// True on success, false otherwise public Task TurnByAsync(Angle degrees, TurnDirection direction, CancellationToken token) { return Task.Factory.StartNew(() => TurnBy(degrees, direction, token)); } + /// + /// Turns to the desired heading + /// + /// New desired heading + /// Desired turn direction. Pass null for taking the default (shorter) turn. + /// Cancellation token + /// True on success, false otherwise + /// This operation can take a significant time public bool TurnTo(Angle degrees, TurnDirection? direction, CancellationToken token) { degrees = degrees.Normalize(true); @@ -395,6 +491,13 @@ internal bool AnglesAreClose(Angle angle1, Angle angle2) return false; } + /// + /// Turn by a certain value + /// + /// Degrees to turn, unsigned + /// Direction to turn + /// Cancellation token + /// True on success, false otherwise public bool TurnBy(Angle degrees, TurnDirection direction, CancellationToken token) { if (degrees < Angle.Zero) diff --git a/src/devices/Seatalk1/README.md b/src/devices/Seatalk1/README.md index 0c30d9f360..cdde9360e4 100644 --- a/src/devices/Seatalk1/README.md +++ b/src/devices/Seatalk1/README.md @@ -2,20 +2,67 @@ ## Summary -Provide a brief description on what the component is and its functionality. +Seatalk, also called Seatalk1, is a bus protocol used by the marine equipment company Raymarine. It is used as a protocol to connect various devices on a boat, such as depth sounders, anemometers (wind sensors), autopilots and displays. The protocol is the successor of NMEA-0183, providing the main benefit of being able to connect various devices to a single bus, without the need of complex star networks and bridges as it was required for NMEA-0183. -## Device Family +Data transfer uses a slow transmission rate of 4800 Baud, but this makes the bus quite stable with respect to interference. Collisions do occur, but as most messages are repeated at least every second, lost messages are typically negligible. -Provide a list of component names and link to datasheets (if available) the binding will work with. +Seatalk has been superseeded by NMEA-2000, but some older devices are still only available with NMEA-0183 or Seatalk. Interfaces to convert between the various standards are available from different vendors. -**Seatalk 1 Datagrams**: [http://www.thomasknauf.de/rap/seatalk2.htm] +> Note: Seatalk is often called Seatalk1, to distinguish it from SeatalkNG (Seatalk "Next Generation"). The latter is a branded version of NMEA-2000. NMEA-2000 and SeatalkNG are binary and electrically compatible, but use different plugs and sockets. ## Binding Notes -Provide any specifics related to binding API. This could include how to configure component for particular functions and example code. +The binding provides the message definitions for various Seatalk messages. Using the proper interface (see below), it supports receiving and transmitting Seatalk messages. The binding is primarily intended to control older autopilots, such as the Raymarine ST1000+ and ST2000+. Not all known sentence types are supported, but the binding allows registering of further messages. -**NOTE**: Don't repeat the basics related to System.Device.API* (e.g. connection settings, etc.). This helps keep text/steps down to a minimum for maintainability. +A bi-directional Seatalk to NMEA-0183 message converter is also included. + +Example: (for full source, see example directory) + +```csharp +_seatalk = new SeatalkInterface("/dev/ttyAMA2"); // Or some other serial interface +_seatalk.MessageReceived += ParserOnNewMessageDecoded; +_seatalk.StartDecode(); +var ctrl = _seatalk.GetAutopilotRemoteController(); + +if (ctrl.SetStatus(AutopilotStatus.Auto, ref directionConfirmation)) +{ + Console.WriteLine("Autopilot set to AUTO mode"); +} +else +{ + Console.WriteLine("Setting AUTO mode FAILED!"); +} + +await Task.Delay(500); + +NavigationToWaypoint wp = new NavigationToWaypoint() +{ + BearingToDestination = Angle.FromDegrees(10), + CrossTrackError = Length.FromNauticalMiles(-0.11), + DistanceToDestination = Length.FromNauticalMiles(51.3), +}; + +_seatalk.SendMessage(wp); + +private void ParserOnNewMessageDecoded(SeatalkMessage obj) +{ + if (obj is Keystroke keystroke) + { + Console.WriteLine(); + Console.WriteLine($"Pressed key(s): {keystroke}"); + } +} + +``` + +## Physical interface +The physical bus uses a kind of UART protocol, but since it uses a single wire both for sending and receiving, additional electronics are required to connect the bus to an UART (RS-232) interface. Protocol converters are available on the market. The following scheme shows a schematic that allows connecting a Seatalk network to a Raspberry Pi. The seatalk cable is connected to J3. The grey wire from the bus goes to GND, the yellow wire is the data wire and the red wire is +12V. In this schematic, connecting the 12V wire is optional as long as there's at least one other device on the bus that provides the necessary pull-up. The wiring shows a connection to TXD2/RXD2 (ttyAMA2 on linux), as this interface is easier to configure than the default one on GPIO14/15, as long as it's enabled in `boot/config.txt` with `dtoverlay=uart2`. + +![Seatalk-to-TTL-Uart](SeatalkInterface.png) + +When connecting to a default RS-232 interface (e.g. using an USB-to-RS-232 converter), the inverting stages Q2 on RXD and Q5 on TXD should be skipped. Powering the entire wiring via 12V should work with some minor adjustments, such as changing R9 to 470Ω to avoid destroying D1. ## References -Many tanks to Thomas Knauf for his extensive Seatalk protocol analysis. See http://www.thomasknauf.de/seatalk.htm \ No newline at end of file +Many tanks to Thomas Knauf for his extensive Seatalk protocol analysis. See [here](http://www.thomasknauf.de/seatalk.htm) +OpenCPN Seatalk Support [here](https://opencpn.org/wiki/dokuwiki/doku.php?id=opencpn:supplementary_software:seatalk). The OpenCPN plugin "Raymarine Autopilot" can send the required keypress sentences for remote-controlling an autopilot, but needs an NMEA-0183 to Seatalk1 bridge, which can be built using this binding. diff --git a/src/devices/Seatalk1/Seatalk1.csproj b/src/devices/Seatalk1/Seatalk1.csproj index e699a72f83..3d0adbedd7 100644 --- a/src/devices/Seatalk1/Seatalk1.csproj +++ b/src/devices/Seatalk1/Seatalk1.csproj @@ -6,8 +6,6 @@ false 9 Iot.Device.Seatalk1 - $(NoWarn);CS1591 - diff --git a/src/devices/Seatalk1/SeatalkInterface.png b/src/devices/Seatalk1/SeatalkInterface.png index 79956117d344002c04b9cf5d7bba78ddadbd73c8..68e0227486da8ed41c531fec782b0afd59566ae4 100644 GIT binary patch literal 108709 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 literal 169339 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

kuKxutIOZ5_0qY*%_QIykU1Njdf`BYP$q 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 aR^<+Kwe!mnlAD=E-Sm*f!9pYVxc>ur{|>SM diff --git a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs index c509cc959b..59a483080d 100644 --- a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs +++ b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs @@ -37,6 +37,7 @@ public SeatalkToNmeaConverter(string interfaceName, string portName) /// HTD (Seatalk->Nmea) /// RSA (Seatalk->Nmea) /// MWV (Nmea->Seatalk) + /// RMB (Nmea->Seatalk) /// public List SentencesToTranslate => _sentencesToTranslate; @@ -114,6 +115,13 @@ public override void SendSentence(NmeaSinkAndSource source, NmeaSentence sentenc }; _seatalkInterface.SendMessage(aws); } + + if (DoTranslate(sentence, out RecommendedMinimumNavToDestination? rmb) && rmb != null) + { + // RMB should always report true bearing. + NavigationToWaypoint nwp = new NavigationToWaypoint(rmb.CrossTrackError, rmb.BearingToWayPoint, true, rmb.DistanceToWayPoint); + _seatalkInterface.SendMessage(nwp); + } } private bool DoTranslate(NmeaSentence sentence, out T? convertedSentence) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb index 41cfaf5a7c..919ba8de97 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pcb @@ -97,7 +97,7 @@ (net 9 "GND") (net 10 "unconnected-(J1-GCLK0{slash}GPIO4-Pad7)") (net 11 "TXD") - (net 12 "Net-(J1-GPIO15{slash}RXD)") + (net 12 "unconnected-(J1-GPIO14{slash}TXD-Pad8)") (net 13 "unconnected-(J1-GPIO17-Pad11)") (net 14 "unconnected-(J1-GPIO18{slash}PWM0-Pad12)") (net 15 "unconnected-(J1-GPIO27-Pad13)") @@ -110,8 +110,8 @@ (net 22 "unconnected-(J1-SCLK0{slash}GPIO11-Pad23)") (net 23 "unconnected-(J1-~{CE0}{slash}GPIO8-Pad24)") (net 24 "unconnected-(J1-~{CE1}{slash}GPIO7-Pad26)") - (net 25 "unconnected-(J1-ID_SD{slash}GPIO0-Pad27)") - (net 26 "unconnected-(J1-ID_SC{slash}GPIO1-Pad28)") + (net 25 "unconnected-(J1-GPIO15{slash}RXD-Pad10)") + (net 26 "Net-(J1-ID_SC{slash}GPIO1)") (net 27 "unconnected-(J1-GCLK1{slash}GPIO5-Pad29)") (net 28 "unconnected-(J1-GCLK2{slash}GPIO6-Pad31)") (net 29 "unconnected-(J1-PWM0{slash}GPIO12-Pad32)") @@ -246,7 +246,7 @@ (fp_arc (start 1.27 -2.48) (mid 3.561221 -0.949055) (end 3.023625 1.753625) (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f1966e35-ff93-4ef8-b0a1-627c07ebf593)) (pad "1" thru_hole rect (at 0 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") - (net 12 "Net-(J1-GPIO15{slash}RXD)") (pinfunction "C") (pintype "passive") (tstamp 886df849-4ba5-4146-9eda-70c6ec222944)) + (net 26 "Net-(J1-ID_SC{slash}GPIO1)") (pinfunction "C") (pintype "passive") (tstamp 886df849-4ba5-4146-9eda-70c6ec222944)) (pad "2" thru_hole oval (at 1.27 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") (net 2 "Net-(Q2-B)") (pinfunction "B") (pintype "input") (tstamp b7810ae4-9e2a-440d-9be8-8b5e7738d046)) (pad "3" thru_hole oval (at 2.54 0) (size 1.05 1.5) (drill 0.75) (layers "*.Cu" "*.Mask") @@ -1266,7 +1266,7 @@ (pad "1" thru_hole circle (at 0 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (net 5 "VCC_3.3") (pintype "passive") (tstamp 2a7ef9f0-87ba-4f11-880f-f85eb40e1feb)) (pad "2" thru_hole oval (at 10.16 0 180) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") - (net 12 "Net-(J1-GPIO15{slash}RXD)") (pintype "passive") (tstamp 5a91186c-99a7-4c81-98a8-102cf0ed0200)) + (net 26 "Net-(J1-ID_SC{slash}GPIO1)") (pintype "passive") (tstamp 5a91186c-99a7-4c81-98a8-102cf0ed0200)) (model "${KICAD6_3DMODEL_DIR}/Resistor_THT.3dshapes/R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal.wrl" (offset (xyz 0 0 0)) (scale (xyz 1 1 1)) @@ -2198,11 +2198,11 @@ (pad "7" thru_hole oval (at 0 -7.62 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (net 10 "unconnected-(J1-GCLK0{slash}GPIO4-Pad7)") (pinfunction "GCLK0/GPIO4") (pintype "bidirectional") (tstamp f11e0c36-845c-41bf-a710-ed95038758f1)) (pad "8" thru_hole oval (at -2.54 -7.62 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 11 "TXD") (pinfunction "GPIO14/TXD") (pintype "bidirectional") (tstamp fc31b1c5-4f3d-4ac7-a873-9fe5549d93b7)) + (net 12 "unconnected-(J1-GPIO14{slash}TXD-Pad8)") (pinfunction "GPIO14/TXD") (pintype "bidirectional") (tstamp fc31b1c5-4f3d-4ac7-a873-9fe5549d93b7)) (pad "9" thru_hole oval (at 0 -10.16 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (net 9 "GND") (pinfunction "GND") (pintype "power_in") (tstamp a982eb2e-9f2e-4815-9fb7-ea96cb3bf5fa)) (pad "10" thru_hole oval (at -2.54 -10.16 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 12 "Net-(J1-GPIO15{slash}RXD)") (pinfunction "GPIO15/RXD") (pintype "bidirectional") (tstamp b9b673ce-eeb3-4439-bd48-4db687e008c1)) + (net 25 "unconnected-(J1-GPIO15{slash}RXD-Pad10)") (pinfunction "GPIO15/RXD") (pintype "bidirectional") (tstamp b9b673ce-eeb3-4439-bd48-4db687e008c1)) (pad "11" thru_hole oval (at 0 -12.7 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (net 13 "unconnected-(J1-GPIO17-Pad11)") (pinfunction "GPIO17") (pintype "bidirectional") (tstamp 165ad222-842e-4a6e-86cc-91a0e51aaffa)) (pad "12" thru_hole oval (at -2.54 -12.7 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") @@ -2236,9 +2236,9 @@ (pad "26" thru_hole oval (at -2.54 -30.48 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (net 24 "unconnected-(J1-~{CE1}{slash}GPIO7-Pad26)") (pinfunction "~{CE1}/GPIO7") (pintype "bidirectional") (tstamp 0eb56d41-2792-4c4e-82e3-fbbd68e1a0f2)) (pad "27" thru_hole oval (at 0 -33.02 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 25 "unconnected-(J1-ID_SD{slash}GPIO0-Pad27)") (pinfunction "ID_SD/GPIO0") (pintype "bidirectional") (tstamp c880e36d-41c2-4d06-af9d-2c7617a23133)) + (net 11 "TXD") (pinfunction "ID_SD/GPIO0") (pintype "bidirectional") (tstamp c880e36d-41c2-4d06-af9d-2c7617a23133)) (pad "28" thru_hole oval (at -2.54 -33.02 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") - (net 26 "unconnected-(J1-ID_SC{slash}GPIO1-Pad28)") (pinfunction "ID_SC/GPIO1") (pintype "bidirectional") (tstamp ec5bd783-4334-460e-9233-0365f9ba4fa1)) + (net 26 "Net-(J1-ID_SC{slash}GPIO1)") (pinfunction "ID_SC/GPIO1") (pintype "bidirectional") (tstamp ec5bd783-4334-460e-9233-0365f9ba4fa1)) (pad "29" thru_hole oval (at 0 -35.56 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (net 27 "unconnected-(J1-GCLK1{slash}GPIO5-Pad29)") (pinfunction "GCLK1/GPIO5") (pintype "bidirectional") (tstamp 53924c23-bf68-4cdb-af7e-3a7fc9cb34eb)) (pad "30" thru_hole oval (at -2.54 -35.56 180) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") @@ -2357,212 +2357,174 @@ (style (thickness 0.1) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0.5) keep_text_aligned) ) - (segment (start 87 66) (end 87 70.92) (width 0.25) (layer "F.Cu") (net 1) (tstamp 12de7299-d5bb-46fd-af29-e1851f91feda)) - (segment (start 102.92 52.1269) (end 101.5 53.5469) (width 0.25) (layer "F.Cu") (net 1) (tstamp 669a2170-2cce-4c71-8d88-0555a0258298)) - (segment (start 87 70.92) (end 86.92 71) (width 0.25) (layer "F.Cu") (net 1) (tstamp 932c0858-377b-4fb2-af97-f2586912fe28)) - (segment (start 102.92 51) (end 102.92 52.1269) (width 0.25) (layer "F.Cu") (net 1) (tstamp a7337225-4c21-4d70-9f38-47564f584e87)) - (segment (start 101.5 53.5469) (end 101.5 60) (width 0.25) (layer "F.Cu") (net 1) (tstamp b9e6424d-c285-41c2-9b6c-800b3e41043d)) - (segment (start 99.9731 60) (end 93.9731 66) (width 0.25) (layer "B.Cu") (net 1) (tstamp 135035c0-9d69-4562-8e0a-d991158265d9)) - (segment (start 93.9731 66) (end 87 66) (width 0.25) (layer "B.Cu") (net 1) (tstamp 652efb54-6c84-44be-800e-c1aef8e3cb99)) - (segment (start 101.5 60) (end 99.9731 60) (width 0.25) (layer "B.Cu") (net 1) (tstamp 86a3a902-beff-4f84-a3c5-abbaa0d1864e)) - (segment (start 119 86.6345) (end 119 89.36) (width 0.25) (layer "F.Cu") (net 2) (tstamp 46b6c6b6-be99-4c32-9203-d532cb5ae1cd)) - (segment (start 111 74.1639) (end 111 78.6345) (width 0.25) (layer "F.Cu") (net 2) (tstamp 681d89b9-903b-44d3-9ab8-f84db39722c9)) - (segment (start 109 70.92) (end 109 60) (width 0.25) (layer "F.Cu") (net 2) (tstamp 72979bee-e5ee-404a-9be5-46a26902f1da)) - (segment (start 111 72.92) (end 109 70.92) (width 0.25) (layer "F.Cu") (net 2) (tstamp 773a2291-2ca3-412e-978d-3f0d082f3695)) - (segment (start 111 74.1639) (end 111 72.92) (width 0.25) (layer "F.Cu") (net 2) (tstamp b46460b9-ce42-4c49-ae92-a4cac368ad97)) - (segment (start 111 78.6345) (end 119 86.6345) (width 0.25) (layer "F.Cu") (net 2) (tstamp fa0b1faf-bfde-4e3d-b79d-582368ee2bd4)) - (segment (start 117.3 58.9231) (end 117.298 58.9246) (width 0.25) (layer "B.Cu") (net 2) (tstamp b4ec3c22-5c9d-4ead-b077-5caac6b3c8a2)) - (segment (start 119.23 58.9231) (end 117.3 58.9231) (width 0.25) (layer "B.Cu") (net 2) (tstamp c5981127-fc52-4754-8351-e5cf589641ea)) - (segment (start 119.23 60) (end 119.23 58.9231) (width 0.25) (layer "B.Cu") (net 2) (tstamp e137e365-ddb0-4226-9577-adb814a4c162)) - (segment (start 110.076 58.9246) (end 109 60) (width 0.25) (layer "B.Cu") (net 2) (tstamp e71bf624-54bf-4664-bc64-084e3363e160)) - (segment (start 117.298 58.9246) (end 110.076 58.9246) (width 0.25) (layer "B.Cu") (net 2) (tstamp f45770d1-3e24-4728-862d-d97c79c30275)) - (segment (start 117.73 89.36) (end 116.8781 89.36) (width 0.25) (layer "F.Cu") (net 3) (tstamp 214ff578-63cb-4388-9dde-227d2c854de7)) - (segment (start 115.75 90.4881) (end 116.8781 89.36) (width 0.25) (layer "F.Cu") (net 3) (tstamp c4810feb-b248-4d4a-ae51-7f5da5940cf0)) - (segment (start 115.75 93.9) (end 115.75 90.4881) (width 0.25) (layer "F.Cu") (net 3) (tstamp f9211cbe-c226-4fd3-85f5-f37a0ca11e6c)) - (segment (start 114.207 99) (end 114.207 97.9831) (width 0.25) (layer "B.Cu") (net 4) (tstamp 3f700287-caff-4804-8740-1632b11da9b7)) - (segment (start 114.207 97.9831) (end 118.29 93.9) (width 0.25) (layer "B.Cu") (net 4) (tstamp af87ae71-9e1b-49ec-bd4d-319b146ee1d5)) - (segment (start 113.08 99) (end 114.207 99) (width 0.25) (layer "B.Cu") (net 4) (tstamp e30fdff4-de5f-4c6d-ba80-dd6bb63ff193)) - (segment (start 129.634 67.6431) (end 128.806 66.8149) (width 0.25) (layer "F.Cu") (net 5) (tstamp 000a9cd6-8d22-4b01-9c66-b4ef0bacba7b)) - (segment (start 102.92 99) (end 102.92 96.08) (width 0.25) (layer "F.Cu") (net 5) (tstamp 21b66ff9-ce6d-41f2-90c3-19611ee9deb2)) - (segment (start 129.632 49.6769) (end 130 49.6769) (width 0.25) (layer "F.Cu") (net 5) (tstamp 5f2e5dbc-b6d5-4679-b172-cc7584cecb2d)) - (segment (start 102 78) (end 102 93) (width 0.25) (layer "F.Cu") (net 5) (tstamp 72f02a8d-a0e6-463e-916b-442aacbd65b6)) - (segment (start 130 49.6769) (end 130 48.5) (width 0.25) (layer "F.Cu") (net 5) (tstamp 7d7e2c71-47b6-4a0a-a024-935642a6bec7)) - (segment (start 104 76) (end 102 78) (width 0.25) (layer "F.Cu") (net 5) (tstamp 993df407-53ca-442c-8c37-93531b24641e)) - (segment (start 102 93) (end 104 95) (width 0.25) (layer "F.Cu") (net 5) (tstamp aeb50686-be30-41d2-a6ab-eafbb9189dac)) - (segment (start 130 67.6431) (end 129.634 67.6431) (width 0.25) (layer "F.Cu") (net 5) (tstamp b0559386-dd8d-49a0-b9a4-64aa58cf7d04)) - (segment (start 102.92 96.08) (end 104 95) (width 0.25) (layer "F.Cu") (net 5) (tstamp b930af55-bc63-4587-beac-0ed9cc135c6d)) - (segment (start 130 68.82) (end 130 67.6431) (width 0.25) (layer "F.Cu") (net 5) (tstamp da0d60c6-e9e3-4622-a2e7-e758a990e4f1)) - (segment (start 128.806 50.5031) (end 129.632 49.6769) (width 0.25) (layer "F.Cu") (net 5) (tstamp f1d14b7b-d184-47b7-8b7e-b823085e73d2)) - (segment (start 128.806 66.8149) (end 128.806 50.5031) (width 0.25) (layer "F.Cu") (net 5) (tstamp fd1a7f4d-1d77-41ca-8e84-351c344d7711)) - (segment (start 117.998 70) (end 123.5 70) (width 0.25) (layer "B.Cu") (net 5) (tstamp 0ae8ae0d-3b50-4a40-9e48-ded2a036f9bf)) - (segment (start 117.46 69.4615) (end 117.998 70) (width 0.25) (layer "B.Cu") (net 5) (tstamp 0d0ae462-6f71-41cb-a659-d3d8e56bf847)) - (segment (start 112.175 70.8268) (end 113.54 69.4615) (width 0.25) (layer "B.Cu") (net 5) (tstamp 13d33456-669b-4c11-b534-7c605171e849)) - (segment (start 105.607 76) (end 110.78 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp 2f1eda7f-c6a3-45f0-ae2b-1c2b774a65fa)) - (segment (start 114.5 74.16) (end 114.5 73.1521) (width 0.25) (layer "B.Cu") (net 5) (tstamp 304a3970-f98a-4342-bdc7-592b627e254d)) - (segment (start 117.46 69.4615) (end 118.102 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp 415ead74-eba7-42d0-929d-f7bdcd713f03)) - (segment (start 123.5 70) (end 124.68 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp 4223a899-c365-458f-bcfb-bf1d34f43b3e)) - (segment (start 104 76) (end 105.607 76) (width 0.25) (layer "B.Cu") (net 5) (tstamp 4347d8e3-d621-4312-8bdb-cd0b0e528d26)) - (segment (start 113.54 69.4615) (end 117.46 69.4615) (width 0.25) (layer "B.Cu") (net 5) (tstamp 579ab2f1-9dfb-4765-8cc0-1b105bc4fa7c)) - (segment (start 110.78 70.8268) (end 112.175 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp 8c57fb34-9606-4fc5-a551-96bfbafc9c22)) - (segment (start 89 92) (end 88.92 91.92) (width 0.25) (layer "B.Cu") (net 5) (tstamp a4425cbb-e868-4ba0-a9d1-dddeb619f248)) - (segment (start 101 92) (end 89 92) (width 0.25) (layer "B.Cu") (net 5) (tstamp abd3312e-d1ba-4a3b-94fa-8184c404367c)) - (segment (start 118.102 68.462) (end 118 68.36) (width 0.25) (layer "B.Cu") (net 5) (tstamp b4a18b60-603e-4939-a8cf-0d643631416d)) - (segment (start 114.5 73.1521) (end 112.175 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp beb520f3-38b4-486b-98c0-5457d63fa639)) - (segment (start 104 95) (end 101 92) (width 0.25) (layer "B.Cu") (net 5) (tstamp c105c5db-c2ab-4e2a-b3d9-4a0e50a9b405)) - (segment (start 124.68 68.82) (end 130 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp c222c1cc-e69c-460f-9966-e83aeb1c6eb5)) - (segment (start 88.92 91.92) (end 88.92 89) (width 0.25) (layer "B.Cu") (net 5) (tstamp e2f70e35-b847-4ac9-930f-6ff66e76225c)) - (segment (start 118.102 68.82) (end 118.102 68.462) (width 0.25) (layer "B.Cu") (net 5) (tstamp e6bece4a-bde5-44ea-b625-4714828c80dd)) - (segment (start 132.54 51.04) (end 132.54 48.5) (width 0.25) (layer "F.Cu") (net 6) (tstamp b1bb8fa4-5e4b-4784-b61e-59372a3074d8)) - (segment (start 99.1435 49.8565) (end 98 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 1d48b1b5-0713-4b3e-ad9a-b4064231b803)) - (segment (start 131.363 51.04) (end 131.363 51.4078) (width 0.25) (layer "B.Cu") (net 6) (tstamp 296dfc89-0a81-429f-92c5-8c00e61ef51f)) - (segment (start 126.078 51) (end 120.676 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 37f283a2-4103-440e-b19f-993d05402ab3)) - (segment (start 120.5 51) (end 120.676 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 536fd090-895b-4d2e-9a33-f3e9fff9e87e)) - (segment (start 130.66 52.1103) (end 130.66 52.1104) (width 0.25) (layer "B.Cu") (net 6) (tstamp 577b8187-8ae4-4d70-a461-59643b37ff0e)) - (segment (start 130.66 52.1103) (end 130.54 52.2306) (width 0.25) (layer "B.Cu") (net 6) (tstamp 651f5aef-f1ee-4d32-97b1-0bbd64e3f6c9)) - (segment (start 130.461 52.31) (end 127.388 52.31) (width 0.25) (layer "B.Cu") (net 6) (tstamp 8d70dc4f-c843-4e49-9fcd-977f16f10b21)) - (segment (start 119.532 49.8565) (end 99.1435 49.8565) (width 0.25) (layer "B.Cu") (net 6) (tstamp 9116f3ea-f62e-4555-8523-2487df84ebb2)) - (segment (start 130.66 52.1104) (end 130.461 52.31) (width 0.25) (layer "B.Cu") (net 6) (tstamp 9e14b3bd-4ac2-4a90-91bc-414727e78565)) - (segment (start 127.388 52.31) (end 126.078 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp bdbb3d65-a15c-4e0e-a5c5-a31287edad20)) - (segment (start 120.676 51) (end 119.532 49.8565) (width 0.25) (layer "B.Cu") (net 6) (tstamp c248b53e-3202-4c32-bc80-5bbb06acc8b4)) - (segment (start 131.363 51.4078) (end 130.66 52.1103) (width 0.25) (layer "B.Cu") (net 6) (tstamp e5936714-5c9f-42ce-900d-eaa9a8ce353e)) - (segment (start 132.54 51.04) (end 131.363 51.04) (width 0.25) (layer "B.Cu") (net 6) (tstamp f6530600-0257-4fc5-8db4-260b31eceb59)) - (segment (start 131.349 69.3583) (end 131.349 65.7397) (width 0.25) (layer "F.Cu") (net 9) (tstamp 015d5d70-ad28-486a-affd-1ccb889446a1)) - (segment (start 132.174 82.8831) (end 131.177 81.8858) (width 0.25) (layer "F.Cu") (net 9) (tstamp 01e1e3da-69bf-4092-bc0d-2ddb405b0628)) - (segment (start 132.172 85.2369) (end 132.54 85.2369) (width 0.25) (layer "F.Cu") (net 9) (tstamp 0450cd28-2b63-4b2c-9bfc-ea172a3c502d)) - (segment (start 130 58.66) (end 130 59.2484) (width 0.25) (layer "F.Cu") (net 9) (tstamp 111b30e5-030f-4154-bc17-0072c902a082)) - (segment (start 132.172 64.9169) (end 132.54 64.9169) (width 0.25) (layer "F.Cu") (net 9) (tstamp 178a5ee7-2545-458d-a3f2-5d01dbc18b07)) - (segment (start 131.349 65.7397) (end 132.172 64.9169) (width 0.25) (layer "F.Cu") (net 9) (tstamp 1a3ac35c-d7de-4cc6-ba0f-0435231f5a4f)) - (segment (start 130 59.8369) (end 130 59.2484) (width 0.25) (layer "F.Cu") (net 9) (tstamp 1cb2c6fe-3b67-4ca1-a01e-690c315fc20a)) - (segment (start 132.54 63.74) (end 132.54 62.5631) (width 0.25) (layer "F.Cu") (net 9) (tstamp 1d77abb7-8287-4441-8daf-eea764b830fd)) - (segment (start 132.54 64.9169) (end 132.54 63.74) (width 0.25) (layer "F.Cu") (net 9) (tstamp 2791a470-c6b5-42d2-9d4a-409c7675fc4f)) - (segment (start 132.54 62.5631) (end 132.174 62.5631) (width 0.25) (layer "F.Cu") (net 9) (tstamp 2bdfa8fd-7ea8-4d50-86a6-e83be73dfb43)) - (segment (start 132.174 70.1831) (end 131.349 69.3583) (width 0.25) (layer "F.Cu") (net 9) (tstamp 2c4bacf8-4c15-4c02-b020-5c97a546d1b6)) - (segment (start 131.35 87.1389) (end 131.35 86.0591) (width 0.25) (layer "F.Cu") (net 9) (tstamp 36b23fe4-d023-4e40-8b79-f7dc8ad3f903)) - (segment (start 132.54 53.58) (end 132.54 54.7569) (width 0.25) (layer "F.Cu") (net 9) (tstamp 3a7cbdab-b813-4db7-b288-05711d3813ff)) - (segment (start 130 80.1569) (end 130 78.98) (width 0.25) (layer "F.Cu") (net 9) (tstamp 3d79828a-ae4f-4f94-9ecc-e37e44709f33)) - (segment (start 132.54 85.2369) (end 132.54 84.06) (width 0.25) (layer "F.Cu") (net 9) (tstamp 45241f53-575d-490c-b36c-2b0c31fb6aaf)) - (segment (start 132.54 82.8831) (end 132.174 82.8831) (width 0.25) (layer "F.Cu") (net 9) (tstamp 463917a6-a822-43cc-a9fb-f56614037679)) - (segment (start 132.54 54.7569) (end 132.174 54.7569) (width 0.25) (layer "F.Cu") (net 9) (tstamp 4c69ca62-d215-4b92-917a-114269249a49)) - (segment (start 131.35 86.0591) (end 132.172 85.2369) (width 0.25) (layer "F.Cu") (net 9) (tstamp 4f6dbb33-f713-4f5a-90c1-d17cc6d3df20)) - (segment (start 131.27 57.9784) (end 130 59.2484) (width 0.25) (layer "F.Cu") (net 9) (tstamp 542ca533-a7e2-4be1-a319-dd3cae691b87)) - (segment (start 131.177 61.5658) (end 131.177 60.6459) (width 0.25) (layer "F.Cu") (net 9) (tstamp 65ee1135-93f8-4edc-b3af-a0f87b32abad)) - (segment (start 130.368 59.8369) (end 130 59.8369) (width 0.25) (layer "F.Cu") (net 9) (tstamp 6c88593b-940f-492b-aefc-110b4f41bb96)) - (segment (start 132.174 62.5631) (end 131.177 61.5658) (width 0.25) (layer "F.Cu") (net 9) (tstamp 74bb7a96-850e-4001-8091-fe45ef8694fb)) - (segment (start 132.174 54.7569) (end 131.27 55.6611) (width 0.25) (layer "F.Cu") (net 9) (tstamp 9c033c6f-2945-471d-916e-3569ad2e7976)) - (segment (start 132.54 84.06) (end 132.54 82.8831) (width 0.25) (layer "F.Cu") (net 9) (tstamp 9dbe77dd-9f99-42fc-9407-c953f6d502e6)) - (segment (start 132.54 89.14) (end 132.54 87.9631) (width 0.25) (layer "F.Cu") (net 9) (tstamp c1549742-20ed-46d4-a5b0-cda02bd51367)) - (segment (start 132.54 70.1831) (end 132.174 70.1831) (width 0.25) (layer "F.Cu") (net 9) (tstamp c2008f27-52eb-4e19-959c-e5aa1e0e0226)) - (segment (start 130.368 80.1569) (end 130 80.1569) (width 0.25) (layer "F.Cu") (net 9) (tstamp c6892cb1-32be-471d-9e4e-15a91f719a1a)) - (segment (start 132.174 87.9631) (end 131.35 87.1389) (width 0.25) (layer "F.Cu") (net 9) (tstamp cc28b2c9-2ef4-4fec-b657-36206be2c294)) - (segment (start 131.177 80.9659) (end 130.368 80.1569) (width 0.25) (layer "F.Cu") (net 9) (tstamp e044c3ac-cc65-4258-97f2-cfef39ea1bcc)) - (segment (start 132.54 87.9631) (end 132.174 87.9631) (width 0.25) (layer "F.Cu") (net 9) (tstamp e9df421e-17f3-48b2-9f8a-a43aa531d0fb)) - (segment (start 131.177 81.8858) (end 131.177 80.9659) (width 0.25) (layer "F.Cu") (net 9) (tstamp ecaafa16-adf0-4d59-b6b6-683fa7596d8d)) - (segment (start 131.27 55.6611) (end 131.27 57.9784) (width 0.25) (layer "F.Cu") (net 9) (tstamp f89bc0cc-961e-4306-bed1-5d79f9b37e36)) - (segment (start 131.177 60.6459) (end 130.368 59.8369) (width 0.25) (layer "F.Cu") (net 9) (tstamp fd5ed285-e053-40ab-b553-aa28c66a8d74)) - (segment (start 132.54 71.36) (end 132.54 70.1831) (width 0.25) (layer "F.Cu") (net 9) (tstamp fe1aa7d9-9a24-4c3a-b284-cac114130df3)) - (segment (start 130 96.76) (end 128.823 96.76) (width 0.25) (layer "B.Cu") (net 9) (tstamp 074943c8-ea7d-4e5c-a237-e2426bf73dc3)) - (segment (start 128.823 58.66) (end 128.504 58.3409) (width 0.25) (layer "B.Cu") (net 9) (tstamp 0b4c38ea-a800-4fb8-9a1a-d170bcfb7c6d)) - (segment (start 107 84.2914) (end 107 83.16) (width 0.25) (layer "B.Cu") (net 9) (tstamp 2d6b5396-75eb-4f01-9ccc-3f1639e82ef7)) - (segment (start 128.823 78.98) (end 128.263 78.42) (width 0.25) (layer "B.Cu") (net 9) (tstamp 2e57a579-a598-4019-8e97-97311cf98b26)) - (segment (start 104.291 87) (end 107 84.2914) (width 0.25) (layer "B.Cu") (net 9) (tstamp 378ee728-d507-4070-b4b0-2ad5ae48d5f1)) - (segment (start 121.3626 78.42) (end 128.263 78.42) (width 0.25) (layer "B.Cu") (net 9) (tstamp 4180254c-95a8-4d79-876a-57242821beb0)) - (segment (start 130 58.66) (end 128.823 58.66) (width 0.25) (layer "B.Cu") (net 9) (tstamp 57679316-d8d5-4ca8-9e86-ca11039775bc)) - (segment (start 128.423 96.36) (end 120.9 96.36) (width 0.25) (layer "B.Cu") (net 9) (tstamp 74f680d6-bb6f-4f64-9565-5d3901bd4a64)) - (segment (start 87.46 87) (end 104.291 87) (width 0.25) (layer "B.Cu") (net 9) (tstamp 7616ea0a-24e0-42ef-b5ec-54a6ab87053e)) - (segment (start 84 90.46) (end 87.46 87) (width 0.25) (layer "B.Cu") (net 9) (tstamp 7ff22eab-721c-437a-8946-edbadb95f38d)) - (segment (start 111 83) (end 111 83.08) (width 0.25) (layer "B.Cu") (net 9) (tstamp b59138c2-7e22-4ecb-84be-a17e476467d3)) - (segment (start 130 78.98) (end 128.823 78.98) (width 0.25) (layer "B.Cu") (net 9) (tstamp bd30812b-4b82-466a-821a-3fb6026bd65b)) - (segment (start 128.823 96.76) (end 128.423 96.36) (width 0.25) (layer "B.Cu") (net 9) (tstamp f021be97-82b3-4788-8919-507b810bad35)) - (segment (start 128.504 58.3409) (end 121.228 58.3409) (width 0.25) (layer "B.Cu") (net 9) (tstamp f5f9a00a-488f-4d92-9bc4-d0fe03d04371)) - (segment (start 111 89) (end 111 83.08) (width 0.25) (layer "B.Cu") (net 9) (tstamp fa638c11-e51e-44c9-9a90-770a63a58d1c)) - (segment (start 94.46 80.46) (end 93.42 81.5) (width 0.25) (layer "B.Cu") (net 11) (tstamp 01733c9c-0d5c-40b6-9bd8-30709222c85f)) - (segment (start 93.42 84.1) (end 94.16 84.84) (width 0.25) (layer "B.Cu") (net 11) (tstamp 04132aa3-fbdb-4c6d-9fda-72d3a8a98154)) - (segment (start 133.776 59.0995) (end 133.039 59.8369) (width 0.25) (layer "B.Cu") (net 11) (tstamp 18d46a4c-23ed-4db7-b389-e7d4bfe4a0cb)) - (segment (start 132.54 57.2969) (end 132.908 57.2969) (width 0.25) (layer "B.Cu") (net 11) (tstamp 1b524de6-a4b3-4e2a-a2ba-a36ad5dc0988)) - (segment (start 130.344 62.557) (end 112.363 62.557) (width 0.25) (layer "B.Cu") (net 11) (tstamp 1efba9fa-edf9-4e0b-aa72-ea2c89d61ec7)) - (segment (start 133.039 59.8369) (end 132.224 59.8369) (width 0.25) (layer "B.Cu") (net 11) (tstamp 383dded2-5852-4f3d-b54f-11124872fd4c)) - (segment (start 131.27 61.6309) (end 130.344 62.557) (width 0.25) (layer "B.Cu") (net 11) (tstamp 3b3098d9-d7ae-430c-8e23-aca1a8e971a3)) - (segment (start 131.27 60.791) (end 131.27 61.6309) (width 0.25) (layer "B.Cu") (net 11) (tstamp 4da0dcb0-feb6-4b2f-877a-f899796a14b7)) - (segment (start 94.46 80.46) (end 93.92 81) (width 0.25) (layer "B.Cu") (net 11) (tstamp 56692325-45c4-46cc-b8f8-dc76c18ba661)) - (segment (start 104 84.84) (end 94.16 84.84) (width 0.25) (layer "B.Cu") (net 11) (tstamp 84285f7b-2b92-4b9c-a805-c85805b8f764)) - (segment (start 132.54 56.12) (end 132.54 57.2969) (width 0.25) (layer "B.Cu") (net 11) (tstamp 90e6a160-29a3-4503-bfcd-0fdeb49fcde7)) - (segment (start 112.363 62.557) (end 94.46 80.46) (width 0.25) (layer "B.Cu") (net 11) (tstamp 9ab701d9-3312-4afd-8f75-2c09eb622c3f)) - (segment (start 133.776 58.1653) (end 133.776 59.0995) (width 0.25) (layer "B.Cu") (net 11) (tstamp a1dd10ed-b3f8-49d8-8521-96d5a3d97d7f)) - (segment (start 132.224 59.8369) (end 131.27 60.791) (width 0.25) (layer "B.Cu") (net 11) (tstamp c76c8697-c39c-4007-89ec-a05cfaee27d7)) - (segment (start 132.908 57.2969) (end 133.776 58.1653) (width 0.25) (layer "B.Cu") (net 11) (tstamp d35b49da-e779-4d34-a77e-a595fe1ceded)) - (segment (start 93.92 81) (end 93.92 82) (width 0.25) (layer "B.Cu") (net 11) (tstamp e5c16329-a17f-4d7c-9e1c-9d6d677c354a)) - (segment (start 93.42 81.5) (end 93.42 84.1) (width 0.25) (layer "B.Cu") (net 11) (tstamp e8d78740-11e9-4cac-b149-2f97b7cfad5e)) - (segment (start 118.006 61.0843) (end 122.111 61.0843) (width 0.25) (layer "B.Cu") (net 12) (tstamp 0a2f789c-e685-4c35-9bf7-4bda9120be89)) - (segment (start 130.554 59.8369) (end 131.363 59.0279) (width 0.25) (layer "B.Cu") (net 12) (tstamp 26bcd68d-c0f2-4f8a-91b6-48c0cd23ecb3)) - (segment (start 117.46 60.2692) (end 117.46 60.5384) (width 0.25) (layer "B.Cu") (net 12) (tstamp 2a2635c9-82b7-44df-93fa-2098f4b6c779)) - (segment (start 123.358 59.8369) (end 130.554 59.8369) (width 0.25) (layer "B.Cu") (net 12) (tstamp 3995de97-fed8-49af-9675-2f9484dce630)) - (segment (start 131.363 58.66) (end 132.54 58.66) (width 0.25) (layer "B.Cu") (net 12) (tstamp 5774f9f6-5f53-4929-b1f6-fb6c8fb5f58c)) - (segment (start 117.46 60.2692) (end 117.691 60.2692) (width 0.25) (layer "B.Cu") (net 12) (tstamp 5c6a91cf-bdc8-4115-ba42-9d55d36c83d8)) - (segment (start 117.46 60) (end 117.46 60.2692) (width 0.25) (layer "B.Cu") (net 12) (tstamp 83c81229-cc6c-421f-924d-3c7b962af46b)) - (segment (start 96.5137 76) (end 111.975 60.5384) (width 0.25) (layer "B.Cu") (net 12) (tstamp 84daa2bf-3a4d-41f5-9aa8-9db5ff931586)) - (segment (start 117.691 60.2692) (end 117.96 60) (width 0.25) (layer "B.Cu") (net 12) (tstamp 8dc752de-0bf6-4019-be85-12312fea1983)) - (segment (start 111.975 60.5384) (end 117.46 60.5384) (width 0.25) (layer "B.Cu") (net 12) (tstamp 945e5762-7f6d-4189-92e7-06dcff46d3e7)) - (segment (start 131.363 59.0279) (end 131.363 58.66) (width 0.25) (layer "B.Cu") (net 12) (tstamp 9f65880f-f285-44c8-b06a-d781948e6e09)) - (segment (start 122.111 61.0843) (end 123.358 59.8369) (width 0.25) (layer "B.Cu") (net 12) (tstamp bdb565dd-d031-4978-a774-9722d30fb140)) - (segment (start 93.84 76) (end 96.5137 76) (width 0.25) (layer "B.Cu") (net 12) (tstamp d741666e-5a34-4d4b-a9fe-e636c6bb3f77)) - (segment (start 117.46 60.5384) (end 118.006 61.0843) (width 0.25) (layer "B.Cu") (net 12) (tstamp f76e1fb2-b32c-4dc3-b41e-4077d1986ebc)) - (segment (start 101 94) (end 99 96) (width 0.25) (layer "F.Cu") (net 36) (tstamp 39e36e71-341f-40b4-a8c9-063647e9354c)) - (segment (start 99.6748 56.5948) (end 99.6748 85.6748) (width 0.25) (layer "F.Cu") (net 36) (tstamp 78ef3220-d731-4c99-ab89-273e98604dd7)) - (segment (start 98.08 55) (end 99.6748 56.5948) (width 0.25) (layer "F.Cu") (net 36) (tstamp c951465e-49f3-4013-8e2f-aea6ecf9fe69)) - (segment (start 101 87) (end 101 94) (width 0.25) (layer "F.Cu") (net 36) (tstamp cbb2e4e1-17ab-4fc9-981e-b0295b340175)) - (segment (start 99.6748 85.6748) (end 101 87) (width 0.25) (layer "F.Cu") (net 36) (tstamp dd36e835-146a-4797-85d1-dc7f1d562859)) - (segment (start 99 96) (end 99.1973 96.1973) (width 0.25) (layer "B.Cu") (net 36) (tstamp 6aeccbc8-68fa-4f53-8483-15d7530a52e1)) - (segment (start 99.1973 96.1973) (end 107.3027 96.1973) (width 0.25) (layer "B.Cu") (net 36) (tstamp 83bccfac-675e-44b8-944f-f96fae70b791)) - (segment (start 84 93) (end 85.1769 93) (width 0.25) (layer "B.Cu") (net 36) (tstamp 96736583-c06e-4882-9a0e-30062fe247e8)) - (segment (start 85.1769 93) (end 85.1784 93.0015) (width 0.25) (layer "B.Cu") (net 36) (tstamp b1dcc291-0653-4234-90b6-dd7f59aff230)) - (segment (start 107.3027 96.1973) (end 117.73 85.77) (width 0.25) (layer "B.Cu") (net 36) (tstamp c7fa1d27-c602-4b81-979d-3c90538432c7)) - (segment (start 85.1784 93.0015) (end 96.0015 93.0015) (width 0.25) (layer "B.Cu") (net 36) (tstamp d25c8750-b5b5-44b0-8a33-0ef2f82cd8fa)) - (segment (start 117.73 85.77) (end 117.73 81) (width 0.25) (layer "B.Cu") (net 36) (tstamp dd529443-f598-475e-b43f-9e30ec21e1c7)) - (segment (start 96.0015 93.0015) (end 99 96) (width 0.25) (layer "B.Cu") (net 36) (tstamp eb11030d-e0a0-4f2e-a1f8-e5a74a7d3c79)) - (segment (start 87.2531 95.54) (end 84 95.54) (width 0.25) (layer "B.Cu") (net 37) (tstamp 4e3041b3-2e86-4764-876d-b671564d9448)) - (segment (start 88.84 96) (end 87.7131 96) (width 0.25) (layer "B.Cu") (net 37) (tstamp 5f5b7574-4170-488e-b9ac-3c33a3d44a3b)) - (segment (start 87.7131 96) (end 87.2531 95.54) (width 0.25) (layer "B.Cu") (net 37) (tstamp ab1b15f1-2238-48e2-9bfc-4851c7a94ea1)) - (segment (start 113.08 51) (end 117.96 51) (width 0.25) (layer "B.Cu") (net 38) (tstamp 05473841-1cf1-4ad7-a6ab-c99e45477171)) - (segment (start 87.84 51) (end 87.84 52.1269) (width 0.25) (layer "F.Cu") (net 39) (tstamp 12fea319-949f-4551-b905-7c78de52c57f)) - (segment (start 87.92 52.2069) (end 87.92 55) (width 0.25) (layer "F.Cu") (net 39) (tstamp 184a30f5-b071-4b8f-b113-f9458d4bf1a7)) - (segment (start 87.84 52.1269) (end 87.92 52.2069) (width 0.25) (layer "F.Cu") (net 39) (tstamp d74e3c5e-00cc-46fd-8e64-48af99eb63fa)) - (segment (start 119.23 52.0769) (end 119.165 52.1419) (width 0.25) (layer "B.Cu") (net 39) (tstamp 365f03ee-43af-4610-9c23-4dc654230482)) - (segment (start 119.165 52.1419) (end 90.1088 52.1419) (width 0.25) (layer "B.Cu") (net 39) (tstamp 43ad19ca-5a57-49e6-92e1-c91d35d7f9bc)) - (segment (start 90.1088 52.1419) (end 88.9669 51) (width 0.25) (layer "B.Cu") (net 39) (tstamp 81ed1a3c-d903-4318-b8bd-c002887f8c23)) - (segment (start 119.23 51) (end 119.23 52.0769) (width 0.25) (layer "B.Cu") (net 39) (tstamp 982e8d46-3493-4d04-a5d8-3b94f41341e5)) - (segment (start 88.9669 51) (end 87.84 51) (width 0.25) (layer "B.Cu") (net 39) (tstamp a2dbcbd8-197f-42ec-bd23-ced41d018f77)) - (segment (start 120.659 68.7623) (end 120.659 65.5634) (width 0.25) (layer "F.Cu") (net 40) (tstamp 0904e793-3c42-489b-b607-e91780981713)) - (segment (start 115.627 62.8732) (end 116.798 61.7022) (width 0.25) (layer "F.Cu") (net 40) (tstamp 1ae8792e-e390-4325-a55f-0ad68268702f)) - (segment (start 119 76.5) (end 119 81) (width 0.25) (layer "F.Cu") (net 40) (tstamp 3be305e0-e8c3-46dd-99e9-88beb45ada93)) - (segment (start 108.343 58.4731) (end 107 59.8161) (width 0.25) (layer "F.Cu") (net 40) (tstamp 3df34c56-ab63-4071-acee-83d81190c479)) - (segment (start 120.54 72.0804) (end 120.659 71.9613) (width 0.25) (layer "F.Cu") (net 40) (tstamp 4a47f56b-356b-48c4-b282-24d9ee80eace)) - (segment (start 120.54 74.96) (end 120.54 72.0804) (width 0.25) (layer "F.Cu") (net 40) (tstamp 55d71abe-1345-47c6-8988-3ca9a07aa985)) - (segment (start 120.659 71.9613) (end 120.659 68.7623) (width 0.25) (layer "F.Cu") (net 40) (tstamp 6d944b5d-e173-4bd7-840c-efc1cee12fbb)) - (segment (start 119 76.5) (end 120.54 74.96) (width 0.25) (layer "F.Cu") (net 40) (tstamp 9e45a6f4-1a14-4500-b6b5-1f027a4721df)) - (segment (start 115.627 64) (end 115.627 62.8732) (width 0.25) (layer "F.Cu") (net 40) (tstamp ac43a70e-5bec-43cd-a86d-c71ed780dbde)) - (segment (start 113.569 58.4731) (end 108.343 58.4731) (width 0.25) (layer "F.Cu") (net 40) (tstamp ae3cb963-5995-49fe-80f8-d75c184db4c4)) - (segment (start 114.5 64) (end 115.627 64) (width 0.25) (layer "F.Cu") (net 40) (tstamp af2a4461-7189-4dd6-93e3-756ba0aa73d1)) - (segment (start 116.798 61.7022) (end 113.569 58.4731) (width 0.25) (layer "F.Cu") (net 40) (tstamp cbe3133f-c1af-4cb3-9ae5-9e4390e033f6)) - (segment (start 107 59.8161) (end 107 73) (width 0.25) (layer "F.Cu") (net 40) (tstamp d6d7bd3b-6518-479c-b871-3942dff9ef21)) - (segment (start 120.659 68.7623) (end 120.54 68.6433) (width 0.25) (layer "F.Cu") (net 40) (tstamp e5471a8d-15c1-4d44-89eb-83d1bf2fcceb)) - (segment (start 120.54 68.6433) (end 120.54 68.36) (width 0.25) (layer "F.Cu") (net 40) (tstamp fae59cf4-133d-4b0c-a632-f10821800187)) - (segment (start 120.659 65.5634) (end 116.798 61.7022) (width 0.25) (layer "F.Cu") (net 40) (tstamp ff1d352a-b2b8-4e4f-a9e7-30f3c9de6acc)) - (segment (start 107 72.4487) (end 107 73) (width 0.25) (layer "B.Cu") (net 40) (tstamp 71e514c3-d67f-4e54-a104-1c1e0f50e2d8)) - (segment (start 99.08 89) (end 100.207 89) (width 0.25) (layer "B.Cu") (net 41) (tstamp 4550b75b-9c2e-424f-8fde-6e37b4aa6c47)) - (segment (start 102.824 75.5627) (end 102.824 77.192) (width 0.25) (layer "B.Cu") (net 41) (tstamp 4ae7ab7c-2340-4bff-9595-48ec06db68f9)) - (segment (start 102.824 77.192) (end 108.46 82.828) (width 0.25) (layer "B.Cu") (net 41) (tstamp 668d8dcd-dd4c-40a0-ac79-9ceb16e23643)) - (segment (start 108.46 82.828) (end 108.46 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp 6a668c91-cbad-4416-8dab-1e054354f1fc)) - (segment (start 101.094 88.1125) (end 108.46 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp 6f8ce3e2-1717-4a44-b9d7-e61d98aeba6a)) - (segment (start 108.46 88.1125) (end 108.46 89) (width 0.25) (layer "B.Cu") (net 41) (tstamp 7fc9d907-0924-4566-8c99-b2b2c366936e)) - (segment (start 100.207 89) (end 101.094 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp 810d8137-f0b1-46aa-bfc5-c4f480afb4d1)) - (segment (start 111.104 67.2831) (end 102.824 75.5627) (width 0.25) (layer "B.Cu") (net 41) (tstamp b7c52624-cbb9-409e-b774-e85e765108ac)) - (segment (start 119.27 68.36) (end 119.27 67.2831) (width 0.25) (layer "B.Cu") (net 41) (tstamp cbc4bf54-e3a1-4652-93ee-6603ff767c47)) - (segment (start 119.27 67.2831) (end 111.104 67.2831) (width 0.25) (layer "B.Cu") (net 41) (tstamp ccb3a081-fe9a-4abe-9f86-e399bea2d90d)) - (segment (start 109.73 87) (end 108.805 87) (width 0.25) (layer "F.Cu") (net 42) (tstamp 01e61a23-b173-4cfe-b055-fd79a5e70654)) - (segment (start 104.932 83.1269) (end 104.08 83.1269) (width 0.25) (layer "F.Cu") (net 42) (tstamp 5fce7aec-561a-4b69-b758-477e9a68c72d)) - (segment (start 109.73 89) (end 109.73 87) (width 0.25) (layer "F.Cu") (net 42) (tstamp 62b4e8fb-e83a-4b56-9e46-2481ccc01753)) - (segment (start 108.805 87) (end 104.932 83.1269) (width 0.25) (layer "F.Cu") (net 42) (tstamp 7b67057a-6f03-4b84-90b4-4fb4a422a5ee)) - (segment (start 104.08 83.1269) (end 104.08 82) (width 0.25) (layer "F.Cu") (net 42) (tstamp feaea463-c235-4a46-8f64-a934b08bf957)) + (segment (start 101.5 53.5469) (end 101.5 60) (width 0.25) (layer "F.Cu") (net 1) (tstamp 5498cbd2-490c-4ded-9057-4b680c4dc6d4)) + (segment (start 102.92 52.1269) (end 101.5 53.5469) (width 0.25) (layer "F.Cu") (net 1) (tstamp 5c8db4ff-ccd7-4772-89ab-b7583455be72)) + (segment (start 87 70.92) (end 86.92 71) (width 0.25) (layer "F.Cu") (net 1) (tstamp 9079f1d2-3351-463a-90dc-96a62278a904)) + (segment (start 102.92 51) (end 102.92 52.1269) (width 0.25) (layer "F.Cu") (net 1) (tstamp aee6a61e-2b90-4050-99f8-3a3b92abf96d)) + (segment (start 87 66) (end 87 70.92) (width 0.25) (layer "F.Cu") (net 1) (tstamp de77477d-28a3-4f04-ba6b-1663ed36a6e2)) + (segment (start 99.9731 60) (end 93.9731 66) (width 0.25) (layer "B.Cu") (net 1) (tstamp 0f385048-751d-4464-9020-17647bf03595)) + (segment (start 101.5 60) (end 99.9731 60) (width 0.25) (layer "B.Cu") (net 1) (tstamp b749be7a-f406-4e2e-bf33-01729a000cc4)) + (segment (start 93.9731 66) (end 87 66) (width 0.25) (layer "B.Cu") (net 1) (tstamp b7d6cc83-66db-4ebc-b9b7-4133a5aac753)) + (segment (start 111 72.92) (end 109 70.92) (width 0.25) (layer "F.Cu") (net 2) (tstamp 560cf3ef-ec16-4e20-af8f-0cf4da6d0f1a)) + (segment (start 109 70.92) (end 109 60) (width 0.25) (layer "F.Cu") (net 2) (tstamp 8b4ca131-d4cd-4f91-9957-4a012ad31232)) + (segment (start 111 78.6345) (end 119 86.6345) (width 0.25) (layer "F.Cu") (net 2) (tstamp 939148f2-1344-4edb-93c2-b818f6af19c3)) + (segment (start 111 72.92) (end 111 78.6345) (width 0.25) (layer "F.Cu") (net 2) (tstamp dface084-a7c1-4552-a9fc-c578d87cf143)) + (segment (start 119 86.6345) (end 119 89.36) (width 0.25) (layer "F.Cu") (net 2) (tstamp e6784f1e-56ee-421c-b920-6cff790e430b)) + (segment (start 117.298 58.9246) (end 110.076 58.9246) (width 0.25) (layer "B.Cu") (net 2) (tstamp 12bc6725-64eb-4b03-97f7-f86567c3a5cc)) + (segment (start 110.076 58.9246) (end 109 60) (width 0.25) (layer "B.Cu") (net 2) (tstamp 3a8ece8c-6813-4c79-a48f-66964f81e7a8)) + (segment (start 117.3 58.9231) (end 117.298 58.9246) (width 0.25) (layer "B.Cu") (net 2) (tstamp 80a7af35-8e8e-42aa-9631-cd74da638c01)) + (segment (start 119.23 58.9231) (end 117.3 58.9231) (width 0.25) (layer "B.Cu") (net 2) (tstamp d241275a-b868-43c5-bc1c-27e7609d6aee)) + (segment (start 119.23 60) (end 119.23 58.9231) (width 0.25) (layer "B.Cu") (net 2) (tstamp f6a71f4b-ad6c-4240-9886-f96c8e8f601b)) + (segment (start 117.73 89.36) (end 116.878 89.36) (width 0.25) (layer "F.Cu") (net 3) (tstamp 041dd159-1df9-4c88-8def-e90640f0efca)) + (segment (start 116.878 89.36) (end 115.75 90.4881) (width 0.25) (layer "F.Cu") (net 3) (tstamp b570b690-bf28-4f40-80fc-ab07d23ccec3)) + (segment (start 115.75 90.4881) (end 115.75 93.9) (width 0.25) (layer "F.Cu") (net 3) (tstamp dfc2231a-cf41-4995-9dd7-b72ed1a9efe6)) + (segment (start 114.207 99) (end 114.207 97.9831) (width 0.25) (layer "B.Cu") (net 4) (tstamp 11e0708d-dc9a-407f-b983-2fc8252db302)) + (segment (start 114.207 97.9831) (end 118.29 93.9) (width 0.25) (layer "B.Cu") (net 4) (tstamp 26fca0ae-520d-4e63-85a1-657986e0a7a0)) + (segment (start 113.08 99) (end 114.207 99) (width 0.25) (layer "B.Cu") (net 4) (tstamp 53754b24-fc5d-4322-a6ab-4f5ad48991f0)) + (segment (start 130 68.82) (end 130 67.6431) (width 0.25) (layer "F.Cu") (net 5) (tstamp 099e3480-c2db-4254-b979-a8644ef33234)) + (segment (start 104 76) (end 102 78) (width 0.25) (layer "F.Cu") (net 5) (tstamp 1d98c998-4efd-4f2f-a1dc-fab88b376e88)) + (segment (start 130 49.6769) (end 130 48.5) (width 0.25) (layer "F.Cu") (net 5) (tstamp 3cde2a39-e45d-44cb-8441-9f46b7f245fa)) + (segment (start 130 67.6431) (end 129.634 67.6431) (width 0.25) (layer "F.Cu") (net 5) (tstamp 3fb1b4c9-baf8-44f4-bc33-4017bfb718ee)) + (segment (start 102.92 96.08) (end 104 95) (width 0.25) (layer "F.Cu") (net 5) (tstamp 41f201a5-077a-4e6d-b9fa-22663816ee76)) + (segment (start 102 78) (end 102 93) (width 0.25) (layer "F.Cu") (net 5) (tstamp 8283a78f-3f69-428e-af2b-6053869b81cf)) + (segment (start 102 93) (end 104 95) (width 0.25) (layer "F.Cu") (net 5) (tstamp a41c1f06-10ae-421b-bd1e-22812137163b)) + (segment (start 129.632 49.6769) (end 130 49.6769) (width 0.25) (layer "F.Cu") (net 5) (tstamp b6929396-1906-4ece-8339-2a8d23a3a30c)) + (segment (start 128.806 50.5031) (end 129.632 49.6769) (width 0.25) (layer "F.Cu") (net 5) (tstamp e6cff794-37ee-49df-aca6-7bdd71c560c2)) + (segment (start 128.806 66.8149) (end 128.806 50.5031) (width 0.25) (layer "F.Cu") (net 5) (tstamp ea8caf41-7d10-4847-a14e-c149b2f21d20)) + (segment (start 102.92 99) (end 102.92 96.08) (width 0.25) (layer "F.Cu") (net 5) (tstamp f5d020cf-539d-4e37-aadb-4c7d74cc412a)) + (segment (start 129.634 67.6431) (end 128.806 66.8149) (width 0.25) (layer "F.Cu") (net 5) (tstamp f966c5d6-b189-4bd3-a21e-302ddc29dac2)) + (segment (start 117.998 70) (end 123.5 70) (width 0.25) (layer "B.Cu") (net 5) (tstamp 058d0766-d157-4ad5-b887-b9cd3f82af30)) + (segment (start 89 92) (end 88.92 91.92) (width 0.25) (layer "B.Cu") (net 5) (tstamp 07080396-b88f-4386-a0a6-caa87dde2efc)) + (segment (start 123.5 70) (end 124.68 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp 15aaa9cd-cf72-4f78-bf63-fb1b152da96a)) + (segment (start 124.68 68.82) (end 130 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp 1d18aa60-97a4-4cd9-9c4a-9b3591c8ecf8)) + (segment (start 110.78 70.8268) (end 112.175 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp 34962aaf-d556-419b-870f-9d2f359584c3)) + (segment (start 114.5 73.1521) (end 112.175 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp 4916d75d-7cef-4d73-94cc-220130c1ba41)) + (segment (start 118.102 68.82) (end 118.102 68.462) (width 0.25) (layer "B.Cu") (net 5) (tstamp 49456390-7a5c-4ef0-b596-c664471ce557)) + (segment (start 104 76) (end 105.607 76) (width 0.25) (layer "B.Cu") (net 5) (tstamp 4f02288e-70b8-4291-a74e-8f68c5cbfb41)) + (segment (start 117.46 69.4615) (end 117.998 70) (width 0.25) (layer "B.Cu") (net 5) (tstamp 6a55b72e-2d2c-4965-ab8c-af0e3768b19a)) + (segment (start 113.54 69.4615) (end 117.46 69.4615) (width 0.25) (layer "B.Cu") (net 5) (tstamp 787f6e91-649f-4d33-805e-7e971682bb1a)) + (segment (start 105.607 76) (end 110.78 70.8268) (width 0.25) (layer "B.Cu") (net 5) (tstamp 7b4231df-9e51-4196-9138-959db39c6215)) + (segment (start 112.175 70.8268) (end 113.54 69.4615) (width 0.25) (layer "B.Cu") (net 5) (tstamp 88a9065d-e433-4aaf-b8a8-aad1ec6534bd)) + (segment (start 88.92 91.92) (end 88.92 89) (width 0.25) (layer "B.Cu") (net 5) (tstamp a1fce58b-2bbd-46ad-ba51-8dbb5af9fe25)) + (segment (start 117.46 69.4615) (end 118.102 68.82) (width 0.25) (layer "B.Cu") (net 5) (tstamp a6156602-346a-4ac7-8929-d99a806a768d)) + (segment (start 118.102 68.462) (end 118 68.36) (width 0.25) (layer "B.Cu") (net 5) (tstamp c0687df2-2f5a-4fe6-ada3-453eec4099b8)) + (segment (start 114.5 74.16) (end 114.5 73.1521) (width 0.25) (layer "B.Cu") (net 5) (tstamp c4867604-f89c-41e1-9978-e4cae7f56f8e)) + (segment (start 101 92) (end 89 92) (width 0.25) (layer "B.Cu") (net 5) (tstamp d337486f-c42b-4a1e-8216-bdb945137a4e)) + (segment (start 104 95) (end 101 92) (width 0.25) (layer "B.Cu") (net 5) (tstamp df5e4fe6-87cf-4186-a757-684990fc4e81)) + (segment (start 132.54 51.04) (end 132.54 48.5) (width 0.25) (layer "F.Cu") (net 6) (tstamp b1753268-4e23-49e0-b77c-e23b30be1c32)) + (segment (start 131.363 51.4078) (end 130.66 52.1103) (width 0.25) (layer "B.Cu") (net 6) (tstamp 035c42b6-7a67-4a0d-9144-a743c0c189ab)) + (segment (start 120.676 51) (end 119.532 49.8565) (width 0.25) (layer "B.Cu") (net 6) (tstamp 0a7e3d14-78eb-4035-9d92-67baf7528850)) + (segment (start 131.363 51.04) (end 131.363 51.4078) (width 0.25) (layer "B.Cu") (net 6) (tstamp 12603f53-0a90-4a61-9918-cce20d774bfe)) + (segment (start 99.1435 49.8565) (end 98 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 49c9d42e-1d30-4cb2-b353-460e66d88911)) + (segment (start 130.66 52.1103) (end 130.66 52.1104) (width 0.25) (layer "B.Cu") (net 6) (tstamp 51690e55-b208-4091-84f8-8a75420ca860)) + (segment (start 130.66 52.1104) (end 130.461 52.31) (width 0.25) (layer "B.Cu") (net 6) (tstamp 5638f6b0-4660-437f-bb8e-c6ae59ed9f3f)) + (segment (start 126.078 51) (end 120.676 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 5f2a8586-df24-4237-9bae-357f8c9fb1d1)) + (segment (start 127.388 52.31) (end 126.078 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp 8faff738-7e3c-4904-ab14-b2a981ad959f)) + (segment (start 130.66 52.1103) (end 130.54 52.2306) (width 0.25) (layer "B.Cu") (net 6) (tstamp 97d65620-99c4-4614-88b8-25338d37b24a)) + (segment (start 132.54 51.04) (end 131.363 51.04) (width 0.25) (layer "B.Cu") (net 6) (tstamp c72f8da5-1fe6-4e24-8d3b-f73274a97617)) + (segment (start 130.461 52.31) (end 127.388 52.31) (width 0.25) (layer "B.Cu") (net 6) (tstamp c94ea24a-6af7-4ba9-bb1a-f656f44a7e2a)) + (segment (start 120.5 51) (end 120.676 51) (width 0.25) (layer "B.Cu") (net 6) (tstamp d38701b0-5e36-4788-9d9c-741589dcf2e4)) + (segment (start 119.532 49.8565) (end 99.1435 49.8565) (width 0.25) (layer "B.Cu") (net 6) (tstamp db89cdd6-1624-4492-9a4e-ce78495eaed0)) + (segment (start 130 58.66) (end 130 59.2484) (width 0.25) (layer "F.Cu") (net 9) (tstamp 072a6e73-fd5c-4f0e-883e-14b28a88ee18)) + (segment (start 107 84.2914) (end 107 83.16) (width 0.25) (layer "B.Cu") (net 9) (tstamp 0de07b54-1336-486f-a1bf-6dd6cc9b8814)) + (segment (start 111 89) (end 111 83.08) (width 0.25) (layer "B.Cu") (net 9) (tstamp 16458e6e-63ce-4b4a-baf7-8b90771d092f)) + (segment (start 128.823 58.66) (end 128.504 58.3409) (width 0.25) (layer "B.Cu") (net 9) (tstamp 1e31eb01-291d-4b9f-ae95-9c9928fe02cf)) + (segment (start 128.423 96.36) (end 120.9 96.36) (width 0.25) (layer "B.Cu") (net 9) (tstamp 23df3904-ee75-4c6f-8f5e-9addc3b06356)) + (segment (start 130 58.66) (end 128.823 58.66) (width 0.25) (layer "B.Cu") (net 9) (tstamp 4f4e95f4-49f2-4820-8584-59a5449dc3f7)) + (segment (start 128.823 96.76) (end 128.423 96.36) (width 0.25) (layer "B.Cu") (net 9) (tstamp 611a1bb5-9248-42fd-83c7-8632027677cc)) + (segment (start 128.823 78.98) (end 130 78.98) (width 0.25) (layer "B.Cu") (net 9) (tstamp 70f48851-e60b-49ec-8f79-168bd8cda84f)) + (segment (start 104.291 87) (end 107 84.2914) (width 0.25) (layer "B.Cu") (net 9) (tstamp 7515a736-0bb1-4f1c-b7e2-edc896e9ae4f)) + (segment (start 130 96.76) (end 128.823 96.76) (width 0.25) (layer "B.Cu") (net 9) (tstamp 7b1dd970-e272-4ab8-86f4-1853775f1c94)) + (segment (start 87.46 87) (end 104.291 87) (width 0.25) (layer "B.Cu") (net 9) (tstamp 7d7d32c4-c260-468d-a376-da221ffa7905)) + (segment (start 128.504 58.3409) (end 121.228 58.3409) (width 0.25) (layer "B.Cu") (net 9) (tstamp 99c2680e-e095-4908-9809-3eea0b1387bb)) + (segment (start 111 83) (end 111 83.08) (width 0.25) (layer "B.Cu") (net 9) (tstamp c345cee1-3767-4b86-98ef-c670bb33d755)) + (segment (start 128.263 78.42) (end 128.823 78.98) (width 0.25) (layer "B.Cu") (net 9) (tstamp e231b4cd-02ce-460e-81ba-76e6807ae11b)) + (segment (start 121.363 78.42) (end 128.263 78.42) (width 0.25) (layer "B.Cu") (net 9) (tstamp e841e63b-e83c-4e2c-94e3-ad38ec8fbc35)) + (segment (start 84 90.46) (end 87.46 87) (width 0.25) (layer "B.Cu") (net 9) (tstamp f23648c9-4191-4678-9384-573583dfeabd)) + (segment (start 109.182 95.182) (end 121.818 95.182) (width 0.25) (layer "F.Cu") (net 11) (tstamp 52d8b18a-0fd9-42bc-b131-8bf98d018cf9)) + (segment (start 121.818 95.182) (end 128.6354 88.3646) (width 0.25) (layer "F.Cu") (net 11) (tstamp 7f8f4772-58cd-4cdc-8719-03ea9f593990)) + (segment (start 128.6354 88.3646) (end 128.6354 83.6957) (width 0.25) (layer "F.Cu") (net 11) (tstamp 8d13660c-6bb6-4865-bceb-249c51395787)) + (segment (start 104 84.84) (end 104 90) (width 0.25) (layer "F.Cu") (net 11) (tstamp 8d78deb1-ddbc-4546-9d6c-6ab8f3e28e49)) + (segment (start 129.6342 82.6969) (end 130 82.6969) (width 0.25) (layer "F.Cu") (net 11) (tstamp 94a58151-ce41-4036-96ce-db99376007e5)) + (segment (start 128.6354 83.6957) (end 129.6342 82.6969) (width 0.25) (layer "F.Cu") (net 11) (tstamp a2993b73-7dd7-485c-a4ca-695ce3bcec99)) + (segment (start 104 90) (end 109.182 95.182) (width 0.25) (layer "F.Cu") (net 11) (tstamp a48d37be-e463-4854-98fa-8e301de17caa)) + (segment (start 130 82.6969) (end 130 81.52) (width 0.25) (layer "F.Cu") (net 11) (tstamp d39949ad-ae14-4db6-99fe-7c72ab9dfebe)) + (segment (start 93.92 82) (end 93.92 81) (width 0.25) (layer "B.Cu") (net 11) (tstamp 321ce515-c543-48eb-ae92-ced308d0c51c)) + (segment (start 94.16 84.84) (end 93.42 84.1) (width 0.25) (layer "B.Cu") (net 11) (tstamp 4af5e233-c99e-482f-8f06-439a6db036d4)) + (segment (start 93.42 84.1) (end 93.42 81.5) (width 0.25) (layer "B.Cu") (net 11) (tstamp 67175e71-3c4b-47f6-b16d-02705d983bbf)) + (segment (start 104 84.84) (end 94.16 84.84) (width 0.25) (layer "B.Cu") (net 11) (tstamp b9fd3e0c-2be9-457c-a611-354af1218bee)) + (segment (start 93.92 81) (end 93.42 81.5) (width 0.25) (layer "B.Cu") (net 11) (tstamp d8463a83-e3b8-4ab6-af76-4e04595ac608)) + (segment (start 131.27 65.8108) (end 131.27 79.4389) (width 0.25) (layer "B.Cu") (net 26) (tstamp 0309c7e5-6850-4c4e-881d-483e38f3b65c)) + (segment (start 114.8665 60) (end 111.403 60) (width 0.25) (layer "B.Cu") (net 26) (tstamp 36746830-e933-4902-a36d-c4603000e8ee)) + (segment (start 111.403 60) (end 95.403 76) (width 0.25) (layer "B.Cu") (net 26) (tstamp 376545e8-a727-4796-8a97-9698ec6e4bbb)) + (segment (start 95.403 76) (end 93.84 76) (width 0.25) (layer "B.Cu") (net 26) (tstamp 45593f94-367a-45f6-ab5b-8edcf0fc6822)) + (segment (start 117.96 60) (end 114.8665 60) (width 0.25) (layer "B.Cu") (net 26) (tstamp 53a10622-f0eb-40a0-86b3-3bdd45b8738f)) + (segment (start 119.8765 65.01) (end 130.4692 65.01) (width 0.25) (layer "B.Cu") (net 26) (tstamp 7e8d22e4-ecea-4056-82c3-5399eb589862)) + (segment (start 130.4692 65.01) (end 131.27 65.8108) (width 0.25) (layer "B.Cu") (net 26) (tstamp 8ff80aef-ec85-414d-a1ec-5720455a7b87)) + (segment (start 132.54 81.52) (end 132.54 80.3431) (width 0.25) (layer "B.Cu") (net 26) (tstamp bef4b6c2-0692-4720-8b2b-2d37d2568178)) + (segment (start 114.8665 60) (end 119.8765 65.01) (width 0.25) (layer "B.Cu") (net 26) (tstamp f15af1b0-680a-46a7-970b-4211c41f82ee)) + (segment (start 131.27 79.4389) (end 132.1742 80.3431) (width 0.25) (layer "B.Cu") (net 26) (tstamp f5b6afeb-43c2-4ff0-b1d4-e7ee754758c0)) + (segment (start 132.1742 80.3431) (end 132.54 80.3431) (width 0.25) (layer "B.Cu") (net 26) (tstamp fa4a1282-9fb1-4027-8455-ef9d6ef1dbef)) + (segment (start 101 94) (end 99 96) (width 0.25) (layer "F.Cu") (net 36) (tstamp 1396e1eb-3f18-48ed-bf7c-445681cc74b5)) + (segment (start 98.08 55) (end 99.6748 56.5948) (width 0.25) (layer "F.Cu") (net 36) (tstamp 15115f24-c0b7-48b5-8b69-070281928f53)) + (segment (start 101 87) (end 101 94) (width 0.25) (layer "F.Cu") (net 36) (tstamp d18451fa-c220-44eb-ae78-97509a4d279b)) + (segment (start 99.6748 85.6748) (end 101 87) (width 0.25) (layer "F.Cu") (net 36) (tstamp dce1b756-e351-4d0c-9167-a53a12649425)) + (segment (start 99.6748 56.5948) (end 99.6748 85.6748) (width 0.25) (layer "F.Cu") (net 36) (tstamp f2a58050-4d4c-4008-a88b-c5367d1301fb)) + (segment (start 99.1973 96.1973) (end 107.303 96.1973) (width 0.25) (layer "B.Cu") (net 36) (tstamp 0d277be7-bf11-42ad-9748-77aa1a5158ee)) + (segment (start 117.73 85.77) (end 117.73 81) (width 0.25) (layer "B.Cu") (net 36) (tstamp 36bd6859-5e69-45bc-9f65-b4a76a4b4ba9)) + (segment (start 85.1769 93) (end 85.1784 93.0015) (width 0.25) (layer "B.Cu") (net 36) (tstamp 484df566-336d-4b5f-ab0d-8cdfd6451894)) + (segment (start 96.0015 93.0015) (end 99 96) (width 0.25) (layer "B.Cu") (net 36) (tstamp 75f30d3b-526e-435e-8baa-4cbd67c76684)) + (segment (start 99 96) (end 99.1973 96.1973) (width 0.25) (layer "B.Cu") (net 36) (tstamp 80b7110c-155d-45d5-8edd-34ced3e51672)) + (segment (start 85.1784 93.0015) (end 96.0015 93.0015) (width 0.25) (layer "B.Cu") (net 36) (tstamp 9799c6d4-e2d2-4928-ae63-39bd4d323a4d)) + (segment (start 84 93) (end 85.1769 93) (width 0.25) (layer "B.Cu") (net 36) (tstamp c1b15869-6dc8-4a9c-a91a-9f0df6f98a04)) + (segment (start 107.303 96.1973) (end 117.73 85.77) (width 0.25) (layer "B.Cu") (net 36) (tstamp ef643056-219a-417d-bfcd-93311160049a)) + (segment (start 88.84 96) (end 87.7131 96) (width 0.25) (layer "B.Cu") (net 37) (tstamp 84fad0ff-2996-4166-aa19-a81c56ca0730)) + (segment (start 87.7131 96) (end 87.2531 95.54) (width 0.25) (layer "B.Cu") (net 37) (tstamp 95a72369-79b4-4982-b905-18168dad7e88)) + (segment (start 87.2531 95.54) (end 84 95.54) (width 0.25) (layer "B.Cu") (net 37) (tstamp e6dc2311-9fdd-42c9-a1ed-c83399bc910a)) + (segment (start 113.08 51) (end 117.96 51) (width 0.25) (layer "B.Cu") (net 38) (tstamp 2315076a-6424-4268-9210-2b9349aaa627)) + (segment (start 87.84 51) (end 87.84 52.1269) (width 0.25) (layer "F.Cu") (net 39) (tstamp 32325514-a1ce-428c-ad09-6d0d06612c54)) + (segment (start 87.84 52.1269) (end 87.92 52.2069) (width 0.25) (layer "F.Cu") (net 39) (tstamp 9f9cb85b-020f-4cd9-bd0b-f6daebdc76de)) + (segment (start 87.92 52.2069) (end 87.92 55) (width 0.25) (layer "F.Cu") (net 39) (tstamp f3d043f2-49db-4969-b025-3101e90dc085)) + (segment (start 119.23 52.0769) (end 119.165 52.1419) (width 0.25) (layer "B.Cu") (net 39) (tstamp 0f3fedad-4133-4eb2-977c-99a45469dcff)) + (segment (start 119.165 52.1419) (end 90.1088 52.1419) (width 0.25) (layer "B.Cu") (net 39) (tstamp 17306139-5112-4828-af17-8da041fe3d28)) + (segment (start 90.1088 52.1419) (end 88.9669 51) (width 0.25) (layer "B.Cu") (net 39) (tstamp 42ae41d2-ab59-47ca-b873-492679f9c376)) + (segment (start 88.9669 51) (end 87.84 51) (width 0.25) (layer "B.Cu") (net 39) (tstamp 6beec8d2-a6c9-4ce8-9f77-55b891fbd23c)) + (segment (start 119.23 51) (end 119.23 52.0769) (width 0.25) (layer "B.Cu") (net 39) (tstamp d93d823c-b52b-4858-b166-b92b7a1f916d)) + (segment (start 120.659 68.7623) (end 120.54 68.6433) (width 0.25) (layer "F.Cu") (net 40) (tstamp 358f4d08-901e-4fbe-ac5d-6f5f66f987dd)) + (segment (start 120.54 74.96) (end 119 76.5) (width 0.25) (layer "F.Cu") (net 40) (tstamp 4546d7f3-bfb4-412c-a9f5-833da21fb079)) + (segment (start 108.343 58.4731) (end 107 59.8161) (width 0.25) (layer "F.Cu") (net 40) (tstamp 4e38bfae-5936-4fd2-82aa-343d47b8a7fe)) + (segment (start 115.627 62.8732) (end 116.798 61.7022) (width 0.25) (layer "F.Cu") (net 40) (tstamp 6a1c199e-d7ed-455d-937f-eaea7e451933)) + (segment (start 107 59.8161) (end 107 73) (width 0.25) (layer "F.Cu") (net 40) (tstamp 6b0624b3-28e5-49c4-bf7c-1cbf6c2d9b75)) + (segment (start 119 76.5) (end 119 81) (width 0.25) (layer "F.Cu") (net 40) (tstamp 787580c0-c0a0-4c65-aaf4-d49dacd95e22)) + (segment (start 120.54 68.6433) (end 120.54 68.36) (width 0.25) (layer "F.Cu") (net 40) (tstamp 83dd1d74-35ce-43a9-be11-c96dfa0d1221)) + (segment (start 113.569 58.4731) (end 108.343 58.4731) (width 0.25) (layer "F.Cu") (net 40) (tstamp 859b5e6e-2677-4ab4-8320-56b2365a1b0b)) + (segment (start 115.627 64) (end 115.627 62.8732) (width 0.25) (layer "F.Cu") (net 40) (tstamp 87f8cf12-a184-4a57-bd06-f03f38b9595f)) + (segment (start 120.659 65.5634) (end 116.798 61.7022) (width 0.25) (layer "F.Cu") (net 40) (tstamp 97677773-904a-45a3-976a-08254870ac84)) + (segment (start 120.659 68.7623) (end 120.659 71.9613) (width 0.25) (layer "F.Cu") (net 40) (tstamp a655e14a-d55b-4159-84de-1efb1e18b6d8)) + (segment (start 116.798 61.7022) (end 113.569 58.4731) (width 0.25) (layer "F.Cu") (net 40) (tstamp c1530938-c8cd-4896-a103-8091555a4920)) + (segment (start 120.54 72.0804) (end 120.54 74.96) (width 0.25) (layer "F.Cu") (net 40) (tstamp c6fbe2f1-036f-4f8c-be4f-7f6618052f54)) + (segment (start 120.659 68.7623) (end 120.659 65.5634) (width 0.25) (layer "F.Cu") (net 40) (tstamp e830e75c-e9f1-4202-a8a7-fb6a00c8eadb)) + (segment (start 120.659 71.9613) (end 120.54 72.0804) (width 0.25) (layer "F.Cu") (net 40) (tstamp eb565370-5e0b-4b40-a5da-bb80646c535f)) + (segment (start 114.5 64) (end 115.627 64) (width 0.25) (layer "F.Cu") (net 40) (tstamp fc65c88f-6d1d-41c5-bf46-69b3f878f12e)) + (segment (start 107 72.4487) (end 107 73) (width 0.25) (layer "B.Cu") (net 40) (tstamp 52a6ab16-f781-43bf-b4f8-129b2876eb28)) + (segment (start 119.27 68.36) (end 119.27 67.2831) (width 0.25) (layer "B.Cu") (net 41) (tstamp 0505d570-f5dc-494d-93f2-026cc623ca4a)) + (segment (start 119.27 67.2831) (end 111.104 67.2831) (width 0.25) (layer "B.Cu") (net 41) (tstamp 24bd6d47-6f4e-4eb9-b57d-02085ca668c4)) + (segment (start 111.104 67.2831) (end 102.824 75.5627) (width 0.25) (layer "B.Cu") (net 41) (tstamp 4514f89a-2317-4eda-ab20-c493365dbcc4)) + (segment (start 102.824 75.5627) (end 102.824 77.192) (width 0.25) (layer "B.Cu") (net 41) (tstamp 475f8150-5653-40a9-99dc-e83991cf95b1)) + (segment (start 108.46 88.1125) (end 108.46 89) (width 0.25) (layer "B.Cu") (net 41) (tstamp 4c06ad8a-5527-4ac8-ab21-a758f5538bfc)) + (segment (start 101.094 88.1125) (end 108.46 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp 8927fb9f-3f03-4307-931f-a18e49b908c8)) + (segment (start 102.824 77.192) (end 108.46 82.828) (width 0.25) (layer "B.Cu") (net 41) (tstamp 8a640845-080b-45b5-9082-880a850ac8a1)) + (segment (start 108.46 82.828) (end 108.46 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp 8f7ac55a-9151-42be-8d1b-066ba6d5b159)) + (segment (start 100.207 89) (end 101.094 88.1125) (width 0.25) (layer "B.Cu") (net 41) (tstamp bb135795-7797-46f6-a576-83905996a5d0)) + (segment (start 99.08 89) (end 100.207 89) (width 0.25) (layer "B.Cu") (net 41) (tstamp d8abfd79-84ec-49b1-82ea-95cca67077d1)) + (segment (start 104.932 83.1269) (end 104.08 83.1269) (width 0.25) (layer "F.Cu") (net 42) (tstamp 2e2cb8ff-3726-46d9-bf2a-194940002256)) + (segment (start 104.08 82.5634) (end 104.08 82) (width 0.25) (layer "F.Cu") (net 42) (tstamp 40ab708b-c617-4a2f-a221-e786f984c528)) + (segment (start 108.805 87) (end 104.932 83.1269) (width 0.25) (layer "F.Cu") (net 42) (tstamp 66fafe1e-1a86-4f2b-be54-7c75d549621d)) + (segment (start 104.08 82.5634) (end 103.58 82.0634) (width 0.25) (layer "F.Cu") (net 42) (tstamp 6b62a823-346a-4a58-842c-eb27215d1909)) + (segment (start 109.73 89) (end 109.73 87) (width 0.25) (layer "F.Cu") (net 42) (tstamp 81830828-75a0-42a6-b54e-8d4bc380c068)) + (segment (start 104.08 83.1269) (end 104.08 82.5634) (width 0.25) (layer "F.Cu") (net 42) (tstamp a2cbe440-f74a-41ab-af4f-4abb087ddc7b)) + (segment (start 109.73 87) (end 108.805 87) (width 0.25) (layer "F.Cu") (net 42) (tstamp ad3f71c9-dfb0-4177-831f-dc3fb4b3ccc9)) + (segment (start 103.58 82.0634) (end 103.58 81.5) (width 0.25) (layer "F.Cu") (net 42) (tstamp ef407493-1d26-43f8-97b2-72537c984257)) (zone (net 9) (net_name "GND") (layer "B.Cu") (tstamp 0439734c-1f86-4b67-9c14-36cdfe2e2799) (name "GND") (hatch edge 0.5) (connect_pads (clearance 0.5)) @@ -2570,24 +2532,100 @@ (fill yes (thermal_gap 0.5) (thermal_bridge_width 0.5)) (polygon (pts - (xy 83 47) - (xy 123 47) - (xy 123 102) - (xy 88 102) - (xy 88 84) - (xy 83 84) + (xy 82.044 47.008) + (xy 134.544 47.008) + (xy 134.5 99.5) + (xy 87 99) + (xy 87.044 84.008) + (xy 82.044 84.008) ) ) (filled_polygon (layer "B.Cu") (pts - (xy 122.943039 47.019685) - (xy 122.988794 47.072489) - (xy 123 47.124) - (xy 123 50.2505) - (xy 122.980315 50.317539) - (xy 122.927511 50.363294) - (xy 122.876 50.3745) + (xy 128.866918 47.027685) + (xy 128.912673 47.080489) + (xy 128.922617 47.149647) + (xy 128.893592 47.213203) + (xy 128.874193 47.231263) + (xy 128.792454 47.292454) + (xy 128.792453 47.292455) + (xy 128.792452 47.292456) + (xy 128.706206 47.407664) + (xy 128.706202 47.407671) + (xy 128.655908 47.542517) + (xy 128.649501 47.602116) + (xy 128.6495 47.602135) + (xy 128.6495 49.39787) + (xy 128.649501 49.397876) + (xy 128.655908 49.457483) + (xy 128.706202 49.592328) + (xy 128.706206 49.592335) + (xy 128.792452 49.707544) + (xy 128.792455 49.707547) + (xy 128.907664 49.793793) + (xy 128.907671 49.793797) + (xy 129.039081 49.84281) + (xy 129.095015 49.884681) + (xy 129.119432 49.950145) + (xy 129.10458 50.018418) + (xy 129.08343 50.046673) + (xy 128.961503 50.1686) + (xy 128.825965 50.362169) + (xy 128.825964 50.362171) + (xy 128.726098 50.576335) + (xy 128.726094 50.576344) + (xy 128.664938 50.804586) + (xy 128.664936 50.804596) + (xy 128.644341 51.039999) + (xy 128.644341 51.04) + (xy 128.664936 51.275403) + (xy 128.664938 51.275413) + (xy 128.726094 51.503655) + (xy 128.726099 51.503669) + (xy 128.728163 51.508094) + (xy 128.738656 51.577171) + (xy 128.710137 51.640955) + (xy 128.651661 51.679196) + (xy 128.615782 51.6845) + (xy 127.698452 51.6845) + (xy 127.631413 51.664815) + (xy 127.610771 51.648181) + (xy 126.578803 50.616212) + (xy 126.56898 50.60395) + (xy 126.568759 50.604134) + (xy 126.563786 50.598123) + (xy 126.540594 50.576344) + (xy 126.513364 50.550773) + (xy 126.502919 50.540328) + (xy 126.492475 50.529883) + (xy 126.486986 50.525625) + (xy 126.482561 50.521847) + (xy 126.448582 50.489938) + (xy 126.44858 50.489936) + (xy 126.448577 50.489935) + (xy 126.431029 50.480288) + (xy 126.414763 50.469604) + (xy 126.398933 50.457325) + (xy 126.356168 50.438818) + (xy 126.350922 50.436248) + (xy 126.310093 50.413803) + (xy 126.310092 50.413802) + (xy 126.290693 50.408822) + (xy 126.272281 50.402518) + (xy 126.253898 50.394562) + (xy 126.253892 50.39456) + (xy 126.207874 50.387272) + (xy 126.202152 50.386087) + (xy 126.157021 50.3745) + (xy 126.157019 50.3745) + (xy 126.136984 50.3745) + (xy 126.117586 50.372973) + (xy 126.110162 50.371797) + (xy 126.097805 50.36984) + (xy 126.097804 50.36984) + (xy 126.051416 50.374225) + (xy 126.045578 50.3745) (xy 121.523054 50.3745) (xy 121.456015 50.354815) (xy 121.413696 50.308953) @@ -2666,6 +2704,7 @@ (xy 98.757079 49.35833) (xy 98.742908 49.3725) (xy 98.728123 49.385128) + (xy 98.713963 49.395417) (xy 98.711912 49.396907) (xy 98.682209 49.43281) (xy 98.678277 49.437131) @@ -2708,7 +2747,7 @@ (xy 89.45788 50.60395) (xy 89.457659 50.604134) (xy 89.452686 50.598123) - (xy 89.420867 50.568243) + (xy 89.429494 50.576344) (xy 89.402264 50.550773) (xy 89.391819 50.540328) (xy 89.381375 50.529883) @@ -2789,7 +2828,7 @@ (xy 88.854389 51.852634) (xy 88.924081 51.857618) (xy 88.968428 51.886118) - (xy 89.304185 52.221876) + (xy 89.291039 52.20873) (xy 89.607997 52.525688) (xy 89.617822 52.537951) (xy 89.618043 52.537769) @@ -2885,27 +2924,223 @@ (xy 121.413696 51.691047) (xy 121.462658 51.641203) (xy 121.523054 51.6255) - (xy 122.876 51.6255) - (xy 122.943039 51.645185) - (xy 122.988794 51.697989) - (xy 123 51.7495) - (xy 123 59.258931) - (xy 122.980315 59.32597) - (xy 122.963688 59.346605) - (xy 122.957372 59.352922) - (xy 122.942573 59.365563) - (xy 122.926416 59.377302) - (xy 122.926413 59.377304) - (xy 122.896674 59.413252) - (xy 122.892749 59.417567) - (xy 121.888172 60.422467) - (xy 121.826855 60.455962) - (xy 121.800477 60.4588) - (xy 121.643746 60.4588) - (xy 121.576707 60.439115) - (xy 121.530952 60.386311) - (xy 121.520343 60.322647) - (xy 121.525 60.275358) + (xy 125.767548 51.6255) + (xy 125.834587 51.645185) + (xy 125.855229 51.661819) + (xy 126.887194 52.693784) + (xy 126.897019 52.706048) + (xy 126.89724 52.705866) + (xy 126.90221 52.711873) + (xy 126.902213 52.711876) + (xy 126.902214 52.711877) + (xy 126.952651 52.759241) + (xy 126.97353 52.78012) + (xy 126.979004 52.784366) + (xy 126.983442 52.788156) + (xy 127.017418 52.820062) + (xy 127.017422 52.820064) + (xy 127.034973 52.829713) + (xy 127.051231 52.840392) + (xy 127.067064 52.852674) + (xy 127.089015 52.862172) + (xy 127.109837 52.871183) + (xy 127.115081 52.873752) + (xy 127.155908 52.896197) + (xy 127.175312 52.901179) + (xy 127.19371 52.907478) + (xy 127.212105 52.915438) + (xy 127.258129 52.922726) + (xy 127.263832 52.923907) + (xy 127.308981 52.9355) + (xy 127.329016 52.9355) + (xy 127.348413 52.937026) + (xy 127.368196 52.94016) + (xy 127.414584 52.935775) + (xy 127.420422 52.9355) + (xy 128.615782 52.9355) + (xy 128.682821 52.955185) + (xy 128.728576 53.007989) + (xy 128.73852 53.077147) + (xy 128.728163 53.111906) + (xy 128.726099 53.11633) + (xy 128.726094 53.116344) + (xy 128.664938 53.344586) + (xy 128.664936 53.344596) + (xy 128.644341 53.579999) + (xy 128.644341 53.58) + (xy 128.664936 53.815403) + (xy 128.664938 53.815413) + (xy 128.726094 54.043655) + (xy 128.726096 54.043659) + (xy 128.726097 54.043663) + (xy 128.809155 54.221781) + (xy 128.825965 54.25783) + (xy 128.825967 54.257834) + (xy 128.934281 54.412521) + (xy 128.961501 54.451396) + (xy 128.961506 54.451402) + (xy 129.128597 54.618493) + (xy 129.128603 54.618498) + (xy 129.314158 54.748425) + (xy 129.357783 54.803002) + (xy 129.364977 54.8725) + (xy 129.333454 54.934855) + (xy 129.314158 54.951575) + (xy 129.128597 55.081505) + (xy 128.961505 55.248597) + (xy 128.825965 55.442169) + (xy 128.825964 55.442171) + (xy 128.726098 55.656335) + (xy 128.726094 55.656344) + (xy 128.664938 55.884586) + (xy 128.664936 55.884596) + (xy 128.644341 56.119999) + (xy 128.644341 56.12) + (xy 128.664936 56.355403) + (xy 128.664938 56.355413) + (xy 128.726094 56.583655) + (xy 128.726096 56.583659) + (xy 128.726097 56.583663) + (xy 128.73 56.592032) + (xy 128.825965 56.79783) + (xy 128.825967 56.797834) + (xy 128.934281 56.952521) + (xy 128.961501 56.991396) + (xy 128.961506 56.991402) + (xy 129.128597 57.158493) + (xy 129.128603 57.158498) + (xy 129.314594 57.28873) + (xy 129.358219 57.343307) + (xy 129.365413 57.412805) + (xy 129.33389 57.47516) + (xy 129.314595 57.49188) + (xy 129.128922 57.62189) + (xy 129.12892 57.621891) + (xy 128.961891 57.78892) + (xy 128.961886 57.788926) + (xy 128.8264 57.98242) + (xy 128.826399 57.982422) + (xy 128.72657 58.196507) + (xy 128.726567 58.196513) + (xy 128.669364 58.409999) + (xy 128.669364 58.41) + (xy 129.566314 58.41) + (xy 129.540507 58.450156) + (xy 129.5 58.588111) + (xy 129.5 58.731889) + (xy 129.540507 58.869844) + (xy 129.566314 58.91) + (xy 128.669364 58.91) + (xy 128.726567 59.123486) + (xy 128.72657 59.123492) + (xy 128.826399 59.337578) + (xy 128.961894 59.531082) + (xy 129.128917 59.698105) + (xy 129.314595 59.828119) + (xy 129.358219 59.882696) + (xy 129.365412 59.952195) + (xy 129.33389 60.014549) + (xy 129.314595 60.031269) + (xy 129.128594 60.161508) + (xy 128.961505 60.328597) + (xy 128.825965 60.522169) + (xy 128.825964 60.522171) + (xy 128.726098 60.736335) + (xy 128.726094 60.736344) + (xy 128.664938 60.964586) + (xy 128.664936 60.964596) + (xy 128.644341 61.199999) + (xy 128.644341 61.2) + (xy 128.664936 61.435403) + (xy 128.664938 61.435413) + (xy 128.726094 61.663655) + (xy 128.726096 61.663659) + (xy 128.726097 61.663663) + (xy 128.803135 61.82887) + (xy 128.825965 61.87783) + (xy 128.825967 61.877834) + (xy 128.934281 62.032521) + (xy 128.961501 62.071396) + (xy 128.961506 62.071402) + (xy 129.128597 62.238493) + (xy 129.128603 62.238498) + (xy 129.314158 62.368425) + (xy 129.357783 62.423002) + (xy 129.364977 62.4925) + (xy 129.333454 62.554855) + (xy 129.314158 62.571575) + (xy 129.128597 62.701505) + (xy 128.961505 62.868597) + (xy 128.825965 63.062169) + (xy 128.825964 63.062171) + (xy 128.726098 63.276335) + (xy 128.726094 63.276344) + (xy 128.664938 63.504586) + (xy 128.664936 63.504596) + (xy 128.644341 63.739999) + (xy 128.644341 63.74) + (xy 128.664936 63.975403) + (xy 128.664938 63.975413) + (xy 128.726094 64.203655) + (xy 128.726099 64.203669) + (xy 128.728163 64.208094) + (xy 128.738656 64.277171) + (xy 128.710137 64.340955) + (xy 128.651661 64.379196) + (xy 128.615782 64.3845) + (xy 120.186952 64.3845) + (xy 120.119913 64.364815) + (xy 120.099271 64.348181) + (xy 117.200557 61.449466) + (xy 117.167072 61.388143) + (xy 117.172056 61.318451) + (xy 117.213928 61.262518) + (xy 117.279392 61.238101) + (xy 117.319592 61.243882) + (xy 117.319965 61.242307) + (xy 117.327516 61.244091) + (xy 117.334444 61.244835) + (xy 117.387127 61.2505) + (xy 118.532872 61.250499) + (xy 118.592483 61.244091) + (xy 118.727331 61.193796) + (xy 118.727335 61.193792) + (xy 118.735118 61.189544) + (xy 118.736252 61.191621) + (xy 118.789715 61.171671) + (xy 118.834576 61.176694) + (xy 118.835656 61.177021) + (xy 118.835659 61.177023) + (xy 119.028967 61.235662) + (xy 119.23 61.255462) + (xy 119.431033 61.235662) + (xy 119.624341 61.177023) + (xy 119.802494 61.081798) + (xy 119.802493 61.081798) + (xy 119.807078 61.079348) + (xy 119.87548 61.065106) + (xy 119.923985 61.079348) + (xy 120.105848 61.176557) + (xy 120.25 61.220285) + (xy 120.25 60.33427) + (xy 120.250299 60.32819) + (xy 120.254629 60.28422) + (xy 120.319052 60.334363) + (xy 120.437424 60.375) + (xy 120.531073 60.375) + (xy 120.623446 60.359586) + (xy 120.733514 60.300019) + (xy 120.75 60.28211) + (xy 120.75 61.220285) + (xy 120.894153 61.176557) + (xy 121.072209 61.081384) + (xy 121.072215 61.081379) + (xy 121.228292 60.953292) + (xy 121.356379 60.797215) + (xy 121.356384 60.797209) + (xy 121.451556 60.619154) + (xy 121.51017 60.425932) + (xy 121.525 60.275357) (xy 121.525 60.25) (xy 120.77956 60.25) (xy 120.818278 60.207941) @@ -3044,7 +3279,7 @@ (xy 107.294732 59.999995) (xy 107.294732 60.000004) (xy 107.313777 60.254154) - (xy 107.359838 60.455962) + (xy 107.353007 60.426033) (xy 107.370492 60.502637) (xy 107.463607 60.739888) (xy 107.591041 60.960612) @@ -3054,24 +3289,18 @@ (xy 108.147371 61.476807) (xy 108.147372 61.476808) (xy 108.147373 61.476809) - (xy 108.261373 61.531708) + (xy 108.269328 61.535538) (xy 108.376992 61.587387) (xy 108.376993 61.587387) (xy 108.376996 61.587389) - (xy 108.620542 61.662513) - (xy 108.872565 61.7005) - (xy 109.127435 61.7005) - (xy 109.379458 61.662513) - (xy 109.623004 61.587389) - (xy 109.77262 61.515337) - (xy 109.841558 61.503986) - (xy 109.905693 61.531708) - (xy 109.944659 61.589703) - (xy 109.946084 61.659558) - (xy 109.914101 61.714738) - (xy 96.290925 75.33818) - (xy 96.229602 75.371666) - (xy 96.203243 75.3745) + (xy 108.603766 61.657338) + (xy 108.662025 61.695908) + (xy 108.690183 61.759853) + (xy 108.679299 61.82887) + (xy 108.654897 61.86351) + (xy 95.180228 75.338181) + (xy 95.118905 75.371666) + (xy 95.092547 75.3745) (xy 95.054188 75.3745) (xy 94.987149 75.354815) (xy 94.952613 75.321623) @@ -3132,368 +3361,37 @@ (xy 94.952613 76.678377) (xy 95.007189 76.634752) (xy 95.054188 76.6255) - (xy 96.430961 76.6255) - (xy 96.446578 76.627224) - (xy 96.446605 76.626939) - (xy 96.454366 76.627671) - (xy 96.454373 76.627673) - (xy 96.523506 76.6255) - (xy 96.55305 76.6255) - (xy 96.553051 76.6255) - (xy 96.553051 76.625499) - (xy 96.55855 76.624804) - (xy 96.559925 76.624631) - (xy 96.565757 76.624171) - (xy 96.612333 76.622708) - (xy 96.631569 76.617118) - (xy 96.650614 76.613174) - (xy 96.670492 76.610664) - (xy 96.71383 76.593504) - (xy 96.719348 76.591615) - (xy 96.764096 76.578615) - (xy 96.78133 76.568422) - (xy 96.798805 76.55986) - (xy 96.817432 76.552486) - (xy 96.855149 76.525081) - (xy 96.859988 76.521902) - (xy 96.900125 76.498166) - (xy 96.914287 76.484002) - (xy 96.929083 76.471366) - (xy 96.93061 76.470256) - (xy 96.945287 76.459594) - (xy 96.975013 76.42366) - (xy 96.978904 76.419384) - (xy 110.381436 63.016594) - (xy 112.197775 61.20022) - (xy 112.259098 61.166734) - (xy 112.285457 61.1639) - (xy 117.111461 61.1639) - (xy 117.1785 61.183585) - (xy 117.185771 61.188633) - (xy 117.192664 61.193793) - (xy 117.192671 61.193797) - (xy 117.22829 61.207082) - (xy 117.272628 61.235573) - (xy 117.505214 61.468115) - (xy 117.515017 61.480353) - (xy 117.515242 61.480168) - (xy 117.520212 61.486175) - (xy 117.520213 61.486176) - (xy 117.520214 61.486177) - (xy 117.543401 61.507951) - (xy 117.570654 61.533544) - (xy 117.591571 61.554458) - (xy 117.597029 61.558691) - (xy 117.601478 61.56249) - (xy 117.635418 61.594362) - (xy 117.635419 61.594363) - (xy 117.643514 61.598812) - (xy 117.653 61.604028) - (xy 117.669252 61.614701) - (xy 117.685114 61.627003) - (xy 117.723933 61.643797) - (xy 117.727853 61.645493) - (xy 117.733096 61.64806) - (xy 117.773908 61.670497) - (xy 117.793345 61.675487) - (xy 117.811733 61.681782) - (xy 117.83016 61.689754) - (xy 117.837323 61.692853) - (xy 117.836281 61.69526) - (xy 117.884458 61.726023) - (xy 117.91367 61.789493) - (xy 117.903929 61.858681) - (xy 117.858329 61.911618) - (xy 117.791348 61.931499) - (xy 117.790984 61.9315) - (xy 112.445737 61.9315) - (xy 112.43012 61.929776) - (xy 112.430093 61.930062) - (xy 112.422331 61.929327) - (xy 112.353203 61.9315) - (xy 112.32365 61.9315) - (xy 112.322929 61.93159) - (xy 112.316757 61.932369) - (xy 112.310945 61.932826) - (xy 112.264372 61.93429) - (xy 112.264369 61.934291) - (xy 112.245126 61.939881) - (xy 112.226083 61.943825) - (xy 112.206204 61.946336) - (xy 112.206203 61.946337) - (xy 112.162878 61.96349) - (xy 112.157352 61.965382) - (xy 112.112608 61.978383) - (xy 112.112604 61.978385) - (xy 112.095365 61.98858) - (xy 112.077898 61.997137) - (xy 112.059269 62.004512) - (xy 112.059267 62.004513) - (xy 112.021564 62.031906) - (xy 112.016682 62.035112) - (xy 111.97658 62.058828) - (xy 111.962408 62.073) - (xy 111.947623 62.085628) - (xy 111.931412 62.097407) - (xy 111.901709 62.13331) - (xy 111.897777 62.137631) - (xy 94.073579 79.96183) - (xy 93.834821 80.200587) - (xy 93.773498 80.234071) - (xy 93.715048 80.23268) - (xy 93.646697 80.214366) - (xy 93.646693 80.214365) - (xy 93.646692 80.214365) - (xy 93.506811 80.202127) - (xy 93.420001 80.194532) - (xy 93.419998 80.194532) - (xy 93.193313 80.214364) - (xy 93.193302 80.214366) - (xy 92.973511 80.273258) - (xy 92.973502 80.273261) - (xy 92.767267 80.369431) - (xy 92.767265 80.369432) - (xy 92.580858 80.499954) - (xy 92.419954 80.660858) - (xy 92.289432 80.847265) - (xy 92.289431 80.847267) - (xy 92.193261 81.053502) - (xy 92.193258 81.053511) - (xy 92.134366 81.273302) - (xy 92.134364 81.273313) - (xy 92.114532 81.499998) - (xy 92.114532 81.500001) - (xy 92.134364 81.726686) - (xy 92.134366 81.726697) - (xy 92.193258 81.946488) - (xy 92.193261 81.946497) - (xy 92.289431 82.152732) - (xy 92.289432 82.152734) - (xy 92.419954 82.339141) - (xy 92.580858 82.500045) - (xy 92.741623 82.612613) - (xy 92.785248 82.667189) - (xy 92.7945 82.714188) - (xy 92.7945 84.017255) - (xy 92.792775 84.032872) - (xy 92.793061 84.032899) - (xy 92.792326 84.040665) - (xy 92.7945 84.109814) - (xy 92.7945 84.139343) - (xy 92.794501 84.13936) - (xy 92.795368 84.146231) - (xy 92.795826 84.15205) - (xy 92.79729 84.198624) - (xy 92.797291 84.198627) - (xy 92.80288 84.217867) - (xy 92.806824 84.236911) - (xy 92.809336 84.256791) - (xy 92.82649 84.300119) - (xy 92.828382 84.305647) - (xy 92.841382 84.35039) - (xy 92.846397 84.358871) - (xy 92.85158 84.367634) - (xy 92.860136 84.3851) - (xy 92.863464 84.393504) - (xy 92.867514 84.403732) - (xy 92.894898 84.441423) - (xy 92.898106 84.446307) - (xy 92.921827 84.486416) - (xy 92.921833 84.486424) - (xy 92.93599 84.50058) - (xy 92.948628 84.515376) - (xy 92.960405 84.531586) - (xy 92.960406 84.531587) - (xy 92.996309 84.561288) - (xy 93.00062 84.56521) - (xy 93.275408 84.839998) - (xy 93.659197 85.223788) - (xy 93.669022 85.236051) - (xy 93.669243 85.235869) - (xy 93.674214 85.241878) - (xy 93.700217 85.266295) - (xy 93.724635 85.289226) - (xy 93.745529 85.31012) - (xy 93.751011 85.314373) - (xy 93.755443 85.318157) - (xy 93.789418 85.350062) - (xy 93.806976 85.359714) - (xy 93.823233 85.370393) - (xy 93.839064 85.382673) - (xy 93.858737 85.391186) - (xy 93.881833 85.401182) - (xy 93.887077 85.40375) - (xy 93.927908 85.426197) - (xy 93.940523 85.429435) - (xy 93.947305 85.431177) - (xy 93.965719 85.437481) - (xy 93.984104 85.445438) - (xy 94.030157 85.452732) - (xy 94.035826 85.453906) - (xy 94.080981 85.4655) - (xy 94.101016 85.4655) - (xy 94.120413 85.467026) - (xy 94.140196 85.47016) - (xy 94.186584 85.465775) - (xy 94.192422 85.4655) - (xy 102.785812 85.4655) - (xy 102.852851 85.485185) - (xy 102.887387 85.518377) - (xy 102.999954 85.679141) - (xy 103.160858 85.840045) - (xy 103.160861 85.840047) - (xy 103.347266 85.970568) - (xy 103.553504 86.066739) - (xy 103.773308 86.125635) - (xy 103.93523 86.139801) - (xy 103.999998 86.145468) - (xy 104 86.145468) - (xy 104.000002 86.145468) - (xy 104.056673 86.140509) - (xy 104.226692 86.125635) - (xy 104.446496 86.066739) - (xy 104.652734 85.970568) - (xy 104.839139 85.840047) - (xy 105.000047 85.679139) - (xy 105.130568 85.492734) - (xy 105.226739 85.286496) - (xy 105.285635 85.066692) - (xy 105.305468 84.84) - (xy 105.285635 84.613308) - (xy 105.226739 84.393504) - (xy 105.130568 84.187266) - (xy 105.000047 84.000861) - (xy 105.000045 84.000858) - (xy 104.839141 83.839954) - (xy 104.652734 83.709432) - (xy 104.652732 83.709431) - (xy 104.446497 83.613261) - (xy 104.446488 83.613258) - (xy 104.226697 83.554366) - (xy 104.226693 83.554365) - (xy 104.226692 83.554365) - (xy 104.226691 83.554364) - (xy 104.226686 83.554364) - (xy 104.000002 83.534532) - (xy 103.999998 83.534532) - (xy 103.773313 83.554364) - (xy 103.773302 83.554366) - (xy 103.553511 83.613258) - (xy 103.553502 83.613261) - (xy 103.347267 83.709431) - (xy 103.347265 83.709432) - (xy 103.160858 83.839954) - (xy 102.999954 84.000858) - (xy 102.887387 84.161623) - (xy 102.832811 84.205248) - (xy 102.785812 84.2145) - (xy 94.470452 84.2145) - (xy 94.403413 84.194815) - (xy 94.382771 84.178181) - (xy 94.081819 83.877228) - (xy 94.048334 83.815905) - (xy 94.0455 83.789547) - (xy 94.0455 82.714187) - (xy 94.065185 82.647148) - (xy 94.098379 82.612611) - (xy 94.117527 82.599204) - (xy 94.150328 82.58285) - (xy 94.188441 82.570467) - (xy 94.321877 82.485786) - (xy 94.430062 82.370582) - (xy 94.506197 82.232092) - (xy 94.507074 82.228673) - (xy 94.525605 82.188383) - (xy 94.550568 82.152734) - (xy 94.646739 81.946496) - (xy 94.705635 81.726692) - (xy 94.725468 81.500001) - (xy 102.274532 81.500001) - (xy 102.294364 81.726686) - (xy 102.294366 81.726697) - (xy 102.353258 81.946488) - (xy 102.353261 81.946497) - (xy 102.449431 82.152732) - (xy 102.449432 82.152734) - (xy 102.579954 82.339141) - (xy 102.740858 82.500045) - (xy 102.740861 82.500047) - (xy 102.927266 82.630568) - (xy 103.133504 82.726739) - (xy 103.133509 82.72674) - (xy 103.133511 82.726741) - (xy 103.143334 82.729373) - (xy 103.353308 82.785635) - (xy 103.51523 82.799801) - (xy 103.579998 82.805468) - (xy 103.58 82.805468) - (xy 103.580002 82.805468) - (xy 103.636673 82.800509) - (xy 103.806692 82.785635) - (xy 104.026496 82.726739) - (xy 104.232734 82.630568) - (xy 104.419139 82.500047) - (xy 104.580047 82.339139) - (xy 104.710568 82.152734) - (xy 104.806739 81.946496) - (xy 104.865635 81.726692) - (xy 104.885468 81.5) - (xy 104.865635 81.273308) - (xy 104.806739 81.053504) - (xy 104.710568 80.847266) - (xy 104.580047 80.660861) - (xy 104.580045 80.660858) - (xy 104.419141 80.499954) - (xy 104.232734 80.369432) - (xy 104.232732 80.369431) - (xy 104.026497 80.273261) - (xy 104.026488 80.273258) - (xy 103.806697 80.214366) - (xy 103.806693 80.214365) - (xy 103.806692 80.214365) - (xy 103.806691 80.214364) - (xy 103.806686 80.214364) - (xy 103.580002 80.194532) - (xy 103.579998 80.194532) - (xy 103.353313 80.214364) - (xy 103.353302 80.214366) - (xy 103.133511 80.273258) - (xy 103.133502 80.273261) - (xy 102.927267 80.369431) - (xy 102.927265 80.369432) - (xy 102.740858 80.499954) - (xy 102.579954 80.660858) - (xy 102.449432 80.847265) - (xy 102.449431 80.847267) - (xy 102.353261 81.053502) - (xy 102.353258 81.053511) - (xy 102.294366 81.273302) - (xy 102.294364 81.273313) - (xy 102.274532 81.499998) - (xy 102.274532 81.500001) - (xy 94.725468 81.500001) - (xy 94.725468 81.5) - (xy 94.705635 81.273308) - (xy 94.687318 81.204948) - (xy 94.688981 81.135103) - (xy 94.719408 81.085181) - (xy 94.93012 80.874471) - (xy 94.930121 80.874468) - (xy 94.93549 80.8691) - (xy 94.935498 80.86909) - (xy 112.585772 63.218819) - (xy 112.647095 63.185334) - (xy 112.673453 63.1825) - (xy 113.251623 63.1825) - (xy 113.318662 63.202185) - (xy 113.364417 63.254989) - (xy 113.374361 63.324147) - (xy 113.364005 63.358905) - (xy 113.273261 63.553502) - (xy 113.273258 63.553511) - (xy 113.214366 63.773302) - (xy 113.214364 63.773313) - (xy 113.194532 63.999998) + (xy 95.320257 76.6255) + (xy 95.335877 76.627224) + (xy 95.335904 76.626939) + (xy 95.34366 76.627671) + (xy 95.343667 76.627673) + (xy 95.412814 76.6255) + (xy 95.44235 76.6255) + (xy 95.449228 76.62463) + (xy 95.455041 76.624172) + (xy 95.501627 76.622709) + (xy 95.520869 76.617117) + (xy 95.539912 76.613174) + (xy 95.559792 76.610664) + (xy 95.603122 76.593507) + (xy 95.608646 76.591617) + (xy 95.612396 76.590527) + (xy 95.65339 76.578618) + (xy 95.670629 76.568422) + (xy 95.688103 76.559862) + (xy 95.706727 76.552488) + (xy 95.706727 76.552487) + (xy 95.706732 76.552486) + (xy 95.744449 76.525082) + (xy 95.749305 76.521892) + (xy 95.78942 76.49817) + (xy 95.803589 76.483999) + (xy 95.818379 76.471368) + (xy 95.834587 76.459594) + (xy 95.864299 76.423676) + (xy 95.868218 76.419371) + (xy 108.28759 64.000001) (xy 113.194532 64.000001) (xy 113.214364 64.226686) (xy 113.214366 64.226697) @@ -3521,21 +3419,143 @@ (xy 115.726739 64.446496) (xy 115.785635 64.226692) (xy 115.805468 64) + (xy 115.803316 63.975408) + (xy 115.798251 63.917511) (xy 115.785635 63.773308) (xy 115.726739 63.553504) - (xy 115.635994 63.358903) - (xy 115.625503 63.289828) - (xy 115.654023 63.226044) - (xy 115.712499 63.187804) - (xy 115.748377 63.1825) - (xy 122.876 63.1825) - (xy 122.943039 63.202185) - (xy 122.988794 63.254989) - (xy 123 63.3065) - (xy 123 69.2505) - (xy 122.980315 69.317539) - (xy 122.927511 69.363294) - (xy 122.876 69.3745) + (xy 115.630568 63.347266) + (xy 115.500047 63.160861) + (xy 115.500045 63.160858) + (xy 115.339141 62.999954) + (xy 115.152734 62.869432) + (xy 115.152732 62.869431) + (xy 114.946497 62.773261) + (xy 114.946488 62.773258) + (xy 114.726697 62.714366) + (xy 114.726693 62.714365) + (xy 114.726692 62.714365) + (xy 114.726691 62.714364) + (xy 114.726686 62.714364) + (xy 114.500002 62.694532) + (xy 114.499998 62.694532) + (xy 114.273313 62.714364) + (xy 114.273302 62.714366) + (xy 114.053511 62.773258) + (xy 114.053502 62.773261) + (xy 113.847267 62.869431) + (xy 113.847265 62.869432) + (xy 113.660858 62.999954) + (xy 113.499954 63.160858) + (xy 113.369432 63.347265) + (xy 113.369431 63.347267) + (xy 113.273261 63.553502) + (xy 113.273258 63.553511) + (xy 113.214366 63.773302) + (xy 113.214364 63.773313) + (xy 113.194532 63.999998) + (xy 113.194532 64.000001) + (xy 108.28759 64.000001) + (xy 111.625772 60.661819) + (xy 111.687095 60.628334) + (xy 111.713453 60.6255) + (xy 114.556048 60.6255) + (xy 114.623087 60.645185) + (xy 114.643729 60.661819) + (xy 119.375697 65.393788) + (xy 119.385522 65.406051) + (xy 119.385743 65.405869) + (xy 119.390714 65.411878) + (xy 119.416717 65.436295) + (xy 119.441135 65.459226) + (xy 119.462029 65.48012) + (xy 119.467511 65.484373) + (xy 119.471943 65.488157) + (xy 119.505918 65.520062) + (xy 119.523476 65.529714) + (xy 119.539733 65.540393) + (xy 119.555564 65.552673) + (xy 119.575237 65.561186) + (xy 119.598333 65.571182) + (xy 119.603577 65.57375) + (xy 119.644408 65.596197) + (xy 119.657023 65.599435) + (xy 119.663805 65.601177) + (xy 119.682219 65.607481) + (xy 119.700604 65.615438) + (xy 119.746657 65.622732) + (xy 119.752326 65.623906) + (xy 119.797481 65.6355) + (xy 119.817516 65.6355) + (xy 119.836913 65.637026) + (xy 119.856696 65.64016) + (xy 119.903084 65.635775) + (xy 119.908922 65.6355) + (xy 128.615782 65.6355) + (xy 128.682821 65.655185) + (xy 128.728576 65.707989) + (xy 128.73852 65.777147) + (xy 128.728163 65.811906) + (xy 128.726099 65.81633) + (xy 128.726094 65.816344) + (xy 128.664938 66.044586) + (xy 128.664936 66.044596) + (xy 128.644341 66.279999) + (xy 128.644341 66.28) + (xy 128.664936 66.515403) + (xy 128.664938 66.515413) + (xy 128.726094 66.743655) + (xy 128.726096 66.743659) + (xy 128.726097 66.743663) + (xy 128.812844 66.929692) + (xy 128.825965 66.95783) + (xy 128.825967 66.957834) + (xy 128.961501 67.151395) + (xy 128.961506 67.151402) + (xy 129.128597 67.318493) + (xy 129.128603 67.318498) + (xy 129.314158 67.448425) + (xy 129.357783 67.503002) + (xy 129.364977 67.5725) + (xy 129.333454 67.634855) + (xy 129.314158 67.651575) + (xy 129.128597 67.781505) + (xy 128.961505 67.948597) + (xy 128.826348 68.141623) + (xy 128.771771 68.185248) + (xy 128.724773 68.1945) + (xy 124.762743 68.1945) + (xy 124.747122 68.192775) + (xy 124.747096 68.193061) + (xy 124.739334 68.192327) + (xy 124.739333 68.192327) + (xy 124.670186 68.1945) + (xy 124.640649 68.1945) + (xy 124.633766 68.195369) + (xy 124.627949 68.195826) + (xy 124.581373 68.19729) + (xy 124.562129 68.202881) + (xy 124.543079 68.206825) + (xy 124.523211 68.209334) + (xy 124.479884 68.226488) + (xy 124.474358 68.228379) + (xy 124.429614 68.241379) + (xy 124.42961 68.241381) + (xy 124.412366 68.251579) + (xy 124.394905 68.260133) + (xy 124.376274 68.26751) + (xy 124.376262 68.267517) + (xy 124.33857 68.294902) + (xy 124.333687 68.298109) + (xy 124.29358 68.321829) + (xy 124.279414 68.335995) + (xy 124.264624 68.348627) + (xy 124.248414 68.360404) + (xy 124.248411 68.360407) + (xy 124.21871 68.396309) + (xy 124.214777 68.400631) + (xy 123.277228 69.338181) + (xy 123.215905 69.371666) + (xy 123.189547 69.3745) (xy 121.480882 69.3745) (xy 121.413843 69.354815) (xy 121.368088 69.302011) @@ -3556,7 +3576,7 @@ (xy 121.396801 67.562511) (xy 121.396799 67.562509) (xy 121.396798 67.562506) - (xy 121.357824 67.515016) + (xy 121.347965 67.503002) (xy 121.268647 67.406352) (xy 121.112495 67.278203) (xy 121.112488 67.278198) @@ -3707,7 +3727,7 @@ (xy 102.364406 77.623587) (xy 102.400309 77.653288) (xy 102.40462 77.65721) - (xy 104.491948 79.744538) + (xy 104.462342 79.714932) (xy 106.515384 81.767974) (xy 106.548869 81.829297) (xy 106.543885 81.898989) @@ -3907,7 +3927,7 @@ (xy 109.73 90.255462) (xy 109.931033 90.235662) (xy 110.124341 90.177023) - (xy 110.134354 90.171671) + (xy 110.142739 90.167189) (xy 110.307078 90.079348) (xy 110.37548 90.065106) (xy 110.423985 90.079348) @@ -4063,7 +4083,7 @@ (xy 109.0855 82.78865) (xy 109.084631 82.781779) (xy 109.084173 82.775952) - (xy 109.083672 82.76) + (xy 109.083917 82.767804) (xy 109.08271 82.729373) (xy 109.077119 82.71013) (xy 109.073173 82.691078) @@ -4082,7 +4102,7 @@ (xy 108.944006 82.427415) (xy 108.931368 82.412619) (xy 108.919594 82.396413) - (xy 108.888369 82.370582) + (xy 108.913535 82.391401) (xy 108.883688 82.366709) (xy 108.879376 82.362786) (xy 104.024407 77.507816) @@ -4111,7 +4131,7 @@ (xy 105.724871 76.617118) (xy 105.743916 76.613174) (xy 105.763792 76.610664) - (xy 105.807119 76.593509) + (xy 105.795522 76.5981) (xy 105.807127 76.593506) (xy 105.812643 76.591616) (xy 105.857401 76.578613) @@ -4204,7 +4224,7 @@ (xy 113.369432 74.812734) (xy 113.499954 74.999141) (xy 113.660858 75.160045) - (xy 113.706659 75.192115) + (xy 113.675075 75.17) (xy 113.847266 75.290568) (xy 114.053504 75.386739) (xy 114.273308 75.445635) @@ -4222,7 +4242,7 @@ (xy 115.726739 74.606496) (xy 115.785635 74.386692) (xy 115.805468 74.16) - (xy 115.803148 74.133488) + (xy 115.803316 74.135408) (xy 115.791474 74.000047) (xy 115.785635 73.933308) (xy 115.726739 73.713504) @@ -4250,7 +4270,7 @@ (xy 114.984016 72.751532) (xy 114.971381 72.736737) (xy 114.959596 72.720515) - (xy 114.9267 72.693302) + (xy 114.947395 72.710422) (xy 114.92371 72.690828) (xy 114.919385 72.686893) (xy 113.147172 70.91445) @@ -4272,7 +4292,7 @@ (xy 117.583311 70.469928) (xy 117.588924 70.474286) (xy 117.593332 70.478052) - (xy 117.607586 70.491438) + (xy 117.604561 70.488597) (xy 117.627416 70.510061) (xy 117.627421 70.510064) (xy 117.644813 70.519625) @@ -4281,7 +4301,7 @@ (xy 117.689723 70.548119) (xy 117.719719 70.561116) (xy 117.724942 70.563676) - (xy 117.752122 70.578618) + (xy 117.75212 70.578617) (xy 117.765908 70.586197) (xy 117.785142 70.591135) (xy 117.803603 70.597461) @@ -4297,100 +4317,851 @@ (xy 118.013547 70.626798) (xy 118.02445 70.625773) (xy 118.03026 70.6255) - (xy 122.876 70.6255) - (xy 122.943039 70.645185) - (xy 122.988794 70.697989) - (xy 123 70.7495) - (xy 123 101.876) - (xy 122.980315 101.943039) - (xy 122.927511 101.988794) - (xy 122.876 102) - (xy 88.124 102) - (xy 88.056961 101.980315) - (xy 88.011206 101.927511) - (xy 88 101.876) - (xy 88 99.000001) - (xy 101.614532 99.000001) - (xy 101.634364 99.226686) - (xy 101.634366 99.226697) - (xy 101.693258 99.446488) - (xy 101.693261 99.446497) - (xy 101.789431 99.652732) - (xy 101.789432 99.652734) - (xy 101.919954 99.839141) - (xy 102.080858 100.000045) - (xy 102.080861 100.000047) - (xy 102.267266 100.130568) - (xy 102.473504 100.226739) - (xy 102.693308 100.285635) - (xy 102.85523 100.299801) - (xy 102.919998 100.305468) - (xy 102.92 100.305468) - (xy 102.920002 100.305468) - (xy 102.976673 100.300509) - (xy 103.146692 100.285635) - (xy 103.366496 100.226739) - (xy 103.572734 100.130568) - (xy 103.759139 100.000047) - (xy 103.920047 99.839139) - (xy 104.050568 99.652734) - (xy 104.146739 99.446496) - (xy 104.205635 99.226692) - (xy 104.225468 99.000001) - (xy 111.774532 99.000001) - (xy 111.794364 99.226686) - (xy 111.794366 99.226697) - (xy 111.853258 99.446488) - (xy 111.853261 99.446497) - (xy 111.949431 99.652732) - (xy 111.949432 99.652734) - (xy 112.079954 99.839141) - (xy 112.240858 100.000045) - (xy 112.240861 100.000047) - (xy 112.427266 100.130568) - (xy 112.633504 100.226739) - (xy 112.853308 100.285635) - (xy 113.01523 100.299801) - (xy 113.079998 100.305468) - (xy 113.08 100.305468) - (xy 113.080002 100.305468) - (xy 113.136673 100.300509) - (xy 113.306692 100.285635) - (xy 113.526496 100.226739) - (xy 113.732734 100.130568) - (xy 113.919139 100.000047) - (xy 114.080047 99.839139) - (xy 114.195546 99.674188) - (xy 114.250122 99.630563) - (xy 114.289333 99.621556) - (xy 114.325138 99.619304) - (xy 114.332905 99.61678) - (xy 114.35568 99.611688) - (xy 114.363792 99.610664) - (xy 114.417195 99.589519) - (xy 114.420835 99.588209) - (xy 114.475441 99.570467) - (xy 114.482337 99.56609) - (xy 114.503133 99.555494) - (xy 114.510732 99.552486) - (xy 114.557191 99.51873) - (xy 114.56039 99.516555) - (xy 114.608877 99.485786) - (xy 114.614466 99.479833) - (xy 114.631979 99.464394) - (xy 114.638587 99.459594) - (xy 114.67519 99.415347) - (xy 114.677736 99.412457) - (xy 114.717062 99.370582) - (xy 114.720998 99.363421) - (xy 114.734119 99.344114) - (xy 114.739324 99.337823) - (xy 114.763769 99.285874) - (xy 114.765528 99.282419) - (xy 114.793197 99.232092) - (xy 114.795227 99.224181) - (xy 114.803135 99.202218) - (xy 114.806614 99.194826) + (xy 123.417257 70.6255) + (xy 123.432877 70.627224) + (xy 123.432904 70.626939) + (xy 123.44066 70.627671) + (xy 123.440667 70.627673) + (xy 123.509814 70.6255) + (xy 123.53935 70.6255) + (xy 123.546228 70.62463) + (xy 123.552041 70.624172) + (xy 123.598627 70.622709) + (xy 123.617869 70.617117) + (xy 123.636912 70.613174) + (xy 123.656792 70.610664) + (xy 123.700122 70.593507) + (xy 123.705646 70.591617) + (xy 123.709396 70.590527) + (xy 123.75039 70.578618) + (xy 123.767629 70.568422) + (xy 123.785103 70.559862) + (xy 123.803727 70.552488) + (xy 123.803727 70.552487) + (xy 123.803732 70.552486) + (xy 123.841449 70.525082) + (xy 123.846305 70.521892) + (xy 123.88642 70.49817) + (xy 123.900589 70.483999) + (xy 123.915379 70.471368) + (xy 123.931587 70.459594) + (xy 123.961299 70.423676) + (xy 123.965212 70.419376) + (xy 124.902772 69.481819) + (xy 124.964095 69.448334) + (xy 124.990453 69.4455) + (xy 128.724773 69.4455) + (xy 128.791812 69.465185) + (xy 128.826348 69.498377) + (xy 128.961501 69.691396) + (xy 128.961506 69.691402) + (xy 129.128597 69.858493) + (xy 129.128603 69.858498) + (xy 129.314158 69.988425) + (xy 129.357783 70.043002) + (xy 129.364977 70.1125) + (xy 129.333454 70.174855) + (xy 129.314158 70.191575) + (xy 129.128597 70.321505) + (xy 128.961505 70.488597) + (xy 128.825965 70.682169) + (xy 128.825964 70.682171) + (xy 128.726098 70.896335) + (xy 128.726094 70.896344) + (xy 128.664938 71.124586) + (xy 128.664936 71.124596) + (xy 128.644341 71.359999) + (xy 128.644341 71.36) + (xy 128.664936 71.595403) + (xy 128.664938 71.595413) + (xy 128.726094 71.823655) + (xy 128.726096 71.823659) + (xy 128.726097 71.823663) + (xy 128.825847 72.037578) + (xy 128.825965 72.03783) + (xy 128.825967 72.037834) + (xy 128.961501 72.231395) + (xy 128.961506 72.231402) + (xy 129.128597 72.398493) + (xy 129.128603 72.398498) + (xy 129.314158 72.528425) + (xy 129.357783 72.583002) + (xy 129.364977 72.6525) + (xy 129.333454 72.714855) + (xy 129.314158 72.731575) + (xy 129.128597 72.861505) + (xy 128.961505 73.028597) + (xy 128.825965 73.222169) + (xy 128.825964 73.222171) + (xy 128.726098 73.436335) + (xy 128.726094 73.436344) + (xy 128.664938 73.664586) + (xy 128.664936 73.664596) + (xy 128.644341 73.899999) + (xy 128.644341 73.9) + (xy 128.664936 74.135403) + (xy 128.664938 74.135413) + (xy 128.726094 74.363655) + (xy 128.726096 74.363659) + (xy 128.726097 74.363663) + (xy 128.736833 74.386686) + (xy 128.825965 74.57783) + (xy 128.825967 74.577834) + (xy 128.961501 74.771395) + (xy 128.961506 74.771402) + (xy 129.128597 74.938493) + (xy 129.128603 74.938498) + (xy 129.314158 75.068425) + (xy 129.357783 75.123002) + (xy 129.364977 75.1925) + (xy 129.333454 75.254855) + (xy 129.314158 75.271575) + (xy 129.128597 75.401505) + (xy 128.961505 75.568597) + (xy 128.825965 75.762169) + (xy 128.825964 75.762171) + (xy 128.726098 75.976335) + (xy 128.726094 75.976344) + (xy 128.664938 76.204586) + (xy 128.664936 76.204596) + (xy 128.644341 76.439999) + (xy 128.644341 76.44) + (xy 128.664936 76.675403) + (xy 128.664938 76.675413) + (xy 128.726094 76.903655) + (xy 128.726096 76.903659) + (xy 128.726097 76.903663) + (xy 128.771041 77.000045) + (xy 128.825965 77.11783) + (xy 128.825967 77.117834) + (xy 128.910271 77.238231) + (xy 128.943463 77.285635) + (xy 128.961501 77.311395) + (xy 128.961506 77.311402) + (xy 129.128597 77.478493) + (xy 129.128603 77.478498) + (xy 129.314594 77.60873) + (xy 129.358219 77.663307) + (xy 129.365413 77.732805) + (xy 129.33389 77.79516) + (xy 129.314595 77.81188) + (xy 129.128922 77.94189) + (xy 129.12892 77.941891) + (xy 128.961891 78.10892) + (xy 128.961886 78.108926) + (xy 128.8264 78.30242) + (xy 128.826399 78.302422) + (xy 128.72657 78.516507) + (xy 128.726567 78.516513) + (xy 128.669364 78.729999) + (xy 128.669364 78.73) + (xy 129.566314 78.73) + (xy 129.540507 78.770156) + (xy 129.5 78.908111) + (xy 129.5 79.051889) + (xy 129.540507 79.189844) + (xy 129.566314 79.23) + (xy 128.669364 79.23) + (xy 128.726567 79.443486) + (xy 128.72657 79.443492) + (xy 128.826399 79.657578) + (xy 128.961894 79.851082) + (xy 129.128917 80.018105) + (xy 129.314595 80.148119) + (xy 129.358219 80.202696) + (xy 129.365412 80.272195) + (xy 129.33389 80.334549) + (xy 129.314595 80.351269) + (xy 129.128594 80.481508) + (xy 128.961505 80.648597) + (xy 128.825965 80.842169) + (xy 128.825964 80.842171) + (xy 128.726098 81.056335) + (xy 128.726094 81.056344) + (xy 128.664938 81.284586) + (xy 128.664936 81.284596) + (xy 128.644341 81.519999) + (xy 128.644341 81.52) + (xy 128.664936 81.755403) + (xy 128.664938 81.755413) + (xy 128.726094 81.983655) + (xy 128.726096 81.983659) + (xy 128.726097 81.983663) + (xy 128.804936 82.152733) + (xy 128.825965 82.19783) + (xy 128.825967 82.197834) + (xy 128.912335 82.321179) + (xy 128.961501 82.391396) + (xy 128.961506 82.391402) + (xy 129.128597 82.558493) + (xy 129.128603 82.558498) + (xy 129.314158 82.688425) + (xy 129.357783 82.743002) + (xy 129.364977 82.8125) + (xy 129.333454 82.874855) + (xy 129.314158 82.891575) + (xy 129.128597 83.021505) + (xy 128.961505 83.188597) + (xy 128.825965 83.382169) + (xy 128.825964 83.382171) + (xy 128.726098 83.596335) + (xy 128.726094 83.596344) + (xy 128.664938 83.824586) + (xy 128.664936 83.824596) + (xy 128.644341 84.059999) + (xy 128.644341 84.06) + (xy 128.664936 84.295403) + (xy 128.664938 84.295413) + (xy 128.726094 84.523655) + (xy 128.726096 84.523659) + (xy 128.726097 84.523663) + (xy 128.809155 84.701781) + (xy 128.825965 84.73783) + (xy 128.825967 84.737834) + (xy 128.897504 84.839998) + (xy 128.961501 84.931396) + (xy 128.961506 84.931402) + (xy 129.128597 85.098493) + (xy 129.128603 85.098498) + (xy 129.314158 85.228425) + (xy 129.357783 85.283002) + (xy 129.364977 85.3525) + (xy 129.333454 85.414855) + (xy 129.314158 85.431575) + (xy 129.128597 85.561505) + (xy 128.961505 85.728597) + (xy 128.825965 85.922169) + (xy 128.825964 85.922171) + (xy 128.726098 86.136335) + (xy 128.726094 86.136344) + (xy 128.664938 86.364586) + (xy 128.664936 86.364596) + (xy 128.644341 86.599999) + (xy 128.644341 86.6) + (xy 128.664936 86.835403) + (xy 128.664938 86.835413) + (xy 128.726094 87.063655) + (xy 128.726096 87.063659) + (xy 128.726097 87.063663) + (xy 128.73 87.072032) + (xy 128.825965 87.27783) + (xy 128.825967 87.277834) + (xy 128.932543 87.430039) + (xy 128.961501 87.471396) + (xy 128.961506 87.471402) + (xy 129.128597 87.638493) + (xy 129.128603 87.638498) + (xy 129.314158 87.768425) + (xy 129.357783 87.823002) + (xy 129.364977 87.8925) + (xy 129.333454 87.954855) + (xy 129.314158 87.971575) + (xy 129.128597 88.101505) + (xy 128.961505 88.268597) + (xy 128.825965 88.462169) + (xy 128.825964 88.462171) + (xy 128.726098 88.676335) + (xy 128.726094 88.676344) + (xy 128.664938 88.904586) + (xy 128.664936 88.904596) + (xy 128.644341 89.139999) + (xy 128.644341 89.14) + (xy 128.664936 89.375403) + (xy 128.664938 89.375413) + (xy 128.726094 89.603655) + (xy 128.726096 89.603659) + (xy 128.726097 89.603663) + (xy 128.816658 89.797872) + (xy 128.825965 89.81783) + (xy 128.825967 89.817834) + (xy 128.85373 89.857483) + (xy 128.961501 90.011396) + (xy 128.961506 90.011402) + (xy 129.128597 90.178493) + (xy 129.128603 90.178498) + (xy 129.314158 90.308425) + (xy 129.357783 90.363002) + (xy 129.364977 90.4325) + (xy 129.333454 90.494855) + (xy 129.314158 90.511575) + (xy 129.128597 90.641505) + (xy 128.961505 90.808597) + (xy 128.825965 91.002169) + (xy 128.825964 91.002171) + (xy 128.726098 91.216335) + (xy 128.726094 91.216344) + (xy 128.664938 91.444586) + (xy 128.664936 91.444596) + (xy 128.644341 91.679999) + (xy 128.644341 91.68) + (xy 128.664936 91.915403) + (xy 128.664938 91.915413) + (xy 128.726094 92.143655) + (xy 128.726096 92.143659) + (xy 128.726097 92.143663) + (xy 128.754724 92.205053) + (xy 128.825965 92.35783) + (xy 128.825967 92.357834) + (xy 128.925163 92.4995) + (xy 128.961501 92.551396) + (xy 128.961506 92.551402) + (xy 129.128597 92.718493) + (xy 129.128603 92.718498) + (xy 129.314158 92.848425) + (xy 129.357783 92.903002) + (xy 129.364977 92.9725) + (xy 129.333454 93.034855) + (xy 129.314158 93.051575) + (xy 129.128597 93.181505) + (xy 128.961505 93.348597) + (xy 128.825965 93.542169) + (xy 128.825964 93.542171) + (xy 128.726098 93.756335) + (xy 128.726094 93.756344) + (xy 128.664938 93.984586) + (xy 128.664936 93.984596) + (xy 128.644341 94.219999) + (xy 128.644341 94.22) + (xy 128.664936 94.455403) + (xy 128.664938 94.455413) + (xy 128.726094 94.683655) + (xy 128.726096 94.683659) + (xy 128.726097 94.683663) + (xy 128.799936 94.842011) + (xy 128.825965 94.89783) + (xy 128.825967 94.897834) + (xy 128.897505 95) + (xy 128.961505 95.091401) + (xy 129.128599 95.258495) + (xy 129.29211 95.372987) + (xy 129.314594 95.38873) + (xy 129.358219 95.443307) + (xy 129.365413 95.512805) + (xy 129.33389 95.57516) + (xy 129.314595 95.59188) + (xy 129.128922 95.72189) + (xy 129.12892 95.721891) + (xy 128.961891 95.88892) + (xy 128.961886 95.888926) + (xy 128.8264 96.08242) + (xy 128.826399 96.082422) + (xy 128.72657 96.296507) + (xy 128.726567 96.296513) + (xy 128.669364 96.509999) + (xy 128.669364 96.51) + (xy 129.566314 96.51) + (xy 129.540507 96.550156) + (xy 129.5 96.688111) + (xy 129.5 96.831889) + (xy 129.540507 96.969844) + (xy 129.566314 97.01) + (xy 128.669364 97.01) + (xy 128.726567 97.223486) + (xy 128.72657 97.223492) + (xy 128.826399 97.437578) + (xy 128.961894 97.631082) + (xy 129.128917 97.798105) + (xy 129.322421 97.9336) + (xy 129.536507 98.033429) + (xy 129.536516 98.033433) + (xy 129.75 98.090634) + (xy 129.75 97.195501) + (xy 129.857685 97.24468) + (xy 129.964237 97.26) + (xy 130.035763 97.26) + (xy 130.142315 97.24468) + (xy 130.25 97.195501) + (xy 130.25 98.090633) + (xy 130.463483 98.033433) + (xy 130.463492 98.033429) + (xy 130.677578 97.9336) + (xy 130.871082 97.798105) + (xy 131.038105 97.631082) + (xy 131.168119 97.445405) + (xy 131.222696 97.401781) + (xy 131.292195 97.394588) + (xy 131.354549 97.42611) + (xy 131.371269 97.445405) + (xy 131.501505 97.631401) + (xy 131.668599 97.798495) + (xy 131.765384 97.866265) + (xy 131.862165 97.934032) + (xy 131.862167 97.934033) + (xy 131.86217 97.934035) + (xy 132.076337 98.033903) + (xy 132.304592 98.095063) + (xy 132.492918 98.111539) + (xy 132.539999 98.115659) + (xy 132.54 98.115659) + (xy 132.540001 98.115659) + (xy 132.579234 98.112226) + (xy 132.775408 98.095063) + (xy 133.003663 98.033903) + (xy 133.21783 97.934035) + (xy 133.411401 97.798495) + (xy 133.578495 97.631401) + (xy 133.714035 97.43783) + (xy 133.813903 97.223663) + (xy 133.875063 96.995408) + (xy 133.895659 96.76) + (xy 133.875063 96.524592) + (xy 133.813903 96.296337) + (xy 133.714035 96.082171) + (xy 133.708731 96.074595) + (xy 133.578494 95.888597) + (xy 133.411402 95.721506) + (xy 133.411396 95.721501) + (xy 133.225842 95.591575) + (xy 133.182217 95.536998) + (xy 133.175023 95.4675) + (xy 133.206546 95.405145) + (xy 133.225842 95.388425) + (xy 133.248026 95.372891) + (xy 133.411401 95.258495) + (xy 133.578495 95.091401) + (xy 133.714035 94.89783) + (xy 133.813903 94.683663) + (xy 133.875063 94.455408) + (xy 133.895659 94.22) + (xy 133.875063 93.984592) + (xy 133.813903 93.756337) + (xy 133.714035 93.542171) + (xy 133.708425 93.534158) + (xy 133.578494 93.348597) + (xy 133.411402 93.181506) + (xy 133.411396 93.181501) + (xy 133.225842 93.051575) + (xy 133.182217 92.996998) + (xy 133.175023 92.9275) + (xy 133.206546 92.865145) + (xy 133.225842 92.848425) + (xy 133.329478 92.775858) + (xy 133.411401 92.718495) + (xy 133.578495 92.551401) + (xy 133.714035 92.35783) + (xy 133.813903 92.143663) + (xy 133.875063 91.915408) + (xy 133.895659 91.68) + (xy 133.875063 91.444592) + (xy 133.813903 91.216337) + (xy 133.714035 91.002171) + (xy 133.708425 90.994158) + (xy 133.578494 90.808597) + (xy 133.411402 90.641506) + (xy 133.411401 90.641505) + (xy 133.225405 90.511269) + (xy 133.181781 90.456692) + (xy 133.174588 90.387193) + (xy 133.20611 90.324839) + (xy 133.225405 90.308119) + (xy 133.411082 90.178105) + (xy 133.578105 90.011082) + (xy 133.7136 89.817578) + (xy 133.813429 89.603492) + (xy 133.813432 89.603486) + (xy 133.870636 89.39) + (xy 132.973686 89.39) + (xy 132.999493 89.349844) + (xy 133.04 89.211889) + (xy 133.04 89.068111) + (xy 132.999493 88.930156) + (xy 132.973686 88.89) + (xy 133.870636 88.89) + (xy 133.870635 88.889999) + (xy 133.813432 88.676513) + (xy 133.813429 88.676507) + (xy 133.7136 88.462422) + (xy 133.713599 88.46242) + (xy 133.578113 88.268926) + (xy 133.578108 88.26892) + (xy 133.411078 88.10189) + (xy 133.225405 87.971879) + (xy 133.18178 87.917302) + (xy 133.174588 87.847804) + (xy 133.20611 87.785449) + (xy 133.225406 87.76873) + (xy 133.225842 87.768425) + (xy 133.411401 87.638495) + (xy 133.578495 87.471401) + (xy 133.714035 87.27783) + (xy 133.813903 87.063663) + (xy 133.875063 86.835408) + (xy 133.895659 86.6) + (xy 133.875063 86.364592) + (xy 133.815041 86.140584) + (xy 133.813905 86.136344) + (xy 133.813904 86.136343) + (xy 133.813903 86.136337) + (xy 133.714035 85.922171) + (xy 133.708425 85.914158) + (xy 133.578494 85.728597) + (xy 133.411402 85.561506) + (xy 133.411401 85.561505) + (xy 133.225405 85.431269) + (xy 133.181781 85.376692) + (xy 133.174588 85.307193) + (xy 133.20611 85.244839) + (xy 133.225405 85.228119) + (xy 133.411082 85.098105) + (xy 133.578105 84.931082) + (xy 133.7136 84.737578) + (xy 133.813429 84.523492) + (xy 133.813432 84.523486) + (xy 133.870636 84.31) + (xy 132.973686 84.31) + (xy 132.999493 84.269844) + (xy 133.04 84.131889) + (xy 133.04 83.988111) + (xy 132.999493 83.850156) + (xy 132.973686 83.81) + (xy 133.870636 83.81) + (xy 133.870635 83.809999) + (xy 133.813432 83.596513) + (xy 133.813429 83.596507) + (xy 133.7136 83.382422) + (xy 133.713599 83.38242) + (xy 133.578113 83.188926) + (xy 133.578108 83.18892) + (xy 133.411078 83.02189) + (xy 133.225405 82.891879) + (xy 133.18178 82.837302) + (xy 133.174588 82.767804) + (xy 133.20611 82.705449) + (xy 133.225406 82.68873) + (xy 133.25617 82.667189) + (xy 133.411401 82.558495) + (xy 133.578495 82.391401) + (xy 133.714035 82.19783) + (xy 133.813903 81.983663) + (xy 133.875063 81.755408) + (xy 133.895659 81.52) + (xy 133.875063 81.284592) + (xy 133.813903 81.056337) + (xy 133.714035 80.842171) + (xy 133.708425 80.834158) + (xy 133.578494 80.648597) + (xy 133.411402 80.481506) + (xy 133.411401 80.481505) + (xy 133.301609 80.404628) + (xy 133.225839 80.351573) + (xy 133.182216 80.296997) + (xy 133.175023 80.227498) + (xy 133.206545 80.165144) + (xy 133.225831 80.148432) + (xy 133.411401 80.018495) + (xy 133.578495 79.851401) + (xy 133.714035 79.65783) + (xy 133.813903 79.443663) + (xy 133.875063 79.215408) + (xy 133.895659 78.98) + (xy 133.875063 78.744592) + (xy 133.813903 78.516337) + (xy 133.714035 78.302171) + (xy 133.578495 78.108599) + (xy 133.578494 78.108597) + (xy 133.411402 77.941506) + (xy 133.411396 77.941501) + (xy 133.225842 77.811575) + (xy 133.182217 77.756998) + (xy 133.175023 77.6875) + (xy 133.206546 77.625145) + (xy 133.225842 77.608425) + (xy 133.268699 77.578416) + (xy 133.411401 77.478495) + (xy 133.578495 77.311401) + (xy 133.714035 77.11783) + (xy 133.813903 76.903663) + (xy 133.875063 76.675408) + (xy 133.895659 76.44) + (xy 133.894232 76.423695) + (xy 133.876997 76.226697) + (xy 133.875063 76.204592) + (xy 133.813903 75.976337) + (xy 133.714035 75.762171) + (xy 133.595012 75.592187) + (xy 133.578494 75.568597) + (xy 133.411402 75.401506) + (xy 133.411396 75.401501) + (xy 133.225842 75.271575) + (xy 133.182217 75.216998) + (xy 133.175023 75.1475) + (xy 133.206546 75.085145) + (xy 133.225842 75.068425) + (xy 133.248026 75.052891) + (xy 133.411401 74.938495) + (xy 133.578495 74.771401) + (xy 133.714035 74.57783) + (xy 133.813903 74.363663) + (xy 133.875063 74.135408) + (xy 133.895659 73.9) + (xy 133.875063 73.664592) + (xy 133.813903 73.436337) + (xy 133.714035 73.222171) + (xy 133.713958 73.22206) + (xy 133.578494 73.028597) + (xy 133.411402 72.861506) + (xy 133.411401 72.861505) + (xy 133.225405 72.731269) + (xy 133.181781 72.676692) + (xy 133.174588 72.607193) + (xy 133.20611 72.544839) + (xy 133.225405 72.528119) + (xy 133.411082 72.398105) + (xy 133.578105 72.231082) + (xy 133.7136 72.037578) + (xy 133.813429 71.823492) + (xy 133.813432 71.823486) + (xy 133.870636 71.61) + (xy 132.973686 71.61) + (xy 132.999493 71.569844) + (xy 133.04 71.431889) + (xy 133.04 71.288111) + (xy 132.999493 71.150156) + (xy 132.973686 71.11) + (xy 133.870636 71.11) + (xy 133.870635 71.109999) + (xy 133.813432 70.896513) + (xy 133.813429 70.896507) + (xy 133.7136 70.682422) + (xy 133.713599 70.68242) + (xy 133.578113 70.488926) + (xy 133.578108 70.48892) + (xy 133.411078 70.32189) + (xy 133.225405 70.191879) + (xy 133.18178 70.137302) + (xy 133.174588 70.067804) + (xy 133.20611 70.005449) + (xy 133.225406 69.98873) + (xy 133.225842 69.988425) + (xy 133.411401 69.858495) + (xy 133.578495 69.691401) + (xy 133.714035 69.49783) + (xy 133.813903 69.283663) + (xy 133.875063 69.055408) + (xy 133.895659 68.82) + (xy 133.875063 68.584592) + (xy 133.813903 68.356337) + (xy 133.714035 68.142171) + (xy 133.713652 68.141623) + (xy 133.578494 67.948597) + (xy 133.411402 67.781506) + (xy 133.411396 67.781501) + (xy 133.225842 67.651575) + (xy 133.182217 67.596998) + (xy 133.175023 67.5275) + (xy 133.206546 67.465145) + (xy 133.225842 67.448425) + (xy 133.285928 67.406352) + (xy 133.411401 67.318495) + (xy 133.578495 67.151401) + (xy 133.714035 66.95783) + (xy 133.813903 66.743663) + (xy 133.875063 66.515408) + (xy 133.895659 66.28) + (xy 133.875063 66.044592) + (xy 133.813903 65.816337) + (xy 133.714035 65.602171) + (xy 133.692337 65.571182) + (xy 133.578494 65.408597) + (xy 133.411402 65.241506) + (xy 133.411401 65.241505) + (xy 133.225405 65.111269) + (xy 133.181781 65.056692) + (xy 133.174588 64.987193) + (xy 133.20611 64.924839) + (xy 133.225405 64.908119) + (xy 133.411082 64.778105) + (xy 133.578105 64.611082) + (xy 133.7136 64.417578) + (xy 133.813429 64.203492) + (xy 133.813432 64.203486) + (xy 133.870636 63.99) + (xy 132.973686 63.99) + (xy 132.999493 63.949844) + (xy 133.04 63.811889) + (xy 133.04 63.668111) + (xy 132.999493 63.530156) + (xy 132.973686 63.49) + (xy 133.870636 63.49) + (xy 133.870635 63.489999) + (xy 133.813432 63.276513) + (xy 133.813429 63.276507) + (xy 133.7136 63.062422) + (xy 133.713599 63.06242) + (xy 133.578113 62.868926) + (xy 133.578108 62.86892) + (xy 133.411078 62.70189) + (xy 133.225405 62.571879) + (xy 133.18178 62.517302) + (xy 133.174588 62.447804) + (xy 133.20611 62.385449) + (xy 133.225406 62.36873) + (xy 133.225842 62.368425) + (xy 133.411401 62.238495) + (xy 133.578495 62.071401) + (xy 133.714035 61.87783) + (xy 133.813903 61.663663) + (xy 133.875063 61.435408) + (xy 133.895659 61.2) + (xy 133.89318 61.171671) + (xy 133.883252 61.058189) + (xy 133.875063 60.964592) + (xy 133.828626 60.791285) + (xy 133.813905 60.736344) + (xy 133.813904 60.736343) + (xy 133.813903 60.736337) + (xy 133.714035 60.522171) + (xy 133.708425 60.514158) + (xy 133.578494 60.328597) + (xy 133.411402 60.161506) + (xy 133.411396 60.161501) + (xy 133.225842 60.031575) + (xy 133.182217 59.976998) + (xy 133.175023 59.9075) + (xy 133.206546 59.845145) + (xy 133.225842 59.828425) + (xy 133.374089 59.724621) + (xy 133.411401 59.698495) + (xy 133.578495 59.531401) + (xy 133.714035 59.33783) + (xy 133.813903 59.123663) + (xy 133.875063 58.895408) + (xy 133.895659 58.66) + (xy 133.893722 58.637866) + (xy 133.886706 58.557669) + (xy 133.875063 58.424592) + (xy 133.813903 58.196337) + (xy 133.714035 57.982171) + (xy 133.708731 57.974595) + (xy 133.578494 57.788597) + (xy 133.411402 57.621506) + (xy 133.411396 57.621501) + (xy 133.225842 57.491575) + (xy 133.182217 57.436998) + (xy 133.175023 57.3675) + (xy 133.206546 57.305145) + (xy 133.225842 57.288425) + (xy 133.248026 57.272891) + (xy 133.411401 57.158495) + (xy 133.578495 56.991401) + (xy 133.714035 56.79783) + (xy 133.813903 56.583663) + (xy 133.875063 56.355408) + (xy 133.895659 56.12) + (xy 133.875063 55.884592) + (xy 133.813903 55.656337) + (xy 133.714035 55.442171) + (xy 133.708425 55.434158) + (xy 133.578494 55.248597) + (xy 133.411402 55.081506) + (xy 133.411401 55.081505) + (xy 133.225405 54.951269) + (xy 133.181781 54.896692) + (xy 133.174588 54.827193) + (xy 133.20611 54.764839) + (xy 133.225405 54.748119) + (xy 133.411082 54.618105) + (xy 133.578105 54.451082) + (xy 133.7136 54.257578) + (xy 133.813429 54.043492) + (xy 133.813432 54.043486) + (xy 133.870636 53.83) + (xy 132.973686 53.83) + (xy 132.999493 53.789844) + (xy 133.04 53.651889) + (xy 133.04 53.508111) + (xy 132.999493 53.370156) + (xy 132.973686 53.33) + (xy 133.870636 53.33) + (xy 133.870635 53.329999) + (xy 133.813432 53.116513) + (xy 133.813429 53.116507) + (xy 133.7136 52.902422) + (xy 133.713599 52.90242) + (xy 133.578113 52.708926) + (xy 133.578108 52.70892) + (xy 133.411078 52.54189) + (xy 133.225405 52.411879) + (xy 133.18178 52.357302) + (xy 133.174588 52.287804) + (xy 133.20611 52.225449) + (xy 133.225406 52.20873) + (xy 133.232331 52.203881) + (xy 133.411401 52.078495) + (xy 133.578495 51.911401) + (xy 133.714035 51.71783) + (xy 133.813903 51.503663) + (xy 133.875063 51.275408) + (xy 133.895659 51.04) + (xy 133.875063 50.804592) + (xy 133.821302 50.60395) + (xy 133.813905 50.576344) + (xy 133.813904 50.576343) + (xy 133.813903 50.576337) + (xy 133.714035 50.362171) + (xy 133.708885 50.354815) + (xy 133.578494 50.168597) + (xy 133.411402 50.001506) + (xy 133.411396 50.001501) + (xy 133.225842 49.871575) + (xy 133.182217 49.816998) + (xy 133.175023 49.7475) + (xy 133.206546 49.685145) + (xy 133.225842 49.668425) + (xy 133.248026 49.652891) + (xy 133.411401 49.538495) + (xy 133.578495 49.371401) + (xy 133.714035 49.17783) + (xy 133.813903 48.963663) + (xy 133.875063 48.735408) + (xy 133.895659 48.5) + (xy 133.875063 48.264592) + (xy 133.813903 48.036337) + (xy 133.714035 47.822171) + (xy 133.578495 47.628599) + (xy 133.578494 47.628597) + (xy 133.411402 47.461506) + (xy 133.411395 47.461501) + (xy 133.217834 47.325967) + (xy 133.21783 47.325965) + (xy 133.042875 47.244382) + (xy 132.990436 47.19821) + (xy 132.971284 47.131016) + (xy 132.9915 47.064135) + (xy 133.044665 47.0188) + (xy 133.09528 47.008) + (xy 134.419896 47.008) + (xy 134.486935 47.027685) + (xy 134.53269 47.080489) + (xy 134.543896 47.132104) + (xy 134.500104 99.374793) + (xy 134.480363 99.441816) + (xy 134.427521 99.487527) + (xy 134.374799 99.498682) + (xy 132.599604 99.479995) + (xy 132.546065 99.467214) + (xy 132.411017 99.400615) + (xy 132.411007 99.400611) + (xy 132.116156 99.300523) + (xy 132.116136 99.300518) + (xy 131.81074 99.23977) + (xy 131.810731 99.239769) + (xy 131.81073 99.239769) + (xy 131.5 99.219403) + (xy 131.18927 99.239769) + (xy 131.189269 99.239769) + (xy 131.189259 99.23977) + (xy 130.883863 99.300518) + (xy 130.883843 99.300523) + (xy 130.588992 99.400611) + (xy 130.588988 99.400613) + (xy 130.499949 99.444522) + (xy 130.443801 99.457302) + (xy 114.936266 99.294065) + (xy 114.869437 99.273676) + (xy 114.824241 99.220393) + (xy 114.815026 99.151134) + (xy 114.815767 99.14684) (xy 114.817377 99.138401) (xy 114.81821 99.13467) (xy 114.8325 99.079019) @@ -4538,9 +5309,18 @@ (xy 111.794366 98.773302) (xy 111.794364 98.773313) (xy 111.774532 98.999998) - (xy 111.774532 99.000001) - (xy 104.225468 99.000001) + (xy 111.774532 99.000002) + (xy 111.785449 99.124785) + (xy 111.771682 99.193285) + (xy 111.723067 99.243468) + (xy 111.660616 99.259585) + (xy 104.343512 99.182562) + (xy 104.276683 99.162173) + (xy 104.231487 99.10889) + (xy 104.221289 99.047762) (xy 104.225468 99) + (xy 104.223797 98.980906) + (xy 104.205635 98.773313) (xy 104.205635 98.773308) (xy 104.146739 98.553504) (xy 104.050568 98.347266) @@ -4573,17 +5353,52 @@ (xy 101.634366 98.773302) (xy 101.634364 98.773313) (xy 101.614532 98.999998) - (xy 101.614532 99.000001) - (xy 88 99.000001) - (xy 88 97.237223) - (xy 88.019685 97.170184) - (xy 88.072489 97.124429) - (xy 88.141647 97.114485) - (xy 88.18224 97.128537) - (xy 88.18236 97.12828) - (xy 88.184846 97.129439) - (xy 88.186012 97.129843) - (xy 88.187255 97.13056) + (xy 101.614532 99.000006) + (xy 101.616083 99.017741) + (xy 101.602315 99.086241) + (xy 101.553698 99.136422) + (xy 101.49125 99.152538) + (xy 87.123055 99.001295) + (xy 87.056226 98.980906) + (xy 87.01103 98.927623) + (xy 87.000361 98.876938) + (xy 87.00131 98.553502) + (xy 87.007395 96.480095) + (xy 87.027276 96.413117) + (xy 87.080214 96.367517) + (xy 87.149401 96.357776) + (xy 87.212871 96.386988) + (xy 87.22694 96.401424) + (xy 87.22731 96.401871) + (xy 87.227314 96.401877) + (xy 87.256412 96.429202) + (xy 87.277736 96.449227) + (xy 87.298623 96.470115) + (xy 87.298627 96.470118) + (xy 87.298629 96.47012) + (xy 87.304111 96.474373) + (xy 87.308543 96.478157) + (xy 87.342518 96.510062) + (xy 87.360076 96.519714) + (xy 87.376335 96.530395) + (xy 87.392164 96.542673) + (xy 87.434938 96.561182) + (xy 87.440156 96.563738) + (xy 87.481008 96.586197) + (xy 87.500416 96.59118) + (xy 87.518817 96.59748) + (xy 87.537204 96.605437) + (xy 87.580588 96.612308) + (xy 87.583219 96.612725) + (xy 87.588939 96.613909) + (xy 87.634081 96.6255) + (xy 87.634088 96.6255) + (xy 87.641309 96.626413) + (xy 87.705352 96.654346) + (xy 87.727341 96.678312) + (xy 87.839953 96.83914) + (xy 88.000858 97.000045) + (xy 88.000861 97.000047) (xy 88.187266 97.130568) (xy 88.393504 97.226739) (xy 88.613308 97.285635) @@ -4602,7 +5417,10 @@ (xy 90.125635 96.226692) (xy 90.145468 96) (xy 90.125635 95.773308) - (xy 90.066739 95.553504) + (xy 90.077022 95.59188) + (xy 90.066741 95.553511) + (xy 90.066738 95.553502) + (xy 90.058334 95.53548) (xy 89.970568 95.347266) (xy 89.840047 95.160861) (xy 89.840045 95.160858) @@ -4622,19 +5440,56 @@ (xy 88.613302 94.714366) (xy 88.393511 94.773258) (xy 88.393502 94.773261) - (xy 88.187263 94.869433) - (xy 88.185998 94.870164) - (xy 88.18537 94.870316) - (xy 88.18236 94.87172) - (xy 88.182077 94.871114) - (xy 88.118098 94.886635) - (xy 88.052071 94.863782) - (xy 88.008882 94.80886) - (xy 88 94.762776) - (xy 88 93.751) - (xy 88.019685 93.683961) - (xy 88.072489 93.638206) - (xy 88.124 93.627) + (xy 88.187267 94.869431) + (xy 88.187265 94.869432) + (xy 88.000862 94.999951) + (xy 87.887702 95.113111) + (xy 87.826379 95.146595) + (xy 87.756687 95.141611) + (xy 87.715137 95.115821) + (xy 87.712251 95.113111) + (xy 87.688464 95.090773) + (xy 87.674028 95.076337) + (xy 87.667575 95.069883) + (xy 87.662086 95.065625) + (xy 87.657661 95.061847) + (xy 87.623682 95.029938) + (xy 87.62368 95.029936) + (xy 87.623677 95.029935) + (xy 87.606129 95.020288) + (xy 87.589863 95.009604) + (xy 87.577482 95) + (xy 87.574036 94.997327) + (xy 87.574035 94.997326) + (xy 87.574033 94.997325) + (xy 87.531268 94.978818) + (xy 87.526022 94.976248) + (xy 87.485193 94.953803) + (xy 87.485192 94.953802) + (xy 87.465793 94.948822) + (xy 87.447381 94.942518) + (xy 87.428998 94.934562) + (xy 87.428992 94.93456) + (xy 87.382974 94.927272) + (xy 87.377252 94.926087) + (xy 87.332121 94.9145) + (xy 87.332119 94.9145) + (xy 87.312084 94.9145) + (xy 87.292686 94.912973) + (xy 87.285262 94.911797) + (xy 87.272905 94.90984) + (xy 87.272904 94.90984) + (xy 87.226516 94.914225) + (xy 87.220678 94.9145) + (xy 87.136355 94.9145) + (xy 87.069316 94.894815) + (xy 87.023561 94.842011) + (xy 87.012356 94.790136) + (xy 87.014289 94.131297) + (xy 87.015406 93.750634) + (xy 87.035287 93.683655) + (xy 87.088225 93.638055) + (xy 87.139405 93.627) (xy 95.691048 93.627) (xy 95.758087 93.646685) (xy 95.778729 93.663319) @@ -4669,37 +5524,40 @@ (xy 99.980068 96.859117) (xy 100.041389 96.825634) (xy 100.067748 96.8228) - (xy 107.219957 96.8228) - (xy 107.235577 96.824524) - (xy 107.235604 96.824239) - (xy 107.24336 96.824971) - (xy 107.243367 96.824973) - (xy 107.312514 96.8228) - (xy 107.34205 96.8228) - (xy 107.348928 96.82193) - (xy 107.354741 96.821472) - (xy 107.401327 96.820009) - (xy 107.420569 96.814417) - (xy 107.439612 96.810474) - (xy 107.459492 96.807964) - (xy 107.502822 96.790807) - (xy 107.508346 96.788917) - (xy 107.512096 96.787827) - (xy 107.55309 96.775918) - (xy 107.570329 96.765722) - (xy 107.587803 96.757162) - (xy 107.606427 96.749788) - (xy 107.606427 96.749787) - (xy 107.606432 96.749786) - (xy 107.644149 96.722382) - (xy 107.649005 96.719192) - (xy 107.68912 96.69547) - (xy 107.703289 96.681299) - (xy 107.718079 96.668668) - (xy 107.734287 96.656894) - (xy 107.763999 96.620976) - (xy 107.767912 96.616676) - (xy 114.226719 90.15787) + (xy 107.220264 96.8228) + (xy 107.235881 96.824524) + (xy 107.235908 96.824239) + (xy 107.243669 96.824971) + (xy 107.243676 96.824973) + (xy 107.312809 96.8228) + (xy 107.34235 96.8228) + (xy 107.349234 96.821929) + (xy 107.355063 96.821471) + (xy 107.364799 96.821165) + (xy 107.401636 96.820008) + (xy 107.401638 96.820007) + (xy 107.40164 96.820007) + (xy 107.420869 96.81442) + (xy 107.439923 96.810473) + (xy 107.459792 96.807964) + (xy 107.503129 96.790804) + (xy 107.508647 96.788915) + (xy 107.553398 96.775914) + (xy 107.570637 96.765718) + (xy 107.588099 96.757163) + (xy 107.606732 96.749786) + (xy 107.644434 96.722391) + (xy 107.649303 96.719193) + (xy 107.689428 96.695465) + (xy 107.703594 96.681298) + (xy 107.718388 96.668664) + (xy 107.734583 96.656897) + (xy 107.734585 96.656896) + (xy 107.734587 96.656894) + (xy 107.76429 96.620987) + (xy 107.768215 96.616675) + (xy 108.885547 95.499311) + (xy 114.226833 90.15787) (xy 116.7045 90.15787) (xy 116.704501 90.157876) (xy 116.710908 90.217483) @@ -4727,8 +5585,7 @@ (xy 119 90.615462) (xy 119.201033 90.595662) (xy 119.394341 90.537023) - (xy 119.572494 90.441798) - (xy 119.572493 90.441798) + (xy 119.441951 90.511575) (xy 119.577078 90.439348) (xy 119.64548 90.425106) (xy 119.693985 90.439348) @@ -4816,36 +5673,36 @@ (xy 116.704501 88.562116) (xy 116.7045 88.562135) (xy 116.7045 90.15787) - (xy 114.226719 90.15787) - (xy 118.113788 86.270801) - (xy 118.126042 86.260986) - (xy 118.125859 86.260764) - (xy 118.131866 86.255792) + (xy 114.226833 90.15787) + (xy 118.113795 86.270795) + (xy 118.126051 86.26098) + (xy 118.125867 86.260757) + (xy 118.13187 86.255789) (xy 118.131877 86.255786) - (xy 118.162775 86.222882) - (xy 118.179227 86.205364) - (xy 118.189671 86.194918) - (xy 118.20012 86.184471) - (xy 118.204379 86.178978) - (xy 118.208152 86.174561) + (xy 118.179232 86.205358) + (xy 118.200126 86.184464) + (xy 118.204379 86.178979) + (xy 118.208163 86.174548) (xy 118.240062 86.140582) - (xy 118.249713 86.123024) - (xy 118.260396 86.106761) - (xy 118.272673 86.090936) - (xy 118.291185 86.048153) - (xy 118.293738 86.042941) + (xy 118.249718 86.123015) + (xy 118.260395 86.106762) + (xy 118.272678 86.090928) + (xy 118.29119 86.048145) + (xy 118.293738 86.042943) (xy 118.316197 86.002092) - (xy 118.32118 85.98268) - (xy 118.327481 85.96428) - (xy 118.335437 85.945896) - (xy 118.342729 85.899852) - (xy 118.343906 85.894171) + (xy 118.321181 85.982676) + (xy 118.327484 85.964271) + (xy 118.33544 85.945886) + (xy 118.33544 85.945884) + (xy 118.337409 85.933454) + (xy 118.342726 85.899869) + (xy 118.343911 85.89415) (xy 118.3555 85.849019) - (xy 118.3555 85.828983) - (xy 118.357027 85.809582) - (xy 118.36016 85.789804) - (xy 118.355775 85.743415) - (xy 118.3555 85.737577) + (xy 118.3555 85.828979) + (xy 118.357026 85.809583) + (xy 118.36016 85.789795) + (xy 118.355775 85.743408) + (xy 118.3555 85.73757) (xy 118.3555 82.33279) (xy 118.375185 82.265751) (xy 118.427989 82.219996) @@ -4862,7 +5719,7 @@ (xy 119 82.255462) (xy 119.201033 82.235662) (xy 119.394341 82.177023) - (xy 119.425549 82.160342) + (xy 119.4355 82.155023) (xy 119.577078 82.079348) (xy 119.64548 82.065106) (xy 119.693985 82.079348) @@ -4963,12 +5820,14 @@ (xy 117.079766 82.258478) (xy 117.104184 82.323942) (xy 117.1045 82.33279) - (xy 117.1045 85.459547) - (xy 117.084815 85.526586) - (xy 117.068181 85.547228) - (xy 107.079928 95.535481) - (xy 107.018605 95.568966) - (xy 106.992247 95.5718) + (xy 117.1045 85.459551) + (xy 117.084815 85.52659) + (xy 117.068183 85.547231) + (xy 112.655542 89.96) + (xy 107.199993 95.415707) + (xy 107.080223 95.53548) + (xy 107.0189 95.568966) + (xy 106.99254 95.5718) (xy 105.354764 95.5718) (xy 105.287725 95.552115) (xy 105.24197 95.499311) @@ -4976,10 +5835,10 @@ (xy 105.234989 95.415707) (xy 105.265858 95.3005) (xy 105.285635 95.226692) - (xy 105.302849 95.029938) + (xy 105.303693 95.020288) (xy 105.305468 95.000001) (xy 105.305468 94.999998) - (xy 105.29355 94.863782) + (xy 105.294045 94.869431) (xy 105.285635 94.773308) (xy 105.226739 94.553504) (xy 105.130568 94.347266) @@ -5043,7 +5902,7 @@ (xy 89.5455 90.214188) (xy 89.565185 90.147149) (xy 89.598377 90.112613) - (xy 89.675102 90.05889) + (xy 89.666224 90.065106) (xy 89.759139 90.000047) (xy 89.920047 89.839139) (xy 90.050568 89.652734) @@ -5072,17 +5931,336 @@ (xy 88.473511 87.773258) (xy 88.473502 87.773261) (xy 88.267267 87.869431) - (xy 88.195122 87.919947) - (xy 88.128916 87.942274) - (xy 88.061149 87.925262) - (xy 88.013336 87.874313) - (xy 88 87.818371) - (xy 88 84) - (xy 83.124 84) - (xy 83.056961 83.980315) - (xy 83.011206 83.927511) - (xy 83 83.876) - (xy 83 71.000001) + (xy 88.267265 87.869432) + (xy 88.080858 87.999954) + (xy 87.919954 88.160858) + (xy 87.789432 88.347265) + (xy 87.789431 88.347267) + (xy 87.693261 88.553502) + (xy 87.693258 88.553511) + (xy 87.634366 88.773302) + (xy 87.634364 88.773313) + (xy 87.614532 88.999998) + (xy 87.614532 89.000001) + (xy 87.634364 89.226686) + (xy 87.634366 89.226697) + (xy 87.693258 89.446488) + (xy 87.693261 89.446497) + (xy 87.789431 89.652732) + (xy 87.789432 89.652734) + (xy 87.919954 89.839141) + (xy 88.080858 90.000045) + (xy 88.241623 90.112613) + (xy 88.285248 90.167189) + (xy 88.2945 90.214188) + (xy 88.2945 91.837255) + (xy 88.292775 91.852872) + (xy 88.293061 91.852899) + (xy 88.292326 91.860665) + (xy 88.2945 91.929814) + (xy 88.2945 91.959343) + (xy 88.294501 91.95936) + (xy 88.295368 91.966231) + (xy 88.295826 91.97205) + (xy 88.29729 92.018624) + (xy 88.297291 92.018627) + (xy 88.30288 92.037867) + (xy 88.306824 92.056911) + (xy 88.309336 92.076791) + (xy 88.32649 92.120119) + (xy 88.328382 92.125647) + (xy 88.341381 92.170388) + (xy 88.35158 92.187634) + (xy 88.360117 92.205052) + (xy 88.360612 92.206301) + (xy 88.367021 92.275874) + (xy 88.334798 92.337869) + (xy 88.274172 92.372602) + (xy 88.245341 92.376) + (xy 87.143805 92.376) + (xy 87.076766 92.356315) + (xy 87.031011 92.303511) + (xy 87.019806 92.251636) + (xy 87.044001 84.008) + (xy 87.044 84.008) + (xy 82.168 84.008) + (xy 82.100961 83.988315) + (xy 82.055206 83.935511) + (xy 82.044 83.884) + (xy 82.044 81.500001) + (xy 92.114532 81.500001) + (xy 92.134364 81.726686) + (xy 92.134366 81.726697) + (xy 92.193258 81.946488) + (xy 92.193261 81.946497) + (xy 92.289431 82.152732) + (xy 92.289432 82.152734) + (xy 92.419954 82.339141) + (xy 92.580858 82.500045) + (xy 92.741623 82.612613) + (xy 92.785248 82.667189) + (xy 92.7945 82.714188) + (xy 92.7945 84.017255) + (xy 92.792775 84.032872) + (xy 92.793061 84.032899) + (xy 92.792326 84.040665) + (xy 92.7945 84.109814) + (xy 92.7945 84.139343) + (xy 92.794501 84.13936) + (xy 92.795368 84.146231) + (xy 92.795826 84.15205) + (xy 92.79729 84.198624) + (xy 92.797291 84.198627) + (xy 92.80288 84.217867) + (xy 92.806824 84.236911) + (xy 92.809336 84.256791) + (xy 92.82649 84.300119) + (xy 92.828382 84.305647) + (xy 92.841382 84.35039) + (xy 92.846397 84.358871) + (xy 92.85158 84.367634) + (xy 92.860136 84.3851) + (xy 92.863464 84.393504) + (xy 92.867514 84.403732) + (xy 92.894898 84.441423) + (xy 92.898106 84.446307) + (xy 92.921827 84.486416) + (xy 92.921833 84.486424) + (xy 92.93599 84.50058) + (xy 92.948628 84.515376) + (xy 92.960405 84.531586) + (xy 92.960406 84.531587) + (xy 92.996309 84.561288) + (xy 93.00062 84.56521) + (xy 93.502095 85.066686) + (xy 93.659197 85.223788) + (xy 93.669022 85.236051) + (xy 93.669243 85.235869) + (xy 93.674214 85.241878) + (xy 93.69877 85.264937) + (xy 93.724635 85.289226) + (xy 93.745529 85.31012) + (xy 93.751011 85.314373) + (xy 93.755443 85.318157) + (xy 93.789418 85.350062) + (xy 93.806976 85.359714) + (xy 93.823233 85.370393) + (xy 93.839064 85.382673) + (xy 93.858737 85.391186) + (xy 93.881833 85.401182) + (xy 93.887077 85.40375) + (xy 93.927908 85.426197) + (xy 93.940523 85.429435) + (xy 93.947305 85.431177) + (xy 93.965719 85.437481) + (xy 93.984104 85.445438) + (xy 94.030157 85.452732) + (xy 94.035826 85.453906) + (xy 94.080981 85.4655) + (xy 94.101016 85.4655) + (xy 94.120413 85.467026) + (xy 94.140196 85.47016) + (xy 94.186584 85.465775) + (xy 94.192422 85.4655) + (xy 102.785812 85.4655) + (xy 102.852851 85.485185) + (xy 102.887387 85.518377) + (xy 102.999954 85.679141) + (xy 103.160858 85.840045) + (xy 103.173674 85.849019) + (xy 103.347266 85.970568) + (xy 103.553504 86.066739) + (xy 103.773308 86.125635) + (xy 103.93523 86.139801) + (xy 103.999998 86.145468) + (xy 104 86.145468) + (xy 104.000002 86.145468) + (xy 104.056673 86.140509) + (xy 104.226692 86.125635) + (xy 104.446496 86.066739) + (xy 104.652734 85.970568) + (xy 104.839139 85.840047) + (xy 105.000047 85.679139) + (xy 105.130568 85.492734) + (xy 105.226739 85.286496) + (xy 105.285635 85.066692) + (xy 105.305468 84.84) + (xy 105.285635 84.613308) + (xy 105.226739 84.393504) + (xy 105.130568 84.187266) + (xy 105.000047 84.000861) + (xy 105.000045 84.000858) + (xy 104.839141 83.839954) + (xy 104.652734 83.709432) + (xy 104.652732 83.709431) + (xy 104.446497 83.613261) + (xy 104.446488 83.613258) + (xy 104.226697 83.554366) + (xy 104.226693 83.554365) + (xy 104.226692 83.554365) + (xy 104.226691 83.554364) + (xy 104.226686 83.554364) + (xy 104.000002 83.534532) + (xy 103.999998 83.534532) + (xy 103.773313 83.554364) + (xy 103.773302 83.554366) + (xy 103.553511 83.613258) + (xy 103.553502 83.613261) + (xy 103.347267 83.709431) + (xy 103.347265 83.709432) + (xy 103.160858 83.839954) + (xy 102.999954 84.000858) + (xy 102.887387 84.161623) + (xy 102.832811 84.205248) + (xy 102.785812 84.2145) + (xy 94.470452 84.2145) + (xy 94.403413 84.194815) + (xy 94.382771 84.178181) + (xy 94.081819 83.877228) + (xy 94.048334 83.815905) + (xy 94.0455 83.789547) + (xy 94.0455 82.714187) + (xy 94.065185 82.647148) + (xy 94.098379 82.612611) + (xy 94.117527 82.599204) + (xy 94.150328 82.58285) + (xy 94.188441 82.570467) + (xy 94.321877 82.485786) + (xy 94.430062 82.370582) + (xy 94.506197 82.232092) + (xy 94.507074 82.228673) + (xy 94.525605 82.188383) + (xy 94.550568 82.152734) + (xy 94.646739 81.946496) + (xy 94.705635 81.726692) + (xy 94.725468 81.500001) + (xy 102.274532 81.500001) + (xy 102.294364 81.726686) + (xy 102.294366 81.726697) + (xy 102.353258 81.946488) + (xy 102.353261 81.946497) + (xy 102.449431 82.152732) + (xy 102.449432 82.152734) + (xy 102.579954 82.339141) + (xy 102.740858 82.500045) + (xy 102.740861 82.500047) + (xy 102.927266 82.630568) + (xy 103.133504 82.726739) + (xy 103.133509 82.72674) + (xy 103.133511 82.726741) + (xy 103.143334 82.729373) + (xy 103.353308 82.785635) + (xy 103.51523 82.799801) + (xy 103.579998 82.805468) + (xy 103.58 82.805468) + (xy 103.580002 82.805468) + (xy 103.636673 82.800509) + (xy 103.806692 82.785635) + (xy 104.026496 82.726739) + (xy 104.232734 82.630568) + (xy 104.419139 82.500047) + (xy 104.580047 82.339139) + (xy 104.710568 82.152734) + (xy 104.806739 81.946496) + (xy 104.865635 81.726692) + (xy 104.885468 81.5) + (xy 104.865635 81.273308) + (xy 104.806739 81.053504) + (xy 104.710568 80.847266) + (xy 104.580047 80.660861) + (xy 104.580045 80.660858) + (xy 104.419141 80.499954) + (xy 104.232734 80.369432) + (xy 104.232732 80.369431) + (xy 104.026497 80.273261) + (xy 104.026488 80.273258) + (xy 103.806697 80.214366) + (xy 103.806693 80.214365) + (xy 103.806692 80.214365) + (xy 103.806691 80.214364) + (xy 103.806686 80.214364) + (xy 103.580002 80.194532) + (xy 103.579998 80.194532) + (xy 103.353313 80.214364) + (xy 103.353302 80.214366) + (xy 103.133511 80.273258) + (xy 103.133502 80.273261) + (xy 102.927267 80.369431) + (xy 102.927265 80.369432) + (xy 102.740858 80.499954) + (xy 102.579954 80.660858) + (xy 102.449432 80.847265) + (xy 102.449431 80.847267) + (xy 102.353261 81.053502) + (xy 102.353258 81.053511) + (xy 102.294366 81.273302) + (xy 102.294364 81.273313) + (xy 102.274532 81.499998) + (xy 102.274532 81.500001) + (xy 94.725468 81.500001) + (xy 94.725468 81.5) + (xy 94.705635 81.273308) + (xy 94.646739 81.053504) + (xy 94.550568 80.847266) + (xy 94.517337 80.799807) + (xy 94.502247 80.770696) + (xy 94.481754 80.713772) + (xy 94.481751 80.713767) + (xy 94.478208 80.706812) + (xy 94.478464 80.706681) + (xy 94.476497 80.702966) + (xy 94.476244 80.703106) + (xy 94.472489 80.696276) + (xy 94.472486 80.696268) + (xy 94.431819 80.640295) + (xy 94.392924 80.583062) + (xy 94.392923 80.583061) + (xy 94.387763 80.577208) + (xy 94.387977 80.577018) + (xy 94.38514 80.5739) + (xy 94.384932 80.574097) + (xy 94.379596 80.568414) + (xy 94.326289 80.524316) + (xy 94.274383 80.478553) + (xy 94.267928 80.474167) + (xy 94.268088 80.473931) + (xy 94.264562 80.471615) + (xy 94.26441 80.471855) + (xy 94.257825 80.467676) + (xy 94.195222 80.438217) + (xy 94.126616 80.403261) + (xy 94.126653 80.403187) + (xy 94.104655 80.391783) + (xy 94.103657 80.391084) + (xy 94.072734 80.369432) + (xy 94.033784 80.351269) + (xy 93.866497 80.273261) + (xy 93.866488 80.273258) + (xy 93.646697 80.214366) + (xy 93.646693 80.214365) + (xy 93.646692 80.214365) + (xy 93.646691 80.214364) + (xy 93.646686 80.214364) + (xy 93.420002 80.194532) + (xy 93.419998 80.194532) + (xy 93.193313 80.214364) + (xy 93.193302 80.214366) + (xy 92.973511 80.273258) + (xy 92.973502 80.273261) + (xy 92.767267 80.369431) + (xy 92.767265 80.369432) + (xy 92.580858 80.499954) + (xy 92.419954 80.660858) + (xy 92.289432 80.847265) + (xy 92.289431 80.847267) + (xy 92.193261 81.053502) + (xy 92.193258 81.053511) + (xy 92.134366 81.273302) + (xy 92.134364 81.273313) + (xy 92.114532 81.499998) + (xy 92.114532 81.500001) + (xy 82.044 81.500001) + (xy 82.044 71.000001) (xy 85.614532 71.000001) (xy 85.634364 71.226686) (xy 85.634366 71.226697) @@ -5095,6 +6273,9 @@ (xy 86.080861 72.000047) (xy 86.267266 72.130568) (xy 86.473504 72.226739) + (xy 86.473509 72.22674) + (xy 86.473511 72.226741) + (xy 86.526415 72.240916) (xy 86.693308 72.285635) (xy 86.85523 72.299801) (xy 86.919998 72.305468) @@ -5217,8 +6398,8 @@ (xy 85.634364 70.773313) (xy 85.614532 70.999998) (xy 85.614532 71.000001) - (xy 83 71.000001) - (xy 83 66.000001) + (xy 82.044 71.000001) + (xy 82.044 66.000001) (xy 85.694532 66.000001) (xy 85.714364 66.226686) (xy 85.714366 66.226697) @@ -5397,7 +6578,7 @@ (xy 99.856206 58.557664) (xy 99.856202 58.557671) (xy 99.805908 58.692517) - (xy 99.80391 58.711107) + (xy 99.799501 58.752116) (xy 99.799501 58.752123) (xy 99.7995 58.752135) (xy 99.7995 59.3067) @@ -5419,7 +6600,8 @@ (xy 99.557723 59.528628) (xy 99.541512 59.540407) (xy 99.511809 59.57631) - (xy 99.507877 59.580631) + (xy 99.507876 59.580631) + (xy 96.614606 62.473903) (xy 93.750328 65.338181) (xy 93.689005 65.371666) (xy 93.662647 65.3745) @@ -5455,8 +6637,8 @@ (xy 85.714364 65.773313) (xy 85.694532 65.999998) (xy 85.694532 66.000001) - (xy 83 66.000001) - (xy 83 55.000001) + (xy 82.044 66.000001) + (xy 82.044 55.000001) (xy 86.614532 55.000001) (xy 86.634364 55.226686) (xy 86.634366 55.226697) @@ -5579,12 +6761,12 @@ (xy 86.634364 54.773313) (xy 86.614532 54.999998) (xy 86.614532 55.000001) - (xy 83 55.000001) - (xy 83 47.124) - (xy 83.019685 47.056961) - (xy 83.072489 47.011206) - (xy 83.124 47) - (xy 122.876 47) + (xy 82.044 55.000001) + (xy 82.044 47.132) + (xy 82.063685 47.064961) + (xy 82.116489 47.019206) + (xy 82.168 47.008) + (xy 128.799879 47.008) ) ) ) diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl index c328dcb49c..d8a0e67e44 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_prl @@ -1,6 +1,6 @@ { "board": { - "active_layer": 0, + "active_layer": 31, "active_layer_preset": "All Layers", "auto_track_width": false, "hidden_netclasses": [], @@ -65,7 +65,7 @@ 40 ], "visible_layers": "fffffff_ffffffff", - "zone_display_mode": 1 + "zone_display_mode": 0 }, "meta": { "filename": "SeaTalk1.kicad_prl", diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro index 003f68f8f4..7a3969c3d3 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_pro @@ -49,7 +49,13 @@ } }, "diff_pair_dimensions": [], - "drc_exclusions": [], + "drc_exclusions": [ + "starved_thermal|132540000|53580000|0439734c-1f86-4b67-9c14-36cdfe2e2799|01717d6d-6600-4cb3-8880-34ec125e8282|B.Cu", + "starved_thermal|132540000|63740000|0439734c-1f86-4b67-9c14-36cdfe2e2799|43c6842c-1f58-4b5a-aa64-cc798e2a154e|B.Cu", + "starved_thermal|132540000|71360000|0439734c-1f86-4b67-9c14-36cdfe2e2799|304e0b03-1cea-4d23-91a2-dc41d5ce210d|B.Cu", + "starved_thermal|132540000|84060000|0439734c-1f86-4b67-9c14-36cdfe2e2799|41884a76-5a3d-4fec-97a3-f190dcb4359e|B.Cu", + "starved_thermal|132540000|89140000|0439734c-1f86-4b67-9c14-36cdfe2e2799|de446f11-bb46-40f4-b427-395e6936a157|B.Cu" + ], "meta": { "version": 2 }, diff --git a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch index 56d245dc79..e90bbd5825 100644 --- a/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch +++ b/src/devices/Seatalk1/schematics/SeaTalk1/SeaTalk1.kicad_sch @@ -995,9 +995,6 @@ (junction (at 236.22 161.29) (diameter 0) (color 0 0 0 0) (uuid 2c3a7927-41d0-47b5-bc63-3a1da5f562c0) ) - (junction (at 148.59 38.1) (diameter 0) (color 0 0 0 0) - (uuid 2f9af179-68d0-4e40-8430-c84ef94f7bdc) - ) (junction (at 241.3 19.05) (diameter 0) (color 0 0 0 0) (uuid 333af6be-105f-445a-8f3e-7e986caf4e58) ) @@ -1067,6 +1064,9 @@ (junction (at 93.98 71.12) (diameter 0) (color 0 0 0 0) (uuid d736eead-cbaa-43b0-8dc3-22839d3ea164) ) + (junction (at 148.59 39.37) (diameter 0) (color 0 0 0 0) + (uuid d98e79d0-b38e-41be-9a19-ca676cc54129) + ) (junction (at 231.14 22.86) (diameter 0) (color 0 0 0 0) (uuid da35b086-93cc-486a-90d1-17aa47b306d8) ) @@ -1114,6 +1114,10 @@ (stroke (width 0) (type default)) (uuid 07616570-01cf-4d5f-a6fe-efdb7e5ff878) ) + (wire (pts (xy 203.2 34.29) (xy 256.54 34.29)) + (stroke (width 0) (type default)) + (uuid 0c9b4583-5977-4735-8928-12b65c0756ad) + ) (wire (pts (xy 224.79 161.29) (xy 236.22 161.29)) (stroke (width 0) (type default)) (uuid 0cdb394d-7b35-4730-8a70-762a1875597f) @@ -1222,10 +1226,6 @@ (stroke (width 0) (type default)) (uuid 450e7a3b-76d3-47b6-b23b-7b8e9883ce80) ) - (wire (pts (xy 203.2 35.56) (xy 215.9 35.56)) - (stroke (width 0) (type default)) - (uuid 452060c5-3f97-48a1-b7a2-74ca2d0d8252) - ) (wire (pts (xy 71.12 69.85) (xy 71.12 67.31)) (stroke (width 0) (type default)) (uuid 45710f38-26a7-4688-85be-54a6e32b00b3) @@ -1274,6 +1274,10 @@ (stroke (width 0) (type default)) (uuid 5a2bfc69-993b-4173-8737-f7ff8f3d85d0) ) + (wire (pts (xy 256.54 34.29) (xy 256.54 35.56)) + (stroke (width 0) (type default)) + (uuid 5ad0dc39-f36f-455c-946c-412f8b542573) + ) (wire (pts (xy 148.59 160.02) (xy 167.64 160.02)) (stroke (width 0) (type default)) (uuid 5e2215c9-0b9a-4480-b70b-5e0fffc6842f) @@ -1282,11 +1286,15 @@ (stroke (width 0) (type default)) (uuid 621877c7-134b-4bdb-9eeb-a62f425b71c4) ) + (wire (pts (xy 148.59 39.37) (xy 148.59 57.15)) + (stroke (width 0) (type default)) + (uuid 625509e4-0842-4a5a-8a0b-117c6a421e34) + ) (wire (pts (xy 71.12 53.34) (xy 77.47 53.34)) (stroke (width 0) (type default)) (uuid 6536fb26-c818-4a30-a617-fa2ec6d474ba) ) - (wire (pts (xy 148.59 35.56) (xy 148.59 38.1)) + (wire (pts (xy 148.59 35.56) (xy 148.59 39.37)) (stroke (width 0) (type default)) (uuid 659c9797-24f8-4c5b-bd1d-8a54b51a02cf) ) @@ -1310,10 +1318,6 @@ (stroke (width 0) (type default)) (uuid 6f7b28ef-1ebc-4e0e-a7ed-804c1ad2fe50) ) - (wire (pts (xy 148.59 38.1) (xy 148.59 57.15)) - (stroke (width 0) (type default)) - (uuid 70743eba-8649-4837-9280-0ed6ff392396) - ) (wire (pts (xy 134.62 91.44) (xy 148.59 91.44)) (stroke (width 0) (type default)) (uuid 70d03e07-ad24-4325-94e6-ef06c1bdc445) @@ -1350,6 +1354,10 @@ (stroke (width 0) (type default)) (uuid 89ce8bc6-7f6b-4856-a39e-4a545f9d4cda) ) + (wire (pts (xy 148.59 39.37) (xy 256.54 39.37)) + (stroke (width 0) (type default)) + (uuid 8bda66b5-537e-46c9-8f5c-636a2d480d32) + ) (wire (pts (xy 168.91 115.57) (xy 168.91 119.38)) (stroke (width 0) (type default)) (uuid 8bf79e71-8dda-4e02-992f-9d684eab025c) @@ -1378,6 +1386,10 @@ (stroke (width 0) (type default)) (uuid 936c209f-d533-41e4-a51c-089c25ee45a7) ) + (wire (pts (xy 256.54 38.1) (xy 256.54 39.37)) + (stroke (width 0) (type default)) + (uuid 97895bc7-b864-4777-9d67-a549479db6f5) + ) (wire (pts (xy 148.59 19.05) (xy 148.59 27.94)) (stroke (width 0) (type default)) (uuid 97fc6270-b096-4834-a0f7-3b73adc27269) @@ -1390,10 +1402,6 @@ (stroke (width 0) (type default)) (uuid 9cfa7a0a-9409-411c-a970-09a18b3031cd) ) - (wire (pts (xy 148.59 38.1) (xy 215.9 38.1)) - (stroke (width 0) (type default)) - (uuid 9e2a6478-96e0-4aa7-bdff-e15f09055971) - ) (wire (pts (xy 124.46 62.23) (xy 124.46 71.12)) (stroke (width 0) (type default)) (uuid 9fb53aa7-3322-410e-8134-3ed110349727) @@ -1588,10 +1596,10 @@ (effects (font (size 1.27 1.27)) (justify left) hide) ) ) - (global_label "TXD" (shape output) (at 203.2 35.56 180) (fields_autoplaced) + (global_label "TXD" (shape output) (at 203.2 34.29 180) (fields_autoplaced) (effects (font (size 1.27 1.27)) (justify right)) (uuid 3121f960-5443-441a-b6eb-0e5528d78a8c) - (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 196.7677 35.56 0) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 196.7677 34.29 0) (effects (font (size 1.27 1.27)) (justify right) hide) ) ) From 353f3d73444897d45814ac5fb5d1e770c9dd33e0 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 14 Jan 2024 13:58:24 +0100 Subject: [PATCH 29/31] Finalize documentation --- .../Seatalk1/Messages/ApparentWindAngle.cs | 17 +++- .../Seatalk1/Messages/ApparentWindSpeed.cs | 15 ++++ .../Seatalk1/Messages/AutopilotAlarms.cs | 16 ++++ .../Seatalk1/Messages/AutopilotButtons.cs | 35 ++++++++ .../Messages/AutopilotCalibrationParameter.cs | 86 +++++++++++++++++++ .../AutopilotCalibrationParameterMessage.cs | 20 +++++ .../CompassHeadingAndRudderPosition.cs | 16 ++++ .../Messages/CompassHeadingAutopilotCourse.cs | 31 +++++++ .../CompassHeadingAutopilotCourseAlt.cs | 1 + .../Seatalk1/Messages/CourseComputerStatus.cs | 12 +++ .../Messages/CourseComputerWarnings.cs | 3 + src/devices/Seatalk1/Messages/DeadbandMode.cs | 17 ++++ .../Seatalk1/Messages/DeadbandSetting.cs | 8 ++ .../Messages/DisplayBacklightLevel.cs | 18 ++++ src/devices/Seatalk1/Messages/Keystroke.cs | 28 ++++++ .../Seatalk1/Messages/NavigationToWaypoint.cs | 31 +++++++ .../Seatalk1/Messages/SeatalkMessage.cs | 42 +++++---- .../Seatalk1/Messages/SetLampIntensity.cs | 20 +++++ .../Seatalk1/Messages/TurnDirection.cs | 10 +++ src/devices/Seatalk1/Seatalk1Parser.cs | 19 +++- src/devices/Seatalk1/SeatalkInterface.cs | 26 ++++++ .../Seatalk1/SeatalkToNmeaConverter.cs | 28 ++++++ 22 files changed, 482 insertions(+), 17 deletions(-) diff --git a/src/devices/Seatalk1/Messages/ApparentWindAngle.cs b/src/devices/Seatalk1/Messages/ApparentWindAngle.cs index fbaad608aa..e52c0adfc2 100644 --- a/src/devices/Seatalk1/Messages/ApparentWindAngle.cs +++ b/src/devices/Seatalk1/Messages/ApparentWindAngle.cs @@ -11,25 +11,38 @@ namespace Iot.Device.Seatalk1.Messages { + ///

+ /// Apparent wind angle, as provided by the wind instrument in the masthead of a sailboat. + /// public record ApparentWindAngle : SeatalkMessage { private readonly Angle _apparentAngle; + /// + /// Create a default instance + /// public ApparentWindAngle() { ApparentAngle = Angle.Zero; } + /// + /// Create a new instance + /// + /// Apparent wind angle (positive for wind from starboard) public ApparentWindAngle(Angle apparentAngle) { ApparentAngle = apparentAngle; } + /// public override byte CommandByte => 0x10; + + /// public override byte ExpectedLength => 0x4; /// - /// Apparent wind angle, relative to bow. + /// Apparent wind angle, relative to bow. 0 means wind comes directly from ahead. /// Positive for right of bow (wind from starboard) /// public Angle ApparentAngle @@ -45,6 +58,7 @@ public Angle ApparentAngle } } + /// public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { uint angle10u = Convert.ToUInt32(data[2] << 8 | data[3]); @@ -61,6 +75,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { short angle10 = (short)Math.Round(ApparentAngle.Degrees * 2); diff --git a/src/devices/Seatalk1/Messages/ApparentWindSpeed.cs b/src/devices/Seatalk1/Messages/ApparentWindSpeed.cs index fea9fc7965..d286dee1fb 100644 --- a/src/devices/Seatalk1/Messages/ApparentWindSpeed.cs +++ b/src/devices/Seatalk1/Messages/ApparentWindSpeed.cs @@ -11,21 +11,34 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// This message provides the apparent wind speed as measured by the wind instrument on the masthead of a sailboat. + /// public record ApparentWindSpeed : SeatalkMessage { private readonly Speed _apparentSpeed; + /// + /// Create a new instance + /// public ApparentWindSpeed() { ApparentSpeed = Speed.FromKnots(0); // Default unit is knots } + /// + /// Create a new instance + /// + /// Apparent wind speed (default unit is knots) public ApparentWindSpeed(Speed apparentSpeed) { ApparentSpeed = apparentSpeed; } + /// public override byte CommandByte => 0x11; + + /// public override byte ExpectedLength => 0x4; /// @@ -49,6 +62,7 @@ public Speed ApparentSpeed } } + /// public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { Speed spd = Speed.Zero; @@ -67,6 +81,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { double rounded = Math.Round(ApparentSpeed.Knots, 1); diff --git a/src/devices/Seatalk1/Messages/AutopilotAlarms.cs b/src/devices/Seatalk1/Messages/AutopilotAlarms.cs index ea2cab57f1..08185d461b 100644 --- a/src/devices/Seatalk1/Messages/AutopilotAlarms.cs +++ b/src/devices/Seatalk1/Messages/AutopilotAlarms.cs @@ -5,11 +5,27 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Autopilot alarm flags + /// [Flags] public enum AutopilotAlarms { + /// + /// No alarm + /// None = 0, + + /// + /// The track offset is too large + /// OffCourse = 4, + + /// + /// There was a wind shift (when in auto-wind mode) + /// This alarm is generated when in auto-wind mode and the true wind direction shifts by a certain amount (20° by default). + /// To continue, safety must be re-evaluated, as the course over ground is changing, too. + /// WindShift = 8, } } diff --git a/src/devices/Seatalk1/Messages/AutopilotButtons.cs b/src/devices/Seatalk1/Messages/AutopilotButtons.cs index 1b363ba35b..838e4f76bb 100644 --- a/src/devices/Seatalk1/Messages/AutopilotButtons.cs +++ b/src/devices/Seatalk1/Messages/AutopilotButtons.cs @@ -16,14 +16,49 @@ namespace Iot.Device.Seatalk1.Messages [Flags] public enum AutopilotButtons { + /// + /// No button was pressed + /// None = 0, + + /// + /// The -1 button was pressed + /// MinusOne = 1, + + /// + /// The -10 button was pressed + /// MinusTen = 2, + + /// + /// The +1 button was pressed + /// PlusOne = 4, + + /// + /// The +10 button was pressed + /// PlusTen = 8, + + /// + /// The Auto button was pressed + /// Auto = 16, + + /// + /// The Standby button was pressed + /// StandBy = 32, + + /// + /// The Disp button was pressed (not always present) + /// Disp = 128, + + /// + /// The button(s) where pressed longer + /// LongPress = 256, } } diff --git a/src/devices/Seatalk1/Messages/AutopilotCalibrationParameter.cs b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameter.cs index e95dd3fed5..54edbf6817 100644 --- a/src/devices/Seatalk1/Messages/AutopilotCalibrationParameter.cs +++ b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameter.cs @@ -9,28 +9,114 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Set of autopilot calibration parameters + /// public enum AutopilotCalibrationParameter { + /// + /// Invalid setting + /// None = 0, + + /// + /// Rudder gain value + /// RudderGain = 1, + + /// + /// Counter rudder setting + /// CounterRudder = 2, + + /// + /// Rudder limit in degrees + /// RudderLimit = 3, + + /// + /// Turn rate limit (degrees/second) + /// TurnRateLimit = 4, + + /// + /// Default speed (used if the autopilot doesn't get any speed messages) + /// Speed = 5, + + /// + /// Off-course limit in nautical miles + /// OffCourseLimit = 6, + + /// + /// Auto-trim setting + /// AutoTrim = 7, + + /// + /// Power steer + /// PowerSteer = 9, + + /// + /// Drive type + /// DriveType = 0xa, + + /// + /// Rudder damping + /// RudderDamping = 0xb, + + /// + /// Fixed variation, if cannot be derived from other messages + /// Variation = 0xc, + + /// + /// Auto adapt value (0=Off, 1=North, 2=South) + /// AutoAdapt = 0xd, + + /// + /// Auto-adapt latitude (if the value of AutoAdapt is not 0) + /// AutoAdaptLatitude = 0xe, + + /// + /// Auto-rlease + /// AutoRelease = 0xf, + + /// + /// Rudder alignment + /// RudderAlignment = 0x10, + + /// + /// Wind trim (Wind response) + /// WindTrim = 0x11, + + /// + /// Response (?) + /// Response = 0x12, + + /// + /// Boat type. 1 = Displacement, 2 = Semi-displacement, 3 = planing, 4 = stern, 5 = work, 6 = sail + /// BoatType = 0x13, + + /// + /// Calibration lock + /// CalLock = 0x15, + + /// + /// Tack angle (Default: 100°) + /// AutoTackAngle = 0x1d, /// diff --git a/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs index 861ef672a2..d6db21ef35 100644 --- a/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs +++ b/src/devices/Seatalk1/Messages/AutopilotCalibrationParameterMessage.cs @@ -9,35 +9,54 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Message generated when autopilot is in calibration mode. + /// public record AutopilotCalibrationParameterMessage : SeatalkMessage { + /// public override byte CommandByte => 0x88; + + /// public override byte ExpectedLength => 0x06; + /// + /// The parameter in this message. Defines the meaning of the other fields. + /// public AutopilotCalibrationParameter Parameter { get; init; } + /// + /// The value of the parameter + /// public int CurrentSetting { get; init; } + /// + /// Minimum allowed value for the setting + /// public int MinValue { get; init; } + /// + /// Maximum allowed value for the setting + /// public int MaxValue { get; init; } + /// public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { int param = data[2]; @@ -53,6 +72,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { byte[] data = new byte[ExpectedLength]; diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs index 5aa1b24066..58baaef515 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAndRudderPosition.cs @@ -11,23 +11,38 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Compass heading and rudder position message from autopilot + /// public record CompassHeadingAndRudderPosition : SeatalkMessage { + /// public override byte CommandByte => 0x9c; + + /// public override byte ExpectedLength => 4; + /// + /// Compass heading from the autopilot's internal sensor + /// public Angle CompassHeading { get; init; } + /// + /// Rudder position. The autopilot may consistently report 0 here if no such sensor is fitted. + /// public Angle RudderPosition { get; init; } + /// + /// Direction the boat is currently turning + /// public TurnDirection TurnDirection { get; @@ -59,6 +74,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { byte[] data = new byte[4]; diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs index 0376102ed3..e2372164a0 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourse.cs @@ -13,25 +13,54 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Compass heading and current autopilot course and parameters. This message contains the same fields as , + /// plus some more. + /// public record CompassHeadingAutopilotCourse : SeatalkMessage { + /// public override byte CommandByte => 0x84; + + /// public override byte ExpectedLength => 0x9; + /// + /// Heading of the internal sensor of the autopilot. + /// public Angle CompassHeading { get; init; } + /// + /// Autopilot type, not really relevant + /// public byte AutoPilotType { get; init; } + /// + /// Autopilot target course. Often not available when not in auto mode + /// public Angle AutoPilotCourse { get; init; } + /// + /// Rudder position. Positive when turning to starboard + /// public Angle RudderPosition { get; init; } + /// + /// Current autopilot status + /// public AutopilotStatus AutopilotStatus { get; init; } = AutopilotStatus.Standby; + /// + /// Active alarms + /// public AutopilotAlarms Alarms { get; init; } + /// + /// Turn direction. Not really reliable when no Rudder sensor is fitted. + /// public TurnDirection TurnDirection { get; init; } + /// public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { VerifyPacket(data); @@ -78,6 +107,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { byte[] data = new byte[ExpectedLength]; @@ -195,6 +225,7 @@ private byte GetAutopilotStatusByte(AutopilotStatus status) }; } + /// public override bool MatchesMessageType(IReadOnlyList data) { // Add some additional tests to make sure the message is not messed up diff --git a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourseAlt.cs b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourseAlt.cs index 33e7ec035c..2ceddb2277 100644 --- a/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourseAlt.cs +++ b/src/devices/Seatalk1/Messages/CompassHeadingAutopilotCourseAlt.cs @@ -15,6 +15,7 @@ namespace Iot.Device.Seatalk1.Messages /// public record CompassHeadingAutopilotCourseAlt : CompassHeadingAutopilotCourse { + /// public override byte CommandByte => 0x95; } } diff --git a/src/devices/Seatalk1/Messages/CourseComputerStatus.cs b/src/devices/Seatalk1/Messages/CourseComputerStatus.cs index 92267d7b72..0433b90233 100644 --- a/src/devices/Seatalk1/Messages/CourseComputerStatus.cs +++ b/src/devices/Seatalk1/Messages/CourseComputerStatus.cs @@ -10,17 +10,27 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Course computer status. Various autopilots may use this message for different purposes. + /// public record CourseComputerStatus : SeatalkMessage { + /// public override byte CommandByte => 0x83; + + /// public override byte ExpectedLength => 0x0a; // this message has 10 bytes, despite only 3 used. + /// + /// Active warnings + /// public CourseComputerWarnings Warnings { get; init; } + /// public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { Logger.LogInformation($"Course computer warning msg: {string.Join("-", data.Select(x => x.ToString("X2")))}"); @@ -30,6 +40,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { return new byte[] @@ -38,6 +49,7 @@ public override byte[] CreateDatagram() }; } + /// public override bool MatchesMessageType(IReadOnlyList data) { return base.MatchesMessageType(data) && data[3] == 0; diff --git a/src/devices/Seatalk1/Messages/CourseComputerWarnings.cs b/src/devices/Seatalk1/Messages/CourseComputerWarnings.cs index 1d3739a37c..54115f3d76 100644 --- a/src/devices/Seatalk1/Messages/CourseComputerWarnings.cs +++ b/src/devices/Seatalk1/Messages/CourseComputerWarnings.cs @@ -9,6 +9,9 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Course computer warnings + /// [Flags] public enum CourseComputerWarnings { diff --git a/src/devices/Seatalk1/Messages/DeadbandMode.cs b/src/devices/Seatalk1/Messages/DeadbandMode.cs index 755471ed9e..306e6652d7 100644 --- a/src/devices/Seatalk1/Messages/DeadbandMode.cs +++ b/src/devices/Seatalk1/Messages/DeadbandMode.cs @@ -3,10 +3,27 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Deadband mode setting. + /// This value configures whether the AP should try to filter boat movements from waves as good as possible, and save power by + /// minimizing the amount of rudder commands. + /// If it is set to minimal, the AP tries to minimize off-track limits + /// public enum DeadbandMode { + /// + /// Value not available or unknown + /// None = 0, + + /// + /// Automatic deadband mode (default) + /// Automatic, + + /// + /// Minimize off-track limits, possibly increasing the number of rudder commands. + /// Minimal, } } diff --git a/src/devices/Seatalk1/Messages/DeadbandSetting.cs b/src/devices/Seatalk1/Messages/DeadbandSetting.cs index c00a8c7c5f..c04e6f086e 100644 --- a/src/devices/Seatalk1/Messages/DeadbandSetting.cs +++ b/src/devices/Seatalk1/Messages/DeadbandSetting.cs @@ -21,11 +21,18 @@ namespace Iot.Device.Seatalk1.Messages /// public record DeadbandSetting : SeatalkMessage { + /// public override byte CommandByte => 0x87; + + /// public override byte ExpectedLength => 0x03; + /// + /// The new mode + /// public DeadbandMode Mode { get; init; } + /// public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { VerifyPacket(data); @@ -64,6 +71,7 @@ public override byte[] CreateDatagram() }; } + /// public override bool MatchesMessageType(IReadOnlyList data) { return base.MatchesMessageType(data) && data[1] == 0x0; diff --git a/src/devices/Seatalk1/Messages/DisplayBacklightLevel.cs b/src/devices/Seatalk1/Messages/DisplayBacklightLevel.cs index e97b4443f0..ed8e5a028a 100644 --- a/src/devices/Seatalk1/Messages/DisplayBacklightLevel.cs +++ b/src/devices/Seatalk1/Messages/DisplayBacklightLevel.cs @@ -9,11 +9,29 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Backlight level setting. Some devices may only support on or off. + /// public enum DisplayBacklightLevel { + /// + /// Backlight off + /// Off = 0, + + /// + /// Backlight level 1 + /// Level1 = 4, + + /// + /// Backlight level 2 + /// Level2 = 8, + + /// + /// Backlight level 3 + /// Level3 = 0xC, } } diff --git a/src/devices/Seatalk1/Messages/Keystroke.cs b/src/devices/Seatalk1/Messages/Keystroke.cs index d02439fbe2..968790875b 100644 --- a/src/devices/Seatalk1/Messages/Keystroke.cs +++ b/src/devices/Seatalk1/Messages/Keystroke.cs @@ -11,6 +11,9 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Keypress messages from/to the autopilot + /// public record Keystroke : SeatalkMessage { private static readonly Dictionary s_codeToButtonMap; @@ -58,12 +61,22 @@ static Keystroke() } } + /// + /// Empty constructor + /// public Keystroke() { KeyCode = 0; Source = 0; } + /// + /// Create a button command + /// + /// Button combination to press + /// Whether the message is from (0) or to (1) the autopilot + /// When sending a keystroke command to the AP, make sure the source is 1, otherwise it is filtered by the sender, + /// because the source is the only to way to distinguish own messages from remote messages on the bus. public Keystroke(AutopilotButtons buttonsToPress, int source = 1) { Source = source; @@ -78,6 +91,11 @@ public Keystroke(AutopilotButtons buttonsToPress, int source = 1) } } + /// + /// Send a keystroke message, directly with the bytecode + /// + /// Bytecode of the message + /// Source of the command public Keystroke(byte keyCode, int source = 1) { Source = source; @@ -104,6 +122,10 @@ public int Source init; } + /// + /// The buttons that where pressed. Note that not all keycodes are valid and autopilots/remote controllers translate some keycodes differently. (e.g. + /// some remote controllers have a "track" button, while others use a dual-button combination for this) + /// public AutopilotButtons ButtonsPressed { get @@ -112,6 +134,9 @@ public AutopilotButtons ButtonsPressed } } + /// + /// The keycode. + /// public int KeyCode { get; @@ -140,6 +165,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { byte inverseCode = (byte)~KeyCode; @@ -161,6 +187,7 @@ private AutopilotButtons GetButtons(int keyCode) return AutopilotButtons.None; } + /// public override bool MatchesMessageType(IReadOnlyList data) { // Byte 4 must be the binary inverse of byte 3 @@ -179,6 +206,7 @@ public override bool MatchesMessageType(IReadOnlyList data) return base.MatchesMessageType(data); } + /// protected override bool PrintMembers(StringBuilder stringBuilder) { base.PrintMembers(stringBuilder); diff --git a/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs b/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs index cc511befee..1972e7e780 100644 --- a/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs +++ b/src/devices/Seatalk1/Messages/NavigationToWaypoint.cs @@ -10,12 +10,25 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Navigation-to-waypoint message from a navigation computer + /// public record NavigationToWaypoint : SeatalkMessage { + /// + /// Default constructor + /// public NavigationToWaypoint() { } + /// + /// Construct a new instance + /// + /// Cross track error. Positive if right of desired track + /// Bearing to destination + /// The bearing is true, false if it is magnetic + /// Distance to destination public NavigationToWaypoint(Length? crossTrackError, Angle? bearingToDestination, bool bearingIsTrue, Length? distanceToDestination) { CrossTrackError = crossTrackError; @@ -24,33 +37,49 @@ public NavigationToWaypoint(Length? crossTrackError, Angle? bearingToDestination DistanceToDestination = distanceToDestination; } + /// public override byte CommandByte => 0x85; + + /// public override byte ExpectedLength => 0x9; + /// + /// Cross track error. Positive if right of track + /// public Length? CrossTrackError { get; init; } + /// + /// Bearing to destination waypoint. + /// public Angle? BearingToDestination { get; init; } + /// + /// The bearing value is true (means: It is relative to true north) + /// public bool BearingIsTrue { get; init; } + /// + /// Distance to destination + /// public Length? DistanceToDestination { get; init; } + /// public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { byte flags = data[6]; @@ -105,6 +134,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { // 85 X6 XX VU ZW ZZ YF 00 yf @@ -196,6 +226,7 @@ public override byte[] CreateDatagram() return data; } + /// public override bool MatchesMessageType(IReadOnlyList data) { return base.MatchesMessageType(data) && data[6] == (byte)(~data[8]); diff --git a/src/devices/Seatalk1/Messages/SeatalkMessage.cs b/src/devices/Seatalk1/Messages/SeatalkMessage.cs index f9ece71d7f..a0cb6b1be3 100644 --- a/src/devices/Seatalk1/Messages/SeatalkMessage.cs +++ b/src/devices/Seatalk1/Messages/SeatalkMessage.cs @@ -17,6 +17,9 @@ namespace Iot.Device.Seatalk1.Messages /// public abstract record SeatalkMessage { + /// + /// Default constructor + /// protected SeatalkMessage() { Logger = this.GetCurrentClassLogger(); @@ -38,31 +41,30 @@ public abstract byte ExpectedLength get; } + /// + /// Logger instance, to report possible issues + /// [IgnoreDataMember] protected ILogger Logger { get; } /// - /// Creates a new message from this template + /// Creates a new message from this template. + /// This function creates a new instance of the current type with the data fields updated according to the data parameter. /// /// The sliced input data - /// + /// A typed instance + /// The datagram does not match this type + /// + /// Before calling this method, should be used to verify the types match without creating an exception. + /// public abstract SeatalkMessage CreateNewMessage(IReadOnlyList data); + /// + /// Creates a datagram (byte array) from a message + /// + /// The bytes to send public abstract byte[] CreateDatagram(); - // To count the number of bits set in (U >> 4) & 0xc - protected int BitCount(uint v) - { - return v switch - { - 0 => 0, - 0xc => 2, - 0x8 => 1, - 0x4 => 1, - _ => throw new ArgumentOutOfRangeException(nameof(v), "That value was unexpected"), - }; - } - /// /// This checks the precondition for a valid input packet. /// Normally, derived classes do not need to override this, it's sufficient to override to add any per-message verifications. @@ -98,8 +100,14 @@ protected virtual void VerifyPacket(IReadOnlyList data) } } + /// + /// Compares this instance against another one + /// + /// Other instance + /// True or false public virtual bool Equals(SeatalkMessage? other) { + // This method is overriden, because we don't want to compare the logger if (ReferenceEquals(other, null)) { return false; @@ -108,6 +116,10 @@ public virtual bool Equals(SeatalkMessage? other) return ExpectedLength == other.ExpectedLength && CommandByte == other.CommandByte; } + /// + /// Standard hash code implementation + /// + /// A hash code public override int GetHashCode() { return CommandByte << 8 | ExpectedLength; diff --git a/src/devices/Seatalk1/Messages/SetLampIntensity.cs b/src/devices/Seatalk1/Messages/SetLampIntensity.cs index 24f317f336..e543f5ba21 100644 --- a/src/devices/Seatalk1/Messages/SetLampIntensity.cs +++ b/src/devices/Seatalk1/Messages/SetLampIntensity.cs @@ -9,23 +9,40 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Set lamp intensity message. This message can be used to instruct all devices on the bus to adjust their background light. + /// This message is only sent once from a controlling device. + /// public record SetLampIntensity : SeatalkMessage { private readonly DisplayBacklightLevel _intensity; + /// + /// Default constructor + /// public SetLampIntensity() { Intensity = DisplayBacklightLevel.Off; } + /// + /// Create a new instance + /// + /// New brightness setting public SetLampIntensity(DisplayBacklightLevel intensity) { Intensity = intensity; } + /// public override byte CommandByte => 0x30; + + /// public override byte ExpectedLength => 0x3; + /// + /// The new intensity. + /// public DisplayBacklightLevel Intensity { get @@ -43,6 +60,7 @@ public DisplayBacklightLevel Intensity } } + /// public override SeatalkMessage CreateNewMessage(IReadOnlyList data) { int newIntensity = data[2] & 0xF; @@ -53,6 +71,7 @@ public override SeatalkMessage CreateNewMessage(IReadOnlyList data) }; } + /// public override byte[] CreateDatagram() { return new byte[] @@ -61,6 +80,7 @@ public override byte[] CreateDatagram() }; } + /// public override bool MatchesMessageType(IReadOnlyList data) { return base.MatchesMessageType(data) && data[2] is 0 or 0x4 or 0x8 or 0xC; diff --git a/src/devices/Seatalk1/Messages/TurnDirection.cs b/src/devices/Seatalk1/Messages/TurnDirection.cs index 7cb257862a..979a77c2ff 100644 --- a/src/devices/Seatalk1/Messages/TurnDirection.cs +++ b/src/devices/Seatalk1/Messages/TurnDirection.cs @@ -9,9 +9,19 @@ namespace Iot.Device.Seatalk1.Messages { + /// + /// Turn direction, for Autopilot operation + /// public enum TurnDirection { + /// + /// Turn or turning to port (left) + /// Port = 0, + + /// + /// Turn or turning to starboard (right) + /// Starboard = 1, } } diff --git a/src/devices/Seatalk1/Seatalk1Parser.cs b/src/devices/Seatalk1/Seatalk1Parser.cs index e552665f5d..10a0eb8104 100644 --- a/src/devices/Seatalk1/Seatalk1Parser.cs +++ b/src/devices/Seatalk1/Seatalk1Parser.cs @@ -74,14 +74,31 @@ public Seatalk1Parser(Stream inputStream) } } - public int MaxMessageLength { get; private set; } + /// + /// The maximum length of all known messages (used to detect when the parser lost sync) + /// + private int MaxMessageLength { get; set; } + /// + /// True if the input buffer is currently empty + /// public bool IsBufferEmpty => _buffer.Count == 0; + /// + /// This event is fired when a new message was decoded + /// public event Action? NewMessageDecoded; + /// + /// List of known messages + /// internal List MessageTypes => _messageFactories; + /// + /// Register a new message type + /// + /// An instance of the new message type + /// The definition of the message seems incorrect public void RegisterMessageType(SeatalkMessage message) { if (message.ExpectedLength > 18) diff --git a/src/devices/Seatalk1/SeatalkInterface.cs b/src/devices/Seatalk1/SeatalkInterface.cs index e99e22620b..bbe7e19007 100644 --- a/src/devices/Seatalk1/SeatalkInterface.cs +++ b/src/devices/Seatalk1/SeatalkInterface.cs @@ -13,6 +13,11 @@ namespace Iot.Device.Seatalk1 { + /// + /// Seatalk interface handler. + /// This class is the main handler for talking over a seatalk network. + /// Only when also working with NMEA-0183, the should be used instead. + /// public class SeatalkInterface : MarshalByRefObject, IDisposable { private const Parity DefaultParity = Parity.Even; @@ -24,6 +29,9 @@ public class SeatalkInterface : MarshalByRefObject, IDisposable private readonly object _lock; private bool _disposed; + /// + /// This event is fired with every received message + /// public event Action? MessageReceived; /// @@ -70,6 +78,9 @@ protected SeatalkInterface() _disposed = false; } + /// + /// Provides access to the internal parser + /// public Seatalk1Parser Parser => _parser; /// @@ -156,6 +167,10 @@ private void WatchDogStarter() } } + /// + /// Watchdog function. Called at regular intervals for some housekeeping. The + /// default implementation checks for lost connections with the autopilot. + /// protected virtual void WatchDog() { _autopilotController.UpdateStatus(); @@ -221,6 +236,12 @@ public virtual bool SendMessage(SeatalkMessage message) return SendDatagram(bytes); } + /// + /// Synchronously send the given message + /// + /// The message to send + /// Transmission of Seatalk messages can be very slow and include considerable delays. Also, there's no guarantee the + /// message is successfully transmitted or received anywhere. public Task SendMessageAsync(SeatalkMessage message) { return Task.Factory.StartNew(() => SendMessage(message)); @@ -243,6 +264,10 @@ public void SetLampIntensity(DisplayBacklightLevel intensity) SendMessage(msg); } + /// + /// Default dispose method + /// + /// Always true protected virtual void Dispose(bool disposing) { if (_disposed) @@ -263,6 +288,7 @@ protected virtual void Dispose(bool disposing) } } + /// public void Dispose() { Dispose(true); diff --git a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs index 59a483080d..a7ad728676 100644 --- a/src/devices/Seatalk1/SeatalkToNmeaConverter.cs +++ b/src/devices/Seatalk1/SeatalkToNmeaConverter.cs @@ -12,6 +12,13 @@ namespace Iot.Device.Seatalk1 { + /// + /// Seatalk to NMEA-0183 converter. + /// This subclasses and hence can be included in a , which will make + /// the Seatalk interface look very similar to an NMEA-0183 interface. + /// This class embeds the , so no extra instance is required if this class is used. The class supports translation + /// of directly wrapped seatalk messages (that start with $STALK) as well as a set of navigation messages (see ) + /// public class SeatalkToNmeaConverter : NmeaSinkAndSource { private readonly List _sentencesToTranslate; @@ -19,6 +26,11 @@ public class SeatalkToNmeaConverter : NmeaSinkAndSource private bool _isDisposed; private ILogger _logger; + /// + /// Construct an instance of this class. + /// + /// Interface name, for message routing. Can be an arbitrary string. + /// Interface to connect to. e.g. "/dev/ttyAMA2" public SeatalkToNmeaConverter(string interfaceName, string portName) : base(interfaceName) { @@ -74,6 +86,10 @@ private void SeatalkMessageReceived(SeatalkMessage stalk) } } + /// + /// Start receiving data + /// + /// The instance has already been disposed public override void StartDecode() { if (_isDisposed) @@ -84,6 +100,15 @@ public override void StartDecode() _seatalkInterface.StartDecode(); } + /// + /// Send a sentence through the Seatalk port. This ignores unknown or disabled sentences. + /// + /// The source + /// The sentence to send + /// + /// This sends out a message when it is valid and it is a $STALK message and this instance is not the source. Or when the + /// message is valid and one of the supported messages to send as specified in . + /// public override void SendSentence(NmeaSinkAndSource source, NmeaSentence sentence) { if (sentence.Valid == false) @@ -137,6 +162,9 @@ private bool DoTranslate(NmeaSentence sentence, out T? convertedSentence) return false; } + /// + /// Terminate the parsing + /// public override void StopDecode() { _seatalkInterface.Dispose(); From 9b04cc9b7d04e76ad1c6813d41fd98096af6ee1d Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 14 Jan 2024 14:12:09 +0100 Subject: [PATCH 30/31] Fix linter errors --- .../CompatibilitySuppressions.xml | 14 ++++++++++++++ src/devices/Seatalk1/README.md | 5 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Iot.Device.Bindings/CompatibilitySuppressions.xml b/src/Iot.Device.Bindings/CompatibilitySuppressions.xml index fa60bbdc88..bd888108bf 100644 --- a/src/Iot.Device.Bindings/CompatibilitySuppressions.xml +++ b/src/Iot.Device.Bindings/CompatibilitySuppressions.xml @@ -127,6 +127,13 @@ lib/net6.0/Iot.Device.Bindings.dll true + + CP0002 + M:Iot.Device.Nmea0183.Sentences.WaterSpeedAndAngle.#ctor(UnitsNet.Angle,UnitsNet.Angle,UnitsNet.Speed) + lib/net6.0/Iot.Device.Bindings.dll + lib/net6.0/Iot.Device.Bindings.dll + true + CP0002 M:Iot.Device.Ssd13xx.Ssd1306.#ctor(System.Device.I2c.I2cDevice) @@ -267,6 +274,13 @@ lib/netstandard2.0/Iot.Device.Bindings.dll true + + CP0002 + M:Iot.Device.Nmea0183.Sentences.WaterSpeedAndAngle.#ctor(UnitsNet.Angle,UnitsNet.Angle,UnitsNet.Speed) + lib/netstandard2.0/Iot.Device.Bindings.dll + lib/netstandard2.0/Iot.Device.Bindings.dll + true + CP0002 M:Iot.Device.Ssd13xx.Ssd1306.#ctor(System.Device.I2c.I2cDevice) diff --git a/src/devices/Seatalk1/README.md b/src/devices/Seatalk1/README.md index cdde9360e4..00203f6c7b 100644 --- a/src/devices/Seatalk1/README.md +++ b/src/devices/Seatalk1/README.md @@ -2,7 +2,7 @@ ## Summary -Seatalk, also called Seatalk1, is a bus protocol used by the marine equipment company Raymarine. It is used as a protocol to connect various devices on a boat, such as depth sounders, anemometers (wind sensors), autopilots and displays. The protocol is the successor of NMEA-0183, providing the main benefit of being able to connect various devices to a single bus, without the need of complex star networks and bridges as it was required for NMEA-0183. +Seatalk, also called Seatalk1, is a bus protocol used by the marine equipment company Raymarine. It is used as a protocol to connect various devices on a boat, such as depth sounders, anemometers (wind sensors), autopilots and displays. The protocol is the successor of NMEA-0183, providing the main benefit of being able to connect various devices to a single bus, without the need of complex star networks and bridges as it was required for NMEA-0183. Data transfer uses a slow transmission rate of 4800 Baud, but this makes the bus quite stable with respect to interference. Collisions do occur, but as most messages are repeated at least every second, lost messages are typically negligible. @@ -56,11 +56,12 @@ private void ParserOnNewMessageDecoded(SeatalkMessage obj) ``` ## Physical interface + The physical bus uses a kind of UART protocol, but since it uses a single wire both for sending and receiving, additional electronics are required to connect the bus to an UART (RS-232) interface. Protocol converters are available on the market. The following scheme shows a schematic that allows connecting a Seatalk network to a Raspberry Pi. The seatalk cable is connected to J3. The grey wire from the bus goes to GND, the yellow wire is the data wire and the red wire is +12V. In this schematic, connecting the 12V wire is optional as long as there's at least one other device on the bus that provides the necessary pull-up. The wiring shows a connection to TXD2/RXD2 (ttyAMA2 on linux), as this interface is easier to configure than the default one on GPIO14/15, as long as it's enabled in `boot/config.txt` with `dtoverlay=uart2`. ![Seatalk-to-TTL-Uart](SeatalkInterface.png) -When connecting to a default RS-232 interface (e.g. using an USB-to-RS-232 converter), the inverting stages Q2 on RXD and Q5 on TXD should be skipped. Powering the entire wiring via 12V should work with some minor adjustments, such as changing R9 to 470Ω to avoid destroying D1. +When connecting to a default RS-232 interface (e.g. using an USB-to-RS-232 converter), the inverting stages Q2 on RXD and Q5 on TXD should be skipped. Powering the entire wiring via 12V should work with some minor adjustments, such as changing R9 to 470Ω to avoid destroying D1. ## References From af64d8b80516b498994e2e0ecba5f56d913174fa Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sat, 27 Jan 2024 20:36:28 +0100 Subject: [PATCH 31/31] Formatting fix --- src/devices/Seatalk1/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/devices/Seatalk1/README.md b/src/devices/Seatalk1/README.md index 00203f6c7b..047718c44c 100644 --- a/src/devices/Seatalk1/README.md +++ b/src/devices/Seatalk1/README.md @@ -66,4 +66,7 @@ When connecting to a default RS-232 interface (e.g. using an USB-to-RS-232 conve ## References Many tanks to Thomas Knauf for his extensive Seatalk protocol analysis. See [here](http://www.thomasknauf.de/seatalk.htm) -OpenCPN Seatalk Support [here](https://opencpn.org/wiki/dokuwiki/doku.php?id=opencpn:supplementary_software:seatalk). The OpenCPN plugin "Raymarine Autopilot" can send the required keypress sentences for remote-controlling an autopilot, but needs an NMEA-0183 to Seatalk1 bridge, which can be built using this binding. + +OpenCPN Seatalk Support [here](https://opencpn.org/wiki/dokuwiki/doku.php?id=opencpn:supplementary_software:seatalk). + +The OpenCPN plugin "Raymarine Autopilot" can send the required keypress sentences for remote-controlling an autopilot, but needs an NMEA-0183 to Seatalk1 bridge, which can be built using this binding.