When the code activating the GPS is commented out (see below), the servo works as expected. For example, in this video, it is instructed to point straight ahead, which it does.
However, when the servo and GPS are both activated in the code, every time the GPS updates, the servo turns to an extreme position. In this video, while I want the servo to stay pointed straight ahead, you can see it alternates between being straight ahead and a hard right:
Here is what I’ve tried so far:
• I tried plugging the servo into a variety of digital pins, each of which either had the same effect or broke the GPS (e.g., digital pin 2 broke it).
• I tried a variety of different servos—the servo under my ultrasonic sensor and the RC car’s ESC (which receives a servo-like signal)
How can I fix this such that I get GPS data without compromising steering?
every time the GPS updates, the servo turns to an extreme position
Maybe you could detach the servo when GPS updates are due, and reattach when the update is complete, and you're ready to drive it.
This is a creative work around. However, I will only use it as a last resort--while it's better than steering off course while the GPS is updating, I'm not excited about losing steering while the update takes place either.
JeffsInventions:
What are interrupts in this context and why can't they be used simultaneously by two devices?
As far as I can see the Servo library levers off the hardware PWM generation to cause an interrupt when it is time to generate a servo pulse. This stops the code from doing what it is doing briefly and does something else (pulse the servo). They do this to extend the number of pins that can generate servo pulses from more than just the hardware-supported PWM pins.
Also SoftwareSerial uses interrupts to process incoming data. HardwareSerial does as well but not for as long. In the case of the servo, where I gather the exact length of the pulse is important, if it happens to be processing an incoming GPS byte, the servo pulse will be extended, probably sending the wrong length pulse.
JeffsInventions:
Some brief googling did not turn up how to implement HardwareSerial. Do you have advice as to how to do this/a link that describes how?
It's just Serial ... the basic serial examples show that. Use pins 0 and 1, and then do stuff like:
Serial.begin (GPSBAUD);
And then:
// read gps
while(Serial.available())
{
int c = Serial.read();
... and so on.
You've already got Serial.begin there. I don't know why as you don't seem to be using it. The hardware Serial is preferred to software Serial.
If that doesn't work (although I guess lots of people would be doing servos and serial) you could always use the hardware PWM pins and "manually" generate the correct length pulses. The hardware PWM can generate pulses without needing to use interrupts at all.
In my experience, in order for the servo to hold a particular angle, it needs to be constantly receiving a PWM signal. However, if I am manually generating the PWM signal, then any time the Arduino runs other code (e.g, updating the gps or running the obstacle avoidance algorithm), it stops sending the PWM signal. Is there a work around for this?
If I picked up a mega (http://arduino.cc/en/Main/ArduinoBoardMega2560), with multiple serial ports, perhaps the GPS and Servo wouldn't fight over one. I read about other folks having success with getting the Sparkfun GPS shield to work on the mega (Arduino Forum), but I don't understand how UNO shields can work on Megas--it seems like the board layouts are different. Are Uno shields compatible with Mega boards? Might a Mega solve my problem?
JeffsInventions:
In my experience, in order for the servo to hold a particular angle, it needs to be constantly receiving a PWM signal. However, if I am manually generating the PWM signal, then any time the Arduino runs other code (e.g, updating the gps or running the obstacle avoidance algorithm), it stops sending the PWM signal. Is there a work around for this?
The Uno has 3 hardware timers, the Mega more. All of those can be configured to output PWM signals and toggle a pin in hardware. Thus the pin is continually toggled regardless of what the code is doing. If you want reliable, constant PWM, use the hardware PWM.
Are Uno shields compatible with Mega boards? Might a Mega solve my problem?
The first pins are largely compatible. Some shields work on the Mega.
However you should be able to get a Uno to do it you can manage with only 3 timers. Normally one of them is used for timekeeping (the millis() and delay() functions).
All timers have 2 outputs each (the A and B sides) so you have a total of 6 hardware outputs (marked with a ~ on the board). That should be enough.