problem using PS2 mouse

Hi,

I am having problems using a PS2 mouse on my Arduino Mega and wondered if anyone else has experienced this as I am out of ideas how to resolve it:

I am building a robot which uses a PS2 mouse to tell how far it has moved along the ground and how far it has turned.
This is working reasonably well apart from the mouse seems to just randomly stop responding resulting in the robot going out of control. I have tried different power supplies, different pins on the Arduino, even a different PS2 library but every time I think I have resolved the problem it comes back :frowning:

The robot can work for some considerable time without problem, then suddenly this problem seems to start happening

It is annoying as apart from this I think I have resolved all my problems and the robot is ready to start using
see AlanEsq.com is for sale | HugeDomains for more info on the project

The script can be seen here: AlanEsq.com is for sale | HugeDomains
but I am not doing anything clever regarding the mouse, just keeping a track of how far along the ground it has travelled, so I don't think it is a software problem on my side (although I could be doing something obviously wrong?)
the relevant bit of code is below:

The PS2 library I am using is this one: http://thepotterproject.net/TPPNews/?page_id=180
but I had the same problem with the original version

while ( qtemp == 0 ) { // keep checking mouse reading

mouse.getData(&mouseInfo); // get a reading from the mouse

mxpos = mxpos + mouseInfo.x; // update current mouse data
mypos = mypos + mouseInfo.y; // update current mouse data

// check if target reached yet

if ( ndirect == 1 ) { // forward
// moving forward so y will be increasing
if ( mypos > num ) qtemp = 1;
}

else if ( ndirect == 2 ) { // reverse
// moving backwards so y will be decreasing
if ( abs(mypos) > num ) qtemp = 1;
}

else if ( ndirect == 3 ) { // right
// moving right so x will be decreasing
if ( abs(mxpos) > num ) qtemp = 1;
}

else if ( ndirect == 4 ) { // left
// moving left so x will be increasing
if ( mxpos > num ) qtemp = 1;
}

//lcdshow ( "" , String(mxpos) + " , " + String(mypos) );

} // end of while

I don't know what sort of numbers mouseinfo returns, but mxpos and mypos are only ints. Have you checked the values of mxpos/mypos? Have you tried making them longs? You are also doing a fair amount of String class stuff. Have you looked at memory usage?

dxw00d:
I don't know what sort of numbers mouseinfo returns, but mxpos and mypos are only ints. Have you checked the values of mxpos/mypos? Have you tried making them longs? You are also doing a fair amount of String class stuff. Have you looked at memory usage?

Thanks for the response

The numbers returned are only 128 max at a time (as far as I know), it tends to fail on the short runs as much as the long so I am pretty sure it is not to do with numbers getting to large for an INT

I use the MemoryFree library to report free memory when it is turned on an there is well over 6k free

BTW - I am pretty new to the Arduino and the C language, so I am likely to be making a simple mistake

BTW - in case it gives a clue as to what the problem is:

Sometimes it seems to change it's mind as to distance and all turns will suddenly be about 1/4 as far as they should be, then it will go back again after a few tries?

Still no joy on this :frowning:

Does anyone have a different PS2 mouse library I could try

BTW - I tried using a USB mouse (PS2 compatible) but it doesn't work - is there a trick into getting it to switch to PS2 mode or does the mouse have to be a PS2 only one?

I think the problem is with the timer1 interrupt I am using?
I tried adding some more code to it and this made he problem much worse

Problem is that I need it so the robot will react to remote control buttons and more importantly shut down the motors when it goes out of control - and help much appreciated

the interrupt code I am using is below:

if ( digitalRead(radioa) == LOW ) radiobutton = 1;

else if ( digitalRead(radiob) == LOW ) radiobutton = 2;

else if ( digitalRead(radioc) == LOW ) {
// EPO button pressed
radiobutton = 3;
stop_robot();
digitalWrite(sounder,LOW); // sounder off
digitalWrite(ledr, HIGH); // warning led on
lcdshow( "STOPPED !" , "EPO button" );
while (1); // stop
}

else if ( digitalRead(radiod) == LOW ) radiobutton = 4;

// stop robot if bumber activated (i.e. it has hit something)
if ( digitalRead(bumper) == LOW ) {
// bumper activated
stop_robot();
digitalWrite(sounder,LOW); // sounder off
digitalWrite(ledr, HIGH); // warning led on
lcdshow( "STOPPED !" , "bumper hit !" );
while (1==1); // stop
}

// stop robot if motors have been running too long
if ( mtime != 0 && millis() > ( mtime + 25000 ) ) {
stop_robot();
digitalWrite(sounder,LOW); // sounder off
digitalWrite(ledr, HIGH); // warning led on
lcdshow( "STOPPED !" , "motor timeout" );
while (1==1); // stop
}

the interrupt code I am using is below:

It is also completely unrealistic. The key feature of interrupt code is that it must be fast.

None of this stuff is fast, by any stretch of the imagination.

        lcdshow( "STOPPED !" , "EPO button" );
        while (1);    // stop

        lcdshow( "STOPPED !" , "bumper hit !" );
        while (1==1);    // stop

        lcdshow( "STOPPED !" , "motor timeout" );
        while (1==1);    // stop

It's not obvious why the state of all the buttons is being checked in a timer interrupt, rather than being polled in loop, But, you really need to rethink the interrupt routine (and probably the whole use of interrupts).

Thanks for the reply

This is my first attempt to use interrupts so I would be the first to admit I don't really know what I am doing
I did think this was kept pretty short though, all it does is check the state of a few digital input pins?

The loop can't be used to check for the buttons as in the loop it calls procedures to move the robot around which can last minutes, so my plan was to check for a button being pressed in the interrupt and if it is set a flag so that in the loop later on it can act on this
the other thing I use the interrupt for is to stop the robot in an "emergency" - if the bumper hits something or if the motor has been running too long (as this will mean the PS2 mouse has stopped responding)

Is there anything I can do to resolve this or is it back to the drawing board?

BTW - The bits you quote e.g. lcdshow( "STOPPED !" , "bumper hit !" ); would only run if the robot needs to be stopped in an "emergency" so in the normal running of the interrupt these would not matter (that was my logic anyway?)

Is there anything I can do to resolve this or is it back to the drawing board?

Yes, it's back to the drawing board. You need to create a state machine. Determine what states the robot can be in, what causes a transition from one state to another (a sensor reads HIGH or LOW, some time has elapsed, etc.), and what actions to perform as a state change occurs.

No interrupts are needed, but no delay()s are acceptable. Got that part? NO delay()s.

Just Googled "state machine" - I think I understand the concept?
I will see if I can figure out how not to use interrupts at all - shame though :frowning:


Update: Just had a flash of inspiration; in the routine where it uses the PS2 mouse I have modified the sketch so that it turns the interrupt off and calls the procedure the interrupt uses manually during this part, afterwards it turns the interrupt back on

Just Googled "state machine" - I think I understand the concept?

I am not a programmer by any stretch of the imagination so this is probably much more advanced stuff than I am up to doing, but I will see if I can figure out how not to use interrupts at all - shame though :frowning:


Update: Just had a flash of inspiration; in the routine where it uses the PS2 mouse I have modified the sketch so that it turns the interrupt off and calls the procedure the interrupt uses manually during this routine, when it has finished using the mouse it turns the interrupt back on

It will be a while before I know if this has fully resolved the problem, but so far, so good :slight_smile:

It will be a while before I know if this has fully resolved the problem, but so far, so good :slight_smile:

What you mean is that you have not seen the problems that this causes manifested yet.

alanesq:
I have modified the sketch so that it turns the interrupt off and calls the procedure the interrupt uses manually during this routine, when it has finished using the mouse it turns the interrupt back on

Whoa ...

PaulS:
What you mean is that you have not seen the problems that this causes manifested yet.

yep, that is what I ment :wink:

This will be about the 5th time I have thought I have resolved it, but then when I least expect it, the problem starts happening again
fingers crossed though.........