perhaps your demodulator already knows the baud rate
Many wireless communication protocols set the symbol_time to some known integer multiple of the chip-time or carrier cycle time.
Since you are able to demodulate the signal, your demodulator must already know the chip-time or carrier cycle time.
Perhaps you can take that time information and multiply it by the "known integer" to get the symbol_time; then you "merely" need to do phase alignment.
Is there any way to pull that time information out of your demodulator?
FFT
The symbol rate is approximately equal to the bandwidth.
(I hear that the -10 dB bandwidth is 1.19 times the symbol rate for QPSK -- is that true for all signal constellations?)
If you have a high enough SNR, you can put your signal through a FFT, and estimate the bandwidth.
I think this works in almost any format you have handy --
the raw ("real") modulated signal, or the demodulated ("complex" I,Q) baseband signal, or I alone, or Q alone -- but I don't think it will work if you feed phase data from the "Update #2" plot above into the FFT.
It's usually pretty easy for a human to visually pick out the -3dB bandwidth on a graph.
Is there a Matlab function for estimating the -3dB bandwidth?
When you have pure white noise coming in -- the SNR is too bad -- the -3dB "bandwidth" clearly has nothing to do with any real baud rate, but depends entirely on the filters used in your demodulator.
autocorrelation
You can find the autocorrelation of a function using the Matlab autocorr() or xcorr() functions.
There are at least 3 ways of converting that autocorrelation to an estimate of the baud rate:
- With approximately uncorrelated data bits, the autocorrelation at offset time of exactly 1 symbol_time or more are going to be approximately zero, and the normalized autocorrelation at short offset times from 0.0 to 1.0 bit time is approximately linear: 1-(time/symbol_time). Fit a straight line to those short offset times to get a good estimate of the autocorrelation at non-integer offset times, find offset time t_half that gives an estimated autocorrelation of about 1/2 along that fitted line, and your symbol time is about symbol_time ~= 2*t_half.
- During burst transmissions, some transmitters make every 10th bit a start symbol. Your autocorrelation function, as always, has one peak at 0 offset time; skip past that first peak, and search for the positive time t_positive that gives the next biggest positive peak (with expected amplitude roughly 1/10) in the autocorrelation function, and your symbol time is about symbol_time ~= t_positive/10.
- Some transmitters use a stop symbol precisely 9 bit-times after every start symbol, and give the stop symbol the negative amplitude of the start symbol. Search for the offset time t_negative that gives the biggest negative peak in the autocorrelation function (with expected amplitude roughly 1/10), and your symbol time is about symbol_time ~= t_negative/9.
autocorrelation approximation
Many other techniques use some quicker-to-calculate approximation of the autocorrelation function -- in particular, there's really no point computing the autocorrelation amplitude at offset times greater than 10 bit_times.
In particular, let's calculate the autocorrelation function at only one time offset H:
Delay the signal by some time H, and multiply the delayed signal by the original (non-delayed) signal, and use some perfect or leaky integrator get a long-term average.
(If your input signal is already clipped to the +1 -1 range, like most FM and PSK receivers, then that long-term average is already normalized.
Otherwise, normalize by the average of the square of the signal, so your long-term average is guaranteed to be in the range of -1 to +1).
Then tweak H to try to get that normalized long-term average to be exactly 1/2 -- make time offset H shorter if the normalized long-term average is less than 1/2; make H longer if the normalized long-term average is more than 1/2.
Then your symbol time is about symbol_time ~= 2*H.
other techniques
The wikibook "Clock and Data Recovery" sounds promising, although it is still a rough draft. Could you update it to tell what approach worked best for you?
I've been told that many receivers use a Costas loop
or some other relatively simple carrier recovery technique to detect the baud rate.
The communications handbook
mentions a "early-late gate synchronizer".
Could you use something like this?
details
Many wireless communication protocols add many "redundant" features to the signal in order to make it easier for the receiver to lock onto and decode the the signal in spite of noise -- start bit, stop bit, trellis modulation, error detection and correction bits, constant prelude and header bits, etc.
Perhaps your signal has one or more of these features that will make your job easier?
To understand all of this stuff, take a look at "Table 18-1. Equations for Calculating Baud Rate Register Setting" from the datasheet on page 189. The equation you suggested you found in some example code
UBRR1 = (F_CPU / 4 / baud - 1) / 2;
... is kind of close to the equation for Asynchronous Double Speed mode (U2Xn = 1)... but not exactly.
If you know the baud rate and crystal speed you intend to operate at, I would just pull the register settings out of "Table 18-9. Examples of UBRRn Settings for Commonly Used Oscillator Frequencies" on datasheet page 210 and call it a day. The only reason to use any of those equations is if you want to be able to change the settings dynamically at run-time for some reason (or if you want to do thins "elegantly" in software, I prefer compile time certainty for something like this to remove doubt).
For the settings you outlined in your question, that would be:
UCSR1A = 0; // importantly U2X1 = 0
UCSR1B = 0; // interrupts enabled in here if you like
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); // no parity, 8 data bits, 1 stop bit
UCSR1D = 0; // no cts, no rts
UBRR1 = 103; // 9600 baud @ 16MHz XTAL with U2X1 = 0
As a side note, while the hardware does store the baud rate register (UBBRn) as two 8-bit registers, in software there is no need to treat it as such. You can access the High and Low registers (e.g. UBRR1H and UBRR1L respectively) but you can also just
assign to (or read from) the named "combined" register as though it was a 16-bit register.
UBRR1 = 0x0343;
is functionally equivalent to UBRR1H = 0x03; UBRR1L = 0x43;
Best Answer
Baud rate is the number of symbols per second.
You have 36 bits, each bit is made up of 3 symbols (011 or 001), so there are 108 symbols.
One packet takes 44.7ms, so the symbol rate is \$\frac{108}{0.0447}\$ = 2416.1 symbols per second.
As each bit is 3 symbols you also know that it equates to \$\frac{2416.1}{3}\$ = 805.4 bits per second. You can confirm that as \$\frac{36}{0.0447} = 805.4\$ bits per second.