How to determine where to sample for demodulation of BPSK signals? I have a simple BPSK demodulator. Very simply, the signal comes in and is split into two branches, one for I and one for Q. 


The I branch is mixed with a sin wave of the carrier, and the Q branch mixed with the cosine wave of the carrier. 
Then, each of the outputs is convolved with a matched filter, (in this case a root-raised-cosine, which initially pulse shaped my transmitted bits). 
Now, if I combine both outputs and take the magnitude of both of them (I^2 + Q^2), I get the envelope. 
From here, I look for peaks, and choose their indicies. 
I then use those same indicies that I got from (4), and sample my I and Q at those same indicies. Now I have complex softbit values, and am able to correct for any phase or frequency offsets, and can make hard decisions from there. (I have the luxury of post processing btw).


This technique worked well with high to medium SNR. The problem is that with lower SNR (and maybe multipath), I do not know how to perform bullet (4). The problem is that instead of one peak in the envelopes corresponding to one bit, I now have multiple peaks, and 'peak picking' wont work because there are so many to choose from... how is this problem mitigated? This seems to be a bottleneck because if I cannot tell where my 'bit' is, I cannot move forward. Any thoughts?  

Any help is appreciated, math is good, although I would ask the answers be more pesudo-code /concept oriented in advance. Thanks!

Edit: Thanks to feedback from Dilip, I should also add that I can clearly see 'energy' in the envelope when there is a signal and there isnt a signal. (ie, before my signal arrived), so this leads me to believe that I should be able to sync/demod and that it isnt an SNR issue solely...
I have done something similar to this in MATLAB. In my cause, I used an Early/Late Gate clock recovery method to get an estimate of the offset between transmit and receive symbol timing. This method uses 3 samples per symbol - one at the optimal sample time, one that is 1 sample delayed and 1 that is one sample advanced. This works well for on/off keying signals, since there is no negative portion of the signal, but the methods below I think will work better for bipolar signals.

Another method is the Muller and Mueller Algorithm, which uses 1 sample per symbol. This uses the equation $e_n = (\widehat{y_n}y_{n-1}) - (y_n\widehat{y}_{n-1})$, where $e_n$ is the error , $y_{n-1}$ and $y_{n}$ are the previous and current symbol samples, and $\widehat{y_n}$ and $\widehat{y}_{n-1}$ are the decision outputs (-1 or +1 in your case). M&amp;M requires that the carrier is recovered first.

A third algorithm, which is very similar to the one above, is the Gardner algorithm. In this algorithm, the error signal is $e_n = (y_n - y_{n-T})y_{n-T/2}$, where $y_{n-T}$ is the sample one symbol in the past, and $y_{n-T/2}$ is half a symbol in the past. This requires 2 samples per symbol, but is not sensitive to the carrier.

The M&amp;M detector is looking at the peaks, while the Gardner method is looking at the peak and zero crossing to get timing estimates.

In all cases, you'll take the error estimate, feed it into a loop filter whose output is then used to advance or retard the symbol clock for the next timing estimate. The loop filter can be thought of as either a low-pass filter, a smoothing filter or simply as weighting older estimates less than newer ones. The loop filter controls a) how fast the timing converges and b) how much noise affects the estimates.

Another option is to use an equalizer which will then remove timing delay from the signal. This can also help for very noisy signals I believe.

I have used these resources in forming this answer:
http://www.comlab.hut.fi/opetus/333/2004_2005_slides/CarrierTimingRecovery.pdf
http://mobiledevdesign.com/tutorials/radio_matched_filtering_timing/

This article is especially helpful: http://rfdesign.com/images/archive/0901Litwin32.pdf
Here is a link to Gardner's original paper from 1986: http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1096561&amp;tag=1

Note In general this area is called "clock and data recovery" or "CDR". Specifically we're dealing with "symbol synchronization". These terms should aid you in your search.