/// <summary> /// 启动步进电机(绝对移动) /// 根据从零位置开始的步数将步进器移动到所需位置。位置指定为32位带符号的长整数。 /// </summary> /// <param name="session"></param> public static void StepperMoveTo(this ArduinoSession session, int deviceNumber, int stepsNum) { if (deviceNumber < 0 || deviceNumber > 9) { throw new ArgumentOutOfRangeException(nameof(deviceNumber), "Device number must be between 0 and 9."); } var bytes = stepsNum.encode32BitSignedInteger(); var command = new[] { Utility.SysExStart, ACCELSTEPPER_DATA, //ACCELSTEPPER_DATA(0x62) ACCELSTEPPER_TO, //to command(0x03) //ACCELSTEPPER_TO (byte)deviceNumber, //device number(0-9) (Supports up to 10 motors) bytes[0], //4 num steps, bits 0-6 bytes[1], //5 num steps, bits 7-13 bytes[2], //6 num steps, bits 14-20 bytes[3], //7 num steps, bits 21-27 bytes[4], //8 num steps, bits 28-32 Utility.SysExEnd }; session.Write(command, 0, command.Length); }
public static void SerialRead(this ArduinoSession session, HW_SERIAL hw, bool continuously = true, int?maxBytesToRead = null) { var command = new byte[14]; command[0] = Utility.SysExStart; command[1] = SERIAL_MESSAGE; command[2] = (byte)(SERIAL_READ | (int)hw); //SERIAL_READ //OR with port (0x31 = SERIAL_READ | HW_SERIAL1) command[3] = continuously ? (byte)0x00 : (byte)0x01; //SERIAL_READ_MODE 0x00 => read continuously, 0x01 => stop reading if (maxBytesToRead.HasValue) { if (maxBytesToRead.Value >= 32767) { throw new ArgumentOutOfRangeException(nameof(maxBytesToRead), "不能大于32767"); } var bytes = maxBytesToRead.Value.encode32BitSignedInteger(); command[4] = bytes[0]; command[5] = bytes[1]; command[6] = Utility.SysExEnd; } else { command[4] = Utility.SysExEnd; } session.Write(command, 0, maxBytesToRead.HasValue ? 6 : 4); }
/// <summary> /// 根据从其零位置开始的步数将组中的每个步进器设置到所需位置。位置被指定为32位带符号的长整数。 /// 步进运动将被协调,以便所有人都同时到达其所需位置。根据位置变化和步进器的最大速度,此移动的持续时间取决于哪个步进器将花费最长的时间。 /// </summary> /// <param name="session"></param> /// <param name="deviceNumber"></param> /// <param name="stepsNum"></param> public static void MultiStepperMoveTo(this ArduinoSession session, int groupNumber, int stepsNum) { if (groupNumber < 0 || groupNumber > 4) { throw new ArgumentOutOfRangeException(nameof(groupNumber), "Group number must be between 0 and 4."); } var bytes = stepsNum.encode32BitSignedInteger(); var command = new[] { Utility.SysExStart, ACCELSTEPPER_DATA, //ACCELSTEPPER_DATA(0x62) MULTISTEPPER_TO, //multi to command(0x21) //MULTISTEPPER_TO (byte)groupNumber, //group number(0-4) bytes[0], //4 num steps, bits 0-6 bytes[1], //5 num steps, bits 7-13 bytes[2], //6 num steps, bits 14-20 bytes[3], //7 num steps, bits 21-27 bytes[4], //8 num steps, bits 28-32 Utility.SysExEnd }; session.Write(command, 0, command.Length); }
public static void Request_EEPROM_Get(this ArduinoSession session, int index, int length) { if (length <= 0) { throw new ArgumentOutOfRangeException(nameof(length), "length 必须大于0"); } var indexBytes = index.encode32BitSignedInteger(); var lengthBytes = length.encode32BitSignedInteger(); var command = new[] { Utility.SysExStart, EEPROM_DATA, EEPROM_GET, indexBytes[0], //4 num steps, bits 0-6 indexBytes[1], //5 num steps, bits 7-13 indexBytes[2], //6 num steps, bits 14-20 indexBytes[3], //7 num steps, bits 21-27 indexBytes[4], //8 num steps, bits 28-32 lengthBytes[0], //4 num steps, bits 0-6 lengthBytes[1], //5 num steps, bits 7-13 lengthBytes[2], //6 num steps, bits 14-20 lengthBytes[3], //7 num steps, bits 21-27 lengthBytes[4], //8 num steps, bits 28-32 Utility.SysExEnd }; session.Write(command, 0, command.Length); }
public static void Request_EEPROM_Put(this ArduinoSession session, int index, byte[] bytes) { if (bytes == null || bytes.Length <= 0) { throw new ArgumentOutOfRangeException(nameof(bytes), "bytes 不能为空且长度必须大于0"); } var indexBytes = index.encode32BitSignedInteger(); var encoder7Bytes = ByteArrayExtensions.Encoder7Bit(bytes); var command = new List <byte> { Utility.SysExStart, EEPROM_DATA, EEPROM_PUT, indexBytes[0], //4 num steps, bits 0-6 indexBytes[1], //5 num steps, bits 7-13 indexBytes[2], //6 num steps, bits 14-20 indexBytes[3], //7 num steps, bits 21-27 indexBytes[4], //8 num steps, bits 28-32 //(byte)white, //Utility.SysExEnd }; command.AddRange(encoder7Bytes); command.Add(Utility.SysExEnd); session.Write(command.ToArray(), 0, command.Count); }
private static void I2CRead(this ArduinoSession session, bool continuous, int slaveAddress, int slaveRegister = -1, int bytesToRead = 0) { if (slaveAddress < 0 || slaveAddress > 0x3FF) { throw new ArgumentOutOfRangeException(nameof(slaveAddress), Messages.ArgumentEx_I2cAddressRange); } if (bytesToRead < 0 || bytesToRead > 0x3FFF) { throw new ArgumentOutOfRangeException(nameof(bytesToRead), Messages.ArgumentEx_ValueRange0_16383); } byte[] command = new byte[(slaveRegister == -1 ? 7 : 9)]; command[0] = Utility.SysExStart; command[1] = 0x76; command[2] = (byte)(slaveAddress & 0x7F); command[3] = (byte)(((slaveAddress >> 7) & 0x07) | (slaveAddress < 128 ? (continuous ? 0x10 : 0x08) : (continuous ? 0x30 : 0x28))); if (slaveRegister != -1) { command[4] = (byte)(slaveRegister & 0x7F); command[5] = (byte)(slaveRegister >> 7); command[6] = (byte)(bytesToRead & 0x7F); command[7] = (byte)(bytesToRead >> 7); } else { command[4] = (byte)(bytesToRead & 0x7F); command[5] = (byte)(bytesToRead >> 7); } command[command.Length - 1] = Utility.SysExEnd; session.Write(command, 0, command.Length); }
/// <summary> /// 可以将使用上述stepper configuration命令创建的Stepper实例添加到multiStepper组。可以通过单个命令向组发送设备/位置列表,并且将协调它们的移动以同时开始和结束。请注意,multiStepper不支持加速或减速。 /// </summary> /// <param name="session"></param> /// <param name="groupNumber"></param> /// <param name="deviceNumbers"></param> public static void MultiStepperConfiguration(this ArduinoSession session, int groupNumber, params int[] deviceNumbers) { if (groupNumber < 0 || groupNumber > 4) { throw new ArgumentOutOfRangeException(nameof(groupNumber), "Group number must be between 0 and 4."); } if (deviceNumbers == null) { throw new ArgumentNullException(nameof(deviceNumbers)); } if (deviceNumbers.Length <= 2) { throw new ArgumentOutOfRangeException(nameof(deviceNumbers), "驱动器数量必须大于等于2位"); } foreach (var deviceNumber in deviceNumbers) { if (deviceNumber < 0 || deviceNumber > 9) { throw new ArgumentOutOfRangeException(nameof(deviceNumber), "Device number must be between 0 and 9."); } } var command = new List <byte> { Utility.SysExStart, ACCELSTEPPER_DATA, //ACCELSTEPPER_DATA(0x62) MULTISTEPPER_CONFIG, //config command(0x00 = config) //ACCELSTEPPER_CONFIG (byte)groupNumber, //device number(0-9) (Supports up to 10 motors) //Utility.SysExEnd }; command.AddRange(deviceNumbers.Select(f => (byte)f)); command.Add(Utility.SysExEnd); session.Write(command.ToArray(), 0, command.Count); }
public const byte ENCODER_DATA = 0x61; // ENCODER_DATA(0x61) public static void 附加编码器(this ArduinoSession session, int encoderNumber, int encoderPinA, int encoderPinB) { if (encoderNumber < 0 || encoderNumber > 5) { throw new ArgumentOutOfRangeException(nameof(encoderNumber), "Encoder number must be between 0 and 5."); } if (encoderPinA < 0 || encoderPinA > 127) { throw new ArgumentOutOfRangeException(nameof(encoderPinA), "Pin number must be between 0 and 127."); } if (encoderPinB < 0 || encoderPinB > 127) { throw new ArgumentOutOfRangeException(nameof(encoderPinB), "Pin number must be between 0 and 127."); } var command = new[] { Utility.SysExStart, ENCODER_DATA, //ENCODER_DATA(0x61) (byte)0x00, //ENCODER_ATTACH(0x00) (byte)encoderNumber, //encoder # ([0 - MAX_ENCODERS-1]) (byte)encoderPinA, //4 pin A #(first pin) (byte)encoderPinB, //5 pin B #(second pin) Utility.SysExEnd }; session.Write(command, 0, command.Length); }
/// <summary> /// Sets a HI or LO value on a digital output pin. /// </summary> /// <param name="pinNumber">The pin number</param> /// <param name="value">The value (<c>false</c> = Low, <c>true</c> = High)</param> public static void SetDigitalPin(this ArduinoSession session, int pinNumber, bool value) { if (pinNumber < 0 || pinNumber > 127) { throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127); } session.Write(new[] { SetDigitalPinValue, (byte)pinNumber, (byte)(value ? 1 : 0) }); }
/// <summary> /// Sets a pin's mode (digital input/digital output/analog/PWM/servo etc.). /// </summary> /// <param name="pinNumber">The number of the pin</param> /// <param name="mode">The pin's mode</param> public static void SetDigitalPinMode(this ArduinoSession session, int pinNumber, PinMode mode) { if (pinNumber < 0 || pinNumber > 127) { throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127); } session.Write(new byte[] { SetPinModeIO, (byte)pinNumber, (byte)mode }); }
/// <summary> /// Enables or disables digital input pin reporting for the given port. /// </summary> /// <param name="portNumber">The number of the port</param> /// <param name="enable"><c>true</c> if enabled, otherwise <c>false</c></param> /// <remarks> /// When enabled, the party system is expected to return digital I/O messages (0x90) /// for the given port. /// <para> /// Note: as for Firmata version 2.3 digital I/O messages are only returned when /// at least one digital input pin's state has changed from high to low or vice versa. /// </para> /// </remarks> public static void SetDigitalReportMode(this ArduinoSession session, int portNumber, bool enable) { if (portNumber < 0 || portNumber > 15) { throw new ArgumentOutOfRangeException(nameof(portNumber), Messages.ArgumentEx_PortRange0_15); } session.Write(new[] { (byte)(ReportDigitalPort | portNumber), (byte)(enable ? 1 : 0) }, 0, 2); }
/// <summary> /// Enables or disables analog sampling reporting. /// </summary> /// <param name="channel">The channel attached to the analog pin</param> /// <param name="enable"><c>True</c> if enabled, otherwise <c>false</c></param> /// <remarks> /// When enabled, the party system is expected to return analog I/O messages (0xE0) /// for the given channel. The frequency at which these messages are returned can /// be controlled by method <see cref="SetSamplingInterval"/>. /// </remarks> public static void SetAnalogReportMode(this ArduinoSession session, int channel, bool enable) { if (channel < 0 || channel > 15) { throw new ArgumentOutOfRangeException(nameof(channel), Messages.ArgumentEx_ChannelRange0_15); } session.Write(new[] { (byte)(ReportAnalogPin | channel), (byte)(enable ? 1 : 0) }, 0, 2); }
/// <summary> /// Sets an analog value on a PWM or Servo enabled analog output pin. /// </summary> /// <param name="pinNumber">The pin number.</param> /// <param name="value">The value</param> public static void SetDigitalPin(this ArduinoSession session, int pinNumber, long value) { if (pinNumber < 0 || pinNumber > 127) { throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127); } if (value < 0) { throw new ArgumentOutOfRangeException(nameof(value), Messages.ArgumentEx_NoNegativeValue); } byte[] message; if (pinNumber < 16 && value < 0x4000) { // Send value in a conventional Analog Message. message = new[] { (byte)(AnalogMessage | pinNumber), (byte)(value & 0x7F), (byte)((value >> 7) & 0x7F) }; session.Write(message); return; } // Send long value in an Extended Analog Message. message = new byte[14]; message[0] = Utility.SysExStart; message[1] = EXTENDED_ANALOG; message[2] = (byte)pinNumber; int index = 3; do { message[index] = (byte)(value & 0x7F); value >>= 7; index++; } while (value > 0 || index < 5); message[index] = Utility.SysExEnd; session.Write(message, 0, index + 1); }
public static void SerialListen(this ArduinoSession session, SW_SERIAL sw) { var command = new[] { Utility.SysExStart, SERIAL_MESSAGE, (byte)(SERIAL_LISTEN | (int)sw),//OR with port to switch to (0x79 = switch to SW_SERIAL1) Utility.SysExEnd }; session.Write(command); }
public static void SerialClose(this ArduinoSession session, HW_SERIAL hw) { var command = new[] { Utility.SysExStart, SERIAL_MESSAGE, (byte)(SERIAL_CLOSE | (int)hw),//SERIAL_CLOSE // OR with port (0x51 = SERIAL_CLOSE | HW_SERIAL1) Utility.SysExEnd }; session.Write(command); }
/// <summary> /// Commands the party system to stop sending I2C_REPLY messages. /// </summary> public static void StopI2CReading(this ArduinoSession session) { byte[] command = new byte[5]; command[0] = Utility.SysExStart; command[1] = 0x76; command[2] = 0x00; command[3] = 0x18; command[4] = Utility.SysExEnd; session.Write(command, 0, command.Length); }
public static void SendSysExCommand(this ArduinoSession session, byte command) { var message = new[] { Utility.SysExStart, command, Utility.SysExEnd }; session.Write(message); }
public static void SerialFlush(this ArduinoSession session, HW_SERIAL hw) { var command = new[] { Utility.SysExStart, SERIAL_MESSAGE, (byte)(SERIAL_FLUSH | (int)hw),//SERIAL_FLUSH OR with port (0x61 = SERIAL_FLUSH | HW_SERIAL1) Utility.SysExEnd }; session.Write(command); }
private static void Request_EEPROM_Length(this ArduinoSession session) { var command = new[] { Utility.SysExStart, EEPROM_DATA, EEPROM_LENGTH, Utility.SysExEnd }; session.Write(command, 0, command.Length); }
/// <summary> /// Sets the digital output pins of a given port LOW or HIGH. /// </summary> /// <param name="portNumber">The 0-based port number</param> /// <param name="pins">Binary value for the port's pins (0 to 7)</param> /// <remarks> /// A binary 1 sets the digital output pin HIGH (+5 or +3.3 volts). /// A binary 0 sets the digital output pin LOW. /// <para> /// The Arduino operates with 8-bit ports, so only bits 0 to 7 of the pins parameter are mapped. /// Higher bits are ignored. /// </para> /// <example> /// For port 0 bit 2 maps to the Arduino Uno's pin 2. /// For port 1 bit 2 maps to pin 10. /// /// The complete mapping of port 1 of the Arduino Uno looks like this: /// <list type=""> /// <item>bit 0: pin 8</item> /// <item>bit 1: pin 9</item> /// <item>bit 2: pin 10</item> /// <item>bit 3: pin 11</item> /// <item>bit 4: pin 12</item> /// <item>bit 5: pin 13</item> /// <item>bit 6: not mapped</item> /// <item>bit 7: not mapped</item> /// </list> /// </example> /// </remarks> public static void SetDigitalPort(this ArduinoSession session, int portNumber, int pins) { if (portNumber < 0 || portNumber > 15) { throw new ArgumentOutOfRangeException(nameof(portNumber), Messages.ArgumentEx_PortRange0_15); } if (pins < 0 || pins > 0xFF) { throw new ArgumentOutOfRangeException(nameof(pins), Messages.ArgumentEx_ValueRange0_255); } session.Write(new[] { (byte)(DigitalMessage | portNumber), (byte)(pins & 0x7F), (byte)((pins >> 7) & 0x03) }, 0, 3); }
public static void SerialWrite(this ArduinoSession session, HW_SERIAL hw, byte[] value) { var b = value.To14BitIso(); var command = new byte[b.Length + 4]; command[0] = Utility.SysExStart; command[1] = SERIAL_MESSAGE; command[2] = (byte)(SERIAL_WRITE | (int)hw);//SERIAL_WRITE //OR with port (0x21 = SERIAL_WRITE | HW_SERIAL1) b.CopyTo(command, 3); command[command.Length - 1] = Utility.SysExEnd; session.Write(command); }
/// <summary> /// Requests the party system to send the state of a given pin. /// </summary> /// <param name="pinNumber">The pin number</param> /// <remarks> /// The party system is expected to return a single SYSEX PINSTATE_RESPONSE message. /// This message triggers the <see cref="MessageReceived"/> event. The pin state /// is passed in the <see cref="FirmataMessageEventArgs"/> in a <see cref="PinState"/> object. /// </remarks> internal static void RequestPinState(this ArduinoSession session, int pinNumber) { if (pinNumber < 0 || pinNumber > 127) { throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127); } var command = new[] { Utility.SysExStart, PIN_STATE_QUERY, (byte)pinNumber, Utility.SysExEnd }; session.Write(command); }
/// <summary> /// Sends a SysEx message. /// </summary> /// <param name="message"></param> public static void SendSysEx(this ArduinoSession session, byte command, byte[] payload) { if (payload == null || payload.Length == 0) { session.SendSysExCommand(command); return; } var message = new byte[3 + payload.Length]; message[0] = Utility.SysExStart; message[1] = command; Array.Copy(payload, 0, message, 2, payload.Length); message[message.Length - 1] = Utility.SysExEnd; session.Write(message); }
/// <summary> /// 立即停止组中的所有步进器。 /// </summary> /// <param name="session"></param> /// <param name="groupNumber"></param> /// <param name="stepsNum"></param> public static void MultiStepperStop(this ArduinoSession session, int groupNumber) { if (groupNumber < 0 || groupNumber > 4) { throw new ArgumentOutOfRangeException(nameof(groupNumber), "Group number must be between 0 and 4."); } var command = new[] { Utility.SysExStart, ACCELSTEPPER_DATA, //ACCELSTEPPER_DATA(0x62) MULTISTEPPER_STOP, //multi stop command(0x23) //MULTISTEPPER_STOP (byte)groupNumber, //group number(0-4) Utility.SysExEnd }; session.Write(command, 0, command.Length); }
/// <summary> /// Sets the frequency at which analog samples must be reported. /// </summary> /// <param name="milliseconds">The sampling interval in milliseconds</param> public static void SetSamplingInterval(this ArduinoSession session, int milliseconds) { if (milliseconds < 0 || milliseconds > 0x3FFF) { throw new ArgumentOutOfRangeException(nameof(milliseconds), Messages.ArgumentEx_SamplingInterval); } var command = new[] { Utility.SysExStart, SAMPLING_INTERVAL, (byte)(milliseconds & 0x7F), (byte)((milliseconds >> 7) & 0x7F), Utility.SysExEnd }; session.Write(command, 0, 5); }
/// <summary> /// 步进停止 /// 停止步进电机。在结果STEPPER_MOVE_COMPLETE被发送到客户端与电机的位置时停止完成注:如果加速设置,停止将不会立竿见影。 /// </summary> /// <param name="session"></param> /// <param name="deviceNumber"></param> public static void StepperStop(this ArduinoSession session, int deviceNumber) { if (deviceNumber < 0 || deviceNumber > 9) { throw new ArgumentOutOfRangeException(nameof(deviceNumber), "Device number must be between 0 and 9."); } var command = new[] { Utility.SysExStart, ACCELSTEPPER_DATA, //ACCELSTEPPER_DATA(0x62) ACCELSTEPPER_STOP, //stop command(0x05) //ACCELSTEPPER_STOP (byte)deviceNumber, //device number(0-9) (Supports up to 10 motors) Utility.SysExEnd }; session.Write(command, 0, command.Length); }
///// <summary> ///// 当限制销(数字)设置为限制状态时,将无法沿该方向移动 ///// </summary> ///// <param name="session"></param> ///// <param name="deviceNumber"></param> ///// <param name="speed"></param> //public static void 步进极限_尚未实现(this ArduinoSession session, int deviceNumber, float speed) //{ // throw new NotSupportedException(); // // if (deviceNumber < 0 || deviceNumber > 9) // // throw new ArgumentOutOfRangeException(nameof(deviceNumber), "Device number must be between 0 and 9."); // // var bytes = encodeCustomFloat(speed); // // var command = new[] // // { // // Utility.SysExStart, // // ACCELSTEPPER_DATA,//ACCELSTEPPER_DATA(0x62) // // ACCELSTEPPER_LIMIT,//stop limit command(0x07) // // (byte)deviceNumber,//device number(0-9) (Supports up to 10 motors) // //// 4 lower limit pin number (0-127) // //// 5 lower limit state (0x00 | 0x01) // //// 6 upper limit pin number (0-127) // //// 7 upper limit state (0x00 | 0x01) // // Utility.SysExEnd // // }; // // session.Write(command, 0, command.Length); //} public static void RequestReportPosition(this ArduinoSession session, int deviceNumber) { if (deviceNumber < 0 || deviceNumber > 9) { throw new ArgumentOutOfRangeException(nameof(deviceNumber), "Device number must be between 0 and 9."); } var command = new[] { Utility.SysExStart, ACCELSTEPPER_DATA, //ACCELSTEPPER_DATA(0x62) ACCELSTEPPER_REPORT_POSITION, //report position command(0x06) //ACCELSTEPPER_REPORT_POSITION (byte)deviceNumber, //device number(0-9) (Supports up to 10 motors) Utility.SysExEnd }; session.Write(command, 0, command.Length); }
/// <summary> /// Sets the frequency at which data is read in the continuous mode. /// </summary> /// <param name="microseconds">The interval, expressed in microseconds</param> public static void SetI2CReadInterval(this ArduinoSession session, int microseconds) { if (microseconds < 0 || microseconds > 0x3FFF) { throw new ArgumentOutOfRangeException(nameof(microseconds), Messages.ArgumentEx_I2cInterval); } var command = new[] { Utility.SysExStart, (byte)0x78, (byte)(microseconds & 0x7F), (byte)((microseconds >> 7) & 0x7F), Utility.SysExEnd }; session.Write(command, 0, 5); }
/// <summary> /// 步进使能 /// 对于配置了使能引脚的步进电机控制器,使能命令管理控制器是否将电压传递给电机。步进电机闲置时,仍会消耗电压,因此,如果步进电机不需要保持其位置,请启用以节省功率。 /// </summary> /// <param name="session"></param> /// <param name="deviceNumber"></param> public static void StepperEnable(this ArduinoSession session, int deviceNumber, bool enable) { if (deviceNumber < 0 || deviceNumber > 9) { throw new ArgumentOutOfRangeException(nameof(deviceNumber), "Device number must be between 0 and 9."); } var command = new[] { Utility.SysExStart, ACCELSTEPPER_DATA, //ACCELSTEPPER_DATA(0x62) ACCELSTEPPER_ENABLE, //enable command(0x04) //ACCELSTEPPER_ENABLE (byte)deviceNumber, //device number(0-9) (Supports up to 10 motors) (byte)(enable ? 1 : 0), //device state(HIGH : enabled | LOW : disabled) Utility.SysExEnd }; session.Write(command, 0, command.Length); }
private static void Request_EEPROM_Read(this ArduinoSession session, int index) { var bytes = index.encode32BitSignedInteger(); var command = new[] { Utility.SysExStart, EEPROM_DATA, EEPROM_READ, bytes[0], //4 num steps, bits 0-6 bytes[1], //5 num steps, bits 7-13 bytes[2], //6 num steps, bits 14-20 bytes[3], //7 num steps, bits 21-27 bytes[4], //8 num steps, bits 28-32 Utility.SysExEnd }; session.Write(command, 0, command.Length); }