/// <summary> /// Searches the given list of com ports for a firmata device. /// </summary> /// <remarks> /// Scanning ports and testing for devices may affect unrelated devices. It is advisable to exclude ports known to contain other hardware from this scan. /// A board won't be found if its port is already open (by the same or a different process). /// </remarks> /// <param name="comPorts">List of com ports. Can be used with <see cref="SerialPort.GetPortNames"/>.</param> /// <param name="baudRates">List of baud rates to test. <see cref="CommonBaudRates"/>.</param> /// <param name="board">[Out] Returns the board reference. It is already initialized.</param> /// <returns>True on success, false if no board was found</returns> public static bool TryFindBoard(IEnumerable <string> comPorts, IEnumerable <int> baudRates, #if !NETCOREAPP2_1 [NotNullWhen(true)] #endif out ArduinoBoard?board) { foreach (var port in comPorts) { foreach (var baud in baudRates) { ArduinoBoard?b = null; try { b = new ArduinoBoard(port, baud); b.Initialize(); board = b; return(true); } catch (Exception x) when(x is NotSupportedException || x is TimeoutException || x is IOException || x is UnauthorizedAccessException) { b?.Dispose(); } } } board = null !; return(false); }
public ArduinoAnalogInputPin(ArduinoBoard board, AnalogController controller, SupportedPinConfiguration configuration, int pinNumber, ElectricPotential voltageReference) : base(controller, pinNumber, voltageReference) { _board = board; _configuration = configuration; }
public ArduinoSpiDevice(ArduinoBoard board, SpiConnectionSettings connectionSettings) { Board = board; ConnectionSettings = connectionSettings; board.EnableSpi(); board.Firmata.ConfigureSpiDevice(connectionSettings); }
/// <summary> /// Tries to connect to an arduino over network. /// This requires an arduino with an ethernet shield or an ESP32 with enabled WIFI support. /// </summary> /// <param name="boardAddress">The IP address of the board</param> /// <param name="port">The network port to use</param> /// <param name="board">Returns the board if successful</param> /// <returns>True on success, false otherwise</returns> public static bool TryConnectToNetworkedBoard(IPAddress boardAddress, int port, #if NET5_0_OR_GREATER [NotNullWhen(true)] #endif out ArduinoBoard?board) { board = null; try { var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(boardAddress, port); socket.NoDelay = true; var networkStream = new NetworkStream(socket, true); board = new ArduinoBoard(networkStream); if (!(board.FirmataVersion > new Version(1, 0))) { // Actually not expecting to get here (but the above will throw a SocketException if the remote end is not there) throw new NotSupportedException("Very old firmware found on board"); } return(true); } catch (SocketException) { return(false); } }
/// <summary> /// Create a PWM Channel on the Arduino. Depending on the board, it has 4-8 pins that support PWM. /// This expects to take the normal pin number (i.e. D6, D9) as input /// </summary> /// <param name="board">Reference to Board</param> /// <param name="chip">Always needs to be 0</param> /// <param name="channel">See above. Valid values depend on the board.</param> /// <param name="frequency">This parameter is ignored and exists only for compatibility</param> /// <param name="dutyCyclePercentage">PWM duty cycle (0 - 1)</param> public ArduinoPwmChannel(ArduinoBoard board, int chip, int channel, int frequency = 400, double dutyCyclePercentage = 0.5) { Chip = chip; if (chip != 0) { throw new NotSupportedException("No such chip: {0}"); } Channel = channel; _pin = channel; var caps = board.SupportedPinConfigurations.FirstOrDefault(x => x.Pin == _pin); if (caps == null || !caps.PinModes.Contains(SupportedMode.Pwm)) { throw new NotSupportedException($"Pin {_pin} does not support PWM"); } _frequency = frequency; _dutyCycle = dutyCyclePercentage; _board = board; _enabled = false; }
public ArduinoAnalogController(ArduinoBoard board, IReadOnlyList <SupportedPinConfiguration> supportedPinConfigurations, PinNumberingScheme scheme) : base(scheme) { _board = board ?? throw new ArgumentNullException(nameof(board)); _supportedPinConfigurations = supportedPinConfigurations ?? throw new ArgumentNullException(nameof(supportedPinConfigurations)); PinCount = _supportedPinConfigurations.Count; // Note: While the Arduino does have an external analog input reference pin, Firmata doesn't allow configuring it. VoltageReference = ElectricPotential.FromVolts(5.0); }
internal ArduinoGpioControllerDriver(ArduinoBoard arduinoBoard, IReadOnlyCollection <SupportedPinConfiguration> supportedPinConfigurations) { _arduinoBoard = arduinoBoard ?? throw new ArgumentNullException(nameof(arduinoBoard)); _supportedPinConfigurations = supportedPinConfigurations ?? throw new ArgumentNullException(nameof(supportedPinConfigurations)); _callbackContainers = new Dictionary <int, CallbackContainer>(); _waitForEventResetEvent = new AutoResetEvent(false); _callbackContainersLock = new object(); _pinModes = new ConcurrentDictionary <int, PinMode>(); PinCount = _supportedPinConfigurations.Count; _arduinoBoard.Firmata.DigitalPortValueUpdated += FirmataOnDigitalPortValueUpdated; }
public ArduinoI2cDevice(ArduinoBoard board, ArduinoI2cBus bus, I2cConnectionSettings connectionSettings) { _board = board ?? throw new ArgumentNullException(nameof(board)); _bus = bus ?? throw new ArgumentNullException(nameof(bus)); if (connectionSettings == null) { throw new ArgumentNullException(nameof(connectionSettings)); } if (connectionSettings.BusId != 0) { throw new NotSupportedException("Only I2C Bus 0 is supported"); } if (connectionSettings.DeviceAddress > 127) { throw new NotSupportedException("The device address must be less than 128."); } ConnectionSettings = connectionSettings; // Ensure the corresponding pins are set to I2C (not strictly necessary, but consistent) foreach (SupportedPinConfiguration supportedPinConfiguration in _board.SupportedPinConfigurations.Where(x => x.PinModes.Contains(SupportedMode.I2c))) { _board.Firmata.SetPinMode(supportedPinConfiguration.Pin, SupportedMode.I2c); } _board.Firmata.SendI2cConfigCommand(); // Sometimes, the very first I2C command fails (nothing happens), so try reading a byte int retries = 3; while (retries-- > 0) { try { ReadByte(); break; } catch (Exception x) when(x is TimeoutException || x is IOException) { } } // If the above still failed, there's probably no device on the other end. But this shall not throw here but only if // the client calls ReadByte. }
/// <summary> /// This is internally called when the command handler is registered /// </summary> internal void Registered(FirmataDevice firmata, ArduinoBoard board) { _firmata = firmata; _board = board; _firmata.OnSysexReply += OnSysexDataInternal; }
public ArduinoI2cBus(ArduinoBoard board, int busId) { _board = board; _busId = busId; _usedAddresses = new HashSet <int>(); }