-
Notifications
You must be signed in to change notification settings - Fork 585
/
ArduinoAnalogInputPin.cs
89 lines (77 loc) · 3.39 KB
/
ArduinoAnalogInputPin.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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.Device.Analog;
using System.Device.Gpio;
using System.Text;
using UnitsNet;
namespace Iot.Device.Arduino
{
internal class ArduinoAnalogInputPin : AnalogInputPin
{
private readonly SupportedPinConfiguration _configuration;
private int _autoReportingReferenceCount;
private ArduinoBoard _board;
public ArduinoAnalogInputPin(ArduinoBoard board, AnalogController controller, SupportedPinConfiguration configuration,
int pinNumber, ElectricPotential voltageReference)
: base(controller, pinNumber, voltageReference)
{
_board = board;
_configuration = configuration;
}
public override void EnableAnalogValueChangedEvent(GpioController? masterController, int masterPin)
{
// The pin is already open, so analog reporting is enabled, we just need to forward it.
if (_autoReportingReferenceCount == 0)
{
_board.Firmata.AnalogPinValueUpdated += FirmataOnAnalogPinValueUpdated;
}
_autoReportingReferenceCount += 1;
}
public override void DisableAnalogValueChangedEvent()
{
if (_autoReportingReferenceCount == 0)
{
throw new InvalidOperationException("Attempt to disable event when no events are connected");
}
_autoReportingReferenceCount -= 1;
if (_autoReportingReferenceCount == 0)
{
_board.Firmata.AnalogPinValueUpdated -= FirmataOnAnalogPinValueUpdated;
}
}
private void FirmataOnAnalogPinValueUpdated(int channel, uint rawvalue)
{
if (_autoReportingReferenceCount > 0)
{
int physicalPin = Controller.ConvertAnalogChannelNumberToPinNumber(channel);
ElectricPotential voltage = ConvertToVoltage(rawvalue);
var message = new ValueChangedEventArgs(rawvalue, voltage, physicalPin, TriggerReason.Timed);
FireValueChanged(message);
}
}
public override ElectricPotential MinVoltage => ElectricPotential.Zero;
/// <summary>
/// The arduino would theoretically allow for an external analog reference, but firmata currently doesn't support that.
/// </summary>
public override ElectricPotential MaxVoltage => VoltageReference;
/// <summary>
/// The ADC resolution for this pin, as reported by the firmware.
/// </summary>
public override int AdcResolutionBits => _configuration.AnalogInputResolutionBits;
/// <summary>
/// Reads the analog raw value from a given pin.
/// </summary>
/// <returns>The analog raw value of the given pin</returns>
/// <remarks>
/// This returns the last cached value from the board. The board sends regular updates when a value changes,
/// but this does not request an update before returning a value, so that the read value might be incorrect
/// if the analog pin has just been opened.
/// </remarks>
public override uint ReadRaw()
{
return _board.Firmata.GetAnalogRawValue(PinNumber);
}
}
}