[dil isi lib] dil's somewhat pointless blog

Xbox 360 RF module + Arduino

I was going to make a huge write-up on this, but I can't be bothered right now. I'll probably do something about it later. Until then, have an Arduino sketch. If you don't know what you're doing with it then chances are you don't have an Arduino, in which case the file is useless to you.

The sketch:

/* Arduino code to communicate with xbox 360 RF module.
Original work by (yaywoop) / additional ideas from Alexander Martinez - modified by dilandou (www.dilandou.com, www.diru.org/wordpress)
First sends LED initialisation code followed by LED startup animation code, then sleeps until a button press for sync command.
RF module must be powered with 3.3V, two diodes in series with USB 5v will do. Connect the USB wires to a host computer, and the data and serial wires to Arduino.
of course, make sure to have a common ground */

#include <avr/sleep.h>

#define sync_pin 2 //power button repurposed for sync button (pin 5 on the module)
#define data_pin 3 //data line (pin 6 on the module)
#define clock_pin 4 //clock line (pin 7 on module) 

int led_cmd[10] =  {0,0,1,0,0,0,0,1,0,0}; //Activates/initialises the LEDs, leaving the center LED lit.
int anim_cmd[10] = {0,0,1,0,0,0,0,1,0,1}; //Makes the startup animation on the ring of light.
int sync_cmd[10] = {0,0,0,0,0,0,0,1,0,0}; //Initiates the sync process.
volatile boolean sync_enable = 0;

void sendData(int cmd_do[]) {
  pinMode(data_pin, OUTPUT);
  digitalWrite(data_pin, LOW);    //start sending data.
  int prev = 1;
  for(int i = 0; i < 10; i++){

    while (prev == digitalRead(clock_pin)){} //detects change in clock
    prev = digitalRead(clock_pin);
      // should be after downward edge of clock, so send bit of data now
    digitalWrite(data_pin, cmd_do[i]);

    while (prev == digitalRead(clock_pin)){} //detects upward edge of clock
    prev = digitalRead(clock_pin);
  }
  digitalWrite(data_pin, HIGH);
  pinMode(data_pin, INPUT);
}

void initLEDs(){
	sendData(led_cmd);
	delay(50);
	sendData(anim_cmd);
	delay(50);
}

void wakeUp(){
  sync_enable = 1;
}

void sleepNow() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // set sleep mode
  sleep_enable(); //enable sleep bit
  attachInterrupt(0, wakeUp, LOW);
  sleep_mode();
  sleep_disable(); //disable sleep bit
  detachInterrupt(0); // disables interrupt 0 on pin 2
}

void setup() {
  Serial.begin(9600);
  pinMode(sync_pin, INPUT);
  digitalWrite(sync_pin,HIGH);
  pinMode(data_pin, INPUT);
  pinMode(clock_pin, INPUT);
  delay(2000);

  initLEDs();
//  sendData(sync_cmd);
}

void loop(){
  Serial.println("Sleeping.");
  sleepNow();
  delay(200);
  if(sync_enable==1) {
    Serial.println("Syncing.");
    sendData(sync_cmd);
    sync_enable = 0;
  }
}

 

xbox360_rf_plus_arduino_schematic

Comments (32) Trackbacks (2)
  1. I have ATMEGA8 uC, could you send me hex file for arduino with this uC? I triet to compile it on arduino, but i have only project file and i dont know the path of hex files.

    • In the Arduino IDE, hold Shift while clicking the Upload button. This triggers verbose mode, and will show where the hex file is temporarily held. The hex files are deleted as soon as you close the IDE.

  2. cool.. appreciate the work you have put in.

  3. wer do we type these??????

  4. This controls the sync process and state of the leds. Am I correct in assuming that the state of the controller buttons are not accessible to the arduino, but over usb only?

    • To be honest, I haven’t dug that far into it. I was planning on a little experimentation, but never got around to it. What I do know is that when you send certain commands to the RF unit, it will send data back over the same line. I think, however, it’s mostly things like “I have X controllers connected” or “This controller is controller X” etc. Useful for fine tuning the lights, if you wanted to be more fancy, but not much else.

  5. my controller wont sync … the module does the sync light animation and so does the controller but they wont do it at the same time. when both are syncing it automatically starts all leds flashing and then the module stops and the controller just keeps flashing instead of a player # light turning on like with a real xbox. any ideas on how to fix this? the xbox rf module is x802779-010 rev:A-1-1 and the controllers are x809478-001 and x817145-006 (i think these are the model numbers)

    • Sounds like a bit of a dumb question, and I apologise for asking it, but when you say the sync animation, you mean after you’ve pressed the center button and not the animation when it’s first powered on, correct?

      Also, the module itself won’t have an LED lit to show it has a controller connected. Unfortunately it would require figuring out the data sequence it replies with to say what number controller is connected, then telling it to light whichever LED. Extra effort for an entirely cosmetic feature. :P

      It would seem that there’s a rev B hardware now with different pinouts. It’s easily identified with the RF02 moniker. The main differences seem to be DATA on pin 7, and CLK on pin 9 (at 130hz).

  6. Is it possible to use this to control servos without needing a pc to send the data over serial?

    • There are people asking a similar thing here: http://forums.xbox-experts.com/viewtopic.php?t=4029&p=26982

      Personally I’ve not gone that deep into it as I’m not confident enough to start reverse engineering protocols. From the seems of it, though, the general idea is that you could either set a uC up as a USB host and decode whatever data is sent over USB, or directly hook into the logic going between the RF chip and the USB chip and use the raw data from there. If you have a logic analyser or oscilloscope give it a try. I’d be curious to know the results myself.

  7. Hi there, I was wondering if I could get a quick schematic that corresponds with the code posted here. I have only worked with Motorola chips and assembly in the past and don’t have much experience with the arduino, it’s libraries, and much c.

    I’ve gone ahead and made sense of the code (save a few lines) and I would like to confirm a few speculations based on the arduino’s pinout and a schematic.

    Sorry for the trouble.

    • I’ve added a schematic to the bottom of the post. It’s pretty simple so far as things go. If you’re paranoid about the logic being above the 3.3V supply for the board, you can either ignore it, or stick some voltage dividers in there, but considering the logic only happens for -very- short times, it’s mostly unnecessary.

      If you wanted a more permanent and less wire hogging solution, you could always power the Arduino from the usb supply powering the RF module. Essentially the only need for the Arduino to have a USB connection is for the serial debugging (which you can safely remove from the code).

      Personally I’ve moved the whole thing over to an ATTINY45 soldered directly onto the board. Using an Arduino permanently is a wee bit overkill, afterall.

      • Can you give me a bit more details on how to hook the TINY up? In your other post they used the test points on the module. I would like to get a good idea on how to use it. Also the TINY code you use was the file he posted?

        • I used a quick and dirty port of my Arduino code for the ATTINY45, nothing made public yet. I might clean it up at some point. As for my wiring, I used near on exactly the same wiring as with the Arduino, only to pins 5, 6, and 7 on the TINY, instead of Arduino pins d2, d3, and d4. I didn’t use the test points.

  8. I miss data on how the Arduino is powered here.
    I’d also like to know the current draw of the module, because it might be possible to pair everything up in a nice looking setup.

    • Two choices for power, really. Either plug the arduino in separately when it’s needed for syncing, or tie it in to the USB cable before the diodes. As for current draw, device manager is reporting 260mA. I’m not going to argue with it.

  9. personally i dont think your going to be able to use it to be able to sniff buttons using only commands.

    I think its a pretty simple USB HID interface? Arduinos can host these. I’m sure I’ve even heard of some people bit banging HID hosts.

    …try setting an arduino up in HID host mode and implementing a simple joypad sketch.

  10. Hey there. I got my hands on some of this RF-Modules (Rev H) and wired up everything correctly and in the same way as you schematics (except that I don’t use the Power SW and set up DATA and CLK to PIN 3&4 on Arduino). The module itself works great over USB but I cant get the LED initialization done. The clock just won’t change. One of my thoughts was that maybe the voltage of the DATA line is slightly too high (because it’s powered by arduinos 5V). Any ideas on that how to get this thing working? See the following link for the wiring: http://twitpic.com/8mirxx

    Thanks and best regards

    • I’ve not personally noticed any problem with the logic voltage being too high. When you say the clock won’t change, you mean the module is keeping it high or low? Remember that the CLK pin is an output only; the module dictates the clock, not the Arduino.

      • The clock is always kept low. I know that the CLK comes from the module.
        I thought maybe I broke the module because the 5v was too much for serial but connected to an xbox it’s still working fine…

        • Odd. Maybe the rev H has a different pinout? I know that the RF02 modules are different. Have you tried probing with a logic analyser or such?

          • Unfortunately I got no logic analyzer in here and I also searched the web for a pinout of the rev H – no success :\

        • I would possibly suggest, in lack of a logic analyser, a look at using an Arduino as a logic analyser. There are plenty of projects out there, including a couple on the Arduino playground. That’s about the only thing I can suggest, I’m afraid.

          • I’ve found out, that CLOCK and DATA (if the module is connected to the xbox) runs at 1,8V. Afair you’re using an Arduino mini (which runs at 3,3V). 1,8V would trigger a HIGH on a mini while I’m using an Arduino Duemilanove (running at 5V) where 1,8V is slightly too little to trigger HIGH. So I guess to get this thing working I’d need some pull-up resistors – will try that these days.

  11. Hi

    I want to know if the Teensy + + 2.0 can do the same with the code shown above. I did a manual in Spanish for now.

    See manual.
    http://www.slideshare.net/Metaconta2/teensy20

    Best regards.

  12. I cant get this to work with attiny13
    the code is from user cuba in post
    http://diru.org/wordpress/2011/03/wireless-xbox360-controller-on-a-pc-without-the-commercial-dongle/#comment-205
    #include
    #include
    #include
    #include

    #define B(x) (1<<x)
    #define sync_pin PB1 //sync pin
    #define data_pin PB3 //data line
    #define clock_pin PB4 //clock line

    #define digitalRead(x) (((PINB & B(x)) != 0)?1:0)
    #define digitalWrite(x, y) (y == 1 ? (PORTB |= B(x)):(PORTB &= ~B(x)))

    int led_cmd[10] = {0,0,1,0,0,0,0,1,0,0}; //Activates/initialises the LEDs, leaving the center LED lit.
    int anim_cmd[10] = {0,0,1,0,0,0,0,1,0,1}; //Makes the startup animation on the ring of light.
    int sync_cmd[10] = {0,0,0,0,0,0,0,1,0,0}; //Initiates the sync process.

    void sendData(int cmd_do[])
    {
    DDRB |= B(data_pin);
    PORTB &= ~B(data_pin);
    int prev = 1;
    for(int i = 0; i < 10; i++)
    {
    while (prev == digitalRead(clock_pin)); //detects change in clock
    prev = digitalRead(clock_pin);

    digitalWrite(data_pin, cmd_do[i]);

    while (prev == digitalRead(clock_pin)); //detects upward edge of clock
    prev = digitalRead(clock_pin);
    }
    PORTB |= B(data_pin);
    DDRB &= ~B(data_pin);
    }

    int __attribute__((OS_main)) main()
    {

    DDRB = 0b000000;
    DDRB |= 0b1;
    PORTB |= B(sync_pin);

    _delay_ms(2000);

    sendData(led_cmd);
    _delay_ms(50);
    sendData(anim_cmd);
    _delay_ms(50);

    for (;;)
    {
    if ( (PINB&B(sync_pin)) == 0 )
    {
    sendData(sync_cmd);
    _delay_ms(500);
    }
    }
    }

  13. Hi

    Here is the source code for the PIC16F629.

    ;**********************************************************************
    ; This file is a basic code template for assembly code generation *
    ; on the PIC12F629. This file contains the basic code *
    ; building blocks to build upon. *
    ; *
    ; Refer to the MPASM User’s Guide for additional information on *
    ; features of the assembler (Document DS33014). *
    ; *
    ; Refer to the respective PIC data sheet for additional *
    ; information on the instruction set. *
    ; *
    ;**********************************************************************
    ; *
    ; Filename: xxx.asm *
    ; Date: *
    ; File Version: *
    ; *
    ; Author: *
    ; Company: *
    ; *
    ; *
    ;**********************************************************************
    ; *
    ; Files Required: P12F629.INC *
    ; *
    ;**********************************************************************
    ; *
    ; Notes: *
    ; *
    ;**********************************************************************

    list p=12f629 ; list directive to define processor
    #include ; processor specific variable definitions

    errorlevel -302 ; suppress message 302 from list file

    __CONFIG 0x3FD4

    ; ‘__CONFIG’ directive is used to embed configuration word within .asm file.
    ; The lables following the directive are located in the respective .inc file.
    ; See data sheet for additional information on configuration word settings.

    CBLOCK 0×15
    ENDC

    ;***** VARIABLE DEFINITIONS

    ;**********************************************************************
    ORG 0
    BSF STATUS,RP0
    CALL 0x3ff
    MOVWF T1CON
    BCF STATUS,RP0
    MOVLW 0×7
    MOVWF CMCON
    BSF STATUS,RP0
    MOVLW 0xfd
    MOVWF GPIO
    MOVLW 0×1
    MOVWF TMR0
    MOVLW 0xff
    MOVWF 0×15
    BCF STATUS,RP0
    BSF INTCON,T0IE
    CLRF 0×23
    BSF GPIO,GPIO1
    CALL 0xf
    CALL 0×78
    CALL 0xf
    GOTO 0×68
    CALL 0xb
    CALL 0xb
    CALL 0xb
    CALL 0xb
    CALL 0x7c
    CALL 0×9
    CALL 0×76
    BTFSC GPIO,GPIO5
    GOTO 0x6b
    BTFSS GPIO,GPIO5
    GOTO 0x6d
    CALL 0x7c
    CALL 0×9
    CALL 0x7a
    GOTO 0×64
    CLRF 0×23
    BSF GPIO,GPIO1
    RETURN
    MOVLW 0xaf
    GOTO 0×21
    MOVLW 0×84
    GOTO 0×21
    MOVLW 0×4
    GOTO 0×21
    MOVLW 0×90
    GOTO 0×21

    end

    • can you post some more details for newbies, how to assamble code or just send hex file

    • how would i load this into a program for altering/playing around with? which program would i use? i have codeblocks installed but i dont seem to be able to paste it to it, it only ever takes the first line and then throws up errors

  14. Is that a coded with pawno?


Leave a comment

(required)