Help with Parallax standard servo with Raspberry Pi and Java programming for full 180
BlazedGun
Posts: 2
Hello, this is my first thread so I hope I am posting within the rules and in the correct place. I really need help in that I am using Java to send pulses that control the servo via the Thread.sleep. However, I can't seem to get the servo to actually rotate all the way counter clockwise. I can only get 0 degrees and 90 degrees but not 180 degrees of rotation. This is a sample of what I have.
// HIGH: Set GPIO port ON
commandChannel.write(GPIO_ON);
commandChannel.flush();
// Pulse Width determined by amount of
// time while HIGH
java.lang.Thread.sleep(2, 200000);
// LOW: Set GPIO port OFF
commandChannel.write(GPIO_OFF);
commandChannel.flush();
// Frequency determined by amount of
// time while LOW
java.lang.Thread.sleep(20);
Reading the specs, apparently neutral is 1.5 milliseconds. but I only got it to rotate to neutral with .5 milliseconds. java.lang.Thread.sleep( 0 , 500000); Can anyone give me a clue?
// HIGH: Set GPIO port ON
commandChannel.write(GPIO_ON);
commandChannel.flush();
// Pulse Width determined by amount of
// time while HIGH
java.lang.Thread.sleep(2, 200000);
// LOW: Set GPIO port OFF
commandChannel.write(GPIO_OFF);
commandChannel.flush();
// Frequency determined by amount of
// time while LOW
java.lang.Thread.sleep(20);
Reading the specs, apparently neutral is 1.5 milliseconds. but I only got it to rotate to neutral with .5 milliseconds. java.lang.Thread.sleep( 0 , 500000); Can anyone give me a clue?
Comments
From my very limited knowledge of Jave, I understand the "Thread.sleep" command isn't necessarily very accurate.
Could there be system overhead messing up the timing?
Regardless of platform I would not be using Java for driving pulse width modulated signals to anything directly like that. Java is a slow interpreted language and has automatic garbage collection. That basically means you can never really know how long that sleep is going to take. Although I imagine the time you specify in the parameter is a guaranteed minimum. Throw threads and processes into the mix, as you do on a Linux based system. and it's hopeless.
The Parallax propeller chip is ideal for such "bit banging" interfaces. But even there I would not be writing the code myself, the are a number of existing modules or "objects" available to do that already. Including one that can drive 32 servos simultaneously from a single Propeller chip!
Similarly the Raspberry Pi has a number of existing libraries fro dealing with it's GPIO and providing servo drive. For example this http://learn.adafruit.com/adafruit-16-channel-servo-driver-with-raspberry-pi/overview
Admittedly that is for Python, another slow and garbage collected language, but I'm there are other solutions for Java.
Of course my solution would involve a Pi and a Propeller
I just find it weird that no matter how I adjust the time, the only thing I can get it to do is go directly to neutral or clockwise but no where in between. Just to confirm, the way I am trying to send the pulses is correct right? It's just that the raspberry pi may not be accurate or something? And that the standard servo takes .75 milliseconds to 2.25 milliseconds with 1.5 milliseconds being neutral? Just making sure I am not doing something wrong with my logic.
Propeller add-on for Raspberry Pi: RoboPi.. the most advanced robot controller for Pi
http://forums.parallax.com/showthread.php/153275-Propeller-add-on-for-Raspberry-Pi-RoboPi..-the-most-advanced-robot-controller-for-Pi
Generally the OS will guarantee at least a given period, but it may also exceed that time (kind of like my teenagers). C/C++ might give you something closer on the OS than Java or Python, but it will never be accurate running on an OS.
Now if the OS is removed by simply using a microcontroller, a language like C/C++ can deliver exact timing. For one, there is no garbage collection in C/C++ to come along and disrupt the timing. Another item is required though, and that is either a timer for interrupt driven devices or a system clock for a non-interrupt device like Propeller.
Some people will complain about interrupts on microcontrollers, but there is a way around that too. Those microcontrollers that offer interrupts usually have timers too. The timers are how to achieve predictable timing or determinism to a point ... that is until you exhaust timers or have timer routines that hog cpu time.
Propeller doesn't use interrupts, so it is easier to have determinism with the system clock than other microcontrollers. If determinism is not important, then that may be another story.
In this case at least, those servos will never work the way you want them to work without using a microcontroller.
Good luck!!!
BTW, The Propeller is a great microcontroller for controlling things like NeoPixels. Here's a link to my Propeller controlled NeoPixel projects.
I didn't find an example of the RPi directly controlling servos, but here's a project where the RPi is used to directly control a h-bridge.
Your 0.75ms to 2.25ms range on servo pulses seems about right. The exact range can vary from servo to servo. The little blue servos I get from HobbyKing need an even greater range to achieve a full 180 degree rotation. The "normal" range is often listed as 1ms to 2ms.
In case you weren't aware, the Propeller can drive up to 32 servos without additional hardware (and many many more if you add some ICs).
There are other options such as Lazarus which runs naively under the Raspbian operating system. Compiling on the Raspberry can be slow however, running speed is fine. You could also use cross compiling to compile faster. I only tried it once but everything seemed to work fine.
http://wiki.lazarus.freepascal.org/Lazarus_on_Raspberry_Pi