Skip to content
This repository was archived by the owner on Aug 10, 2022. It is now read-only.

Commit e802d55

Browse files
authored
Changes to HardwareException and some checks (#64)
* Changes to HardwareException and some checks * Minor change * Bump version
1 parent 30e8bc2 commit e802d55

25 files changed

+308
-463
lines changed

src/Unosquare.RaspberryIO.Peripherals/HardwareServo.cs

+8-15
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using Gpio;
44
using System;
55
using System.Linq;
6-
using Unosquare.Swan;
6+
using Swan;
77

88
/// <summary>
99
/// Represents a standard 50hz pulse-controlled servo using Hardware-assited PWM.
@@ -31,7 +31,7 @@ public HardwareServo(GpioPin outputPin)
3131
OutputPin.PwmRange = 4000;
3232
OutputPin.PwmRegister = 0;
3333

34-
Frequency = (double)Pi.Gpio.PwmBaseFrequency / OutputPin.PwmClockDivisor / OutputPin.PwmRange;
34+
Frequency = (double) Pi.Gpio.PwmBaseFrequency / OutputPin.PwmClockDivisor / OutputPin.PwmRange;
3535
PeriodMs = 1d / Frequency * 1000;
3636
MaxPulseLengthMs = PeriodMs * 1024d / OutputPin.PwmRange;
3737
PulseLengthMs = 1.0d; // default is 1ms pulses
@@ -62,10 +62,7 @@ public HardwareServo(GpioPin outputPin)
6262
/// </summary>
6363
public double PulseLengthMs
6464
{
65-
get
66-
{
67-
return PeriodMs * OutputPin.PwmRegister.Clamp(0, 1024) / OutputPin.PwmRange;
68-
}
65+
get => PeriodMs * OutputPin.PwmRegister.Clamp(0, 1024) / OutputPin.PwmRange;
6966
set
7067
{
7168
value = value.Clamp(0, MaxPulseLengthMs);
@@ -94,20 +91,16 @@ public double ComputeAngle(double pulseLengthMin, double pulseLengthMax)
9491
/// <param name="pulseLengthMin">The pulse length minimum.</param>
9592
/// <param name="pulseLengthMax">The pulse length maximum.</param>
9693
/// <returns>The pulse length in milliseconds for the given angle (from 0 to 180)</returns>
97-
public double ComputePulseLength(double angle, double pulseLengthMin, double pulseLengthMax)
98-
{
99-
return (angle.Clamp(0, 180) / 180 * (pulseLengthMax - pulseLengthMin)) + pulseLengthMin;
100-
}
94+
public double ComputePulseLength(double angle, double pulseLengthMin, double pulseLengthMax) =>
95+
(angle.Clamp(0, 180) / 180 * (pulseLengthMax - pulseLengthMin)) + pulseLengthMin;
10196

10297
/// <summary>
10398
/// Returns a <see cref="string" /> that represents this instance.
10499
/// </summary>
105100
/// <returns>
106101
/// A <see cref="string" /> that represents this instance.
107102
/// </returns>
108-
public override string ToString()
109-
{
110-
return $"Period: {PeriodMs,6:0.00} ms. | Frequency {Frequency,6:0.000} Hz. | Pulse Length: {PulseLengthMs,8:0.000} ms.";
111-
}
103+
public override string ToString() =>
104+
$"Period: {PeriodMs,6:0.00} ms. | Frequency {Frequency,6:0.000} Hz. | Pulse Length: {PulseLengthMs,8:0.000} ms.";
112105
}
113-
}
106+
}

src/Unosquare.RaspberryIO.Peripherals/InfraredSensor.cs

+48-60
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using System.Linq;
88
using System.Text;
99
using System.Threading;
10-
using Unosquare.Swan;
10+
using Swan;
1111

1212
/// <summary>
1313
/// Implements a digital infrared sensor using the HX1838/VS1838 or the TSOP38238 38kHz digital receiver.
@@ -17,10 +17,10 @@
1717
/// </summary>
1818
public sealed class InfraredSensor : IDisposable
1919
{
20-
private volatile bool IsDisposed = false; // To detect redundant calls
21-
private volatile bool IsInReadInterrupt = false;
22-
private volatile bool CurrentValue = false;
23-
private Timer IdleChecker = null;
20+
private volatile bool _isDisposed; // To detect redundant calls
21+
private volatile bool _isInReadInterrupt;
22+
private volatile bool _currentValue;
23+
private Timer _idleChecker;
2424

2525
/// <summary>
2626
/// Initializes a new instance of the <see cref="InfraredSensor" /> class.
@@ -83,21 +83,13 @@ public static string DebugPulses(InfraredPulse[] pulses, int groupSize = 4)
8383

8484
for (var i = 0; i < pulses.Length; i += groupSize)
8585
{
86-
var p = default(InfraredPulse);
8786
for (var offset = 0; offset < groupSize; offset++)
8887
{
8988
if (i + offset >= pulses.Length)
9089
break;
9190

92-
p = pulses[i + offset];
93-
if (p == null)
94-
{
95-
builder.Append($" ? {-1,7} | ");
96-
}
97-
else
98-
{
99-
builder.Append($" {(p.Value ? "T" : "F")} {p.DurationUsecs,7} | ");
100-
}
91+
var p = pulses[i + offset];
92+
builder.Append(p == null ? $" ? {-1,7} | " : $" {(p.Value ? "T" : "F")} {p.DurationUsecs,7} | ");
10193
}
10294

10395
builder.AppendLine();
@@ -106,9 +98,7 @@ public static string DebugPulses(InfraredPulse[] pulses, int groupSize = 4)
10698
return builder.ToString();
10799
}
108100

109-
/// <summary>
110-
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
111-
/// </summary>
101+
/// <inheritdoc />
112102
public void Dispose()
113103
{
114104
Dispose(true);
@@ -120,13 +110,13 @@ public void Dispose()
120110
/// <param name="alsoManaged"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
121111
private void Dispose(bool alsoManaged)
122112
{
123-
if (IsDisposed) return;
113+
if (_isDisposed) return;
124114

125-
IsDisposed = true;
115+
_isDisposed = true;
126116
if (alsoManaged)
127117
{
128118
// Dispose of Managed objects
129-
IdleChecker.Dispose();
119+
_idleChecker.Dispose();
130120
}
131121
}
132122

@@ -136,11 +126,11 @@ private void Dispose(bool alsoManaged)
136126
private void ReadInterruptDoWork()
137127
{
138128
// Define some constants
139-
const long GapUsecs = 5000;
140-
const long MaxElapsedMicroseconds = 250000;
141-
const long MinElapsedMicroseconds = 50;
142-
const int IdleCheckIntervalMilliSecs = 32;
143-
const int MaxPulseCount = 128;
129+
const long gapUsecs = 5000;
130+
const long maxElapsedMicroseconds = 250000;
131+
const long minElapsedMicroseconds = 50;
132+
const int idleCheckIntervalMilliSecs = 32;
133+
const int maxPulseCount = 128;
144134

145135
// Setup the input pin
146136
InputPin.PinMode = GpioPinDriveMode.Input;
@@ -150,17 +140,17 @@ private void ReadInterruptDoWork()
150140
var pulseTimer = new Native.HighResolutionTimer();
151141
var idleTimer = new Native.HighResolutionTimer();
152142

153-
var pulseBuffer = new List<InfraredPulse>(MaxPulseCount);
143+
var pulseBuffer = new List<InfraredPulse>(maxPulseCount);
154144
var syncLock = new object();
155145

156-
IdleChecker = new Timer((s) =>
146+
_idleChecker = new Timer(s =>
157147
{
158-
if (IsDisposed || IsInReadInterrupt)
148+
if (_isDisposed || _isInReadInterrupt)
159149
return;
160150

161151
lock (syncLock)
162152
{
163-
if (idleTimer.ElapsedMicroseconds < GapUsecs || idleTimer.IsRunning == false || pulseBuffer.Count <= 0)
153+
if (idleTimer.ElapsedMicroseconds < gapUsecs || idleTimer.IsRunning == false || pulseBuffer.Count <= 0)
164154
return;
165155

166156
OnInfraredSensorRawDataAvailable(pulseBuffer.ToArray(), ReceiverFlushReason.Idle);
@@ -171,47 +161,47 @@ private void ReadInterruptDoWork()
171161

172162
InputPin.RegisterInterruptCallback(EdgeDetection.RisingAndFallingEdges, () =>
173163
{
174-
if (IsDisposed) return;
164+
if (_isDisposed) return;
175165

176-
IsInReadInterrupt = true;
166+
_isInReadInterrupt = true;
177167

178168
lock (syncLock)
179169
{
180170
idleTimer.Restart();
181-
IdleChecker.Change(IdleCheckIntervalMilliSecs, IdleCheckIntervalMilliSecs);
171+
_idleChecker.Change(idleCheckIntervalMilliSecs, idleCheckIntervalMilliSecs);
182172

183173
var currentLength = pulseTimer.ElapsedMicroseconds;
184174
var pulse = new InfraredPulse(
185-
IsActiveLow ? !CurrentValue : CurrentValue,
186-
currentLength.Clamp(MinElapsedMicroseconds, MaxElapsedMicroseconds));
175+
IsActiveLow ? !_currentValue : _currentValue,
176+
currentLength.Clamp(minElapsedMicroseconds, maxElapsedMicroseconds));
187177

188178
// Restart for the next bit coming in
189179
pulseTimer.Restart();
190180

191181
// For the next value
192-
CurrentValue = InputPin.Read();
182+
_currentValue = InputPin.Read();
193183

194184
// Do not add an idling pulse
195-
if (pulse.DurationUsecs < MaxElapsedMicroseconds)
185+
if (pulse.DurationUsecs < maxElapsedMicroseconds)
196186
{
197187
pulseBuffer.Add(pulse);
198188
OnInfraredSensorPulseAvailable(pulse);
199189
}
200190

201-
if (pulseBuffer.Count >= MaxPulseCount)
191+
if (pulseBuffer.Count >= maxPulseCount)
202192
{
203193
OnInfraredSensorRawDataAvailable(pulseBuffer.ToArray(), ReceiverFlushReason.Overflow);
204194
pulseBuffer.Clear();
205195
}
206196
}
207197

208-
IsInReadInterrupt = false;
198+
_isInReadInterrupt = false;
209199
});
210200

211201
// Get the timers started
212202
pulseTimer.Start();
213203
idleTimer.Start();
214-
IdleChecker.Change(0, IdleCheckIntervalMilliSecs);
204+
_idleChecker.Change(0, idleCheckIntervalMilliSecs);
215205
}
216206

217207
/// <summary>
@@ -220,10 +210,10 @@ private void ReadInterruptDoWork()
220210
/// <param name="pulse">The pulse.</param>
221211
private void OnInfraredSensorPulseAvailable(InfraredPulse pulse)
222212
{
223-
if (IsDisposed || PulseAvailable == null) return;
213+
if (_isDisposed || PulseAvailable == null) return;
224214

225215
var args = new InfraredSensorPulseEventArgs(pulse);
226-
ThreadPool.QueueUserWorkItem((a) =>
216+
ThreadPool.QueueUserWorkItem(a =>
227217
{
228218
PulseAvailable?.Invoke(this, a as InfraredSensorPulseEventArgs);
229219
},
@@ -237,10 +227,10 @@ private void OnInfraredSensorPulseAvailable(InfraredPulse pulse)
237227
/// <param name="state">The state.</param>
238228
private void OnInfraredSensorRawDataAvailable(InfraredPulse[] pulses, ReceiverFlushReason state)
239229
{
240-
if (IsDisposed || DataAvailable == null) return;
230+
if (_isDisposed || DataAvailable == null) return;
241231

242232
var args = new InfraredSensorDataEventArgs(pulses, state);
243-
ThreadPool.QueueUserWorkItem((a) =>
233+
ThreadPool.QueueUserWorkItem(a =>
244234
{
245235
DataAvailable?.Invoke(this, a as InfraredSensorDataEventArgs);
246236
},
@@ -287,7 +277,8 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
287277
for (var pulseIndex = 0; pulseIndex < pulses.Length; pulseIndex++)
288278
{
289279
var p = pulses[pulseIndex];
290-
if (p.Value == true && p.DurationUsecs >= BurstSpaceLengthMin && p.DurationUsecs <= BurstSpaceLengthMax)
280+
281+
if (p.Value && p.DurationUsecs >= BurstSpaceLengthMin && p.DurationUsecs <= BurstSpaceLengthMax)
291282
{
292283
startPulseIndex = pulseIndex;
293284
break;
@@ -297,14 +288,15 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
297288
// Return a null result if we could not find ACG (1)
298289
if (startPulseIndex == -1)
299290
return null;
300-
else
301-
startPulseIndex += 1;
291+
292+
startPulseIndex += 1;
302293

303294
// Find the first 0 value, 4.5 Millisecond
304295
for (var pulseIndex = startPulseIndex; pulseIndex < pulses.Length; pulseIndex++)
305296
{
306297
var p = pulses[pulseIndex];
307298
startPulseIndex = -1;
299+
308300
if (p.Value == false && p.DurationUsecs >= BurstMarkLengthMin && p.DurationUsecs <= BurstMarkLengthMax)
309301
{
310302
startPulseIndex = pulseIndex;
@@ -315,8 +307,8 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
315307
// Return a null result if we could not find the start of the train of pulses
316308
if (startPulseIndex == -1)
317309
return null;
318-
else
319-
startPulseIndex += 1;
310+
311+
startPulseIndex += 1;
320312

321313
// Verify that the last pulse is a space (1) and and it is a short pulse
322314
var bits = new BitArray(MaxBitLength);
@@ -327,8 +319,8 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
327319
return null;
328320

329321
// preallocate the pulse references
330-
var p1 = default(InfraredPulse);
331-
var p2 = default(InfraredPulse);
322+
InfraredPulse p1;
323+
InfraredPulse p2;
332324

333325
// parse the bits
334326
for (var pulseIndex = startPulseIndex; pulseIndex < pulses.Length - 1; pulseIndex += 2)
@@ -339,8 +331,8 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
339331
p2 = pulses[pulseIndex + 1];
340332

341333
// Expect a short Space pulse followed by a Mark pulse of variable length
342-
if (p1.Value == true && p2.Value == false && p1.DurationUsecs.IsBetween(ShortPulseLengthMin, ShortPulseLengthMax))
343-
bits[bitCount++] = p2.DurationUsecs.IsBetween(ShortPulseLengthMin, ShortPulseLengthMax) ? true : false;
334+
if (p1.Value && p2.Value == false && p1.DurationUsecs.IsBetween(ShortPulseLengthMin, ShortPulseLengthMax))
335+
bits[bitCount++] = p2.DurationUsecs.IsBetween(ShortPulseLengthMin, ShortPulseLengthMax);
344336

345337
if (bitCount >= MaxBitLength)
346338
break;
@@ -376,7 +368,7 @@ public static bool IsRepeatCode(InfraredPulse[] pulses)
376368
for (var pulseIndex = 0; pulseIndex < pulses.Length; pulseIndex++)
377369
{
378370
var p = pulses[pulseIndex];
379-
if (p.Value == true && p.DurationUsecs >= BurstSpaceLengthMin && p.DurationUsecs <= BurstSpaceLengthMax)
371+
if (p.Value && p.DurationUsecs >= BurstSpaceLengthMin && p.DurationUsecs <= BurstSpaceLengthMax)
380372
{
381373
startPulseIndex = pulseIndex;
382374
break;
@@ -391,16 +383,14 @@ public static bool IsRepeatCode(InfraredPulse[] pulses)
391383

392384
// Check the next pulse is a 2.5ms low value
393385
var p1 = pulses[startPulseIndex + 1];
394-
if (p1.Value == true || p1.DurationUsecs.IsBetween(RepeatPulseLengthMin, RepeatPulseLengthMax) == false)
386+
if (p1.Value || p1.DurationUsecs.IsBetween(RepeatPulseLengthMin, RepeatPulseLengthMax) == false)
395387
return false;
396388

397389
// Check the next pulse is a 560 microsecond high value
398390
var p2 = pulses[startPulseIndex + 2];
399-
if (p2.Value == false || p2.DurationUsecs.IsBetween(ShortPulseLengthMin, ShortPulseLengthMax) == false)
400-
return false;
401391

402392
// All checks passed. Looks like it really is a repeat code
403-
return true;
393+
return p2.Value && p2.DurationUsecs.IsBetween(ShortPulseLengthMin, ShortPulseLengthMax);
404394
}
405395
}
406396

@@ -484,7 +474,6 @@ public class InfraredSensorPulseEventArgs : EventArgs
484474
/// </summary>
485475
/// <param name="pulse">The pulse.</param>
486476
internal InfraredSensorPulseEventArgs(InfraredPulse pulse)
487-
: base()
488477
{
489478
Value = pulse.Value;
490479
DurationUsecs = pulse.DurationUsecs;
@@ -494,7 +483,6 @@ internal InfraredSensorPulseEventArgs(InfraredPulse pulse)
494483
/// Prevents a default instance of the <see cref="InfraredSensorPulseEventArgs"/> class from being created.
495484
/// </summary>
496485
private InfraredSensorPulseEventArgs()
497-
: base()
498486
{
499487
// placeholder
500488
}

0 commit comments

Comments
 (0)