Back again! Hope all is well. Added a Pan and Tilt to my rover and it works but as the D pad is pressed the P & T only moves with each press of the pad button. In other words, the servos won’t sweep as I hold the button down (I’ll send a short video from my iPhone so you can see what I mean). I’m sending a copy of my code also. I tried using the writeMicrosecond command but couldn’t get the P & T to move with that. I’m thinking it’s my code but maybe the D pad can only work this way? Thanks!
PS2_Arm_Rover.ino (15.5 KB)
Hey,
That’s some great news! I re-read the entire topic (it has been a nearly year, so I needed a refresher!), and notice you said before you did not think you could write that code. It seems that you did, so kudos on that!
We’ve checked the code quickly (~lines 601-653) and notice it would indeed act that way, since ButtonPressed(buttonNameConstant) is used directly, which only reports the first time a button is pressed. If the button is held, it will not report further presses (by design) once it has reported it (after it gets called the first time during that “button press”).
For reference, here is one of those modules of code:
if(ps2x.ButtonPressed(PSB_PAD_RIGHT))
{
P = min(P + 10*PTSpeed, 170);
Pan.write(P);
...]
}
The typical way to have continuous operation when a button is held is to have code triggered on both a press and a release of a button. Usually, it goes something like this:
if(pressed(button))
{
value = inc/dec;
held = true;
}
if(released(button))
{
held=false;
}
if(held)
{
value = inc/dec;
}
That should not be any more difficult than using .write(), except you’d use µs instead of degrees.
It is a software issue, but it is a product of how the library is built, too. Some gamepad libraries also offer extra functions, such as “isHeld()” or something similar for such cases. This one does not, but as seen in the above example, it is not too completed to reproduce.
We’ve created a small example for you to try. We tested it with a Lynxmotion BotBoarduino & PS2 V4 controller and a small RC servomotor on pins 13 (port jumper set to VS). Please find the source code attached to this post.
The code adds a few definitions and some new variables at lines 112-123. The definitions are about the min/max angles and also the step/continuous move sizes (all in degrees, since that is what you were using before).
Further down in the code, the boolean values are used to indicate when a button is held after a “press” event, causing also a change of position equal to the “step” size. If not of the buttons were pressed, the code then checks to see if any of them was released and changes the boolean value to match if that was the case (lines 654-699). Then, the last check is done which causes a position change of “continuous” size if the corresponding boolean value indicates the button is still being held.
As-is, the code currently moves by 10 degrees and then smoothly. That’s a bit jerky but also allows moving quickly from end to end. If you prefer having only smooth continuous motion, simply change the two defines PAN_STEP & TILT_STEP to be equal to PAN_CONT & TILT_CONT (i.e.: make all four of them equal to 1).
We hope this helps. Good luck with the project!
Sincerely,
2018-03-26_A4WD_AL5D_PanTilt_0001.ino (17.6 KB)
Excellent, thanks much! I did quite a bit of research and never came upon some of those commands! It will be helpful in future projects as well. I’ll try it this weekend (my work keeps me away from home a lot) and let you know the results. I did have another question though. In the code there are “Arm Current Pos” (I assume Pos is short for ”position”) and “Arm Temporary Pos” variables, could you explain how and why they are used? Thanks again, you guys rock!
Hey,
Here are answers to your questions/comments, as usual in-line with them:
Typically, a good place to look is in the .h (header) file of any library you use. Header files should contain all the declarations of the functions available from the library. For example, PS2X_lib.h file from the PS2X library contains a list (declarations) of all the publicly available functions. These are functions you can access (call) from your code. Of course, to know what they actually do, you’d have to go in the related .c file!
We are looking forward to results (and some pics/vids, if possible).
Indeed, it is related to the “position” of the arm.
The temporary variables (tmpx, tmpy, tmpz, tmpg, tmpwa, tmpwr) are used in the main loop and are modified by the code checking for gamepad (user) interactions. At line 701 (in the code attached above), the Arm() function (lines 236-275) is called to perform inverse kinematic based on the values of those temporary variables. At the end of the function (lines 266-273), the current temporary values are stored into the other set of variables. This could also be done outside of the Arm() function, such as after it is called since they are all global variables (visible/accessible everywhere). These secondary values are used in the various calculations in the main loop to determine the new state.
In general in such a main loop, a few things happen in order:
]Read inputs (in this case, actualize the game pad values, line 280)/:m]
]Process inputs against current state (can be seen also as the “last state”, 335-669)/:m]
]Generate outputs (in this case, this is done as part of the Arm() function for simplicity. It may have been clearer to have that done at the end of the main loop, outside of it)/:m]
Therefore, to know both your current state (while you are processing your inputs) and calculating your new state, you need 2 of each relevant variables, one container for current and one container for the new values.
I hope this helps make sense a bit more of what is done in this code. Please note it was created a long time ago and while some minor improvements have been done on it, it sorely needs a good makeover (refactoring) to make it easier to follow… and probably quite a few more comments, too.
Sincerely,
P.-S.: We’ll probably extract that pan & tilt code using the PS2 and move that to its own example, too. I figure you are not the only one who needs something like this as a starting example.
Thanks for answering my question, yes that helps. I’ll have to digest the information more but I can already see how it’s used. I print all this stuff for future reference. I’ll be in touch!
The code modifications worked great! I’ll send some videos. Thanks again for all the help, it was a great project. I’ll be starting my next project soon, building a BH3 Hexapod. I was intrigued by your post about using a RaspberryPi as the controller but decided to use a Botboarduino along with the SSC-32U. I plan on learning some Python and when I do I’ll probably switch the Botboarduino for a RaspberryPi 3 and experiment. I’m gonna try my best to figure things out myself but I might need some help! http://https://www.robotshop.com/forum/https://www.robotshop.com/forum/images/smilies/icon_wink.gif I should center the servos first, correct? Is the best way to center them by using the Servo Sequencer?
youtu.be/KW0dsNNlnuE
Hi,
Thanks for sharing this great info. Informative links.
Regards.
Nice vids! Glad to see that pan & tilt in action. Haven’t even had the time to actually try it out yet…
And yeah, while the RPi would provide much more processing power, it is also a bit more open and most likely would require more learning to get into. Then again, it also has a large community of people using it, just like the Arduino.
As for centering motors, you can use anything that provides you a 1500 µs pulse/RC control signal. It could be the sequencer, it could be an Arduino-compatible board, etc. Most certainly it is preferred to center all servomotors first to ensure you have the right range of motion on all joints.
Sincerely,