Strange problem using the function set_motors(a,b)

I connected one PS2 joystick to the 3pi robot using these pins: PD0, PD1, PC5 and PD7.

The 3pi read perfectly the comands of the PS2, but when add only the function set_motors to the programm, the 3pi always read 0xFF in the bytes sent for the joystick. I tested the communications using the oscilloscope and all is OK.

Not is a problem of noise, because when i use set_motors(0x00, 0x00) the code does not work.

Which may be the problem?

My main code:

/*                    MAIN                */
int main()
unsigned int RetardRaul;
unsigned char varRaul;
unsigned char exit,i;
const unsigned char CMD_PSX[9] = {0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char PSX_DATA[9];



        exit = 9;
        for (i=0; i<exit; i++)
            PSX_DATA[i] = BytePSX(CMD_PSX[i]);              
            if ((i == 1) && (PSX_DATA[1] == 0x41)) exit = 5;
            for (varRaul=17;varRaul!=0;varRaul--) {SEL_off;}    // Delay

        for (RetardRaul=0xFFFF;RetardRaul!=0;RetardRaul--) {SEL_on;}



    int pot = read_trimpot();                
    int motorSpeed = pot/2-256;              
    if(motorSpeed == -256)    motorSpeed = -255;     
 //   set_motors(motorSpeed, motorSpeed);             <------------- PROBLEM 




Are you using any of the mega168’s timers to read the data from the joystick? When you first call the set_motors() function, the mega168 hardware is initialized to generate the necessary PWMs on the timer0 and timer2 hardware PWM outputs. If you have been using these timers for something else, this function call will most likely result in their being reconfigured.

You can look at the timer source code to see exactly what the motor initialization routine does. Check if that does anything that would interfere with your joystick-reading code.

- Ben

Hi Ben,
I’m not using timers. I have seen the source code .cpp of the motors and don’t se any incampatibility.
Is a very strange and I have tried many different things but with the same result :cry:

Can you post the code to BytePSX()? The problem must have to do with the details of how you actually read information from the controller. If you have to do anything extremely time-sensitive, the Timer2 ISR defined in OrangutanTime.cpp could cause a problem, but that seems unlikely. Could you try commenting it out and recompiling the pololu library to see if that fixes it?

Also, just to be completely clear, are you saying the the code you posted works if you leave out the set_motors line, but does not work if you put in set_motors(0,0), with no other changes?


Hi Paul, attached you can find the main programm and other fuctions.
I will try to rebuild the library, but this is the first time working with atmel :slight_smile:

Yes, deleting the line set_motors(0,0) my code works perfectly.

Let’s see if I’m lucky and I can help.

test.rar (1.25 KB)

Hi Paul & Ben,

have you seen anything suspicious in the sourcecode?

Hi! I have solved the problem:

Changing this line:
result |= (DTA_PLAY)? 0x80:0x00;
For this other…
if (PIND & 0b10000000) result |= 0x80;
else result |= 0x00;

Is a bug of the compiler? DATA_PLAY is defined exactly like “PIND & 0b10000000”.

Good night!

Ah-ha! That explains it. In the top of the file you attached, you incorrectly defined DTA_PLAY as
#define DTA_PLAY PIND &=0b10000000
That’s a typo - you meant just & instead of &=.

The incorrect version could potentially work, since x &= 0b10000000 usually has the value x & 0b10000000 (after modifying x). However, if the compiler evaluates the expression by returning x (assuming x has the new value), and x actually changes (as PIND can, since it’s an input port), then the value returned will not be x & 0b10000000 but instead the new value of x.

The reason that starting to use the motors was causing a problem is that that changed the values of PIND, which makes your incorrect expression always return true.

Anyway, I’m glad you got it working! Please write back if you have more questions about using your 3pi.