First some hard facts that need to be understood with a worst-case scenario - that 850Hz PWM...

The period of 850Hz is 1.17ms (1170uS). The resolution of Pulsin at 4MHz is 10uS. That gives us 117 counts (1170/10) for a 4MHz PIC for 100% input period. But we're only interested in 50% of that (30-80% PWM giving 0-21%O2). That means we've only got a maximum range of 58 steps to play with across the scale. 21%O2 divided by 58 steps gives us a resolution of 0.362% which falls short of your required 0.1%. You can't use a 4MHz PIC if you're playing with Pulsin.

At 20MHz, Pulsin returns steps of 2uS. That gives us 585 steps for 100% input period, but again we're only interested in 50% of that, so we have 292 steps to play with. 21%O2 divided by 292 steps gives us increments of 0.07% and we're in business to achieve your 0.1% accuracy requirement. So you've got to use a 20MHz PIC if you want to play with Pulsin or use another method of measuring your pulse period.

Working the figures backwards you can calculate that we need a minimum of 210 counts at 50% Input PWM to maintain 0.1% resolution of 21%O2. 420 counts is 100% multiplied by 2uS (Pulsin resolution at 20MHz) gives you a maximum PWM ceiling of 1190Hz above which we lose 0.1% accuracy in our results. So that is our upper-ceiling for PWM frequency...

The lower-ceiling is determined by our math... in so far that we must never spill out of a word variable (unless it is a prelude to a DIV32 statement). So let's now plan for a worst-case lower-end scenario say 400Hz PWM...

400Hz has a period of 2.5mS or a Pulsin period count of 1250 (remember our 2uS count of a 20MHz PIC). We can multiply our Period count by up to 52 times before we spill out of a word, let's say 50 to make the figures nice and easy to play with. We'll call this Melanie's maximum multiplyer (MMM).

Now having calculated our operational limits we set them aside and start to do some code... remember, we have four possible error conditions that we have to trap before we are confident that everything is going to run smoothly...

1. Input PWM frequency is under 400Hz
2. Input PWM frequency is over 1190Hz
3. Input PWM Percentage exceeds 80% (greater than 21%O2)
4. Input PWM Percentage is below 30% (less than 0%O2)

Fist let's get some data... and your code here is fine...

PulsIn F_pin1, 1, pHigh ' get high portion of input
PulsIn F_pin1, 0, pLow ' get low portion of input
Period = pHigh + pLow
If Period < 420 then goto ErrorPWMtooHigh
If Period > 1250 then goto ErrorPWMtooLow

Those two extra lines trap any Period frequency exceptions and make sure the data we're playing with is within our pre-calculated, pre-determined play range. Error conditions 1 & 2 are now accounted for.

Normally, to get a percentage the formula would be pHigh*100/Period. But we MUST have greater accuracy, preferably to two decimal places if we can get away with it and still NOT spill out of a Word Variable. First we'll deal with Error condition 3 (>80% Input PWM). All Temp (Temporary) variables are WORDS... and notice I avoid integer DIVISION wherever possible to prevent the introduction of math errors...

TempA = Period*40

Why 40? If MMM is 50, mutiplying by 40 is the equivallent of a scaled up 80%. Now to continue...

TempB=pHigh*50
If TempB > TempA then goto ErrorO2tooHigh

What the two lines above have done is to trap the error if the input PWM exceeds 80%. Error condition 3 is now accounted for. Finally...

TempA = Period*15

Why 15? If MMM is 50, multiplying by 15 is the equivallent of a scaled up 30%. To continue...

If TempA > TempB then ErrorO2TooLow

With those lines above we've trapped any possibility of the inputPWM falling below the illegal 30% value... Error condition 4 is now trapped. We can now continue safe in the knowledge that nothing from this point onwards (short of you not paying your electricity bill) can wreck your day... so...

TempB=TempB-TempA

Now we've extracted out the bottom 30% leaving a pure input value referenced to zero. Remember TempB at this point has a range from zero (minimum 0%O2) to Period*25 (maximum 21%O2) - that's because 80%-30% equals 50% (our operational span) therefore 25 is 50% of our MMM.

Now we need to produce a 0-100% PWM Output value for your 0-5v Output...

TempA=Period*25

Notice that TempA will always be a 15 bit unsigned integer satisfying the requirement of the DIV32 divisor...

TempC=TempB*100
TempD=DIV32 TempA

TempD at this point is a WORD value ranging from 0-100 which can be used for your PWM Output (use Hardware PWM in preference rather than software PWM because the software PWM requires constant polling otherwise it will decay).

If you need a whole BYTE (0-255) value for TempD representing 0-100% PWM then simply do this instead...

TempC=TempB*255
TempD=DIV32 TempA

Finally say we need to produce a 0-21.00% LCD Output as well (to two decimal places)...

TempC=TempB*2100
TempE=DIV32 TempA
LCDOut #TempE/100,".",#TempE DIG 1,#TempE DIG 0

And note the above LCDOut line is the only place we've used an integer divide. Errors at a minimum, accuracy at a maximum.

Clear as the driven slush...

Melanie