Shop OBEX P1 Docs P2 Docs Learn Events
Eddie and Xbox 360 wireless controller — Parallax Forums

Eddie and Xbox 360 wireless controller

Rick BrooksRick Brooks Posts: 67
edited 2012-02-07 09:09 in Robotics
Eddie made the first drive around the house using the Xbox 360 wireless controller. It is fantastic!

One little problem did come up. When you gave it a turn right command, it turned left, and a turn left command resulted in a right turn. The immediate fix was to hold the controller upside down, which is OK for an initial run.

So, let’s start out with the basics. With the PST, “GO 20 0” makes the left wheel turn like it should and the left encoder counts up. “GO 0 20” makes the right wheel turn like it should and the right encoder counts up. Everything is good so far.

Back to the Parallax 2011 Reference Platform console application and a right turn from the Xbox controller results in the track ball icon indication a right turn and the X reading goes from 0 up to 1000. A left turn from the Xbox controller results in the track ball icon indication of a left turn and the X reading goes from 0 down to -1000. Everything is good so far.

So I tried the Parallax 2011 Reference Platform console application without the Xbox controller, but using the track ball icon.

With the motors turned on, the track ball icon was moved to the right. The x reading went up to 1000, the right wheel turned forward, the left wheel turned reverse, the right encoder counted up, and the left encoder counted down. With the right wheel going forward and the left wheel going reverse, that is a left hand turn. Something is wrong. For a track ball icon movement to the left, the opposite happened, there was a right turn.

I figured that there was an easy fix. There was probably a command somewhere in the C# programs that sent “GO rightwheel leftwheel” instead of “GO leftwheel rightwheel”.

I did find a Drive.cs program that line 182 reads: “byte[] cmdpacket = board.CreatePacket<sbyte>(board.SetTravelPowerString, rightDrivePower, leftDrivePower);” Is that it?

Rick Brooks

Comments

  • Rick BrooksRick Brooks Posts: 67
    edited 2012-01-15 08:40
    I did try changing Drive.cs line 182 to:
    “byte[] cmdpacket = board.CreatePacket<sbyte>(board.SetTravelPowerString, leftDrivePower, rightDrivePower);”
    That fixed the problem. Note that the Parallax IO Controller service for Eddie must be rebuilt to implement the change. See the instructions for rebuilding the service.

    On the Robot Dashboard, Tools, Options, I changed the X and Y Dead Zone to 20, Translate Scale Factor to 1, and Rotate Scale Factor to 0.3. That made Eddie much easier to drive with the wireless Xbox controller. These changes can be made default by modifying the robotdashboard.config file. There is a minor delay between the command and response, but it is not objectionable.

    I have added a bunch of red and blue LED strips to Eddie and wired them into the AUX Switched Power Ports. Using Parallax Serial Terminal, I can turn the LEDs on and off, but the BLINK command gives an error. Is there a problem with BLINK?

    Rick Brooks
  • Rick BrooksRick Brooks Posts: 67
    edited 2012-01-15 10:38
    "BLINK" (from the Eddie Command Set PDF) does not work, but "BLNK" (from Eddie Firmware) works. Note that it can only blink one pin at a time.

    Rick Brooks
  • Rick BrooksRick Brooks Posts: 67
    edited 2012-01-16 15:10
    I added a few lines of code to the Eddie firmware so the BLNK for pin 16 will work on Counter B and BLNK for any other pin will work on Counter A. Now I can blink two sets of lights at two different frequencies.

    Rick Brooks
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-17 15:39
    Rick,

    I'm guessing there aren't many of us around here who have used Eddie.

    When you say your added to the firmware, did you use the Propeller Tool to do this? If you're using Spin to program, I may be able to help you with blinking multiple LEDs (at multiple frequencies).

    Could you either attach the code you are using (preferably as an "Archive" (look under the "File" menu of the Propeller Tool)) or post the code (if it isn't very long) inside code tags. To use code tags follow this link.

    attachment.php?attachmentid=78421&d=1297987572
  • Rick BrooksRick Brooks Posts: 67
    edited 2012-01-17 17:25
    Duane,
    I agree, there must not be many using Eddie.
    The code that I changed was just adding to the "BLINK" command in the Eddie firmware. Here it is:
      elseif strcomp(@InputBuffer, string("BLNK"))        ' Command: Blink the specified pin at a specified rate
          Parameter[0] := ParseHex(NextParameter)           ' Pin number
          Parameter[1] := ParseHex(NextParameter)           ' Frequency
          CheckLastParameter
    
    
          if Parameter[0] == 16
            Parameter[2] := |< Parameter[0]                   ' Create a pin mask from the pin number
            if Parameter[2] & OUTPUTABLE                      ' Only use this command on a pin that can be an output
              if Parameter[1]                                 
                if Parameter[2] & PingMask                    ' If the pin used to be a PING))) sensor pin
                  ResetPingDriver(PingMask &= !Parameter[0])  ' Restart the PING))) sensor processor with the pin removed from the mask
                GPIOMask &= !Parameter[2]                     ' Flag the pin as a GPIO pin
                outa[Parameter[0]]~                           ' The I/O pin must be set as a low input
                dira[Parameter[0]]~~
                ctrb := constant(%00101 << 26) + Parameter[0] ' Set counter A to toggle the I/O pin
                frqb := constant($8000_0000 / _clkfreq / 10) * Parameter[1] ' Calculate the toggle period            
              else
                ctrb~                                         ' A frequency of 0 turns of the counter
          else
    
    
            Parameter[2] := |< Parameter[0]                   ' Create a pin mask from the pin number
            if Parameter[2] & OUTPUTABLE                      ' Only use this command on a pin that can be an output
              if Parameter[1]                                 
                if Parameter[2] & PingMask                    ' If the pin used to be a PING))) sensor pin
                  ResetPingDriver(PingMask &= !Parameter[0])  ' Restart the PING))) sensor processor with the pin removed from the mask
                GPIOMask &= !Parameter[2]                     ' Flag the pin as a GPIO pin
                outa[Parameter[0]]~                           ' The I/O pin must be set as a low input
                dira[Parameter[0]]~~
                ctra := constant(%00101 << 26) + Parameter[0] ' Set counter A to toggle the I/O pin
                frqa := constant($8000_0000 / _clkfreq / 10) * Parameter[1] ' Calculate the toggle period            
              else
                ctra~                                         ' A frequency of 0 turns of the counter
    
    The rest of the program is not changed. Any time that you send a "BLNK" command to pin 16 it uses the B counter. Any other pin still uses the A counter.
    The next step is to get the Xbox buttons to control the LEDs on/off and blinking rate. I have no idea where to look to do that, yet.
    Last night I ran Eddie from a remote desktop. There were very, very long delays between the commands (desktop or Xbox) and the response. Also, the video update was very slow.
    Rick Brooks
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-18 13:36
    Rick,

    The forum ate my first post. I'll try again but I'll likely just post a part at a time and then edit the post.

    This codde should let you use multiple LEDs.

    You'll want to change the object section to:
    Obj                             
                                    
      Term          : "FullDuplexSerial"
      Encoders      : "FullDuplexSerial"
      ADC           : "MCP3208.spin"                        ' Works with MCP3008, but two LSBs may be incorrect
      Ping          : "ReadPulseWidths.spin"
      Motors        : "Eddie Motor Driver"
     [COLOR=#ff0000] Led           : "FlashLeds"[/COLOR]
     
    
    You'll also want to add to the main method:
    Pub Main
      Term.Start(RX, TX, BAUDMODE, BAUDRATE)                ' Start a UART for the command port
      ADC.Start(ADC_DIO, ADC_CLK, ADC_CS, $FF)              ' Continuously run ADC conversions
      Ping.Start(@PingResults)                              ' Continuously read pulse widths on PING))) pins
      [COLOR=#ff0000]Led.Start
    [/COLOR]cognew(PDLoop, @Stack)                                ' Run the position controller in another core  
    


    You can leave the "BLNK" section as is and just add a "BLINK" section:
    elseif strcomp(@InputBuffer, string("BLNK"))        ' Command: Blink the specified pin at a specified rate
          Parameter[0] := ParseHex(NextParameter)           ' Pin number
          Parameter[1] := ParseHex(NextParameter)           ' Frequency
          CheckLastParameter
          Parameter[2] := |< Parameter[0]                   ' Create a pin mask from the pin number
          if Parameter[2] & OUTPUTABLE                      ' Only use this command on a pin that can be an output
            if Parameter[1]                                 
              if Parameter[2] & PingMask                    ' If the pin used to be a PING))) sensor pin
                ResetPingDriver(PingMask &= !Parameter[0])  ' Restart the PING))) sensor processor with the pin removed from the mask
              GPIOMask &= !Parameter[2]                     ' Flag the pin as a GPIO pin
              outa[Parameter[0]]~                           ' The I/O pin must be set as a low input
              dira[Parameter[0]]~~
              ctra := constant(101 << 26) + Parameter[0] ' Set counter A to toggle the I/O pin
              frqa := constant($8000_0000 / _clkfreq / 10) * Parameter[1] ' Calculate the toggle period            
            else
              ctra~                                         ' A frequency of 0 turns of the counter
        [COLOR=#ff0000]elseif strcomp(@InputBuffer, string("BLINK"))        ' Command: Blink the specified pin at a specified rate
          Parameter[0] := ParseHex(NextParameter)           ' Pin number
          Parameter[1] := ParseHex(NextParameter)           ' Frequency
          CheckLastParameter
          if Parameter[1]
            Parameter[1] := 5000 / Parameter[1]
            Led.AddLed(Parameter[0], Parameter[1], Parameter[1], 0)
          else
            Led.OffLed(Parameter[0]) [/COLOR]
        elseif strcomp(@InputBuffer, string("VERB"))        ' Command: Set verbose mode
    

    You're right about the documentation using "BLINK" and not "BLNK".

    In order to stop and LED from blinking, you'll need to assign it a frequency of zero.

    This new code uses up another cog on the Propeller. I notice there are two FullDuplexSerial objects. If you run out of cogs you can use a serial object that allows multiple ports within one cog.

    Edit: I changed "FlashLed.spin" to release the pin (make it an input). The original version I posted set the pin as an input from the wrong cog. This version will allow the pin to be used as an input if not being used as an LED.
  • Rick BrooksRick Brooks Posts: 67
    edited 2012-01-18 18:33
    Duane,

    Thanks for posting the code. I'll have to try it this weekend. I was trying to avoid using an extra cog for the LED blinkers. I count 6 cogs being used by the firmware already and there are other things that I may want to do, like adding a kill switch.

    Tonight I did notice another situation. Using the Wireless Xbox controller, the buttons control a few functions. One of them toggles the motor enable/disable function and another turns on the stop function. I was running Eddie and tried the motor disable. The only thing that the button did was to disable my control of the motors. It did not stop the motors! Fortunately, Eddie was in a tight spin at the time and I could enable the motors and stop them before a collision.

    Rick
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-19 08:01
    Rick,

    I changed the files in post #7. The new code releases the pins used to flash LEDs once the flashing ends so they can be used for other purposes. If you downloaded the code I posted yesterday, I'd suggest you use the new code instead of the old code.

    Sorry about your problems with the controller. I have no idea what is going on. I don't know if I mentioned earlier or not, I don't have an Eddie robot myself.
  • Jessica UelmenJessica Uelmen Posts: 490
    edited 2012-01-20 16:15
    Rick,

    Thanks for your feedback on the Eddie platform, I'm excited to read about someone who is actively developing on it!

    Your comments on the wireless control did perplex me, so I reached out to Microsoft for some guidance. The button controls should be as follows:

    A - Toggles Enable/Disable Drive
    B - Stop Motors
    X - Re-Enable Motors After Stop

    Was this the response you were seeing? Obviously we don't want any runaway Eddies!

    Cheers,
    Jessica
  • Rick BrooksRick Brooks Posts: 67
    edited 2012-01-21 19:24
    Jessica
    A - Toggles Enable/Disable Drive
    B - Stop Motors
    X - Re-Enable Motors After Stop

    That is exactly how the system works. The problem is that neither "Stop", nor "Disable Drive" stops the motors if they are running.

    This is what happens:

    If the motors are running and "A" is pushed, the Disable Drive is activated in the control panel. The motors keep running until the joystick is moved. Then the motors stop.

    If the motors are running and "B" is pushed, the Stop is activated in the control panel. The motors keep on running. The only way to stop Eddie in this situation (besides the power switch) is to push "X" to re-enable motors after stop and then move the joystick to send a new speed command. The motors will then resume joystick control.

    Rick
  • TLCTLC Posts: 74
    edited 2012-02-07 09:09
    I'm seeing the same things, both the R/L swap as well as the motor disable issue. I'm going to change the Eddie firmware to fix the Right/Left problem and am going to look at the service related to the motor disable.
Sign In or Register to comment.