7
7
using System . Linq ;
8
8
using System . Text ;
9
9
using System . Threading ;
10
- using Unosquare . Swan ;
10
+ using Swan ;
11
11
12
12
/// <summary>
13
13
/// Implements a digital infrared sensor using the HX1838/VS1838 or the TSOP38238 38kHz digital receiver.
17
17
/// </summary>
18
18
public sealed class InfraredSensor : IDisposable
19
19
{
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 ;
24
24
25
25
/// <summary>
26
26
/// Initializes a new instance of the <see cref="InfraredSensor" /> class.
@@ -83,21 +83,13 @@ public static string DebugPulses(InfraredPulse[] pulses, int groupSize = 4)
83
83
84
84
for ( var i = 0 ; i < pulses . Length ; i += groupSize )
85
85
{
86
- var p = default ( InfraredPulse ) ;
87
86
for ( var offset = 0 ; offset < groupSize ; offset ++ )
88
87
{
89
88
if ( i + offset >= pulses . Length )
90
89
break ;
91
90
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 } | ") ;
101
93
}
102
94
103
95
builder . AppendLine ( ) ;
@@ -106,9 +98,7 @@ public static string DebugPulses(InfraredPulse[] pulses, int groupSize = 4)
106
98
return builder . ToString ( ) ;
107
99
}
108
100
109
- /// <summary>
110
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
111
- /// </summary>
101
+ /// <inheritdoc />
112
102
public void Dispose ( )
113
103
{
114
104
Dispose ( true ) ;
@@ -120,13 +110,13 @@ public void Dispose()
120
110
/// <param name="alsoManaged"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
121
111
private void Dispose ( bool alsoManaged )
122
112
{
123
- if ( IsDisposed ) return ;
113
+ if ( _isDisposed ) return ;
124
114
125
- IsDisposed = true ;
115
+ _isDisposed = true ;
126
116
if ( alsoManaged )
127
117
{
128
118
// Dispose of Managed objects
129
- IdleChecker . Dispose ( ) ;
119
+ _idleChecker . Dispose ( ) ;
130
120
}
131
121
}
132
122
@@ -136,11 +126,11 @@ private void Dispose(bool alsoManaged)
136
126
private void ReadInterruptDoWork ( )
137
127
{
138
128
// 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 ;
144
134
145
135
// Setup the input pin
146
136
InputPin . PinMode = GpioPinDriveMode . Input ;
@@ -150,17 +140,17 @@ private void ReadInterruptDoWork()
150
140
var pulseTimer = new Native . HighResolutionTimer ( ) ;
151
141
var idleTimer = new Native . HighResolutionTimer ( ) ;
152
142
153
- var pulseBuffer = new List < InfraredPulse > ( MaxPulseCount ) ;
143
+ var pulseBuffer = new List < InfraredPulse > ( maxPulseCount ) ;
154
144
var syncLock = new object ( ) ;
155
145
156
- IdleChecker = new Timer ( ( s ) =>
146
+ _idleChecker = new Timer ( s =>
157
147
{
158
- if ( IsDisposed || IsInReadInterrupt )
148
+ if ( _isDisposed || _isInReadInterrupt )
159
149
return ;
160
150
161
151
lock ( syncLock )
162
152
{
163
- if ( idleTimer . ElapsedMicroseconds < GapUsecs || idleTimer . IsRunning == false || pulseBuffer . Count <= 0 )
153
+ if ( idleTimer . ElapsedMicroseconds < gapUsecs || idleTimer . IsRunning == false || pulseBuffer . Count <= 0 )
164
154
return ;
165
155
166
156
OnInfraredSensorRawDataAvailable ( pulseBuffer . ToArray ( ) , ReceiverFlushReason . Idle ) ;
@@ -171,47 +161,47 @@ private void ReadInterruptDoWork()
171
161
172
162
InputPin . RegisterInterruptCallback ( EdgeDetection . RisingAndFallingEdges , ( ) =>
173
163
{
174
- if ( IsDisposed ) return ;
164
+ if ( _isDisposed ) return ;
175
165
176
- IsInReadInterrupt = true ;
166
+ _isInReadInterrupt = true ;
177
167
178
168
lock ( syncLock )
179
169
{
180
170
idleTimer . Restart ( ) ;
181
- IdleChecker . Change ( IdleCheckIntervalMilliSecs , IdleCheckIntervalMilliSecs ) ;
171
+ _idleChecker . Change ( idleCheckIntervalMilliSecs , idleCheckIntervalMilliSecs ) ;
182
172
183
173
var currentLength = pulseTimer . ElapsedMicroseconds ;
184
174
var pulse = new InfraredPulse (
185
- IsActiveLow ? ! CurrentValue : CurrentValue ,
186
- currentLength . Clamp ( MinElapsedMicroseconds , MaxElapsedMicroseconds ) ) ;
175
+ IsActiveLow ? ! _currentValue : _currentValue ,
176
+ currentLength . Clamp ( minElapsedMicroseconds , maxElapsedMicroseconds ) ) ;
187
177
188
178
// Restart for the next bit coming in
189
179
pulseTimer . Restart ( ) ;
190
180
191
181
// For the next value
192
- CurrentValue = InputPin . Read ( ) ;
182
+ _currentValue = InputPin . Read ( ) ;
193
183
194
184
// Do not add an idling pulse
195
- if ( pulse . DurationUsecs < MaxElapsedMicroseconds )
185
+ if ( pulse . DurationUsecs < maxElapsedMicroseconds )
196
186
{
197
187
pulseBuffer . Add ( pulse ) ;
198
188
OnInfraredSensorPulseAvailable ( pulse ) ;
199
189
}
200
190
201
- if ( pulseBuffer . Count >= MaxPulseCount )
191
+ if ( pulseBuffer . Count >= maxPulseCount )
202
192
{
203
193
OnInfraredSensorRawDataAvailable ( pulseBuffer . ToArray ( ) , ReceiverFlushReason . Overflow ) ;
204
194
pulseBuffer . Clear ( ) ;
205
195
}
206
196
}
207
197
208
- IsInReadInterrupt = false ;
198
+ _isInReadInterrupt = false ;
209
199
} ) ;
210
200
211
201
// Get the timers started
212
202
pulseTimer . Start ( ) ;
213
203
idleTimer . Start ( ) ;
214
- IdleChecker . Change ( 0 , IdleCheckIntervalMilliSecs ) ;
204
+ _idleChecker . Change ( 0 , idleCheckIntervalMilliSecs ) ;
215
205
}
216
206
217
207
/// <summary>
@@ -220,10 +210,10 @@ private void ReadInterruptDoWork()
220
210
/// <param name="pulse">The pulse.</param>
221
211
private void OnInfraredSensorPulseAvailable ( InfraredPulse pulse )
222
212
{
223
- if ( IsDisposed || PulseAvailable == null ) return ;
213
+ if ( _isDisposed || PulseAvailable == null ) return ;
224
214
225
215
var args = new InfraredSensorPulseEventArgs ( pulse ) ;
226
- ThreadPool . QueueUserWorkItem ( ( a ) =>
216
+ ThreadPool . QueueUserWorkItem ( a =>
227
217
{
228
218
PulseAvailable ? . Invoke ( this , a as InfraredSensorPulseEventArgs ) ;
229
219
} ,
@@ -237,10 +227,10 @@ private void OnInfraredSensorPulseAvailable(InfraredPulse pulse)
237
227
/// <param name="state">The state.</param>
238
228
private void OnInfraredSensorRawDataAvailable ( InfraredPulse [ ] pulses , ReceiverFlushReason state )
239
229
{
240
- if ( IsDisposed || DataAvailable == null ) return ;
230
+ if ( _isDisposed || DataAvailable == null ) return ;
241
231
242
232
var args = new InfraredSensorDataEventArgs ( pulses , state ) ;
243
- ThreadPool . QueueUserWorkItem ( ( a ) =>
233
+ ThreadPool . QueueUserWorkItem ( a =>
244
234
{
245
235
DataAvailable ? . Invoke ( this , a as InfraredSensorDataEventArgs ) ;
246
236
} ,
@@ -287,7 +277,8 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
287
277
for ( var pulseIndex = 0 ; pulseIndex < pulses . Length ; pulseIndex ++ )
288
278
{
289
279
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 )
291
282
{
292
283
startPulseIndex = pulseIndex ;
293
284
break ;
@@ -297,14 +288,15 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
297
288
// Return a null result if we could not find ACG (1)
298
289
if ( startPulseIndex == - 1 )
299
290
return null ;
300
- else
301
- startPulseIndex += 1 ;
291
+
292
+ startPulseIndex += 1 ;
302
293
303
294
// Find the first 0 value, 4.5 Millisecond
304
295
for ( var pulseIndex = startPulseIndex ; pulseIndex < pulses . Length ; pulseIndex ++ )
305
296
{
306
297
var p = pulses [ pulseIndex ] ;
307
298
startPulseIndex = - 1 ;
299
+
308
300
if ( p . Value == false && p . DurationUsecs >= BurstMarkLengthMin && p . DurationUsecs <= BurstMarkLengthMax )
309
301
{
310
302
startPulseIndex = pulseIndex ;
@@ -315,8 +307,8 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
315
307
// Return a null result if we could not find the start of the train of pulses
316
308
if ( startPulseIndex == - 1 )
317
309
return null ;
318
- else
319
- startPulseIndex += 1 ;
310
+
311
+ startPulseIndex += 1 ;
320
312
321
313
// Verify that the last pulse is a space (1) and and it is a short pulse
322
314
var bits = new BitArray ( MaxBitLength ) ;
@@ -327,8 +319,8 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
327
319
return null ;
328
320
329
321
// preallocate the pulse references
330
- var p1 = default ( InfraredPulse ) ;
331
- var p2 = default ( InfraredPulse ) ;
322
+ InfraredPulse p1 ;
323
+ InfraredPulse p2 ;
332
324
333
325
// parse the bits
334
326
for ( var pulseIndex = startPulseIndex ; pulseIndex < pulses . Length - 1 ; pulseIndex += 2 )
@@ -339,8 +331,8 @@ public static byte[] DecodePulses(InfraredPulse[] pulses)
339
331
p2 = pulses [ pulseIndex + 1 ] ;
340
332
341
333
// 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 ) ;
344
336
345
337
if ( bitCount >= MaxBitLength )
346
338
break ;
@@ -376,7 +368,7 @@ public static bool IsRepeatCode(InfraredPulse[] pulses)
376
368
for ( var pulseIndex = 0 ; pulseIndex < pulses . Length ; pulseIndex ++ )
377
369
{
378
370
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 )
380
372
{
381
373
startPulseIndex = pulseIndex ;
382
374
break ;
@@ -391,16 +383,14 @@ public static bool IsRepeatCode(InfraredPulse[] pulses)
391
383
392
384
// Check the next pulse is a 2.5ms low value
393
385
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 )
395
387
return false ;
396
388
397
389
// Check the next pulse is a 560 microsecond high value
398
390
var p2 = pulses [ startPulseIndex + 2 ] ;
399
- if ( p2 . Value == false || p2 . DurationUsecs . IsBetween ( ShortPulseLengthMin , ShortPulseLengthMax ) == false )
400
- return false ;
401
391
402
392
// All checks passed. Looks like it really is a repeat code
403
- return true ;
393
+ return p2 . Value && p2 . DurationUsecs . IsBetween ( ShortPulseLengthMin , ShortPulseLengthMax ) ;
404
394
}
405
395
}
406
396
@@ -484,7 +474,6 @@ public class InfraredSensorPulseEventArgs : EventArgs
484
474
/// </summary>
485
475
/// <param name="pulse">The pulse.</param>
486
476
internal InfraredSensorPulseEventArgs ( InfraredPulse pulse )
487
- : base ( )
488
477
{
489
478
Value = pulse . Value ;
490
479
DurationUsecs = pulse . DurationUsecs ;
@@ -494,7 +483,6 @@ internal InfraredSensorPulseEventArgs(InfraredPulse pulse)
494
483
/// Prevents a default instance of the <see cref="InfraredSensorPulseEventArgs"/> class from being created.
495
484
/// </summary>
496
485
private InfraredSensorPulseEventArgs ( )
497
- : base ( )
498
486
{
499
487
// placeholder
500
488
}
0 commit comments