go_away

Author Topic: Webbotlib - Pull-up resistors - enough for PS2 controller?  (Read 2364 times)

0 Members and 1 Guest are viewing this topic.

Offline KurtEckTopic starter

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 12
Webbotlib - Pull-up resistors - enough for PS2 controller?
« on: January 25, 2010, 11:41:06 AM »
I am having fun with my Axon2 mounted on my Lynxmotion Brat.  I had it walking using my DIY remote control over XBEE.  I did some major rewrite of some of my code which I am now in the process of debugging.

I thought it would next be fun to integrate on to it the PS2 controller as many more people have these than the DIY remote.

A couple of questions.   I believe the Atmega640 have pull-up resistors on each of the IO pins, which you can enable by setting the appropriate pin in the PortX pin to high, while the pin is configured for input.  But looking at the Webbotlib documentation, it sounds like setting the pin to high, will give a run-time error if the pin is not configured for output.  Is this correct?  If so is there a prescribed way in webbotlib to enable a pull-up resistor.

2nd has any one played much with the pull-ups?  Do you know if it is strong enough to use to pull-up the data line for the PS-2 controller, or should I add an external pull-up.

Thanks.

Kurt

Offline hopslink

  • Robot Overlord
  • ****
  • Posts: 202
  • Helpful? 14
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #1 on: January 25, 2010, 04:31:18 PM »
Quote
...is there a prescribed way in webbotlib to enable a pull-up resistor.

From the documentation pin_make_input(const IOPin* io, boolean pullup) so:
Code: [Select]
pin_make_input(B6, TRUE);makes pin B6 an input and enables the pullup.

Pullup resistance is 20-50KOhm from ATMega640 datasheet.

Offline KurtEckTopic starter

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 12
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #2 on: January 25, 2010, 06:34:04 PM »
Thanks somehow I missed that parameter on make input  :-[
Will experiment and see if the pull-up is sufficient
Thanks again
Kurt

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #3 on: January 25, 2010, 06:34:58 PM »
I would be curious to hear when you get this working. With all the tutorials for interfacing PS2 controllers, i though it would be easy. I tried 3 different libraries and 2 tutorials and could never get it to work. (granted on a arduino not an Axon. )

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,632
  • Helpful? 169
    • Society of Robots
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #4 on: January 25, 2010, 08:50:47 PM »
Quote
I had it walking using my DIY remote control over XBEE.
I've been thinking of making a DIY remote myself, but using EasyRadio . . . is it fancy enough to see?

Offline KurtEckTopic starter

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 12
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #5 on: January 26, 2010, 08:42:15 AM »
I've been thinking of making a DIY remote myself, but using EasyRadio . . . is it fancy enough to see?

Here is a picture of mine after the conversion:

There are several images and the like in the thread of me doing the conversion from RC Trans/recv (Spektrum DM8) to XBEE.  http://www.lynxmotion.net/viewtopic.php?f=21&t=5447
Likewise in the thread when Jim Frye of Lynxmotion made the original ones:
http://www.lynxmotion.net/viewtopic.php?f=21&t=4399&start=137

I would be curious to hear when you get this working. With all the tutorials for interfacing PS2 controllers, i though it would be easy. I tried 3 different libraries and 2 tutorials and could never get it to work. (granted on a arduino not an Axon. )
Will post more when I have had a chance to play with this.  One thing I know is not all PS2 controllers are the same.  I have tried out several of them with the Atom Pro.  Some work well like the one Lynxmotion now sells, madcatz...  Never did get the one from Logitech to work.  Not sure of my starting point here yet.
1) The code that is mentioned in the forum that you can download from trossen.
2) Some c++ classes I wrote awhile ago when I was playing with the BDMicro Maveric 1B (Atmega128)
3) try writing a new version using some of the SPI support within webbotlib. 
My guess is I will start with 3) and then add in my stuff from 2)...

Kurt

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,632
  • Helpful? 169
    • Society of Robots
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #6 on: January 26, 2010, 09:11:19 AM »
wow big and fancy!

Offline KurtEckTopic starter

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 12
Re: Webbotlib - Pull-up resistors - enough for PS2 controller? SPISW...
« Reply #7 on: February 02, 2010, 10:43:41 AM »
I just started playing with the code to try the PS2.  I started off with some code I had working earlier on a BDMicro Mavric (Atmega128).  But I thought it would be good to try out the SPISW as I found when I was working on PS2 stuff with Basic Atom Pros in assembly language that the protocol was pretty close...

I have some stuff coded but not sure of the best way to do things here.  For example you have a device list, but I don't see anywhere in the docs on how you are supposed to use it.    I did find a function in the header files that looks like it is supposed to be used: (spiDeviceSelect), but I tried passing my device to it, with both direct or by getting it's address and neither compiled... Will look more later.  My current code that compiles I simply use pin_high/pin_low to set the select line.  I also am trying to see if the internal pull-up will work for the DAT line.  Will hopefully start debugging later (Will probably first set up logic analyzer to see what is generated).  Also need to add test code to get it to work... 

Current untested stuff...
Code: [Select]
#define PS2_DAT K4
#define PS2_CMD K5
#define PS2_SEL K6
#define PS2_CLK K7


// Define our SPI interface
SPI_DEVICE PS2_device = MAKE_SPI_DEVICE(SPI_MODE_0,SPI_DATA_ORDER_LSB,PS2_SEL);
// Now wrap all the devices into a list
SPI_DEVICE_LIST spiBus1[] = {&PS2_device};
SPI_SW g_spiPS2 = MAKE_SW_SPI(spiBus1, PS2_CMD, PS2_DAT, PS2_CLK);

void PS2_Init(void)
{
spiInit(&g_spiPS2, TRUE);
pin_make_output(PS2_SEL); // init the select pin
pin_high(PS2_SEL); // Initialize to high...
    pin_make_input(PS2_DAT, TRUE);  // make the dat line input But also enable pull-up
};


void _PS2_ShiftOut(unsigned char *pb, int cb)
{
while (cb)
{
spiSendByte(&g_spiPS2, *pb++);
cb--;
}
}

boolean PS2_Query(unsigned char *paData, int cb)
{
int iLoopCnt;
unsigned char bMode;

// Hack to not have this loop forever in case of error
for (iLoopCnt = 0; iLoopCnt < 10; iLoopCnt++)
{
//spiDeviceSelect(PS2_device, TRUE);
pin_low(PS2_SEL);


// shiftout CMD,CLK,FASTLSBPRE,[$1\8]
spiSendByte(&g_spiPS2, 0x1);

//shiftin DAT,CLK,FASTLSBPOST,[DS2Mode\8]
bMode = spiSendByte(&g_spiPS2, 0x42);

if (bMode & 0x70)
{
// we are in an analog mode so continue to read in the extra bytes.
while (cb > 0)
{
*paData++ = spiSendByte(&g_spiPS2, 0);
cb--;
}
return TRUE;
}

pin_high(PS2_SEL);
clockWaitms(1);

pin_low(PS2_SEL);
// Not initialized properly, try to send out the correct init sequences.

pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$1\8,$43\8,$0\8,$1\8,$0\8] ;CONFIG_MODE_ENTER
static unsigned char _aps2_2a[] = {0x01, 0x43, 0x0, 0x1, 0x0};
_PS2_ShiftOut(_aps2_2a, sizeof(_aps2_2a));
pin_high(PS2_SEL);
clockWaitms(1);

pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;SET_MODE_AND_LOCK
static unsigned char _aps2_3[] = {0x01, 0x44, 0, 1, 3, 0, 0, 0, 0};
_PS2_ShiftOut(_aps2_3, sizeof(_aps2_3));
pin_high(PS2_SEL);
clockWaitms(1);

//;pin_low(PS2_SEL);
//;shiftout CMD,CLK,FASTLSBPRE,[$01\8,$4D\8,$00\8,$00\8,$01\8,$FF\8,$FF\8,$FF\8,$FF\8] ;VIBRATION_ENABLE
//;pin_high(PS2_SEL);
//;clockWaitms(1);

pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$01\8,$4F\8,$00\8,$FF\8,$FF\8,$03\8,$00\8,$00\8,$00\8] ;SET_DS2_NATIVE_MODE
static unsigned char _aps2_4[] = {0x01, 0x4F, 0, 0xff, 0xff, 3, 0, 0, 0};
_PS2_ShiftOut(_aps2_4, sizeof(_aps2_4));
pin_high(PS2_SEL);
clockWaitms(1);

pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$01\8,$43\8,$00\8,$00\8,$5A\8,$5A\8,$5A\8,$5A\8,$5A\8] ;CONFIG_MODE_EXIT_DS2_NATIVE
static unsigned char _aps2_5[] = {0x01, 0x43, 0, 0, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a};
_PS2_ShiftOut(_aps2_5, sizeof(_aps2_5));
pin_high(PS2_SEL);
clockWaitms(1);

pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;CONFIG_MODE_EXIT
static unsigned char _aps2_6[] = {0x01, 0x43, 0, 0, 0, 0, 0, 0, 0};
_PS2_ShiftOut(_aps2_6, sizeof(_aps2_6));
pin_high(PS2_SEL);
clockWaitms(144); //nap 4
}

// If we got here it means that we tried a number of times and it failed, so set up a set of default values and return.

paData[0] = 255;
paData[1] = 255;
paData[2] = 128;
paData[3] = 128;
paData[4] = 128;
paData[5] = 128;

return FALSE;
}


Offline hopslink

  • Robot Overlord
  • ****
  • Posts: 202
  • Helpful? 14
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #8 on: February 02, 2010, 04:44:24 PM »
Was browsing dunk's thread about his aerial robotics platform. Following the links to his website I see he has some code for AVR / PSx controller interface and wondered if it would be of interest to you.   

Offline KurtEckTopic starter

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 12
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #9 on: February 02, 2010, 05:19:04 PM »
Thanks, if nothing else it did answer that the built-in pull-up resistors are probably sufficient.  IE I don't have to wire up an external one...

Currently playing with SPI doing it, but so far the dat line is not talking back to me.  Fixed first problem that I was outputing MSB first, should be LSB... Not sure if the next problem is I am talking too slow for the PS2.  It looks like my clk is going at about 54khz and from earlier work I think the PS2 defaults to about 250khz... Will check to see about changing the SPI timing values otherwise I may simply import dunks stuff.  If it works, it is good enough for me!

Kurt

Offline dunk

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 1,086
  • Helpful? 21
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #10 on: February 02, 2010, 05:41:36 PM »
hey Kurt,
is had not occurred to me you had not read this:
http://www.societyofrobots.com/member_tutorials/node/200
it's my "PS2 controller on Axon" tutorial.
it bit-bangs SPI instead of using the built in SPI module.

i did try at one point using hardware SPI but never got it to work. i never tried very hard either because i had the bit-banging code working.
i'll be interested to see how you get on.

i didn't need pull up resistors. the internal pullups were fine.


dunk.

Offline KurtEckTopic starter

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 12
Re: Webbotlib - Pull-up resistors - enough for PS2 controller?
« Reply #11 on: February 03, 2010, 11:12:09 AM »
Thanks dunk,

I think I have it working now.  I started off with a cross between your code and some previous code of mine.  Using webbotlib I found that I could not easily use system port variables like: PORTK, PINK, etc,
so I converted to using the pin_high/pin_low/pin_is_high type of calls.  Also I found that delay_us(1) for example was delaying a lot more than that... So I just did some time waster in the code...

I know from some different platforms that sometimes the controller can fall out of analog mode, so I merged the init code into the query code.  Also I had a simple function that passed in an array of init bytes to call of to output instead of individual calls.  Will probably next move those to PROGMEM...

In case anyone is interested, the code currently looks like:
Code: [Select]
//=============================================================================
// PS2 - controller file
//=============================================================================
#ifndef _PS2_CONTROLLER_H_
#define _PS2_CONTROLLER_H_

#define PS2_DAT K4
#define PS2_CMD K5
#define PS2_SEL K6
#define PS2_CLK K7

void PS2_Init(void)
{
    pin_make_input(PS2_DAT, TRUE);  // make the dat line input But also enable pull-up
pin_make_output(PS2_CMD); // Make command pin be output
pin_make_output(PS2_SEL); // init the select pin
pin_high(PS2_SEL); // Initialize to high...
pin_make_output(PS2_CLK); // Make clock be output
};

// PSx controller communication function.
// send a byte on the command line and receive one on the data line.
// needs Attention pin to have gone low before called to activate controller.
BYTE gameByte(BYTE command)
{
        short int i ;
short int j;
        delay_us(1);
        short int data = 0x00;                                   // clear data variable to save setting low bits later.
        for(i=0;i<8;i++)
        {
if (command & 0x1)
pin_high(PS2_CMD); //sbi(PORTK, PScommand);      // bit bang "command" out on PScommand wire.
            else
pin_low(PS2_CMD); //cbi(PORTK, PScommand);
            pin_low(PS2_CLK); //cbi(PORTK, PSclock);                             // CLOCK LOW
            //delay_us(1);              // wait for output to stabilise
for (j=10; j > 0; j--)
;
            if ( pin_is_high(PS2_DAT)) //if((PINK & _BV(PSdata)))
sbi(data, i);
            pin_high(PS2_CLK); //sbi(PORTK, PSclock);                             // CLOCK HIGH
command = command >> 1;
        }
        pin_high(PS2_CMD); //sbi(PORTK, PScommand);

//        delay_us(20);                                            // wait for ACK to pass.
for (j=100; j > 0; j--)
;


        return(data);
}

void _PS2_ShiftOut(unsigned char *pb, int cb)
{
while (cb)
{
gameByte(*pb++);
cb--;
}
}

boolean PS2_Query(unsigned char *paData, int cb)
{
int iLoopCnt;
unsigned char bMode;

// Hack to not have this loop forever in case of error
for (iLoopCnt = 0; iLoopCnt < 10; iLoopCnt++)
{
//spiDeviceSelect(PS2_device, TRUE);
pin_low(PS2_SEL);


// shiftout CMD,CLK,FASTLSBPRE,[$1\8]
gameByte(0x1);

//shiftin DAT,CLK,FASTLSBPOST,[DS2Mode\8]
bMode = gameByte(0x42);

if ((bMode & 0xf0) == 0x70)
{
// we are in an analog mode so continue to read in the extra bytes.
gameByte(0); // ignore first byte which should return 0x5a
while (cb > 0)
{
*paData++ = gameByte(0);
cb--;
}

// And clear our select line...
pin_high(PS2_SEL);

return TRUE;
}

pin_high(PS2_SEL);
clockWaitms(1);

pin_low(PS2_SEL);
// Not initialized properly, try to send out the correct init sequences.

pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$1\8,$43\8,$0\8,$1\8,$0\8] ;CONFIG_MODE_ENTER
static unsigned char _aps2_2a[] = {0x01, 0x43, 0x0, 0x1, 0x0};
_PS2_ShiftOut(_aps2_2a, sizeof(_aps2_2a));
pin_high(PS2_SEL);
clockWaitms(1);

pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;SET_MODE_AND_LOCK
static unsigned char _aps2_3[] = {0x01, 0x44, 0, 1, 3, 0, 0, 0, 0};
_PS2_ShiftOut(_aps2_3, sizeof(_aps2_3));
pin_high(PS2_SEL);
clockWaitms(1);

//;pin_low(PS2_SEL);
//;shiftout CMD,CLK,FASTLSBPRE,[$01\8,$4D\8,$00\8,$00\8,$01\8,$FF\8,$FF\8,$FF\8,$FF\8] ;VIBRATION_ENABLE
//;pin_high(PS2_SEL);
//;clockWaitms(1);

//pin_low(PS2_SEL);
        //shiftout CMD,CLK,FASTLSBPRE,[$01\8,$4F\8,$00\8,$FF\8,$FF\8,$03\8,$00\8,$00\8,$00\8] ;SET_DS2_NATIVE_MODE
//static unsigned char _aps2_4[] = {0x01, 0x4F, 0, 0xff, 0xff, 3, 0, 0, 0};
//_PS2_ShiftOut(_aps2_4, sizeof(_aps2_4));
//pin_high(PS2_SEL);
//clockWaitms(1);

pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$01\8,$43\8,$00\8,$00\8,$5A\8,$5A\8,$5A\8,$5A\8,$5A\8] ;CONFIG_MODE_EXIT_DS2_NATIVE
static unsigned char _aps2_5[] = {0x01, 0x43, 0, 0, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a};
_PS2_ShiftOut(_aps2_5, sizeof(_aps2_5));
pin_high(PS2_SEL);
// clockWaitms(1);

// pin_low(PS2_SEL);
// shiftout CMD,CLK,FASTLSBPRE,[$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;CONFIG_MODE_EXIT
//// static unsigned char _aps2_6[] = {0x01, 0x43, 0, 0, 0, 0, 0, 0, 0};
// _PS2_ShiftOut(_aps2_6, sizeof(_aps2_6));
// pin_high(PS2_SEL);
clockWaitms(144); //nap 4
}

// If we got here it means that we tried a number of times and it failed, so set up a set of default values and return.

paData[0] = 255;
paData[1] = 255;
paData[2] = 128;
paData[3] = 128;
paData[4] = 128;
paData[5] = 128;

return FALSE;
}
#endif

Kurt

 


Get Your Ad Here

data_list