/** * Setup all of the configuration parameters. */ public void SetupConfig() { /* Factory Default all hardware to prevent unexpected behaviour */ _talon.ConfigFactoryDefault(); /* specify sensor characteristics */ _talon.ConfigSelectedFeedbackSensor(FeedbackDevice.CTRE_MagEncoder_Relative, 0); _talon.SetSensorPhase(false); /* make sure positive motor output means sensor moves in position direction */ /* brake or coast during neutral */ _talon.SetNeutralMode(NeutralMode.Brake); /* closed-loop and motion-magic parameters */ _talon.Config_kF(kSlotIdx, 0.1153f, kTimeoutMs); // 8874 native sensor units per 100ms at full motor output (+1023) _talon.Config_kP(kSlotIdx, 2.00f, kTimeoutMs); _talon.Config_kI(kSlotIdx, 0f, kTimeoutMs); _talon.Config_kD(kSlotIdx, 20f, kTimeoutMs); _talon.Config_IntegralZone(kSlotIdx, 0, kTimeoutMs); _talon.SelectProfileSlot(kSlotIdx, 0); /* select this slot */ _talon.ConfigNominalOutputForward(0f, kTimeoutMs); _talon.ConfigNominalOutputReverse(0f, kTimeoutMs); _talon.ConfigPeakOutputForward(1.0f, kTimeoutMs); _talon.ConfigPeakOutputReverse(-1.0f, kTimeoutMs); _talon.ConfigMotionCruiseVelocity(8000, kTimeoutMs); // 8000 native units _talon.ConfigMotionAcceleration(16000, kTimeoutMs); // 16000 native units per sec, (0.5s to reach cruise velocity). /* Home the relative sensor, * alternatively you can throttle until limit switch, * use an absolute signal like CtreMagEncoder_Absolute or analog sensor. */ _talon.SetSelectedSensorPosition(0, kTimeoutMs); }
public static void Main() { /* Get the Joystick values from the CANbus. */ GameController _gamepad = new GameController(new CANJoystickSource(0)); TalonSRX leftTalon = new TalonSRX(10); TalonSRX rightTalon = new TalonSRX(11); /* Factory Default all hardware to prevent unexpected behaviour */ leftTalon.ConfigFactoryDefault(); rightTalon.ConfigFactoryDefault(); /* Set Inverted on one side so "forward" relative to the robot is a Green LED state */ leftTalon.SetInverted(false); rightTalon.SetInverted(true); /* loop forever */ while (true) { /* Basic Drivetrain, negate the axes so forward is positive */ leftTalon.Set(ControlMode.PercentOutput, _gamepad.GetAxis(1) * -1); rightTalon.Set(ControlMode.PercentOutput, _gamepad.GetAxis(3) * -1); /* wait a bit */ Thread.Sleep(10); /* Normally we would need to feed the Watchdog here. * We're relying on the roboRIO to provide the enable * signal, so it's not necessary. **/ } }
uint [] _debLeftY = { 0, 0 }; // _debLeftY[0] is how many times leftY is zero, _debLeftY[1] is how many times leftY is not zeero. public void Run() { /* Factory Default all hardware to prevent unexpected behaviour */ _talon.ConfigFactoryDefault(); /* first choose the sensor */ _talon.ConfigSelectedFeedbackSensor(FeedbackDevice.CTRE_MagEncoder_Relative, 0, kTimeoutMs); _talon.SetSensorPhase(false); /* set closed loop gains in slot0 */ _talon.Config_kP(0, 0.2f, kTimeoutMs); /* tweak this first, a little bit of overshoot is okay */ _talon.Config_kI(0, 0f, kTimeoutMs); _talon.Config_kD(0, 0f, kTimeoutMs); _talon.Config_kF(0, 0f, kTimeoutMs); /* For position servo kF is rarely used. Leave zero */ /* use slot0 for closed-looping */ _talon.SelectProfileSlot(0, 0); /* set the peak and nominal outputs, 1.0 means full */ _talon.ConfigNominalOutputForward(0.0f, kTimeoutMs); _talon.ConfigNominalOutputReverse(0.0f, kTimeoutMs); _talon.ConfigPeakOutputForward(+1.0f, kTimeoutMs); _talon.ConfigPeakOutputReverse(-1.0f, kTimeoutMs); /* how much error is allowed? This defaults to 0. */ _talon.ConfigAllowableClosedloopError(0, 0, kTimeoutMs); /* put in a ramp to prevent the user from flipping their mechanism in open loop mode */ _talon.ConfigClosedloopRamp(0, kTimeoutMs); _talon.ConfigOpenloopRamp(1, kTimeoutMs); /* zero the sensor and throttle */ ZeroSensorAndThrottle(); /* loop forever */ while (true) { Loop10Ms(); //if (_gamepad.GetConnectionStatus() == CTRE.UsbDeviceConnection.Connected) // check if gamepad is plugged in OR.... if (_gamepad.GetButton(kEnableButton)) // check if bottom left shoulder buttom is held down. { /* then enable motor outputs*/ Watchdog.Feed(); } /* print signals to Output window */ Instrument(); /* 10ms loop */ Thread.Sleep(10); } }
public static void Main() { /* Factory Default all hardware to prevent unexpected behaviour */ leftFrnt.ConfigFactoryDefault(); leftRear.ConfigFactoryDefault(); rghtFrnt.ConfigFactoryDefault(); rghtRear.ConfigFactoryDefault(); /* loop forever */ while (true) { /* keep feeding watchdog to enable motors */ Watchdog.Feed(); Drive(); Thread.Sleep(20); } }
public static void Main() { /* Factory Default all hardware to prevent unexpected behaviour */ rightSlave.ConfigFactoryDefault(); right.ConfigFactoryDefault(); leftSlave.ConfigFactoryDefault(); left.ConfigFactoryDefault(); /* loop forever */ while (true) { /* drive robot using gamepad */ Drive(); /* print whatever is in our string builder */ Debug.Print(stringBuilder.ToString()); stringBuilder.Clear(); /* feed watchdog to keep Talon's enabled */ CTRE.Phoenix.Watchdog.Feed(); /* run this task every 20ms */ Thread.Sleep(20); } }
private void initMotors() { leftTalon.ConfigFactoryDefault(); rightTalon.ConfigFactoryDefault(); switch (isCoast) { case true: leftTalon.SetNeutralMode(NeutralMode.Coast); rightTalon.SetNeutralMode(NeutralMode.Coast); break; case false: leftTalon.SetNeutralMode(NeutralMode.Brake); rightTalon.SetNeutralMode(NeutralMode.Brake); break; default: break; } }
public void init() { /* Factory Default all hardware to prevent unexpected behaviour */ _talon.ConfigFactoryDefault(); /* nonzero to block the config until success, zero to skip checking */ const int kTimeoutMs = 30; /* first choose the sensor */ _talon.ConfigSelectedFeedbackSensor(FeedbackDevice.CTRE_MagEncoder_Absolute, 0, kTimeoutMs); _talon.SetSensorPhase(false); /* set closed loop gains in slot0 */ _talon.Config_kP(0, 0.5f, kTimeoutMs); /* tweak this first, a little bit of overshoot is okay */ _talon.Config_kI(0, 0f, kTimeoutMs); _talon.Config_kD(0, 0f, kTimeoutMs); _talon.Config_kF(0, 0f, kTimeoutMs); /* For position servo kF is rarely used. Leave zero */ /* use slot0 for closed-looping */ _talon.SelectProfileSlot(0, 0); /*set target to the current position */ ResetTargetPosition(); }
static Hardware() { _leftDrive = new VictorSPX(1); _rightDrive = new VictorSPX(2); _lid = new TalonSRX(9); _leftDrive.ConfigFactoryDefault(); _rightDrive.ConfigFactoryDefault(); _lid.ConfigFactoryDefault(); _lid.ConfigForwardLimitSwitchSource(CTRE.Phoenix.MotorControl.LimitSwitchSource.FeedbackConnector, CTRE.Phoenix.MotorControl.LimitSwitchNormal.NormallyOpen); _lid.ConfigReverseLimitSwitchSource(CTRE.Phoenix.MotorControl.LimitSwitchSource.FeedbackConnector, CTRE.Phoenix.MotorControl.LimitSwitchNormal.NormallyOpen); _lid.ConfigContinuousCurrentLimit(2); // on port 3: Hardware Pin 1 is CTRE.HERO.IO.Port3.Pin3. // Hardware Pin 6 is CTRE.HERO.IO.Port3.Pin8. _testOutputPort = new OutputPort(CTRE.HERO.IO.Port5.Pin8, false); b0_supply = new OutputPort(CTRE.HERO.IO.Port3.Pin3, false); b0_tank = new OutputPort(CTRE.HERO.IO.Port3.Pin4, false); b0_shot = new OutputPort(CTRE.HERO.IO.Port3.Pin5, false); b1_supply = new OutputPort(CTRE.HERO.IO.Port3.Pin6, false); b1_tank = new OutputPort(CTRE.HERO.IO.Port3.Pin7, false); b1_shot = new OutputPort(CTRE.HERO.IO.Port3.Pin8, false); voltage = new AnalogInput(CTRE.HERO.IO.Port8.Analog_Pin5); lid_limit_switch = new InputPort(CTRE.HERO.IO.Port8.Pin6, false, Port.ResistorMode.PullUp); lid_limit_switch_led = new OutputPort(CTRE.HERO.IO.Port5.Pin3, false); UsbHostDevice usb = CTRE.Phoenix.UsbHostDevice.GetInstance(); _gamepad = new GameController(usb); usb.SetSelectableXInputFilter(UsbHostDevice.SelectableXInputFilter.XInputDevices); _display = new Display(); }
public void Run() { /* Factory Default all hardware to prevent unexpected behaviour */ _talon.ConfigFactoryDefault(); _talon.ConfigSelectedFeedbackSensor(FeedbackDevice.CTRE_MagEncoder_Relative, 0); _talon.SetSensorPhase(false); _talon.Config_kP(0, 0.80f); _talon.Config_kI(0, 0f); _talon.Config_kD(0, 0f); _talon.Config_kF(0, 0.09724488664269079041176191004297f); _talon.SelectProfileSlot(0, 0); _talon.ConfigNominalOutputForward(0f, 50); _talon.ConfigNominalOutputReverse(0f, 50); _talon.ConfigPeakOutputForward(+1.0f, 50); _talon.ConfigPeakOutputReverse(-1.0f, 50); _talon.ChangeMotionControlFramePeriod(5); _talon.ConfigMotionProfileTrajectoryPeriod(0, 50); /* loop forever */ while (true) { _talon.GetMotionProfileStatus(_motionProfileStatus); Drive(); Watchdog.Feed(); Instrument(); Thread.Sleep(5); } }
public static void Main() { talon.ConfigFactoryDefault(); talon2.ConfigFactoryDefault(); /* simple counter to print and watch using the debugger */ int counter = 0; bool on = false; // boolean to control on or off /* loop forever */ while (true) { if (counter % 50 == 0) // runs code every 50 iterations { if (on) { on = false; // set to off talon.Set(ControlMode.PercentOutput, 0.0); // set talon to 0% } else { on = true; // set to on talon.Set(ControlMode.PercentOutput, 1); // set talon 100% } } if (gamepad.GetButton(0)) // is button with id 0 pressed { currentFlagState = FlagState.IDLE; } if (gamepad.GetButton(1)) { currentFlagState = FlagState.TURN; } if (gamepad.GetButton(2)) { currentFlagState = FlagState.TURN_SLOW; } if (gamepad.GetButton(3)) { currentFlagState = FlagState.REVERSE; } if (gamepad.GetButton(4)) { talon2.Set(ControlMode.PercentOutput, 1.0); // set talon to 100% } else { talon2.Set(ControlMode.PercentOutput, 0.0); // set talon to 0% } if (currentFlagState != lastFlagState) // make code not run every update to have faster run time { lastFlagState = currentFlagState; // update the last state for flag spinner switch (currentFlagState) // switch on current state for flag spinner { case FlagState.INIT: // is it in INIT? talon.Set(ControlMode.PercentOutput, 0.0); // set talon to 0% currentFlagState = FlagState.IDLE; // set current state to IDLE break; // leave the switch statement case FlagState.IDLE: // is is in IDLE? talon.Set(ControlMode.PercentOutput, 0.0); // set talon to 0% break; case FlagState.TURN: talon.Set(ControlMode.PercentOutput, 1); // set talon 100% break; case FlagState.TURN_SLOW: talon.Set(ControlMode.PercentOutput, 0.2); // set talon 20% break; case FlagState.REVERSE: talon.Set(ControlMode.PercentOutput, -1); // set talon 100% break; default: talon.Set(ControlMode.PercentOutput, 0.0); // set talon to 0% to prevent broken behavior currentFlagState = FlagState.IDLE; // set state to idle to prevent further errors break; } } /* * the ifs are the equivalent of the case statement * * * if (currentIntakeState == IntakeState.INIT) * { * * } else if (currentIntakeState == IntakeState.IDLE) * { * * } else if (currentIntakeState == IntakeState.IN) * { * * } else if (currentIntakeState == IntakeState.IN_SLOW) * { * * } * else if (currentIntakeState == IntakeState.REVERSE) * { * * } else // this is the equivalent of the default section. * { * * } * */ /* print the three analog inputs as three columns */ Debug.Print("Counter Value: " + counter); /* increment counter */ ++counter; /* try to land a breakpoint here and hover over 'counter' to see it's current value. Or add it to the Watch Tab */ /* wait a bit */ System.Threading.Thread.Sleep(100); // make sure the motors stay on CTRE.Phoenix.Watchdog.Feed(); } }
void Loop10Ms() { /* get all the buttons */ FillBtns(ref _btns); /* on button1 press read talon configs */ if (_btns[1] && !_btnsLast[2]) { Debug.Print("read talon"); TalonSRXConfiguration read_talon; _talon.GetAllConfigs(out read_talon); Debug.Print(read_talon.ToString("_talon")); } /* on button2 press read victor configs */ else if (_btns[2] && !_btnsLast[2]) { Debug.Print("read victor"); VictorSPXConfiguration read_victor; _victor.GetAllConfigs(out read_victor); Debug.Print(read_victor.ToString("_victor")); } /* on button3 press read pigeon configs */ else if (_btns[3] && !_btnsLast[3]) { Debug.Print("read pigeon"); PigeonIMUConfiguration read_pigeon; _pigeon.GetAllConfigs(out read_pigeon); Debug.Print(read_pigeon.ToString("_pigeon")); } /* on button4 press read canifier configs */ else if (_btns[4] && !_btnsLast[4]) { Debug.Print("read canifier"); CANifierConfiguration read_canifier; _canifier.GetAllConfigs(out read_canifier); Debug.Print(read_canifier.ToString("_canifier")); } /* on button5 press set custom configs */ else if (_btns[5] && !_btnsLast[5]) { Debug.Print("custom config start"); _talon.ConfigAllSettings(_custom_configs._talon); _victor.ConfigAllSettings(_custom_configs._victor); _pigeon.ConfigAllSettings(_custom_configs._pigeon); _canifier.ConfigAllSettings(_custom_configs._canifier); Debug.Print("custom config finish"); } /* on button6 press set factory default */ else if (_btns[6] && !_btnsLast[6]) { Debug.Print("factory default start"); _talon.ConfigFactoryDefault(); _victor.ConfigFactoryDefault(); _pigeon.ConfigFactoryDefault(); _canifier.ConfigFactoryDefault(); Debug.Print("factory default finish"); } /* set last presses */ _btnsLast = (bool[])_btns.Clone(); }
public static void Main() { /* Hardware */ TalonSRX _talon = new TalonSRX(1); /** Use a USB gamepad plugged into the HERO */ GameController _gamepad = new GameController(UsbHostDevice.GetInstance()); /* String for output */ StringBuilder _sb = new StringBuilder(); /** hold bottom left shoulder button to enable motors */ const uint kEnableButton = 7; /* Loop tracker for prints */ int _loops = 0; /* Initialization */ /* Factory Default all hardware to prevent unexpected behaviour */ _talon.ConfigFactoryDefault(); /* Config sensor used for Primary PID [Velocity] */ _talon.ConfigSelectedFeedbackSensor(FeedbackDevice.CTRE_MagEncoder_Relative, Constants.kPIDLoopIdx, Constants.kTimeoutMs); /** * Phase sensor accordingly. * Positive Sensor Reading should match Green (blinking) Leds on Talon */ _talon.SetSensorPhase(false); /* Config the peak and nominal outputs */ _talon.ConfigNominalOutputForward(0, Constants.kTimeoutMs); _talon.ConfigNominalOutputReverse(0, Constants.kTimeoutMs); _talon.ConfigPeakOutputForward(1, Constants.kTimeoutMs); _talon.ConfigPeakOutputReverse(-1, Constants.kTimeoutMs); /* Config the Velocity closed loop gains in slot0 */ _talon.Config_kF(Constants.kPIDLoopIdx, Constants.kF, Constants.kTimeoutMs); _talon.Config_kP(Constants.kPIDLoopIdx, Constants.kP, Constants.kTimeoutMs); _talon.Config_kI(Constants.kPIDLoopIdx, Constants.kI, Constants.kTimeoutMs); _talon.Config_kD(Constants.kPIDLoopIdx, Constants.kD, Constants.kTimeoutMs); /* loop forever */ while (true) { /* Get gamepad axis */ double leftYstick = -1 * _gamepad.GetAxis(1); /* Get Talon/Victor's current output percentage */ double motorOutput = _talon.GetMotorOutputPercent(); /* Prepare line to print */ _sb.Append("\tout:"); /* Cast to int to remove decimal places */ _sb.Append((int)(motorOutput * 100)); _sb.Append("%"); // Percent _sb.Append("\tspd:"); _sb.Append(_talon.GetSelectedSensorVelocity(Constants.kPIDLoopIdx)); _sb.Append("u"); // Native units /** * When button 1 is held, start and run Velocity Closed loop. * Velocity Closed Loop is controlled by joystick position x2000 RPM, [-2000, 2000] RPM */ if (_gamepad.GetButton(1)) { /* Velocity Closed Loop */ /** * Convert 2000 RPM to units / 100ms. * 4096 Units/Rev * 2000 RPM / 600 100ms/min in either direction: * velocity setpoint is in units/100ms */ double targetVelocity_UnitsPer100ms = leftYstick * 2000.0 * 4096 / 600; /* 2000 RPM in either direction */ _talon.Set(ControlMode.Velocity, targetVelocity_UnitsPer100ms); /* Append more signals to print when in speed mode. */ _sb.Append("\terr:"); _sb.Append(_talon.GetClosedLoopError(Constants.kPIDLoopIdx)); _sb.Append("\ttrg:"); _sb.Append(targetVelocity_UnitsPer100ms); } else { /* Percent Output */ _talon.Set(ControlMode.PercentOutput, leftYstick); } /* Print built string every 10 loops */ if (++_loops >= 10) { _loops = 0; Debug.Print(_sb.ToString()); } /* Reset built string */ _sb.Clear(); //if (_gamepad.GetConnectionStatus() == CTRE.UsbDeviceConnection.Connected) // check if gamepad is plugged in OR.... if (_gamepad.GetButton(kEnableButton)) // check if bottom left shoulder buttom is held down. { /* then enable motor outputs*/ Watchdog.Feed(); } /* wait a bit */ System.Threading.Thread.Sleep(20); } }
static void Everything() { // creates a variable for the time(seconds) float time = stopwatch.Duration; // prevents unexpected behavior rightDriveTalon.ConfigFactoryDefault(); leftDriveTalon.ConfigFactoryDefault(); climbTalon.ConfigFactoryDefault(); // not finished autonomous period if (time < 30) { Debug.Print("Auton is attempting to E"); leftDriveTalon.Set(ControlMode.PercentOutput, 0.5); //sets left drive talon to 50% rightDriveTalon.Set(ControlMode.PercentOutput, 0.5); //sets right drive talon to 50% Thread.Sleep(10); Debug.Print("Auton ending, E complete."); leftDriveTalon.Set(ControlMode.PercentOutput, 0.0); //sets left drive talon to 0% rightDriveTalon.Set(ControlMode.PercentOutput, 0.0); //sets right drive talon to 0% } while (running) { // print axis value ??? Debug.Print("axis:" + gamepad1.GetAxis(1)); // allows motor control CTRE.Phoenix.Watchdog.Feed(); // Teleoperated // determine inputs forwardAxis = gamepad1.GetAxis(1); turnAxis = gamepad1.GetAxis(2); // accounting for forward and turn b4 Eing into the talons finalLeftTalonValue = (forwardAxis * forwardGain) + (turnAxis * turnGain); finalRightTalonValue = (forwardAxis * forwardGain) - (turnAxis * turnGain); // pass motor value to Talons leftDriveTalon.Set(ControlMode.PercentOutput, finalLeftTalonValue); rightDriveTalon.Set(ControlMode.PercentOutput, finalRightTalonValue); // Elevator controls if (gamepad1.GetButton(elevatorRise)) { climbState = ClimbState.RISE; } else if (gamepad1.GetButton(elevatorLower)) { climbState = ClimbState.LOWER; } else { climbState = ClimbState.IDLE; } // if the button is pressed the drivestate will switch if (gamepad1.GetButton(driveStateButton) && driveState == DriveState.PRECISE) { driveState = DriveState.STRONGER; } else if (gamepad1.GetButton(driveStateButton) && driveState == DriveState.STRONGER) { driveState = DriveState.PRECISE; } // elevator state machine switch (climbState) { case ClimbState.IDLE: Debug.Print("nothing"); climbTalon.Set(ControlMode.PercentOutput, 0.0); //sets the climber talon to 0% break; case ClimbState.RISE: Debug.Print("rising"); climbTalon.Set(ControlMode.PercentOutput, 1 * climbGain); //sets the climber talon to 50% break; case ClimbState.LOWER: Debug.Print("lowering"); climbTalon.Set(ControlMode.PercentOutput, -1 * climbGain); //sets the climber talon to -50% break; case ClimbState.ERROR: Debug.Print("ElevatorState error"); break; default: Debug.Print("very bad error"); break; } // drive gain state machine switch (driveState) { case DriveState.PRECISE: forwardGain = 0.3f; turnGain = 0.1f; Debug.Print("precise"); break; case DriveState.STRONGER: forwardGain = 0.5f; turnGain = 0.25f; Debug.Print("stronger"); break; default: Debug.Print("DriveState error"); break; } if (gamepad1.GetButton(emergencyStop)) { running = false; } } }
public void RunForever() { /* enable XInput, if gamepad is in DInput it will disable robot. This way you can * use X mode for drive, and D mode for disable (instead of vice versa as the * stock HERO implementation traditionally does). */ UsbHostDevice.GetInstance(0).SetSelectableXInputFilter(UsbHostDevice.SelectableXInputFilter.XInputDevices); /* Factory Default all hardware to prevent unexpected behaviour */ _tal.ConfigFactoryDefault(); while (true) { if (_gamepad.GetConnectionStatus() == UsbDeviceConnection.Connected) { Watchdog.Feed(); } /* get buttons */ bool[] btns = new bool[_buttons.Length]; for (uint i = 1; i < 20; ++i) { btns[i] = _gamepad.GetButton(i); } /* get sticks */ for (uint i = 0; i < _sticks.Length; ++i) { _sticks[i] = _gamepad.GetAxis(i); } /* yield for a bit, and track timeouts */ System.Threading.Thread.Sleep(10); if (_rumblingTimeMs < 5000) { _rumblingTimeMs += 10; } /* update the Talon using the shoulder analog triggers */ _tal.Set(ControlMode.PercentOutput, (_sticks[5] - _sticks[4]) * 0.60f); /* fire some solenoids based on buttons */ _driver.Set(1, _buttons[1]); _driver.Set(2, _buttons[2]); _driver.Set(3, _buttons[3]); _driver.Set(4, _buttons[4]); /* rumble state machine */ switch (_rumblinSt) { /* rumbling is disabled, require some off time to save battery */ case 0: _gamepad.SetLeftRumble(0); _gamepad.SetRightRumble(0); if (_rumblingTimeMs < 100) { /* waiting for off-time */ } else if ((btns[1] && !_buttons[1])) /* button off => on */ { /* off time long enough, user pressed btn */ _rumblingTimeMs = 0; _rumblinSt = 1; _gamepad.SetLeftRumble(0xFF); } else if ((btns[2] && !_buttons[2])) /* button off => on */ { /* off time long enough, user pressed btn */ _rumblingTimeMs = 0; _rumblinSt = 1; _gamepad.SetRightRumble(0xFF); } break; /* already vibrating, track the time */ case 1: if (_rumblingTimeMs > 500) { /* vibrating too long, turn off now */ _rumblingTimeMs = 0; _rumblinSt = 0; _gamepad.SetLeftRumble(0); _gamepad.SetRightRumble(0); } else if ((btns[3] && !_buttons[3])) /* button off => on */ { /* immedietely turn off */ _rumblingTimeMs = 0; _rumblinSt = 0; _gamepad.SetLeftRumble(0); _gamepad.SetRightRumble(0); } else if ((btns[1] && !_buttons[1])) /* button off => on */ { _gamepad.SetLeftRumble(0xFF); } else if ((btns[2] && !_buttons[2])) /* button off => on */ { _gamepad.SetRightRumble(0xFF); } break; } /* this will likley be replaced with a strongly typed interface, * control the LEDs on the center XBOX emblem. */ if (btns[5] && !_buttons[5]) { _gamepad.SetLEDCode(6); } if (btns[6] && !_buttons[6]) { _gamepad.SetLEDCode(7); } if (btns[7] && !_buttons[7]) { _gamepad.SetLEDCode(8); } if (btns[8] && !_buttons[8]) { _gamepad.SetLEDCode(9); } /* build line to print */ StringBuilder sb = new StringBuilder(); foreach (float stick in _sticks) { sb.Append(Format(stick)); sb.Append(","); } sb.Append("-"); for (uint i = 1; i < _buttons.Length; ++i) { if (_buttons[i]) { sb.Append("b" + i + ","); } } /* print useful info */ sb.AppendLine(); Debug.Print(sb.ToString()); /* save button states for button-change states */ _buttons = btns; } }