Skip to content

Commit 1db83c3

Browse files
author
Marcus Sonestedt
committed
ServoPIDControl: Add log window and log file
1 parent 0c0d8d1 commit 1db83c3

17 files changed

+4363
-71
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ TestServoPID/pid_ms.csv
1616
TestServoPID/.vs/
1717
TestServoPID/Debug/
1818
TestServoPID/packages/
19+
packages

ServoPID.sln.DotSettings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_DECLARATION_NAMES/@EntryValue">True</s:Boolean>
55
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue">Inner</s:String>
66
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CppFormatting/OUTDENT_COMMAS/@EntryValue">True</s:Boolean>
7+
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECpp_002ECodeStyle_002ESettingsUpgrade_002EFunctionReturnStyleSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
78
<s:Boolean x:Key="/Default/UserDictionary/Words/=Arduino/@EntryIndexedValue">True</s:Boolean>
89
<s:Boolean x:Key="/Default/UserDictionary/Words/=coeff/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

ServoPIDControl/App.xaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
xmlns:local="clr-namespace:ServoPIDControl"
55
StartupUri="MainWindow.xaml">
66
<Application.Resources>
7-
7+
<ResourceDictionary>
8+
<ResourceDictionary.MergedDictionaries>
9+
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
10+
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
11+
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
12+
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
13+
<ResourceDictionary
14+
Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
15+
</ResourceDictionary.MergedDictionaries>
16+
</ResourceDictionary>
817
</Application.Resources>
9-
</Application>
18+
</Application>

ServoPIDControl/App.xaml.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Configuration;
4-
using System.Data;
5-
using System.Linq;
6-
using System.Threading.Tasks;
7-
using System.Windows;
1+
using System.Windows;
2+
using System.Windows.Threading;
83

9-
namespace ServoPIDControl
4+
namespace ServoPIDControl1
105
{
116
/// <summary>
127
/// Interaction logic for App.xaml
138
/// </summary>
149
public partial class App : Application
1510
{
11+
public App()
12+
{
13+
DispatcherUnhandledException += OnDispatcherUnhandledException;
14+
}
15+
16+
private static void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
17+
{
18+
MessageBox.Show(e.Exception.Message, e.Exception.GetType().Name);
19+
}
1620
}
1721
}

ServoPIDControl/ArduinoCom.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
using System;
22
using System.Collections.Specialized;
33
using System.ComponentModel;
4-
using System.Diagnostics;
54
using System.IO.Ports;
65
using System.Linq;
76
using System.Text;
87
using System.Windows;
98
using System.Windows.Threading;
9+
using NLog;
1010

1111
namespace ServoPIDControl
1212
{
@@ -35,9 +35,11 @@ internal enum ServoParam : byte
3535

3636
public class ArduinoCom : IDisposable
3737
{
38-
private SerialPort _port;
38+
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
39+
40+
private ISerialPort _port;
3941
private readonly StringBuilder _readBuf = new StringBuilder();
40-
private ArduinoModel _model;
42+
private Model _model;
4143
private readonly DispatcherTimer _timer = new DispatcherTimer {Interval = TimeSpan.FromMilliseconds(250)};
4244
private readonly object _portLock = new object();
4345

@@ -46,7 +48,7 @@ public ArduinoCom()
4648
_timer.Tick += TimerOnTick;
4749
_timer.Start();
4850

49-
MessageReceived += (s, a) => Debug.WriteLine($"Received: {a.Message}");
51+
MessageReceived += (s, a) => Log.Info($"Received: {a.Message}");
5052
}
5153

5254
private void TimerOnTick(object sender, EventArgs e)
@@ -94,7 +96,7 @@ private void LineReceived(string line)
9496
}
9597
catch (Exception e)
9698
{
97-
Debug.WriteLine($"Bad DT received: {line} - {e.Message}");
99+
Log.Error($"Bad DT received: {line} - {e.Message}");
98100
}
99101

100102
return;
@@ -109,7 +111,7 @@ private void LineReceived(string line)
109111

110112
if (numServos >= 33)
111113
{
112-
Debug.WriteLine("Too many servos: " + numServos);
114+
Log.Error("Too many servos: " + numServos);
113115
return;
114116
}
115117

@@ -135,7 +137,7 @@ private void LineReceived(string line)
135137
}
136138
catch (Exception e)
137139
{
138-
Debug.WriteLine("Bad servo data: " + line + " - " + e.Message);
140+
Log.Error("Bad servo data: " + line + " - " + e.Message);
139141
return;
140142
}
141143
}
@@ -153,7 +155,7 @@ private void LineReceived(string line)
153155
}
154156
catch (Exception e)
155157
{
156-
Debug.WriteLine($"Bad servo data: {line} - {e.Message}");
158+
Log.Error($"Bad servo data: {line} - {e.Message}");
157159
return;
158160
}
159161
}
@@ -166,14 +168,14 @@ private void LineReceived(string line)
166168
}
167169
else
168170
{
169-
Debug.WriteLine($"Ignored: {line}");
171+
Log.Warn($"Ignored: {line}");
170172
return;
171173
}
172174

173175
MessageReceived?.Invoke(this, new StringEventArgs {Message = line});
174176
}
175177

176-
public ArduinoModel Model
178+
public Model Model
177179
{
178180
get => _model;
179181
set
@@ -251,10 +253,10 @@ private void ServosOnCollectionChanged(object sender, NotifyCollectionChangedEve
251253

252254
private void ModelOnPropertyChanged(object sender, PropertyChangedEventArgs e)
253255
{
254-
if (e.PropertyName == null || e.PropertyName == nameof(Model.Enabled))
255-
SendCommand(Command.EnableRegulator, (byte) (Model.Enabled ? 1 : 0));
256+
if (e.PropertyName == null || e.PropertyName == nameof(Model.PidEnabled))
257+
SendCommand(Command.EnableRegulator, (byte) (Model.PidEnabled ? 1 : 0));
256258

257-
if (e.PropertyName == null || e.PropertyName == nameof(Model.PortName))
259+
if (e.PropertyName == null || e.PropertyName == nameof(Model.ConnectedPort))
258260
ConnectPort();
259261

260262
if (e.PropertyName == null || e.PropertyName == nameof(Model.PollPidData))
@@ -270,7 +272,7 @@ private void SendCommand(Command cmd, params byte[] data)
270272
if (_port == null || !_port.IsOpen)
271273
return;
272274

273-
Debug.WriteLine($"Sending {cmdData.Length}: {BitConverter.ToString(cmdData)}");
275+
Log.Debug($"Sending {cmdData.Length}: {BitConverter.ToString(cmdData)}");
274276
_port.Write(cmdData, 0, cmdData.Length);
275277
}
276278
}
@@ -303,21 +305,19 @@ private void ConnectPort()
303305
}
304306
}
305307

306-
if (Model?.PortName == null)
308+
if (Model?.ConnectedPort == null)
307309
return;
308310

309311
try
310312
{
311-
_port = new SerialPort(Model.PortName)
313+
_port = new SerialPort(Model.ConnectedPort)
312314
{
313315
BaudRate = 115200,
314-
NewLine = "\n",
315-
ReadBufferSize = 4096,
316-
WriteBufferSize = 4096,
316+
NewLine = "\n"
317317
};
318318
_port.Open();
319319

320-
Debug.WriteLine("Sending: RST");
320+
Log.Info("Sending: RST");
321321
_port.WriteLine("RST");
322322
_port.DataReceived += PortOnDataReceived;
323323

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
EXAMPLES AND USAGE
2+
3+
NOTE: Currently must be configured via code
4+
5+
6+
void MainWindow_Loaded(object sender, RoutedEventArgs e)
7+
{
8+
Dispatcher.Invoke(() =>
9+
{
10+
var target = new WpfRichTextBoxTarget
11+
{
12+
Name = "RichText",
13+
Layout =
14+
"[${longdate:useUTC=false}] :: [${level:uppercase=true}] :: ${logger}:${callsite} :: ${message} ${exception:innerFormat=tostring:maxInnerExceptionLevel=10:separator=,:format=tostring}",
15+
ControlName = LogRichTextBox.Name,
16+
FormName = GetType().Name,
17+
AutoScroll = true,
18+
MaxLines = 100000,
19+
UseDefaultRowColoringRules = true,
20+
};
21+
var asyncWrapper = new AsyncTargetWrapper { Name = "RichTextAsync", WrappedTarget = target };
22+
23+
LogManager.Configuration.AddTarget(asyncWrapper.Name, asyncWrapper);
24+
LogManager.Configuration.LoggingRules.Insert(0, new LoggingRule("*", LogLevel.FromString(MSMQ_Settings.Default.NLog_Log_Level), asyncWrapper));
25+
LogManager.ReconfigExistingLoggers();
26+
27+
});
28+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//
2+
// Copyright (c) 2004-2011 Jaroslaw Kowalski <[email protected]>
3+
//
4+
// All rights reserved.
5+
//
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions
8+
// are met:
9+
//
10+
// * Redistributions of source code must retain the above copyright notice,
11+
// this list of conditions and the following disclaimer.
12+
//
13+
// * Redistributions in binary form must reproduce the above copyright notice,
14+
// this list of conditions and the following disclaimer in the documentation
15+
// and/or other materials provided with the distribution.
16+
//
17+
// * Neither the name of Jaroslaw Kowalski nor the names of its
18+
// contributors may be used to endorse or promote products derived from this
19+
// software without specific prior written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31+
// THE POSSIBILITY OF SUCH DAMAGE.
32+
//
33+
34+
using NLog;
35+
36+
#if !NET_CF && !MONO && !SILVERLIGHT
37+
38+
namespace ServoPIDControl.Helper
39+
{
40+
using System.ComponentModel;
41+
using System.Windows;
42+
using NLog.Conditions;
43+
using NLog.Config;
44+
45+
[NLogConfigurationItem]
46+
public class WpfRichTextBoxRowColoringRule
47+
{
48+
static WpfRichTextBoxRowColoringRule()
49+
{
50+
Default = new WpfRichTextBoxRowColoringRule();
51+
}
52+
53+
public WpfRichTextBoxRowColoringRule()
54+
: this(null, "Empty", "Empty", FontStyles.Normal, FontWeights.Normal)
55+
{
56+
}
57+
58+
public WpfRichTextBoxRowColoringRule(string condition, string fontColor, string backColor, FontStyle fontStyle, FontWeight fontWeight)
59+
{
60+
Condition = condition;
61+
FontColor = fontColor;
62+
BackgroundColor = backColor;
63+
Style = fontStyle;
64+
Weight = fontWeight;
65+
}
66+
67+
public WpfRichTextBoxRowColoringRule(string condition, string fontColor, string backColor)
68+
{
69+
Condition = condition;
70+
FontColor = fontColor;
71+
BackgroundColor = backColor;
72+
Style = FontStyles.Normal;
73+
Weight = FontWeights.Normal;
74+
}
75+
76+
public static WpfRichTextBoxRowColoringRule Default { get; private set; }
77+
78+
[RequiredParameter]
79+
public ConditionExpression Condition { get; set; }
80+
81+
[DefaultValue("Empty")]
82+
public string FontColor { get; set; }
83+
84+
[DefaultValue("Empty")]
85+
public string BackgroundColor { get; set; }
86+
87+
public FontStyle Style { get; set; }
88+
89+
public FontWeight Weight { get; set; }
90+
91+
public bool CheckCondition(LogEventInfo logEvent)
92+
{
93+
return true.Equals(this.Condition.Evaluate(logEvent));
94+
}
95+
}
96+
}
97+
#endif

0 commit comments

Comments
 (0)