Com3 Vs. PulseOut
bot using data from a gps. I have a BX-24p in a Lynxmotion mini atom
bot board. Pin 20 is connected through a level shifter to the rs-232
interface of a handheld gps (Garmin Legend). The gps streams data in
standard 4800 81N nmea format over the serial link. I use com3 on pin
20 to read the serial data. (I'm using com3 and an arbitrary pin so I
can Debug.Pring info to com1.) I can read current lat/long/heading, I
have a waypoint in the BX and the BX calculates bearing to target,
compares to current heading and figures out which way to turn to head
towards the target. I've tested this much while carrying the gps and
board around while walking and it works.
However, I have now plugged the continuous rotation modified servos
from the bot into pin 7 and 8 and put in PulseOut commands to drive
the servos rather than just print "right," "left," or "forward."
Unfortunately, I'm now getting garbage data for lat/long/heading.
When I comment out the PulseOut command -- works. When I uncomment
PulseOut command -- garbage in.
I suspect that it is a timer conflict between com3 and PulseOut. The
manual says that there may be a conflict when using PulseOut and com3
at the same time. However, I'm only sending a 1.5 ms pulse each to 2
servos and while reading the serial data, I don't send any pulses at
all so it isn't like I'm using both at the exact same time. I have
the PulseOut in my main loop and I've thought about putting some extra
delay in. I've also thought about moving the gps input to com1 and
using com3 for debugging, but haven't done that yet as I think I'll
have to use more complicated serial calls rather than the simple
If anyone has experienced this before and can help, it would be much
appreciated. I can post code snippets if that would help.
Consider that COM3 is implemented in firmware, and is buffering input in
the queue ahead of your demand for it so, as long as the port is open,
it will be using Timer2.
A solution might be to close COM3 when you have a complete frame of GPS
data and open it again when you're ready for more. I suspect that the
CloseCom(3,...) will immediately free Timer2; it will also dump whatever
valid data remains in the input queue. You should be able to use
PulseOut with COM3 closed.
If that won't work or you lose too much data, you might need to move to
> The manual says that there may be a conflict when using PulseOut
> and com3 at the same time. However, I'm only sending a 1.5 ms
> pulse each to 2 servos and while reading the serial data, I
> don't send any pulses at all so it isn't like I'm using both
> at the exact same time.
If Com3 is open you are, in fact, "using it".
The way that a software UART like Com3 works is that the processor
is interrupted at some multiple of the bit frequency - often 4 or
more times the bit rate but I don't know the particulars of the BX
implementation. The higher interrupt rate is required in order to
guarantee that each bit is sampled near the center of the bit's time
slot. The goal is to sample right at the 50% point in the bit
window but doing so somewhere in the 25% to 75% range will work as
long as the transmitter's and/or receiver's bit rate clocks are not
too far from the ideal frequency.
(Technical sidebar: It is important to remember that the A in UART
stands for asynchronous. Since the transmitter and receiver are not
synchronized except by detection of the start bit, a 4x multiplier
is about the smallest you could expect to successfully use under
conditions of worst-case clock skew between the transmitter and
receiver. Clock rate inaccuracies can add to the problem because
the timing difference accumulates with each bit in a character.
This causes the receiver to get further ahead of or behind the
transmitter for later bits in a given character.)
Assuming a 4x interrupt rate, at 4800 baud the BX is getting an
interrupt about every 52uS. If you have interrupts disabled for
more than about 1/4 of a bit time you run the risk of the software
UART getting out of sync with the bit stream and, consequently, not
sampling the input line at the right time or missing some bits
If you call PulseOut with a pulse time of 1.5mS, interrupts will be
disabled for approximately 1.5mS. During that time you could miss 7
or 8 bits of the incoming serial data.
Even if you use the hardware UART (Com1) you'll have to be careful
using PulseOut and other routines that disable interrupts. The
longest that you can have interrupts disabled when using the
hardware UART is just short of two character times (but leaving
enough time for the processor to fetch two received characters). At
4800 8N1 there are 10 bits per character so you can keep interrupts
disabled for something like 4mS maximum and still avoid missing
>Even if you use the hardware UART (Com1) you'll have to be careful
>using PulseOut and other routines that disable interrupts. The
>longest that you can have interrupts disabled when using the
>hardware UART is just short of two character times (but leaving
>enough time for the processor to fetch two received characters). At
>4800 8N1 there are 10 bits per character so you can keep interrupts
>disabled for something like 4mS maximum and still avoid missing
>incoming characters. I just finished a project with exactly this problem: that is, not having
enough time to process the data that was streaming from an RS-232 GPS
device. I'm using a Laipac G30 which is capable of transmitting either
NMEA protocol or SiRF protocol , either streamed or polled. The reason I
selected the Laipac was that it is capable of being polled. I don't now
if the Garmin Legend is capable of being polled, but if it is (if it's a
SiRF receiver, it probably is), you can stop the streaming data and only
get data when you want it by polling the receiver for it. That would
allow you to stop multitasking and get some control over the processing
I'm about to post some code that demonstrates how to stop the streaming
and poll for the sentences that you want. I'll get it up as soon as I
get out from under another software project. Oh yeah, Happy Holidays.
(Now where is that code that I'm looking for...)
ps. Warning: Off Topic. I saw the Miller commercial with the Christmas
light show. The very least they (Miller's advert agency) could have done
was credit someone other than themselves for the light show. THAT should
be covered under the Millenium Copyright Act!
>... The very least they (Miller's advert agency) could have done
> was credit someone other than themselves for the light show.
> THAT should be covered under the Millenium Copyright Act!
Of course, what we don't know is whether they used it with permission -
they may have paid the creator handsomely for his work. If not,
it'll soon be Miller time for the him and his attorneys.
>--- In basicx@basi..., Paul Dubinsky <pdubinsky@f...> wrote: >>... The very least they (Miller's advert agency) could have done
>>was credit someone other than themselves for the light show.
>>THAT should be covered under the Millenium Copyright Act!
>Of course, what we don't know is whether they used it with permission -
> they may have paid the creator handsomely for his work. If not,
>it'll soon be Miller time for the him and his attorneys.
Here's hoping. But I can here the lawyers arguing that it was in the
public domain ciruclating on the web just waiting to be salvaged by the
salvage pirates of Madison Avenue so they don't owe him a dime. Who
knows? We can only hope..
>Yahoo! Groups Links >
not getting good lat/long/heading from the gps.
However, I'm now trying to drive my bot around...My bot is a 4WD
skid-steer using modified continuous rotation servos. I've peppered
my code with pulesout's, but I still can't get the servos to run
So, I'm thinking about breaking my program up into 3 pieces with 2 and
3 being separate tasks that I'll spin off of my main program:
1. Main program - navigation and state control
2. Read com3 and decode lat/long/heading
3. Drive servos
So I'll continuously decode the gps data in the background and
continuously send pulses to the servos in the background and use the
main to compute which way to turn and change the values that pulseout
My servo sub will be very simple --
pulseout to left servos
pulseout to right servos
sleep for 20 or 30 ms
I'm a bit concerned that the constant pulseouts will interrupt the
serial reads and I'll lose characters from the incoming gps data.
Does anyone see a problem with the above? The other option I've
thought of is to try to use the pwm output of the Atmega8535 to drive
hardware an H-bridge and used PWM to drive the H-Bridge. It works,
but I think I need to figure out the optimal PWM frequency. I think
that the inductance of the motors interferes with the higher
frequency PWM rates.
I can hear a resonance "sing" in the motors at the high PWM rates, and
the torque of the motors drops to near zero.
You can use PWM to drive servos, sure. As I recall, 28Hz and 56Hz are
available rates from dual-PWM Timer1. But, if you need to generate a
pulse period that can vary by 1mS (1.0mS to 2.0mS) at 56Hz (a ~18mS
period), you might suffer low useful PWM resolution.
If you use 10-bit Timer1 at 56Hz, (1/56/1024) ~= 17uS per PWM count, so
a nominal 1mS pulse width is represented by ~57 of the 1024 PWM counts.
Timer2, and thus COM3, will be unaffected. Tom