Original Xbox Controller S breakout board wip - joystick que

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
stephaneag
 
Posts: 60
Joined: Sat Mar 29, 2014 8:37 pm

Re: Original Xbox Controller S breakout board wip - joystick

Post by stephaneag »

quick update:

- First, I must admit I was quite tired lately, and I didn't actually wanted to omit the additional NPN transistor you suggested: I just didn't notice the difference between our circuits :/ ^^

- Then, I must say I'm pretty happy with 123d Circuits ( once you know how it works & that it 'll gets additional functionalities, plus the kindness of one of their team's dude I've been chatting with )

- Finally, I had the chance to get my hands on a Kymera Wand ( http://www.thewandcompany.com/ ) and I did some silly quick & dirty code to control the sourcing-sinking transisor / ljoy Y axis with it, & thought it may interest some readers

Kymera Wand code:

Code: Select all

/*
  == Arduino Micro - sourcing-sinking test ==
  
  R: pins 3,5,6,9,10,11 are the PWM-capable on USBboarduino
  R: pins 3,5,6,9,10,11,13 are the PWM-capable pins on Arduino Micro
  
  The "sourcing sinking transistors" stuff is to simulate a joystick axis
  The "Kymera Wand mix" stands for the handling of IR codes to be used as alternative to serial cmds
  
  The following code is intented to receive IR codes from any IR remote ( including the Kymera wand ;p )
   The processing is can still be done on the laptop, but we also directly parse the IR codes received
   
   The 'states' hold the value corresponding to the action associated
   aka:  states[4] = "255"        => state 5: run forward
         states[3] = "192"        => state 4: walk forward
         states[2] = "128"||"0"   => state 3: steady
         states[1] = "64"         => state 2: walk backward
         states[0] = "1"          => state 1: run backward
  
  @StephaneAG - 2015
   
*/

// lib necessary to receive IR codes
#include <IRremote.h>

// == IR, Kymera Wand states & vars ==
// IR
int RECV_PIN = 2;
IRrecv irrecv(RECV_PIN);
decode_results results;
// Kymera
int states[] = {1, 64, 128, 192, 255}; // the said-states
int currState = 2; // 3rd state
int currKymVal = 128; // the value to be used as ljoy Y axis value

// == pin configuration ==

// Joysticks
// LJOY Y AXIS
const int ljoyY_dirPin = 7;          // #D7 for DIR on Arduino Micro - source or sink
const int ljoyY_pwmPin = 6;          // #D6 for PWM on Arduino Micro - how much to source or sink

// == states ==
// timeout=None
// chunks   LJOYY
// ex       128
// formerly ljoyYAxis
// default:          0/       128
int read_chunk_LJOYY  = 0;   // chunk #1  ( ljoyYAxis )

void setup() {
  // init serial
  Serial.begin(9600); // may adjust the baud later for efficiency ( .. )
  
  // == IR ==
  irrecv.enableIRIn(); // Start the receiver
  
  // == pins modes ==
  // Joysticks - desactivated
  
  pinMode(ljoyY_dirPin, OUTPUT);
  pinMode(ljoyY_pwmPin, OUTPUT);
  
  //initJoystickAxis(ljoyY_pwmPin);
  analogWrite(ljoyY_pwmPin, 255);
  
  Serial.println("booted !");
  
  // == debug pins mapping ==
  // R: the debug voltages are reset on first serial command received
  // Joysticks
}


void loop() {
  
  // == apply last settings ==
  // we moved the code present in the fcn handling a serial buffer stuf
  // it was doing the following after encountering a "\n" in the said-buffer 
  //handleJoystickAxis( read_chunk_LJOYY, ljoyY_dirPin, ljoyY_pwmPin ); // updates the left joystick Y axis
  
  // == reset ==
  // we reset the controls to their defaults before receiving any command from the serial
  // we do so to bypass the need to catch key releases on the device controlling the Arduino
  // aka, no need for callbacks or trap keys if we use a simple bash script ..
  // although, for analog values, it could be nice to have the increase/decrease gradually to their default ( smoothly )
  // last though: we could also have left them "as is" until new serial call ( .. )
  read_chunk_LJOYY  = 0;   // chunk #1  ( ljoyYAxis )
  
  // == read from the Kymera Wand ==
  if (irrecv.decode(&results)) {
    
    // increase or decrease the current state based on the Kym IR codes
    if( results.value == 0x8038A602 && currState < 4 ) currState++;
    else if( results.value == 0x80382601 && currState > 0 ) currState--;
    // get the value corresponding to that state
    currKymVal = states[currState];
    // use that value as if it was coming from the serial conn, to update LJOYY chunk
    read_chunk_LJOYY = currKymVal;
    
    handleJoystickAxis( read_chunk_LJOYY, ljoyY_dirPin, ljoyY_pwmPin ); // updates the left joystick Y axis
    
    // ACK
    Serial.print("Kymera/");
    Serial.print(results.value, HEX);
    Serial.print("/");
    Serial.print(currState);
    Serial.print("/");
    Serial.print(currKymVal);
    Serial.println("");
    
    // Receive the next value
    irrecv.resume();
  }
  
  // == read from the Serial conn ==
  /*
  while(Serial.available() > 0){ // read any serial available
    
    // == readings ==
    // LJOYY
    read_chunk_LJOYY  = Serial.parseInt(); // chunk #1  ( ljoyYAxis )
    
    // look for a line ending
    if( Serial.read() == '\n' ){
      
      // == update ==
      // R: constrain is used to keep in the 0-255 range
      // Joysticks
      //
      // = theorically / expected by Xbox Controller S =
      // fully forward    4.6V
      // nothing          2.3V
      // fully backward   0.0V
      //handleJoystickAxis( read_chunk_LJOYY, ljoyY_dirPin, ljoyY_pwmPin ); // updates the left joystick Y axis
      
      // == ack ==
      Serial.print("ljoyY:"); Serial.print(read_chunk_LJOYY); Serial.println("");
      
    }
  }
  */
  
  // == other update ==
  //
  //Serial.println("Hy world !");
  //delay(2000); // temporary delay for debug
}


/* == helper fcn(s) == */

// init a joystick axis
void initJoystickAxis( int pwmPin ){
  analogWrite(pwmPin, 0);
}

// accept a value from 0 to 256 & 2 pins to handle a joystick axis
// - maps the value to a direction & a pwm value
// - updates the 2 pins to reflect the value passed
void handleJoystickAxis(int value, int dirPin, int pwmPin){
  
  if( value == 128 ){ 
    Serial.print("value is 128 => don't source nor sink .."); Serial.println("");
    analogWrite(pwmPin, 0); // whatever the direction, don't source nor sink
  }
  
  else if( value > 128 && value <= 256 ) { // forward => source
    Serial.print("value greater than 128 => sourcing .."); Serial.println("");
    digitalWrite( dirPin, LOW ); // source
    analogWrite( pwmPin, map( value, 128, 256, 256, 0 ) ); // 128~256 => 0~256 for pwm forward
  }
  
  else if( value < 128 && value >= 0 ) { // backward => sink
    Serial.print("value smaller than 128 => sinking .."); Serial.println("");
    digitalWrite( dirPin, HIGH ); // sink
    analogWrite( pwmPin, map( value, 0, 128, 256, 0 ) ); // 0~128 => 256~0 for pwm backward
  }
}
Last but not least, I intend to try your circuit & adjust the code in regards to it & I'll be posting an update on this soon

Can't wait to receive my 1st PCB ;)

+

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Original Xbox Controller S breakout board wip - joystick

Post by adafruit_support_mike »

Glad to hear things are working for you..

The additional transistor does change the input signals for the outer PNP/NPN pair. See how the circuit performs with that.

User avatar
stephaneag
 
Posts: 60
Joined: Sat Mar 29, 2014 8:37 pm

Re: Original Xbox Controller S breakout board wip - joystick

Post by stephaneag »

Hi there Mike !

"The time of updates & new questions has arrived" ;P

First of all: I'm thinking that right now, I wouldn't be messing around with NPNs & PNPs without having being helped out & deconstructing your answer .. so THAAAANKS :)

Yet, I still got wayyyy much more stuff to learn to be able to overcome any situation without neither a little headhache nor some web search ..
.. but I can feel it's coming, slowly building itself in the back of my brain ...

Well, onto the interesting stuff !


1: I gave quite an update to the "Xbox Controller S breakout" project, and have no better choice than posting an URL to its schematic ( embedding it in the page 'd slow it down drastically :/ .. )
Schematic on 123D Circuits

2: The Github repo also had it's update but most recent code is not online yet ( .. ):
Github repo for Madtoyslab - Xbox Controller S breakout

3: I also created a hackaday.io project page to host most of the pictures, schematics, research & docs:
Hackaday.io project page for Madtoyslab - Xbox Controller S breakout

( I won't forget to make links to this post where ti's not already done, as well as add parts links ;p )



Now, onto some questions :)

1: ( first picture )
The "überjoy" circuit ( your alternative version, actually, with the additional NPN ) has been added to the main board ( less soldering to do, & handier for new fcnalities ( .. ) ), but I was wondering if the resistors being unconnected 'd cause any troubles ( & also if additional components were required in order to prevent altering the signal when reading it, in addition to fully separate the two circuits / have an AREF == to 5V & not 4.6V )
uberjoy - alternative version, with added &quot;mode control&quot;
uberjoy - alternative version, with added "mode control"
uberjoy_altvers_modeCtrl__wip.JPG (331.07 KiB) Viewed 495 times
2:
Now that the board ( at least, the breadboard version I built ) & its code are fine [ until I hack around again .. ], I wanted to add the ability to either control ( "write" ) or record ( "read" ) using a simple toggle switch:
The idea is to record the way a player controls his gamepad in the latter, while the former allows to control the gamepad from pretty much anything ( .. )
This is, to do so, I needed additional circuitry / routing for the pins ( as seen on 123D Circuits schematic )
While untested yet, I guess the adjustments I made should be ok ( but I'll indeed test on a breadboard to make sure ;p ), but adding 2 shift-in registers to the overall mix increased the complexity a little bit ..
Question(s) on this being:
-if I were to alternate powering the 595's & the 4021's, would the clock, latch & data lines require being disconnected ?
- would connecting / disconnecting +V & Gnd from them be sufficient instead ?
- would the "data" re-routing exposed in the schematic work ?
- is it possible to do the "clear & re-enable output on boot" ( delaying MR & OE from going back to eith HIGH / LOW ) exposed in the schematic, and would it work this way [ or another ] ?
The goal is to have the less possible number of pins taken & not waste any pow ( aka, sharing the data, latch & clock lines as well as toggling the +V & Gnd seemed like a good shot ( .. ) )
shift_in_and_out_registers_1__overall_schematic.JPG
shift_in_and_out_registers_1__overall_schematic.JPG (583.82 KiB) Viewed 495 times
shift_in_and_out_registers_2__data_clock_latch.JPG
shift_in_and_out_registers_2__data_clock_latch.JPG (535.3 KiB) Viewed 495 times
( last picture in next reply, as 3 pics max .. )

Last but not least, on the picture with LEDs, you can have a look at the so-called "breadboard setup": the bottom-left part is the überjoys DIR & PWM pins, left to be connected to the part seen in the top of the picture, aka 4 of the alternative version you proposed :)

User avatar
stephaneag
 
Posts: 60
Joined: Sat Mar 29, 2014 8:37 pm

Re: Original Xbox Controller S breakout board wip - joystick

Post by stephaneag »

Follows, the picture corresponding to the desired "595 clear on reboot & then re-enable output" behavior ( feel free to correct me on this, but I bet it's better than the one exposed in the 1st schematic for the same purpose .. )

=> As you might have guessed, I'm not as comfortable as I'd like in using caps a "delay timers" ( but as for everything, it just needs some time & brain dedication ;p )
-> thus, If you have some particular hint(s)/resource(s) on this, they're much welcome ! ^^ ( => 'd help in cases like the MR & OE desired behavior exposed .. ;p )

This being said, the pics:

MR & OE desired behavior ( circuit is untested ;/ -> I wrote it after the way FTDI pins does the reset on pin 1 of the ATmega328, but I'm such a nooooob in "RC circuits" ( if I'm right in thinking it's what these are called .. ) ):
shift_in_and_out_registers_3__MR_OE_modectrl_reboot_logic.JPG
shift_in_and_out_registers_3__MR_OE_modectrl_reboot_logic.JPG (523.3 KiB) Viewed 495 times
( Next & last reply contains pics of the breadboard setup mirroring the current breakout "debug" PCB )

User avatar
stephaneag
 
Posts: 60
Joined: Sat Mar 29, 2014 8:37 pm

Re: Original Xbox Controller S breakout board wip - joystick

Post by stephaneag »

breakout_debug_using_breadboard__1.jpg
breakout_debug_using_breadboard__1.jpg (422.49 KiB) Viewed 495 times
breakout_debug_using_breadboard__2__LEDs_as_outputs.JPG
breakout_debug_using_breadboard__2__LEDs_as_outputs.JPG (406.86 KiB) Viewed 495 times
breakout_debug_using_breadboard__3__uberjoys_in_top.JPG
breakout_debug_using_breadboard__3__uberjoys_in_top.JPG (614.21 KiB) Viewed 495 times

Looking forward to reading from you on this,
Thanks in advance & .. "Let's do this !! " *


* when enough time to ;p


Keep up the good work
+

User avatar
stephaneag
 
Posts: 60
Joined: Sat Mar 29, 2014 8:37 pm

Re: Original Xbox Controller S breakout board wip - joystick

Post by stephaneag »

Lastly !
( & sorry to post a new reply, I forgot this but I reeeeally wished to have an inspired opinion on this ;p ):

- how hard 'd it be to be able to read stuff while controlling it at the same time
- 'd it absolutely require more pins taken on the uC ?
- 'd it be need for the following silly question ? ^^

- is a "drunk mode" actually doable ? => that is, have one player controlling half of the time ( more or less, adjustable ) the other player's controls, both of them, or invert them :P *


* acutally, I originally had in mind one player "ghosting" the controller of another at random times for a random delay or whenever wanted ( could add quite fun to have a "humanly controlled malfunctionning gamepad controller" :p ), but whithout enough sleep before writing the current post ( as I was updating stuff ), I guess the above ( silly, so silly .. ) idea is a gift from a stoned brain matter that need a rest :|


So long
+

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Original Xbox Controller S breakout board wip - joystick

Post by adafruit_support_mike »

Kind of a firehose-worth of questions there.. let's take them in order as best I can:
stephaneag wrote: but I was wondering if the resistors being unconnected 'd cause any troubles
I'm not sure which resistors you mean, or what you mean by 'unconnected'. If you mean the state of the pin marked SIG when the transistors at 1 and 2 are shut off, the pin will float.
stephaneag wrote: The idea is to record the way a player controls his gamepad in the latter, while the former allows to control the gamepad from pretty much anything
Again, I'm not positive of what you're trying to do, but the chips you're using and the circuits you've sketched make me think you're trying to share microcontroller pins between output to the '595s and input from the 4021s.

If that's the case, let me introduce you to some friends of mine.. the 405x series of multiplexer switches:

The 4051 is an 1P8T (single-pole, 8-throw) switch. It connects a single common line to one of eight selectable lines.

The 4052 is a 2P4T (dual-pole, 4-throw) switch. It has two switches, each of which connects a common line one of four selectable lines. Both switches are controlled by the same address pins, so they change at the same time and to the same output number.

The 4053 is a 3P2T (triple-pole, dual-throw) switch. It has three inputs, each of which connects to one of two selectable lines. Again, all three switches are controlled by the same address pin, so they all connect to Y0 or they all connect to Y1.

They're all analog switches, so signals can go both ways.

It sounds like what you're trying to do is a job for the 4053. Set the address pin high, all the microcontroller pins connect to the '595s. Set the address pin low, all the microcontroller pins connect to the 4021s.

You can build the equivalent circuits from discrete transistors, but they're kind of bulky, and a 4053 costs, like, 20c.
stephaneag wrote: -> thus, If you have some particular hint(s)/resource(s) on this, they're much welcome ! ^^ ( => 'd help in cases like the MR & OE desired behavior exposed
Still guessing, but extrapolating from the above it looks like you're trying to set up break-before-make timing for your switches.. make sure one is all the way off before the next one comes on.

That's an interesting challenge, especially if you want it to act symmetrically: A shuts off, B turns on / B turns off, A turns on. If you pound your head against the logic long enough, you invent the XOR gate: ((A|B)&-(A&B )). Building it from discrete parts takes about 17 transistors. Then you have to connect it to a timing network, and then you have to distribute the control signals to the switches.

The 405x family has all that built in.
stephaneag wrote:how hard 'd it be to be able to read stuff while controlling it at the same time
It depends on where the signals are going. It's technically possible to make a microcontroller pin read its own output, the question is, "why do it?" The code already knows whether it just set the pin high or low.
stephaneag wrote:'d it absolutely require more pins taken on the uC ?
stephaneag wrote:is a "drunk mode" actually doable ? => that is, have one player controlling half of the time ( more or less, adjustable ) the other player's controls, both of them, or invert them
With a microcontroller it's easy. If you have two controllers, the code will have to read two streams of input and generate two streams of output. The basic case is "use input A to generate output A and use input B to generate output B". Swapping them would just be a matter of saying, "use input B to generate output A and use input A to generate output B".

To do it in hardware, you'd just need a 2P2T switch. In position 0, Ain connects to Aout and Bin connects to Bout. In position 1, Ain connects to Bout and Bin connects to Aout. You can flip the selection bit at random intervals, and at any frequency you want.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”