BotBoardunio conversion process:

Hi Devon,

I have played some more with your program and did not get it to fail (this time).

As I mentioned, I have had issues of it falling out of Analog mode and losing contact with the remote… I have some code in place in my Hex code that tries to detect this and do some recovery.

[code] ps2x.read_gamepad(); //read controller and set large motor to spin at ‘vibrate’ speed

// Wish the library had a valid way to verify that the read_gamepad succeeded... Will hack for now
if ((ps2x.Analog(1) & 0xf0) == 0x70) {
    // In an analog mode so should be OK...


} else {
// We may have lost the PS2… See what we can do to recover…
ps2x.reconfig_gamepad();
}

[/code]
The change I made to his library was to make reconfig_gamepad() to be a public function so I could call it.

This is still not robust enough, as I have had many times where I lose contact and my hex robot just keeps on a walkin… I may make a pass through the library and try to add some more robustness measures…

For example: he has code in his init code to try to decide what is the quickest we can call again to read the PS2 data. That may work, but I have found in the past that you can call fast enough that you get valid data, but the receiver never has time to receive information from the remote so you are hung with the old data…

Kurt

I did some hacking on his library, where the read gamepad function detects if we are still in Analog mode or not. If not, it will try to put it back into analog mode and try again, up to 5 times before failing…

You might try my version out and see if it helps… I updated my Arduino Brat code to use your pin numbers as well. So you can try running that one as well…

I will next try to setup one of my Hex robots again to try this out as well.

Kurt
Arduino_Brat-120403a.zip (16.9 KB)
PS2X_lib.zip (10.2 KB)

Your version of PS2X still has the same ghost button like behavior. The imaginary button press only seems to happen when I call one of my move functions after a real button press. If i only print to the terminal after a real button press it never generates a fake button press. This doesn’t make any sense to me but it might give you a clue as to why this is happening.

I just got my THR-4 hooked up to a Seeduino Mega with my old prototype shield and got my current sources converted to run again… So far it looks like I am getting a lot less times where the SSC-32 drops out and does not reconnect. So I think it is working better.

As for your case, the test program you put up did not run any sequences that I could tell, but would instead just print out a message on the serial port like Triangle. It did not fail for me. But if I am using your version of the code that does not return from a command until it completes and as such does not call off to the PS2, than some of your commands take a long time, like turn left may take 4 seconds. The PS2 code does try to reconfigure if your next call is over 1.5 seconds, so it is probably doing this and maybe failing. My Brat code starts up a move and then returns back to the main loop. It is using another timer object to do the group move code. When I started working on the Phoenix code I merged this code into my own version of the Servo library and I keep meaning to come back to the Brat code and have it use this library as well.

Kurt

Could elaborate on how you moved servos to a new position without blocking the flow of the program? I know you must have used one of the internal timers but I’ve never learned how to use them or even how they can be useful. I only recently learned how to use external interrupts… Could you suggest any reading to become more familiar with these lower level aspects of the Arduino?

I am not sure of any good reading material. I do have a few books the Arduino cookbook on my Kindle. That I look at. I also go into the library directory of the different installs and look at how some of the different libraries are implemented… Plus look at lots of processor documents.

For example my Brat code that I uploaded as part of this thread, currently is using the overflow interrupt from timer 2. What it did was to do the adjusting of the servo positions to get to the next location in the sequence… It used the standard servo library.

My later code for the Hex robot, I created as a library, which I modified the actual servo library. In this after each 20ms cycle through the servos, it would adjust the position for the next cycle in much they same way as the SSC-32 code would have and the HSERVO code did for the Bap28…

Kurt

Hi Jim and Devon (and others),

Jim, yesterday you mentioned, the problem of the user still having to have a USB to serial adapter to talk to the SSC-32, in order to do their servo alignments as well as doing firmware updates. As for doing the firmware updates, I personally think the SSC-32 should come by default with the latest xxxEGP version as my guess is that the SSC-32 is used much more often in robots other than 2 DOF hex… That would in the majority case eliminate the case where most users need/want to update the firmware…

As for doing servo alignments, I do it a bit differently with a couple of different options… But I first need to point out that I do not put my SSC-32 on non-mega Arduinos, like the BotBoarduino, I do not connect the SSC-32 to the Arduino using the hardware port, but instead use SoftwareSerial and connect it to pins 2,3. On Megas I use Serial1 (2nd hardware serial port). This allows me to do the Servo Alignment two different ways.

  1. Have Alignment code built into my Program. I use the USB port to get keyboard commands like (+ and -) to adjust the servos. In my current Hex code, I have this working again for non-SSC-32 version and have the beginnings of it working again for SSC-32 version. Today will hack in a little more code here, that in my case have a 4DOF, I can enter a command in this mode to compensate the specific servos that were moved by 1 or more clicks (15 degrees), so that you can do the alignment again as if the servos were back in their original non changed state… Not sure if I said that very well… Most if not all of this could be converted to using the A/B/C buttons on the Botboarduino…

  2. Use a simple forwarder… I have code conditionally compiled for the Hex that does this and it is pretty simple. In the Init/Define code I have:

// Add support for running on non-mega Arduino boards as well. #ifdef __AVR__ #if not defined(UBRR1H) SoftwareSerial SSCSerial(cSSC_IN, cSSC_OUT); #else #define SSCSerial Serial1 #endif #else #define SSCSerial Serial1 #endif
This is a little more complicated as I also define it for Chipkit (Pic32…)
In the Init I call the Init…

SSCSerial.begin(cSSC_BAUD);
Then the code that I have that is called from the Arduino main loop (actually called from my keyboard monitor) is:

[code]//==============================================================================
// SSC Forwarder - used to allow things like Lynxterm to talk to the SSC-32
// through the Arduino… Will see if it is fast enough…
//==============================================================================
#ifdef OPT_SSC_FORWARDER
void ServoDriver::SSCForwarder(void)
{
int sChar;
int sPrevChar;
DBGSerial.println(“SSC Forwarder mode - Enter $ to exit”);

for (;;) {
    if ((sChar = DBGSerial.read()) != -1) {
        SSCSerial.write(sChar & 0xff);
        if (((sChar == '\n') || (sChar == '\r')) && (sPrevChar == '$'))
            break;    // exit out of the loop
        sPrevChar = sChar;
    }
    

    if ((sChar = SSCSerial.read()) != -1) {
        DBGSerial.write(sChar & 0xff);
    }
}
DBGSerial.println("Exited SSC Forwarder mode");

}
#endif // OPT_SSC_FORWARDER
[/code]
Note: part of this code is simply to detect if the user should type: $ as a way to exit the loop. But as you can see it is pretty darn simple. Earlier I used this with the Botboarduino (earlier prototype), and was able the use LynxTerm to talk to the board and adjust the servo offsets… But again this depends on not having the SSC-32 on the same IO pins as the USB… Forgot to mention, that in my code

#define DBGSerial Serial

Kurt

I’m thinking that Jim would like to use the hardware uart to keep from having to use up two more of our precious pins. What i discovered yesterday is that you can flip the cable going from the BotBoarduino so that the tx goes to tx and rx to rx. Then if the arduino sketch isn’t using the uart then it will act as the usb to serial converter for the SSC-32. I hope that made sense to you. I understand why you don’t use the hardware uart but in some cases where I/O pins are in short supply it’s necessary. The benefit to this method is that all the user has to do is flip one connection and with absolutely no code they can talk to the SSC-32 through a usb port with no additional hardware such as a DB-09 and a usb to serial cable.

Would it be possible to convert the PS2X library over to timer2 so that the servo jitter completely goes away? The only problem that I see is the fact that timer1 is the 16bit timer where as timer2 is a 8bit timer. I don’t know which kind of timer event the library uses but couldn’t the 8bit timer be prescaled to overflow around the same time as the 18bit timer with a lower precision. Or is the precision of the 16bit timer necessary?

I understand, what you are saying, but it is always a trade off.

Note: The Botboarduino has 20 IO pins which is not that much different then the BB2 that has 20 IO pins plus the halfway crippled S_IN/S_OUT. Like BB2 the Analog capable pins can be used as standard digital pins as well.

For me, I can and will use 2 other pins to drive the SSC-32 and it has not been an issue of running out of IO pins. Example The Hex robot, only uses 2 pins for the SSC-32 plus 4 pins for the PS2, 1 for speaker, 2 for USB. . For A-pod, may add 1 sensor for Gripper. May enable Voltage divider(s), so still have several IO pins left.

As for hooking the SSC-32 directly up the IO pins associated with the FTDI, your millage may vary. That is it may work sometimes and it may not work sometimes, as the program on the ATMega chip is still running and it may choose receive/send characters at the same time. I believe I have seen XBEE shields that do this, and they end up saying things like, if you hook up the XBEE to use the FTDI chip of the Arduino board, to remove the processor from the board. Likewise with some of them, to update the program on Atmega chip you must remove the XBEE… This does not sound like something I would want to do…

Again I use the serial communications to the PC for debugging as well as ways to do other things…

I see another post came in here while typing. I am somewhat confused as I don’t believe that the PS2 library uses any timers. Yes the servo library uses 16 bit timers and needs this for the precession…

Kurt

If the PS2x library doesn’t use any timers then what is it that causes the servo jitter when calling read_gamepad()??? I must have misunderstood the reasoning back when we first discovered the problem.

Most likely one of two things.

The earlier version of the PS2x library did not disable interrupts when it changed the state of an IO pin, as these operations are not atomic, this can lead to problems. By atomic I mean that it is not done in one non-interrupt-able operation.

That is you will see in the code things like:

	  CLR(*_clk_oreg,_clk_mask);

What this does is clear a bit on an IO port by first reading in the current value, then anding it with the Not of the Mask and then writing it back to the IO port. This caused problems that for example suppose right after the port value was read in, the servo timer interrupt happens and the state of some of the pins on the port was read in is updated during that interrupt. When we return from that interrupt, we than write back our updated value and tromp on what the servo code did. Note: each of these IO ports controls up to 8 IO lines.
So if you look through the PS2X code you will see a bunch of comments with KJE in it. This is where I disabled interrupts around each of these changes to keep this from happening. These changes were than incorporated back into the main sources. So it is possible we could have missed a place…

OR…
When you disable interrupts, the interrupt code is not called until interrupts are re enabled. So maybe there is some place where we are disabling interrupt for too long of a period, which delays the processing of the servo long enough to change the timing too much…

Kurt

P.S. - One thing nice about Pic32 is that for these IO ports, they actually have 4 IO registers (One to set the values, One that will turn on the bits that are set to the register. Another one that will clear the bits that are written to it, and another one to XOR then ones… These are atomic…

Would defining those macros as functions and then using the <util/atomic.h> code blocks solve the problem of the SET and CLR getting interrupted by the servo library?

The atomic functions more or less do the same type stuff as I was doing, but probably with a little more overhead.
We could make them more secure, by putting the stuff into the actual macros. Could also convert these to inline functions.

On the Arm, code is there strong jitters or is it jerkiness that you are seeing? That is you read the PS2, which may say move the ARM 5 units, so it moves there, then stops moving, then reads the PS2, moves again? Versus on BAP or SSC-32 we may tell it to move so far over an amount of time, and during that time, it reads the PS2 and haves a new position to move to… If so may be able to smooth some of that out.

Kurt

We’re seeing a jitter as in the arm twitches even when stationary. I’ve not had a problem with the movement being jerky or not smooth.

Jim and Devon,

As I mentioned yesterday, I received the care package with 4 BotBoarduino’s so I decided to place on on my resurrected CHR-3 that is a semi-standard setup. I found my spare SSC-32 (was on the Arm) and now have it connected up.

I have also taken my current Arduino Pheonix code which has configurations for with or without SSC-32, XBee, PS2, … And I split off a copy of it to a new Sketch. I am in the process of stripping it down to a Botboarduino configuration. There are a few issues that I am needing to work out as the initial position does not feel right and the like.

Also I am going to take a pass through and strip out come convenience code. In particular things like using the streaming class as it is one more thing people have to know about and get the appropriate library. But I do like using it as it makes it easier for more complex serial output.

Also I need to make another pass though and try to minimize memory usage. This is for both program space and data space. I still have several options like my keyboard monitor on, and I am using about 28K out of about 30K maximum in program space. In Data space, I think I ran into cases where I exceeded the 2K of data and the program faulted… So again cleaning that up.

Back to Arm, May have to look at the PS2 code again, to see if there is any obvious place where we are either not protecting or taking too long protecting.

Kurt

Hi again, not sure if any of you are in today or not… But happy Easter!

I believe I have a version of the Botboarduino SSC-32 PS2 CHR-3 robot working OK. There are some quirks and some more testing, that can/should be done. Not sure if you have a setup there you can try it on? As part of this I removed most of the debug code as well as the streaming class.

Took me longer to get it working as when I moved the SSC-32 over to the old CHR-3, the left side got hooked up to the right side servos… So Up was down… :laughing:

Jim and others, up till now, for the most part the code pretty much follows along with the Basic program. That is we have more or less the same variable names… So if you can read one, you should not be that difficult to read through the C++ code and figure out what is going on. There are some hidden gotchas in the conversion. Things like on the BAP all math functions are done in 32 bit, whereas with C it is done differently depending on the size of the variables that are used. That is if you add a byte to a byte and it exceeds 256 it was probably still truncated to a byte value. So in C to get around this you will see places where we cast a variable to a bigger size to tell the compiler…

But soon, I will make a pass through the code and try to make it more maintainable and provide better scoping of data… Also would like to introduce a few more objects to the code. I already defined a class for ServoDriver, where I have two different implementations. I would also like to define a class for ControlInput, which the main code would call. As part of this, would like to reduce the number of globals. Not sure yet if they will simply be member variables of the classes or might create some class state objects… we will see…

But for now I will start simple and see where it goes. May also delay this slightly to do some more testing and to see which other robot classes that there is no code to run on the BotBoardDuino…

Kurt

Saturday Morning update: I have done some more hacking on the PS2x library, which I uploaded here. If you get a chance try it out and see if it helps. What I changed was, I merged in my Pic32xxx code, which had separate inline methods for things like clearing the clock bit, likewise for setting the clock bit. I did this earlier on the Pic as they had separate registers for this and it made them atomic… While doing this I also sped them up on the Arduino. Why, because his old code would at startup time get the bitmask for a pin, then convert it to a pin number and then the set/clr functions would have to convert the pin number back to a mask. Now I simply use the mask… Also to try to minimize the time interrupts are disabled, I moved the atomic code into each of these methods. Probably made the code slightly larger, but I probably removed that much code by the shifts… that were needed before.

Note: I have two versions of the library in the zip file… The new one has the standard name.
PS2X_lib.zip (21 KB)
BotBoardDuino_CHR3_PS2-120406b.zip (27.2 KB)

Happy Easter to you as well!

I’m currently spending time with the family but I’ll be sure to try out your latest ps2 code modifications later after I get home.

Update: The servo jitter is completely gone. I would suggest passing your changes onto Bill so he can roll them into the official version.

Awesome!!! 8)