/// <summary> /// Connects to the specified serial port and sends the observable sequence of Harp messages. /// The return value is an observable sequence of Harp messages coming from the device. /// </summary> /// <param name="source">An observable sequence of Harp messages to send to the device.</param> /// <returns>The observable sequence of Harp messages produced by the device.</returns> public IObservable <HarpMessage> Generate(IObservable <HarpMessage> source) { return(Observable.Create <HarpMessage>(observer => { var transport = new SerialTransport(PortName, observer); transport.IgnoreErrors = IgnoreErrors; transport.Open(); var writeOpCtrl = HarpCommand.OperationControl(DeviceState, LedState, VisualIndicators, Heartbeat, CommandReplies, DumpRegisters); transport.Write(writeOpCtrl); var sourceDisposable = new SingleAssignmentDisposable(); sourceDisposable.Disposable = source.Subscribe( transport.Write, observer.OnError, observer.OnCompleted); var cleanup = Disposable.Create(() => { writeOpCtrl = HarpCommand.OperationControl(DeviceState.Standby, LedState, VisualIndicators, Heartbeat, CommandReplies, false); transport.Write(writeOpCtrl); }); return new CompositeDisposable( cleanup, sourceDisposable, transport); })); }
/// <summary> /// Asynchronously reads the display name of the device. /// </summary> /// <returns> /// A task that represents the asynchronous read operation. The value of the <see cref="Task{TResult}.Result"/> /// parameter contains the name of the device. /// </returns> public async Task <string> ReadDeviceNameAsync() { var deviceName = await CommandAsync(HarpCommand.ReadByte(Registers.DeviceName)); var namePayload = deviceName.GetPayload(); var count = Array.IndexOf(namePayload.Array, (byte)0, namePayload.Offset, namePayload.Count) - namePayload.Offset; return(Encoding.ASCII.GetString(namePayload.Array, namePayload.Offset, count)); }
/// <summary> /// Initializes a new instance of the <see cref="AsyncDevice"/> class on /// the specified port. /// </summary> /// <param name="portName">The name of the serial port used to communicate with the Harp device.</param> public AsyncDevice(string portName) { response = new Subject <HarpMessage>(); transport = new SerialTransport(portName, response); transport.IgnoreErrors = true; transport.Open(); transport.Write(HarpCommand.OperationControl( DeviceState.Standby, LedState.On, LedState.On, EnableType.Disable, EnableType.Enable, false)); }
/// <summary> /// Connects to the specified serial port and returns an observable sequence of Harp messages /// coming from the device. /// </summary> /// <returns>The observable sequence of Harp messages produced by the device.</returns> public override IObservable <HarpMessage> Generate() { return(Observable.Create <HarpMessage>(observer => { var transport = new SerialTransport(PortName, observer); transport.IgnoreErrors = IgnoreErrors; transport.Open(); var writeOpCtrl = HarpCommand.OperationControl(DeviceState, LedState, VisualIndicators, Heartbeat, CommandReplies, DumpRegisters); transport.Write(writeOpCtrl); var cleanup = Disposable.Create(() => { writeOpCtrl = HarpCommand.OperationControl(DeviceState.Standby, LedState, VisualIndicators, Heartbeat, CommandReplies, false); transport.Write(writeOpCtrl); }); return new CompositeDisposable( cleanup, transport); })); }
/// <summary> /// Asynchronously writes a value, or an array of values, to a single-precision floating point register with /// the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="values">The values to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteSingleAsync(int address, params float[] values) => await CommandAsync(HarpCommand.WriteSingle(address, values));
/// <summary> /// Asynchronously writes an array of values to a 64-bit signed integer register with /// the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="values">The values to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteInt64Async(int address, params long[] values) => await CommandAsync(HarpCommand.WriteInt64(address, values));
/// <summary> /// Asynchronously writes a value to a 64-bit signed integer register /// with the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="value">The value to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteInt64Async(int address, long value) => await CommandAsync(HarpCommand.WriteInt64(address, value));
/// <summary> /// Asynchronously writes an array of values to a 32-bit signed integer register with /// the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="values">The values to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteInt32Async(int address, params int[] values) => await CommandAsync(HarpCommand.WriteInt32(address, values));
/// <summary> /// Asynchronously reads the value of a 32-bit signed integer register with /// the specified address. /// </summary> /// <param name="address">The address of the register to read.</param> /// <returns> /// A task that represents the asynchronous read operation. The value of the <see cref="Task{TResult}.Result"/> /// parameter contains the value of the register. /// </returns> public async Task <int> ReadInt32Async(int address) { var reply = await CommandAsync(HarpCommand.ReadInt32(address)); return(reply.GetPayloadInt32()); }
/// <summary> /// Asynchronously writes a value to a 16-bit signed integer register /// with the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="value">The value to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteInt16Async(int address, short value) => await CommandAsync(HarpCommand.WriteInt16(address, value));
/// <summary> /// Asynchronously writes an array of values to an 8-bit signed integer register with /// the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="values">The values to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteSByteAsync(int address, params sbyte[] values) => await CommandAsync(HarpCommand.WriteSByte(address, values));
/// <summary> /// Asynchronously writes a value to an 8-bit signed integer register /// with the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="value">The value to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteSByteAsync(int address, sbyte value) => await CommandAsync(HarpCommand.WriteSByte(address, value));
/// <summary> /// Asynchronously reads the value of a single-precision floating point register with /// the specified address. /// </summary> /// <param name="address">The address of the register to read.</param> /// <returns> /// A task that represents the asynchronous read operation. The value of the <see cref="Task{TResult}.Result"/> /// parameter contains the value of the register. /// </returns> public async Task <float> ReadSingleAsync(int address) { var reply = await CommandAsync(HarpCommand.ReadSingle(address)); return(reply.GetPayloadSingle()); }
/// <summary> /// Asynchronously reads the value of a 64-bit signed integer register with /// the specified address. /// </summary> /// <param name="address">The address of the register to read.</param> /// <returns> /// A task that represents the asynchronous read operation. The value of the <see cref="Task{TResult}.Result"/> /// parameter contains the value of the register. /// </returns> public async Task <long> ReadInt64Async(int address) { var reply = await CommandAsync(HarpCommand.ReadInt64(address)); return(reply.GetPayloadInt64()); }
/// <summary> /// Asynchronously reads the value of an 8-bit unsigned integer register with /// the specified address. /// </summary> /// <param name="address">The address of the register to read.</param> /// <returns> /// A task that represents the asynchronous read operation. The value of the <see cref="Task{TResult}.Result"/> /// parameter contains the value of the register. /// </returns> public async Task <byte> ReadByteAsync(int address) { var reply = await CommandAsync(HarpCommand.ReadByte(address)); return(reply.GetPayloadByte()); }
static IObservable <string> GetDeviceName(string portName, LedState ledState, LedState visualIndicators, EnableType heartbeat) { return(Observable.Create <string>(observer => { var transport = default(SerialTransport); var writeOpCtrl = HarpCommand.OperationControl(DeviceState.Standby, ledState, visualIndicators, heartbeat, EnableType.Enable, false); var cmdReadWhoAmI = HarpCommand.ReadUInt16(Registers.WhoAmI); var cmdReadMajorHardwareVersion = HarpCommand.ReadByte(Registers.HardwareVersionHigh); var cmdReadMinorHardwareVersion = HarpCommand.ReadByte(Registers.HardwareVersionLow); var cmdReadMajorFirmwareVersion = HarpCommand.ReadByte(Registers.FirmwareVersionHigh); var cmdReadMinorFirmwareVersion = HarpCommand.ReadByte(Registers.FirmwareVersionLow); var cmdReadTimestampSeconds = HarpCommand.ReadUInt32(Registers.TimestampSecond); var cmdReadDeviceName = HarpCommand.ReadByte(Registers.DeviceName); var cmdReadSerialNumber = HarpCommand.ReadUInt16(Registers.SerialNumber); var whoAmI = 0; var timestamp = 0u; var hardwareVersionHigh = 0; var hardwareVersionLow = 0; var firmwareVersionHigh = 0; var firmwareVersionLow = 0; var serialNumber = default(ushort?); var messageObserver = Observer.Create <HarpMessage>( message => { switch (message.Address) { case Registers.OperationControl: transport.Write(cmdReadWhoAmI); transport.Write(cmdReadMajorHardwareVersion); transport.Write(cmdReadMinorHardwareVersion); transport.Write(cmdReadMajorFirmwareVersion); transport.Write(cmdReadMinorFirmwareVersion); transport.Write(cmdReadTimestampSeconds); transport.Write(cmdReadSerialNumber); transport.Write(cmdReadDeviceName); break; case Registers.WhoAmI: whoAmI = message.GetPayloadUInt16(); break; case Registers.HardwareVersionHigh: hardwareVersionHigh = message.GetPayloadByte(); break; case Registers.HardwareVersionLow: hardwareVersionLow = message.GetPayloadByte(); break; case Registers.FirmwareVersionHigh: firmwareVersionHigh = message.GetPayloadByte(); break; case Registers.FirmwareVersionLow: firmwareVersionLow = message.GetPayloadByte(); break; case Registers.TimestampSecond: timestamp = message.GetPayloadUInt32(); break; case Registers.SerialNumber: if (!message.Error) { serialNumber = message.GetPayloadUInt16(); } break; case Registers.DeviceName: var deviceName = nameof(Device); if (!message.Error) { var namePayload = message.GetPayload(); deviceName = Encoding.ASCII.GetString(namePayload.Array, namePayload.Offset, namePayload.Count); } Console.WriteLine("Serial Harp device."); if (!serialNumber.HasValue) { Console.WriteLine($"WhoAmI: {whoAmI}"); } else { Console.WriteLine($"WhoAmI: {whoAmI}-{serialNumber:x4}"); } Console.WriteLine($"Hw: {hardwareVersionHigh}.{hardwareVersionLow}"); Console.WriteLine($"Fw: {firmwareVersionHigh}.{firmwareVersionLow}"); Console.WriteLine($"Timestamp (s): {timestamp}"); Console.WriteLine($"DeviceName: {deviceName}"); Console.WriteLine(); observer.OnNext(deviceName); observer.OnCompleted(); break; default: break; } }, observer.OnError, observer.OnCompleted); transport = new SerialTransport(portName, messageObserver); transport.IgnoreErrors = true; transport.Open(); transport.Write(writeOpCtrl); return transport; }).Timeout(TimeSpan.FromMilliseconds(500)) .OnErrorResumeNext(Observable.Return(nameof(Device))) .SubscribeOn(Scheduler.Default) .FirstAsync()); }
/// <summary> /// Asynchronously writes an array of values to a 16-bit signed integer register with /// the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="values">The values to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteInt16Async(int address, params short[] values) => await CommandAsync(HarpCommand.WriteInt16(address, values));
/// <summary> /// Asynchronously writes a value to a 32-bit signed integer register /// with the specified address. /// </summary> /// <param name="address">The address of the register to write.</param> /// <param name="value">The value to be stored in the register.</param> /// <returns> /// The task object representing the asynchronous write operation. /// </returns> public async Task WriteInt32Async(int address, int value) => await CommandAsync(HarpCommand.WriteInt32(address, value));
/// <summary> /// Asynchronously reads the value of a 16-bit unsigned integer register with /// the specified address. /// </summary> /// <param name="address">The address of the register to read.</param> /// <returns> /// A task that represents the asynchronous read operation. The value of the <see cref="Task{TResult}.Result"/> /// parameter contains the value of the register. /// </returns> public async Task <ushort> ReadUInt16Async(int address) { var reply = await CommandAsync(HarpCommand.ReadUInt16(address)); return(reply.GetPayloadUInt16()); }