PDA

View Full Version : MPXA4115A picbasic code



iw2fvo
- 14th May 2009, 17:46
Good day to all,
I am searching for a reference picbasic code to get pressure from a Motorola MPXA4115A absolute pressure sensor.
Did someone write such a code ?
thanks
Ambrogio



Edit from Moderator:
A Wiki has been created from some of the posts in this thread. It is located here: http://www.picbasic.co.uk/forum/content.php?r=184-MPX4115A-picbasic-code

ScaleRobotics
- 14th May 2009, 18:09
Darrel has the basic formula here: http://www.picbasic.co.uk/forum/showthread.php?t=182

Darrel Taylor
- 14th May 2009, 19:24
It's been a few years since that thread. Don't even remember doing it.

However, I think pt3rg asked the wrong question back then.
I'm sure he also wanted to convert the A/D reading from the sensor to a pressure value.
May be why he never came back. :o

With the formula for Vout ...
Vout = Vs*(0.009*P - 0.095)

For 10-bit A/D and 1 decimal, the reverse would be
P = ADC * 0.1086 + 10.6

-- OR --


ADCIN 0, ADval
P = ADval * 1086
P = DIV32 1000
P = P + 106

LCDOUT "P=",DEC P/10,".",DEC P//10,"kPa"


hth,

Darrel Taylor
- 15th May 2009, 02:18
In case you didn't want 10-bit A/D with 1 decimal place in kPa ...

This should cover the other possibilities.
http://www.pbpgroup.com/Calculators/MPX4115A/MPX4115A.htm
<br>

iw2fvo
- 15th May 2009, 07:46
Thanks Darrel for your very professional reply on the matter.
I saw your last post just now.
I think your assistance is great for all people in the forum.
Regards,
Ambrogio
IW2FVO
North Italy

iw2fvo
- 15th May 2009, 12:54
Hi Mr. Taylor,

I am goping to prepare an home made weather station : this will be an hobby project for my small radio ham station.
I have seen the pressure transducer calculator you have post to me: it is very interesting.
I would like to use the PIC 10 Bit ADC instead of using an additional 12 bit ADC.
I have considered that my home is at about 1050 ft above the mean sea level and the baro pressure will never change so widely. I have in mind to put the PIC ADC " -REF " to 3.75 Vdc and the ADC " +REF" to 5Vdc.
The 3.75 Vdc is about 938 mB of presssure that has never been observed here in the years.
In this case I will use 10 bit to read the voltage output from 3.75Vdc to 5Vdc.
What do you think about that ? Do you recomand this solution ?
If it will be Ok, what will be the final PICbasic code ?
Thanks a lot for the interest.
Regards,
Ambrogio
IW2FVO
North Italy

dhouston
- 15th May 2009, 15:38
I'll let Darrel help with the coding but, if you haven't used this sensor, you should be aware that decoupling its voltage supply line is critical (Figure 3 in the datasheet). Otherwise, it will be too noisy to make use of its output.

iw2fvo
- 15th May 2009, 16:04
Thanks,
any suggestion for a practical good decoupling of the power supply based on your experience ?
Thanks
Ambrogio

dhouston
- 15th May 2009, 17:30
I used the 1.0µF and 0.01µF as well as the 470pF capacitor values shown in Figure 3 (Page 5) of the datasheet and the output was clean. Before adding them the output was wildly erratic. In my case, I used SMD ceramic caps.

Darrel Taylor
- 15th May 2009, 20:48
I have in mind to put the PIC ADC " -REF " to 3.75 Vdc and the ADC " +REF" to 5Vdc.
The maximum VREF- is (VREF+ -2.0V). So with VREF+ at 5V, VREF- can be 3.0V MAX.

I'll add the option to the calculator later tonight and see what happens.
<br>

iw2fvo
- 15th May 2009, 21:28
Thanks Darrel,
I forgot the vref- constrain. So the VREF- will be 3Vdc.
Ambrogio

Darrel Taylor
- 16th May 2009, 04:58
You're welcome Ambrogio,

I've added the Vref+/- to the calculator.
It should come up with a good formula for you now.

I haven't figured out how to deal with the +/-1.8% error yet.
So these numbers represent an "Ideal" sensor.

MPX4115A Calculator
http://www.pbpgroup.com/Calculators/MPX4115A/MPX4115A.htm

Now I gotta go back and redo the MPX4250D for Walter. :)

hth,

Acetronics2
- 16th May 2009, 09:50
Hi, Darrel

Handy tool, indeed !

Could you add ( or allow ) the 4.096, 2.56, 2.048 and 1.024v "Classical" Vref values ( 3 decimals !!! ) ???

Alain

Darrel Taylor
- 16th May 2009, 10:17
Could you add ( or allow ) the 4.096, 2.56, 2.048 and 1.024v "Classical" Vref values ( 3 decimals !!! ) ???
Done.

MPX4115A Calculator
http://www.pbpgroup.com/Calculators/MPX4115A/MPX4115A.htm

Hit refresh if you already have the page open.

:cool:

iw2fvo
- 16th May 2009, 11:24
Darrel,
it is a very usefull calculator: thanks again.
I will use a 5Vdc Vref+ and a divide by resistor divider for Vref-. Could it be OK ?
Is there any possibility to compensate for the accuracy error ?
( I am not familiar with those sensors .. ).
Thanks,
regards,
Ambrogio
IW2FVO
North Italy

Darrel Taylor
- 16th May 2009, 22:05
Resistors will work fine.
It's difficult to get exactly 3.0V using standard values, but with a 4.7K and 6.8K divider, you'll get about 2.96V. Use 1% or better resistors.

These pressure sensors are "Ratiometric" which means that their output voltage changes proportionally to the power supply voltage. So using resistors allows the Vref to change with the power supply voltage too, which is a good thing. A voltage reference that does not change with PS differences can cause incorrect readings if VDD is not exactly 5.00V. Many 7805 type regulators will be anywhere from 4.85 to 5.15V

For the accuracy, each sensor will be off by a different amount up to 1.8% of full scale.
You would need to take readings from the sensor being used at both the high and low ends of the range, and compare them against values read by some other device that is known to be calibrated.

The slope and intercept can then be recalculated for the measured values to create a new formula for that specific sensor. The calculations can be done with the PIC, but I wouldn't recommend it. Or you can do the calculation manually and just enter the slope and intercept into the PIC for that specific sensor.

Charles Linquis
- 17th May 2009, 00:00
And if you need more resolution - you can use an 18F8723. They have 12 bit A/D's.

Darrel Taylor
- 17th May 2009, 01:41
I've updated the Calculator again to include a Calibration section at the bottom.

Once you have test data for a sensor, it will calculate the new slope and intercept.
Be sure to set the number of decimals at the top, it affects the calibration numbers.

Cheers,

Acetronics2
- 17th May 2009, 09:48
Hi, Darrel

This tool is becoming from good to better and better !

Just one point :

Don't you think, for a 10 bits ADC i.e., the LSB is Vref / 1024 and not Vref /1023 ???

as 0 is 0v and 1023 is NOT Vref ( see µChip apps ...), but Vref x 1023/1024 ...


Not so big an error ... but for those looking for the 224th bit error !!!

and it is neater tho get exact 4 mv/bit for a 4.096 v ref. ...


BTW ... I think ! ( yes ... I can ! ) ...

What about a " Mouseover " on the graph to show the Pressure and AD Count values pointed at ???

Regards

Alain

Melanie
- 17th May 2009, 10:15
Actually, it's 1024 bits, but you include ZERO, so the range is 0-1023.

But your math is always divided by the MAXIMUM (Full Scale) value (which is 1023).

That is because there are 1023 equal portions of whatever you are dividing up to make your whole. Zero is not a portion! I'd get the hump (big-time) if I went into Maison Alain (French Restaurant) and got the Zero portion of the Cream Cake!

Acetronics2
- 17th May 2009, 10:37
Hi, Mel

I found that in the MAX 1241 datasheet:




Output Coding and Transfer Function

The data output from the MAX1240/MAX1241 is binary,
and Figure 10 depicts the nominal transfer function.
Code transitions occur halfway between successiveinteger
LSB values. If VREF = +2.500V, then 1 LSB =
610μV or 2.500V/4096



This is not the first ADC datasheet where i've found that ...

from MAX 187




Output Coding and Transfer Function

The data output from the MAX187/MAX189 is binary,
and Figure 10 depicts the nominal transfer function.
Code transitions occur halfway between successive
integer LSB values. If VREF = +4.096V, then
1 LSB = 1.00mV or 4.096V/4096.



From MCP 3202




4.2 Digital Output Code

The digital output code produced by an A/D Converter
is a function of the input signal and the reference voltage.
For the MCP3202, VDD is used as the reference
voltage. As the VDD level is reduced, the LSB size is
reduced accordingly. The theoretical digital output code
produced by the A/D Converter is shown below.
where:
VIN = analog input voltage
VDD = supply voltage
Digital Output Code = 4096 * VIN / VDD



From MIC 640 ( a pre-programmed 12F675 )




· Résultat = 256 x VIN/VCC où VIN est la tension d’entrée et où résultat est arrondi à
l’entier le plus proche.
Ainsi par exemple, si VCC = 5 volts et VIN = 3,5 volts, le résultat de la conversion sera :

Résultat = 256 x 3,5 / 5 = 179,2 arrondi donc à 179 soit encore B3 en hexadécimal.



so, I'm a bit confused, here ...

Regards
Alain

Melanie
- 17th May 2009, 11:05
I'm sorry, bit I'm going to 'DISAGREE' with them ALL...

Common sense...

Let's go to the extreeme... a ONE BIT ADC... (the kind every PIC has on every I/O Channel)...

Are you going to consider your I/O pin as having TWO states ZERO and ONE?

Well, I suppose it has got two states... so the 'ADC' range is 0-1.

So therefore whenever I use TWO in my calculations I can never get any more than 50% of the true answer? So with 5v as my VREF, I'll never get more than 2.5v in the calculations with an input state of 1. I must get an input state of 2 before I get 5v... Kinda tough getting 2 out of 1 bit!!!!!!!!

Are you dividing your 'cake' into 1023 or 1024 portions?

Is your range 1024 portions ie 1/1024 all the way to 1024/1024??? No it's not because 1024 is an INVALID number, you NEVER get 1024 out of your ADC... your range is 1/1023 all the way to 1023/1023 because 0/1023 although being the 1024th value is not counted when dealing with mathematical equations.

Taking what you read as Gospel without question is what crashes Mars Landers...

Yes... this is a 'simplistic' view, because many chips have peculiarities which have to be additionally accounted for (like for example not being true rail-to-rail)... what I am arguing is pure mathematics here.

dhouston
- 17th May 2009, 11:40
Melanie,

I usually illustrate this with a short staircase of 4 equal steps. The bottom level is 0 and the top is 4. While there are 5 levels (0-4), there are only 4 steps (or intervals) each of which is 1/4 of the total height. It you let people draw and number it themselves, it sticks with them longer.

Acetronics2
- 17th May 2009, 12:18
Gosh ...

One more manufacturer ( Linear ) in error ?? ...



But here ... he shows output number vs input voltage


look at this joined piece of datasheet ...

Code "1023" is NOT corresponding to Vref ... but Vref MINUS one LSB ...

so ... Vref corresponds to code "1024" !!! and there are 1024 steps, the "1024" value never being displayed ...

May be the explanation is here ...

Alain

Melanie
- 17th May 2009, 13:09
Well, in this instance ADCMAX is correct because VREF is never attainable.

Acetronics2
- 17th May 2009, 14:48
Hi, Mel

...

and I do think it's the same for all the manufacturers ...

just have a look to µChip AN 544d ... or the Midrange Manual ... they all show code $3FF for 1023 LSB ... not Vref , which is 1024 x LSB ! ( see § 23.12 )

Would be interesting to verify which input voltage give code 255 for a 2.56v ref ( quite simple !) , ... give code 4095 for a 4.096 v Vref ( less simple ), etc, etc.

don't you think ???

Regards
Alain

Darrel Taylor
- 17th May 2009, 21:38
I agree with Melanie.

Let's forget about what the overpaid engineers and datasheets have said, and look at it from purely a results perspective.

With 10-bit A/D the resulting values go from 0 - 1023.
If Vref=5.00V and you apply 5.00 volts to the A/D you get a reading of 1023.

If you then use 1024 as the Vref divisor, the formula to calc the Voltage from the A/D reading would be ...

5.00/1024 * 1023 = 4.99 ; Not the 5V we were looking for.

But if you use 1023 ...

5.00/1023 * 1023 = 5.00 ; this is what I want it to read.
&nbsp; Notice how the (/1023 * 1023) cancels out.

In the context of this thread, the results are similar.
If the manufacturer states a pressure of 115kPa at 4.7V ... using 1024 with a 4.7V input, you will only read 114.xxkPa, again not the reading we wanted.

So for this (and any other analog projects), I'll continue using the maximum ADC value for the divisor (255, 1023, 4095).
<br>

bitmaniac
- 1st June 2009, 12:20
Hi Darrel ,
hi Acetronics (It's me bitmaniac from rcgroups -navlights)

I am in the progress of developing my own ALT timer for F5J category
I want to deactivate/arm a mechanism at 300m for example.

I am using MPX4115A a max187 (12bit) and a pic to read altitute.

thought #1: I wonder if I can use an eeprom to store look up table of all alt values you can meat here in Greece (0m to 3000m max) and not use extensive calculation to determine alt.

thought #2: Also I am thinking of just usin ground kPa - specific height kpa and the difference (in kPa) gives me the heigth I want to calculate.

Are my thoughts correct or I miss something?!!

Thank you for your time my friends!


.

Acetronics2
- 1st June 2009, 13:14
Hi, Alexandros

Nice to hear from you !!!

Good choice for sensor and ADC ... also think to MPX 6115 and LTC 1286 , that also are good choices ...

for the tow release mechanism, no big soucy. just think the Zeroing command will be used very often, so it must be really handy ...

lookup tables will be the simplest solution, linear approx between two table values will be enough, as the goal is not to reach EXACT altitude, but everyone being released at the SAME altitude ...

Also think the pressure value will need some smoothing: if some air intake in the nose of the gliders ... measure will be false if no mean value calculated.

I join you a small handy tool to create the lookup table ...

Read you soon
Alain

PS: AZLights have been also seen aboard jet models ... ( a nice "Rafale", between others ... )

bitmaniac
- 1st June 2009, 18:17
hi Alain how are you my friend pleased to here from you again...

In our point now...
Well I will stick to MPX41154 and max 187 already ordered.
I am in the proccess of making/simulating the pcb.

Well I think will follow the table lookup method (although there will be one more chip (eeprom) in the pcb) but I have first to solve the equation you send to calculate meters instead of milibars.
..and better to kPa and not milibars.

I will let you know of my progress...

Acetronics2
- 1st June 2009, 19:41
Well I think will follow the table lookup method (although there will be one more chip (eeprom) in the pcb) but I have first to solve the equation you send to calculate meters instead of milibars.
..and better to kPa and not milibars.

I will let you know of my progress...

Hi, Alexandros

I think the best way for the lookup table is :

1) @ first ... take, say 200 or 250 points to calculate with the Excel Sheet ... ( just copy the formula by selecting the lines where to copy ... )

2) compare results by taking exact 50 points, and linear approx between those points and the exact 200 points you've already calculated .... notice 50 give more precision than required ... ( lol )

3) Take 32 points and idem 2) ...

4) Stop when satisfied ( 32 might be comfortable for 0 -3000 m range)

Do you really think an external EEPROM is needed ??? ... The LOOKUP command stores data in the ... Program memory !!! ( as " retlw xx " lines )


Now, I think XL sheet gives meters too ... no ???

On my side I shall write an XL sheet for that purpose ... might be handy one day ...

Good Evening
Alain

bitmaniac
- 2nd June 2009, 10:07
Hi! Alain

Sorry my friend but I hav not completely followed your idea.
Do you mean sth like the attachment one?

(ie: I have to 'expand' the range 200 , 50 and 32 'between' 0 - 3000 m I want to calculate?)

I have to follow your idea, so help me out , as I can see you have a point here!

Acetronics2
- 2nd June 2009, 14:06
Hi, Alexandros

As a good drawing is worth ...

see this XL sheet ...

shows how things go on ...

And Overall shows a differential amplifier is needed between Sensor and ADC, to get a good resolution ( see the very, very limited ADC result range ... if direct connexion ).

Note @ sea level the 300 m altitude is less than .1 v change @ sensor Output. Not that good for noise impact on signal ...

also note the mean value for altitude meters vs pressure change is precise enough for our use and so, we can consider it only depends on reference pressure @ ground level ... or even, that variation is linear ...

From the datasheets, It looks the ADC ref ( V+ref - V-ref ) must be, at least 3 v ... no hope from the Vref- side.


Another way could be to use the MS 5534 Intersema sensor, a NUMERIC output sensor whose resolution is ... 15 bits. Paying attention to noise would be cancelled too ...

Note particular calibration data from factory is included in the chip memory ... so, no further calibration would be needed ...

For the moment, I let you play with the calc sheet ...

Alain

ScaleRobotics
- 2nd June 2009, 16:19
You may want to use Darrel's A/D Oversampling routine to get some more precision. It allows you to go all the way up to 16 bit, but you may want to stick to 14 bit. That would get you accuracy of about half a meter.
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3446&stc=1&d=1243955850

http://sites.picbasic.net/component/option,com_uhp2/Itemid,6/task,viewpage/user_id,70/pageid,73/

bitmaniac
- 3rd June 2009, 12:31
So... Acetronics

*your XL was perfect for make me understand many things!


After a lot of experiment and according to your very usefull XL I finally decide to two different senarios

Acording to your XL (and 10 , 12 and 14 bit results attached to xl file below)
the 'resolution' is at 10bit -> around 8m, 12bit -> around 2m and 14bit -> around <1m

So I am thinking of
1st. just use simple pic 10 bit adc and Darrel's oversampling method (thank you scalerobotics for the link)

2nd use an LM385 for example dual amp and take just 'a window' od the mesurements of MPX4115 between 0-2300 meters

3rd compine LM385 and MAX187 (12bit) to get better resoloution

My onle concern is that as I want to keep pcb at minimum of costs / and parts count if Darrel oversampling method works , it would be Great!

I let you know.

I am in the progress of schematic and pcb design BUT I have to decide the method first!!

ScaleRobotics
- 3rd June 2009, 16:59
Acording to your XL (and 10 , 12 and 14 bit results attached to xl file below)
the 'resolution' is at 10bit -> around 8m, 12bit -> around 2m and 14bit -> around <1m


Not that it matters much, but in your graph, you are breaking it down to measurements every 0.10 mBar (not A/D conversion resolution). For every 0.10 mBar, your altitude changes by about 0.82 meters. However, this is not the resolution of your analog to digital converter at 14 bits. You will notice that from 0 to 22.13 meters altitude, your a/d conversion reading changes by 40. So ... 22.13 meters/40 = 0.55325 meters per 14 bit increment of your a/d converter. A lot closer to half a meter of resolution with a 14 bit conversion.

bitmaniac
- 3rd June 2009, 19:21
@scalerobotics

Of course you have not notice that in the last attached XL I upload there are three XL sheet in the file 10,12,14bit

Test it

My only concern is what method to choose (to start building) pic A/D with oversampling tehnicue , 12bit MAX and pic or DIF AMP + MAX + pic?

I cannot decide yet.

Acetronics2
- 3rd June 2009, 19:38
Hi, Alexandros

I'd recommend you to read the Freescale AN 1646 ...

Interesting matter !

take care to the LM 358 output voltage range ... I think it's not the good choice ...
LMC662 or AD 623 would be better ...

Have a good Evening

Alain

ScaleRobotics
- 3rd June 2009, 20:19
@scalerobotics

Of course you have not notice that in the last attached XL I upload there are three XL sheet in the file 10,12,14bit


Actually, I did notice, and it looks to be 100% correct. I am only pointing out that the increments with the 14 bit is 0.553 meters (near sea level), and not the ~1 meter that you mentioned in your previous post.

Thanks,

Walter

ScaleRobotics
- 4th June 2009, 08:59
I just tested Darrel's oversampling, using the MPX4115a and a PIC12F675 that I quickly soldered up, and it works very well. I just used the two capacitors on the power side of the MPX4115a, like the data sheet shows, but with no filter capacitor on the output. Even at 16 bit resolution, the A/D output values only varied by +/- 1 digit. It varied more when I breathed though! 16 bit is really sensitive!

My vote is for oversampling, parts count is at 6, running the board from the power of the PicKit2.

Pic12f675
3 capacitors
mpx4115a
20 mhz resonator

Acetronics2
- 4th June 2009, 09:51
Hi, Scalerobotics

Could you tell us what it shows for some close to another calibrated pressures ( water column i.e.) I'm really curious about this "oversampling method" application ...

And moreover after having carefully read the relevant AN 1152 from Microchip ...

Alain

" Surely overpaid Engineer ... ( lol ) , but Graduate Engineer ... "

bitmaniac
- 4th June 2009, 10:55
@Acetronics
VERY good infos in AN thanks for sharing!

@ Scalerobotics

You have done excellent job That was exactly I was thinking to do trying oversampling on 12f pics! so you did the job for me THANKS!

So the conclusion is that we can use 12f675 ir 12f683 as I want to just measure an alt difference of 200m

I did some calculation and I have attaches 2 XL one is the previous 10,12,14bit calculation and bolded out the 200m measurements just to see what is going on and the second one is use pic 10bit ADC but with Dual AMP LMC662 (Acetronics suggestion) to give a narrow-window measurements and the resolution improved to about 4m .

Also attached a fast schematic of my thoughts (not checked , improvements are welcome!)

Final conclusion I take the amp route or MPX connected directly to pic (with oversampling). I think as I will only want to measure 200m difference. the pcb must/and can be kept simple (low weight) and low part count.

(dual amp trick: first subtracts 2.5V from MPX vout and the result is multiplied by 3 , so we have a range just from
0-2300meters but better resolution for 10bit pic adc -see AZAltitude10bit_DUALAMP.xls)

Scalerobotics about oversampling on 12f do you think you can 'go with' just the internal 8Mhz rc oscilator or it will not do the trick?!

Dave
- 4th June 2009, 11:56
bitmaniac, Check your J1 and J2 power wiring....

Dave Purola,
N8NTA

bitmaniac
- 4th June 2009, 12:10
bitmaniac, Check your J1 and J2 power wiring....

Dave Purola,
N8NTA

Oh! you have a sharp eye!
I told you it was a fast schematic he!he! ;)

corrected.

ScaleRobotics
- 4th June 2009, 16:40
Hi, Scalerobotics

Could you tell us what it shows for some close to another calibrated pressures ( water column i.e.) I'm really curious about this "oversampling method" application ...

And moreover after having carefully read the relevant AN 1152 from Microchip ...


At my location and 14 bits, I get an output of 13255. This calculates to a pressure of 1004.86 mBar, and an altitude of 229.85 feet. I don't have a barometer here, so I can't really give you a side by side comparison on the figures. On the internet, it said a nearby weather barometer read 1014.42. But I think this is more a function of the accuracy of the MPX4115a, and to a bigger extent (since I don't have a calibrated barometer side by side) my altitude. The altitude from my calculations seem very close. I think I am between 250 and 285 feet altitude.

Oversampling is really just a form of averaging. So it can't skew your results. At worst, you could have no noise in your A/D conversion, which would give you a 10 bit result with lots of useless bits to the right. Once I find a 470pf capacitor around here, I plan to test results again. I think this will filter the result a bit too much, and take away some of the needed noise. Here, white noise is our friend.

On a side note, at 16 bits, when you watch the results at first power up, you can really see the effects of the MPX4115a and maybe the PIC12F675 warming up. For about two minutes the values really move!

ScaleRobotics
- 4th June 2009, 22:43
Here's a little code to calculate altitude from 0 to about 17,000 feet. I could not quite fit the full 85 value lookup2 table without getting some errors, so it is more of a 74 value lookup table. I may try a 74 value lookup table that covers the range to 36,000 feet later. Also will not work for Death Valley where the altitude goes to negative.

It is a pretty short program. I am using about 900 words of the PIC12F675 though, so not much space left over. Have not tested it too much, so if anyone finds issues, let me know.



DEFINE OSC 20
INCLUDE "DT_Analog.pbp" ; DT's 16-bit Analog Module

DEFINE ADC_BITS 10 '10 BIT A/D CONVERSION RESULT
DEFINE ADC_CLOCK 2 '
DEFINE ADC_SAMPLEUS 5 'SET SAMPLE TIME IN MICROSECONDS


CMCON = 7 'TURN COMPARATORS OFF
TRISIO = %000100 'Set GSIO 0 INPUTS, others to OUTPUT
ANSEL = %00100100 '
ADCON0.7 = 1 'Right Justify for 10-bit
ADCON0 = %10001001

ADbits = 14 ; set to 14-bit resolution


DEFINE DEBUG_REG GPIO
DEFINE DEBUG_BIT 0
DEFINE DEBUGIN_BIT 1
DEFINE DEBUG_BAUD 2400
DEFINE DEBUG_MODE 0
ALTresult var word 'lookup table output
tempALT var word 'base altitude of lookup from table
ADtemp var byte 'lookup table input
ALTdifference var word 'difference of two nearby altitudes
finalALT var word 'final calculated altitude in feet

;---------------------------------------------------------------------------
Main:
ADchan = 2 ; Do only AN2 channel
GOSUB GetADC ; Get A/D value
ADtemp = (ADvalue/100) - 60 ' get to table acceptable value for lookup
gosub lookmeup
tempALT = ALTresult 'save first result for use in math
ADtemp = ADtemp - 1 'run another lookup for nearby altitude for diff calc
gosub lookmeup
ALTdifference = ALTresult - tempALT 'get difference in nearby alt
finalALT = tempalt - (((ADvalue//100)* ALTdifference)/100)
'use difference to calculate slope & adjust altitude accordingly
debug "Alt= ",DEC finalALT," A/D= ",DEC ADvalue," "
pause 1000
GOTO Main:

End

lookmeup:
lookup2 ADtemp,[_
17646,17327,17011,16699,16389,16083,15780,15480,15 183,14888,14597,14308,14022,_
13739,13458,13179,12903,12630,12359,12090,11823,11 559,11297,11037,10779,10524,_
10270,10018,9769,9521,9275,9031,8789,8549,8310,807 4,7838,7605,7373,7143,6915,_
6688,6463,6239,6017,5796,5577,5359,5143,4928,4715, 4502,4292,4082,3874,3667,_
3462,3257,3054,2852,2652,2452,2254,2057,1861,1666, 1472,1280,1088,898,708,520,_
332,146],ALTresult
return

ScaleRobotics
- 5th June 2009, 07:26
Scalerobotics about oversampling on 12f do you think you can 'go with' just the internal 8Mhz rc oscilator or it will not do the trick?!

You can go with the internal, but at least on the 12F675 you have 4mhz internal, so your conversions are a little slower. See the TAD vs device operating frequencies part of your schematic. 1.6 us if fastest. Looks like 4mhz would be 2.0 us. So as long as you are not using 16 bit, you probably won't notice the difference in speed, and you will save one more part in your part count.

bitmaniac
- 5th June 2009, 08:19
@scalerobotics

I have import your code to Proteus Sim and playing around with your code.

It seems to work ok (I have to use meters instead of feets here :) ).

My MPX4115A arrived yesterday (4pieces) so it is time to make the real thing and figure out how it works. I am going to use my schematic ommiting the opamp and hope oversampling method works (12f683,internal 8Mhz,MPX,3caps -> total part count 5!)

For the moment I put everythimg in SIM (i used 12f683 with internal 8Mhz) and here what I found:
According to simulation at 50.400kPa I read 17646 feet ALT (lower limit) and
at 99.900kPa I read 5 feet ALT (upper limit) that is with this code we measure aprox. 49,500Kpa difference. (two screenshots attached)

Note: We must also use calibration data and/or Level0 default presure

(Please note that in the sim I can only vary sensor kPa in .100 increaments)

ScaleRobotics
- 5th June 2009, 08:33
Sounds good. If you beat me to it, try it with and without C3. I am guessing it may work better without it. If not without, it may work best with a much smaller capacitor. That defies most filtering logic, but I think oversampling likes a little bit of noise. I can't find my 470pf, but I know they are around here somewhere.....

bitmaniac
- 5th June 2009, 09:36
.....I can see your 470pf.... over there... yes there.....next to your Pickit2 he!he! :)

bitmaniac
- 5th June 2009, 11:39
3d visualization of a test pcb attached...

As you notice I didn't care much about the placement of sensor caps.
Just wanted to see the size of the board and best placement of connectors

(pcb measured... 45mm X 30 mm)

PLEASE NOTE all connectors will be male (not as seen) except for the sensor that it will be soldered on board
The sensor will be layed above C3 C2 and C1 (low profile cap)

bitmaniac
- 5th June 2009, 16:49
SUCCESS!

Scalerobotics your code worked ok.

I put together a 12f675 , two caps on MPX supply pins , one 100n on pic supply pin one resistor to PC serial RX port and guess....

I get 54-55m ALT here from our MPX4115 project on the desk.

I also turned on my other project with a gps module next to it and I get 54-58m ALT!

PERFECT right on the SPOT!!! I am very please with the result.

May be we must also include a calibration initial setup.

pic settings 4Mhz internal , Clk source Fosc/8 , Define ADC clock 2 (I will try 1 later) and ADC_SAMPLEUS 5.

The only thing left to verify is the accuracy in meters.

I am very happy now!

ScaleRobotics
- 5th June 2009, 17:00
First try success? Nice!

Maybe you are already converting feet to meters in your code, but this seems to work for me. And I think it is better than a new metric lookup table, because there are more feet per increment, which should make it more accurate.



if metric = 1 then 'convert from feet to meters
finalALT = finalalt * 2500
finalALT = div32 8203
endif


So it looks like you are making an altitude hold circuit. An altitude hold has been on my back burner for a few years now. Darrel's code has really made part of this easy, so it looks like I may be able to move this up a burner or two myself!

How smooth is your servo at 4 mhz and 8 mhz? I would think that 20 mhz would be a bit smoother for sensing pulse width, but have not tried the lower mhz.

bitmaniac
- 5th June 2009, 17:13
Altitude hold : oh! you gave me another idea!

For the moment it will be an ALT+TIMER motor cut-out for moto-gliders for F5J-GR . I am trying to make a circuit that will cut motor after 30sec or to an ALT of 200m what comes first!

about your question I think we will have problems with internal 4mhz. I am thinking of going to 12f683 (8 Mhz internal) and more code space , we are in the limit here with f675. Also may be asm is used to pass servo pulses through and/or maybe as final solution we will go to an external low profile crystal and two decopuling caps.

I will experiment and see....

(Now I get 51m here (project running!) the funny thing is that I have closed the door of my lab now , the weather got very hot here now . I think there will be no problem with the calibration because the only think I want to measure is ALT differece of 200m so 1st you have to power the device just 1minutes before flight. It will read the ground alt and if 200m reached motor will cut that's all.

ScaleRobotics
- 11th June 2009, 18:01
Modified the code to handle 0 to 25,900 feet, and a 16 bit conversion lookup table. Now you can select your conversion oversampling rate for Darrel's code, and your result gets shifted to match the 16 bit lookup table for altitude conversion. Works for 10 to 16 bit oversampling rates. My favorite is the 15 bit for accuracy and speed, but it is selectable.

See http://sites.picbasic.net/component/option,com_uhp2/Itemid,6/task,viewpage/user_id,91/pageid,81/ for more info.

bitmaniac
- 13th June 2009, 07:50
scalerobotics , you have done excellent work again my friend!.

But you made me wonder ... (as I have already design the pcb of my ALTMTR) MUST I include a Crystal (20Mhz) after all or I can leave/ and rely on internal 8Mhz oscillator (12f683) with any drawbakcs of it?
May be I need to redesign my mcb and loose button activation option.
Or may be I use led indication both as input and / or output this will make me think.... :))

ScaleRobotics
- 13th June 2009, 08:16
Thanks Bitmaniac,

Don't let me worry you! The speed difference will probably have a bigger affect on your PWM sensing and pass through, than altitude conversion. But I think 8mhz is reasonable for this. Yours is the motor control for a glider, so even if it is a little glitchy, you are not going to notice much, since to get to altitude you will probably be at 50 to 100 percent throttle, or you will be at 0 looking for lift.

I was originally thinking of speed for the higher bit conversions, like 15 and 16 bit. But I think the speed of your conversion will be 2 us, where with 20 mhz, the conversion is 1.6 us. So just the 16 bit analog oversampling takes 100 ms with 20 mhz and 125 ms with your 8mhz internal. Not a big difference there! Of course the 15 and 14 bit samples are MUCH quicker.

So no, really, I think you will be fine.

bitmaniac
- 13th June 2009, 11:19
So you think I have to stick to my already made pcb and don't try an 20 MHZ crystal.
Here it is the final pcb in 3d and shematic I am going to use.
I am finishing the firmware part now thanks to Darrel ADC convertion and your help. I will use 14bit with 8mhz internal (12f683). The pcb will support ICSP an optional button and a led indicator. I have not try the pcb (in real) only in Proteus sim. I will let you know of the progress. for the moment take a look...

EDIT: in schematic the 100n pic decoupling is missing (in pcb is ok)

ScaleRobotics
- 13th June 2009, 15:13
So you think I have to stick to my already made pcb and don't try an 20 MHZ crystal.

I think your design is feasible. There is no harm in designing the board before the firmware is completed. But there might be some harm ($$$) if you have them made before testing. I would recommend that you wait till you write your PWM sensing and generating code, and test it, before you decide on a final layout. On a breadboard, adding a crystal is easy, if you need to...

ScaleRobotics
- 13th June 2009, 16:42
One change you might consider would be to change pin 5 (CCP1 HPWM pin) to your servo connector. That way if you decide to use the HPWM function for PWM out, you could go ahead and do it. You could always reverse your connectors if you decide you want to use the HPWM for PWM in. And if you wanted to make it really flexible, consider moving your two least important inputs/outputs to the crystal pins. You have enough space on your board for a resonator. Why not make some pads for inserting a resonator, and run your LED and Serial connector off of those traces. That way (if you have to) you can sacrifice the LED and serial for a crystal.

bitmaniac
- 13th June 2009, 18:37
You are in my mind actually I have already daone what you suggest but I had already develop and etced the above pcb version so I 'll give a try as it is and I have already residign the pcb with extra crystal pads BUT I have not implement the HPWM idea you suggest . It is a perefect idea I will add this too this weekend. Thanks.

bitmaniac
- 18th June 2009, 12:36
Reviced sch & and pcb...

I improved pcb (after suggestion from Scalerobotics).
Arm button removed (arm will be done by throtle or by default min ALT).
20Mhz crystal included. (although I did notice according to manual at 20Mhz HPWM for THR out has min limit to around 1221Hz not so good!)
(...also In Circuit fw update)

Working on Fw now. I have problems with HPWM though!

ScaleRobotics
- 19th July 2009, 16:32
Well, it looks like I convinced you to go with a crystal, and you convinced me to go without one. Pretty funny. Sorry about the bad advice I gave about the pwm. I didn't do enough homework.

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3533&stc=1&d=1248017245

Code and schematics here: http://sites.picbasic.net/component/option,com_uhp2/Itemid,6/task,viewpage/user_id,91/pageid,81/

bitmaniac
- 20th July 2009, 05:45
Hi Scalerobotics,

I liked your smd version (smaller pcb is always a good one!)

I think I will keep the 20Mhz crystal because I have problems here with the servo read/send signals (passtrough) .The problem is inside adc oversampling convertion routine. I think ot is a liitle bit slow convertion that slows things down and as I only use pulsin and pulsout to read and regenarate servo pulses at tghis point I notice that servo works ok but with speed control (so I can cut the motor) I have no response.

bitmaniac
- 7th September 2009, 15:08
Hi! back again with this unfinished project.
Well after a lot of experiment I will alter my schematic again.
Using Darrel code for 14bit convertion I have problems with servo in / out routine. Using pulsin/pulsout to re-generate servo signals although normal servo response ok (a little bit jerky motion) when it comes to use Speed controller to ontrol brushless motor it does not seem to respond at all. If I disable Darrel convertion routine SC workink ok.
So I am thinking of using a MAX187 12bit ADC (and maybe an op-amp in the future).
I have already put together a 12f683 + MPX4115 and a MAX187 on a raster and SC seems to work now. I will keep you inform of my future proggress.....

Acetronics2
- 7th September 2009, 15:50
Hi, Alexandros

Now we can make good work ... there was no other serious solution than having REAL bits as inputs ... 12 is a minimum.

Just have to find MAX 187 ... ( 4.096v internal ref is a good thing ! ) ... may be we could try to find another ADC with both LoVref and HiVref pins available ... some more bit to win here !!!

An LTC1286 could be the one ... with 4.096v ext ref !!!

The MS5534 was the other solution : a bit expensive, but better resolution !!! ( it's the one used in commercial altitude related devices ... eh ! ). It just needs a 12F683 for 32 khz generation ( HPWM ) ...

Alain

bitmaniac
- 7th September 2009, 17:46
Hi! Alain

Well max 187 is a very good ADC I think and you can also use External Vref (as I can see from datasheet)

I tried tie external Vdd to ref pin (according to datasheet you have to leave pin 3 floatting) and change pin 4 cap from 4.7uf to 100nf.
I tried internal 4.096V ref. but as I did not use op-amp I think I was at the limit of 4.096v so I decide to go roughly with Vdd external but I noticed a jerky ADC reading -/+ 10 values up and down. Maybe this was to a not clear 5v external source (I used an ATX pc supply). I will try again with Speed contrller Bec and let you know.
I must finish this project....

(...Alain maybe we can use a 14bit 8pin SPI IC if exists! ....(I want too much eh!?)

Also about MS5534 you suggest I follow some links you gave me in previous posts but as I have already ordered 5 MPX sensors and as I want a simpler project (just read 200m ALT change) and not even real ALT in meters measurements I think we can just go with an F683 and a 12bit ADC(or 14bit ADC 8 pin if available).

Darrel Taylor
- 7th September 2009, 22:47
The MPX4115A is a "Ratiometric" type of device. Which means that the output voltage is proportional to the power supply voltage.
This is a great feature when using a PIC, because the PIC's A/D converter is also "Ratiometric".
This way you will always get the same results from the sensor, even if your power supply isn't exactly 5.00V or if it drifts a little, like will happen with a battery operated device.

If you try to measure a ratiometric device using a fixed voltage reference ... as the VDD voltage changes, your pressure reading will change too. So you've lost that nice stable signal that a ratiometric sensor gives you.

I don't think you should use a VREF+ at all.<hr>


Using Darrel code for 14bit convertion I have problems with servo in / out routine. Using pulsin/pulsout to re-generate servo signals although normal servo response ok (a little bit jerky motion) when it comes to use Speed controller to ontrol brushless motor it does not seem to respond at all. If I disable Darrel convertion routine SC workink ok.

Trying to do all that in software ... no doubt there are problems.

For 14-bit resolution it takes a minimum of 7.4ms to grab the 256 samples needed.
If you left PBP's default AD defines intact, it could take up to 25ms.
Obviously not fast enough to do software timed servos too.

I agree, an external A/D with higher resolution will probably be best. (without fixed Vref+)

Added:

But if you're just going to a 12-bit external A/D.
You might try the same routines again at the 12-bit resolution. Or even 13-bit.

At 12-bit resolution it only needs 16 samples, which takes <strike>387us</strike> 465us minimum.
Plenty of time left for eveything else.
<br>

bitmaniac
- 8th September 2009, 16:55
Well,
I put together some stuff on a prototype pcb and servo routines worked ok! ( a little bit of improvement needed!)
I notice that without an op-amp and using just a max187 12bit ADC with EXTERNAL Vref tied to Vdd I get readings from ADC that plays between 2-3 value (NOT good). If we think that we use 12bit we have a resolution of about -+2meters and if the value plays between 2-3 values the error increase between -+6 meters (not good at all).
May be the only and better solution is go to 12bit ADC AND an op-amp too!
Also as a final thought is that maybe I have interference somewhere with the sensor although I used decoupling and filter capacitors according to MPX datasheet.
The main thing is that servo routines / speed controller arming e.t.c work fine!

Acetronics2
- 8th September 2009, 19:25
Hi, Alexandros

1) do not forget a LoPass R/C at the sensor output ( Freescale AN's ... )

2) take care to the ground plane (@ 12 bits it becomes useful !!! )

2) you can take 8 or 16 samples and calculate the mean value ( this is pompously called ... "Oversampling" , if you take into account the UNMEANINGFUL LSBits of the result . LOL ! )

or better use a " rolling mean value " ( mean value = 7/8 oldvalue + 1/8 Newvalue i.e. , for 8 samples ) advantage is you access meanvalue after each sampling ...

I am testing an auto zeroing and resolution enhancement design on my side ... but shhhht !!!

Alain

bitmaniac
- 9th September 2009, 12:31
Alain about your suggestions:
1> I think you are right I have not implement an rc filter. AN note is VERY usefull here I think. (although I have read it before I did not use rc filter just decoupling caps). I have some 750ohm and 330nf around here so I can give it a try.
2> for the moment no ground plane just a proto-raster board (this of course causes problem by itself)
3>samples is already there but I get only 4samples maybe get 8 or 16 and see what happens.

ALL the suggestions you make is not difficult to imlemented so I will give them all a try and let you know

(...and shhhhht ,yah waiting for your enhancements!!)

ScaleRobotics
- 12th January 2010, 19:07
Since the sites.picbasic.net had some issues a while back (and erased everyone's attached files) Darrel's DT_Analog.pbp file got gobbled up! So, none of my links to his code work anymore. Attached is his file that takes multiple samples from the A/D converter, and can "oversample" from 10 to 16 bits resolution. It is pretty slick, (no matter what Alain says http://www.picbasic.co.uk/forum/images/icons/icon10.gif) as it can make a 16 bit A/D converter out of a $1.50 PIC12F683.

Some more info on DT-Analog.pbp's sampling rates:
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3446&stc=1&d=1243955850

Hardware for my altimeter using his above code:
http://sites.picbasic.net/index.php?option=com_uhp2&Itemid=6&task=viewpage&user_id=91&pageid=81

Also attached is my AltimeterBlink.pbp code that calculates altitude, and sends it out the serial port, as well as blinks it out on an LED.

Darrel Taylor
- 12th January 2010, 20:46
Sorry about the broken links Walter.
I've re-posted it where I can be sure it stays intact.

http://www.darreltaylor.com/DT_Analog/

And yeah, it is pretty cool isn't it.
(No matter what Alain says). :D

bitmaniac
- 18th January 2010, 11:24
Oh my friends you made me come back with my previous project (that didn't manage to finish yet!)
Well I have tried all methods available with previous mentioned hw and a few not-listed here one.

The problem I came accross was with picbasic pwm routines to pass-through servos signal .

Just to remind: In addition to ALT measurement I also use a servo in and a setvo out pin to pass-through the throttle signal and actually cut the throtle when 200m ALT reached!

All experiments with oversampling or no , with opamp etc worked ok when I connect servo (for throttle) -although a little bit of jerky movement servo works! , but everytime it comes to use SpeedControl it does not arm and this has to do with delays on servo routines.

ScaleRobotics
- 18th January 2010, 16:53
All experiments with oversampling or no , with opamp etc worked ok when I connect servo (for throttle) -although a little bit of jerky movement servo works! , but everytime it comes to use SpeedControl it does not arm and this has to do with delays on servo routines.

Hey Bitmaniac, any chance you could post what you have? I am interested in the pass through, and I know others are too. I just worked on a DT Interrupt servo pass through on a 18F device (just a single channel right now), and I would like work it out for the 12F683. I always enjoy seeing a new perspective to help me think outside my box. In case you are intersted, mine is here: http://www.picbasic.co.uk/forum/showthread.php?p=83186#post83186

Thanks,

Walter

Acetronics2
- 18th January 2010, 19:49
All experiments with oversampling or no , with opamp etc worked ok when I connect servo (for throttle) -although a little bit of jerky movement servo works! , but everytime it comes to use SpeedControl it does not arm and this has to do with delays on servo routines.

Hi, Alexandros

Could you explain a bit ??? I must admit I'm not sure what you mean here ... the altitude measurement routine could take too much time ???

did you notice you send the servo signal twice ... just at this moment ...

Alain

ScaleRobotics
- 18th January 2010, 20:12
did you notice you send the servo signal twice ... just at this moment ...
Alain

Hey Alain,

Can you explain more? I have not seen any code from Bitmaniac, did I miss something?

I think Bitmaniac is saying his code works fine with a servo, but when connected to a motor controller, it does not work, and he thinks it is due to the delays used in his routine for servo output.

Thanks,

Walter

bitmaniac
- 18th January 2010, 20:56
Well my friends
I was a bit confusing trying to explain things!
Well see previous post #65 (http://www.picbasic.co.uk/forum/showpost.php?p=78193&postcount=65) to see what I mean exactly.

If /when using oversampling method this introduces a delay to my pulsin /pulsout routines (simple pass through) .
I even try omiting meter/feet convertion all together and calculating 200m ALT reach by raw data as it comes from ADC only!

Bill Legge
- 19th January 2010, 12:23
I don't see the problem with dividing by 1024?
The process is quantising a variable. Say our variable voltage lies in the range 0 to 10 Volts and we have one bit to use for the digital result of the quantising (2 to the power of 1 = 2, so we have two levels to play with):

A. The result 0 means that the voltage was in the range 0 to 5 Volts (not that it was zero).
B. The result 1 means the voltage was in the range 5 to 10 volts (not that it was 10 volts)

So each level is 10/2 volts wide. Not 10/1 volt wide.

The bit of cake after carving it up into portions has a slice 0 - it is not any smaller than any other slice.

This is not jibberish created by highly paid engineers it is simple maths.

I wonder how many devices you have launched on the world that are happily 'over' measuring analog quantities by assuming that each slice is bigger than it actualy is?

Kind regards to you all

Bill Legge

Acetronics2
- 19th January 2010, 13:03
Hi,

The problem is very simple : the servo signal frame length is too long ( or too short ??? ) and the ESC do not recognise it as a valid frame ...

The solution is not so simple : the total time of the frame must be 30 or 35 ms as a MAXIMUM and , say 17-18 ms as a minimum.

That's why servo works and not the ESC ...

Alain

bitmaniac
- 19th January 2010, 17:09
Sure there is a timing (delay) problem.
You gave a more sophisticating explanation.
You gave me an idea.May be we I will hook the oscilloscope to see the exact pulse..

Acetronics2
- 19th January 2010, 17:50
Hi Alexandros

I had committed that from what you wrote ...



'************************************************* ***************************
' (c)2009 Alexandros Zahariadis (E.A.TH.) Greece *
' Electric Glider electronic switch to be used in F3J-GR competitions.
' The device will cut-off motor if 200m ALT reached or 30seconds passed
' whichever comes first!
' There is also a status led option which idicates if you have reached 200m
' or not (may be because of luck of power!)
' steady led -> 200m ALT reached , blinking led -> 30 secs passed.
' NOTE: after a lot of experiments and because of code execution speed
' I use direct ADC raw sample values without converting them to meters first!
' :: thanks to Acetronics (Alain) and picbasic forum for codding ideas ::
'************************************************* ***************************

'@ DEVICE FCMEN_OFF
'@ DEVICE IESO_OFF
'@ DEVICE BOD_ON
'@ DEVICE CPD_OFF
'@ DEVICE PROTECT_OFF
'@ DEVICE MCLR_OFF
'@ DEVICE PWRT_OFF
'@ DEVICE WDT_OFF
'@ DEVICE INTRC_OSC

@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOD_ON

INCLUDE "modedefs.bas"

clear
DEFINE OSC 4
define PULSIN_MAX 250
;DEFINE DEBUG_REG GPIO
;DEFINE DEBUG_BIT 2
;DEFINE DEBUG_BAUD 9600
;DEFINE DEBUG_MODE 1

OSCCON = $60 ' $60:4 Mhz $70:8 Mhz int.
CMCON0 = 7 'TURN COMPARATORS OFF
TRISIO = %00001010 'Set GPIO1 and GPIO3 0 INPUTS, others to OUTPUT
ANSEL = %00000100 'Set AN2 , Fosc/32
ADCON0 = %00000000 'AN2 select & Right Justify for 10-bit
;---------------------------------------------------------------------------
THROTTLE VAR GPIO.0 'Outputs to throttle servo
RADIO VAR GPIO.1 'Input from receiver
LED var GPIO.2 'status indicator
ADC_DATA var GPIO.3 ' adc serial data
ADC_SCLK var GPIO.5 ' adc serial clock
ADC_CS var GPIO.4 ' adc chip select
;---------------------------------------------------------------------------

advalue var word ' value read from adc
groundALT var word
difalt var word
P VAR WORD ' This stores the PULSIN value
x var byte ' general var
y var byte ' general var
SEC_COUNT VAR BYTE ' seconds counter
O_FLOWS VAR BYTE ' holds the number of timer1 overflows
BRAKE_PULSE var word ' servo pulse to STOP (brake on) THR servo
BRAKE_PULSE = 100

'-= vars for averaging routine =-
AvgCount CON 6 ' = Number of samples to average
FAspread CON 1000 ' = Fast Average threshold +/-
Value VAR WORD
'-= end of vars for averaging routine =-

'************************************************* *****************************
' TIMER1 Cycle MUST be longer than a R/C frame duration to be sure not to miss any ticks.
' 50 ms is a good value for timing precision.
' PL = 15543 @ 4Mhz ( reload = 7 cycle )
'************************************************* *****************************

T1LO CON $49 'timer1 preload values
T1HI CON $C3 '$C349 -> -15543
low throttle

INTCON = 0 ' disable interrupts
T1CON = %00010000 ' 1:2 prescale (1uS per tick), timer1 off (max 1:8!)
' 11 = 1:8 ,10 = 1:4, 01 = 1:2, 00 = 1:1 Prescale Value
TMR1H = T1HI ' 65,536-15536 = 50.000
TMR1L = T1LO ' 50.000 ticks * 1uS =50.000usec.=100msec
' 1 second= 100*10
' every 10 timer1 overflows = 1 second 1uS=
'---------------------------------------------------------------------------
pause 3000

for x=1 to 4
high led
pause 200
low led
pause 100
next x



'************************************************* *****************************
CAL_BP: ' CALIBRATING Brake_Pulse ( P )
'************************************************* *****************************

Pause 50
LOW led
P = 0

For x = 1 TO 16

PulsIn radio,1,P

IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1
GoTo CAL_BP
EndIF


IF P = $00 Then prems

IF ( P < (Brake_Pulse -1)) OR ( P > (Brake_Pulse +1)) THEN
Led = 1
GoTo CAL_BP
ENDIF

prems: Brake_Pulse = P

Next x

LOW Throttle

''************************************************ ******************************
'calibrate: 'check for valid signal
'
'For x = 1 TO 2
'
' PulsIn radio,1,P
' pauseus 10
' IF ( P < 80 ) OR ( P > 200 ) Then calibrate
' next x
'
'for x=1 to 3
' PulsIn radio,1,P
' brake_pulse = P
'next x
'
'low led
'
'low throttle

'************************************************* ****************************
precheck: 'leave some seconds to do a motor test
'then motor brake is ON for some seconds
for y=1 to 3

for x=1 to 255
PULSIN RADIO,1,P

IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1
GoTo Precheck
EndIF

Led = 0
LOW Throttle
pULSOUT THROTTLE, p

next x

next y

for x=1 to 160

LOW Throttle
PULSOUT THROTTLE, brake_pulse
pause 18

next x

low THROTTLE

GOSUB GetAdc 'Get ground ALT
groundalt=value

'************************************************* *****************************
armcheck: ' Now, we can launch the beast ...

PULSIN RADIO,1,P
IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1 ' Show Problem !!!
LOW Throttle
GoTo Armcheck
ENDIF

Led = 0
low throttle
PULSOUT THROTTLE, p

if difalt < 2 OR difalt > 10000 then Armcheck 'Arm if>=5mALT (in adc samples) reached!!


'************************************************* *****************************
'************************************************* *****************************
start: ' We are flying , now ... preset timer1

SEC_COUNT=28 ' load for 30 to 0 seconds countdown
O_FLOWS=0 ' clear overflow count
PIR1.0=0 ' clear timer1 overflow flag
T1CON.0=1 ' start timer1

low throttle ' to be sure ...

'************************************************* *****************************
main:

gosub GetADC

PULSIN RADIO,1,P
pauseUS 10

pULSOUT THROTTLE, p

' Note: Timer1 overflows every 0.050 seconds

IF PIR1.0 THEN ' if timer1 overflow then
O_FLOWS = O_FLOWS + 1 ' inc oveflow counter

IF O_FLOWS = 20 THEN ' if 1 second elapsed
SEC_COUNT = SEC_COUNT - 1 ' decrement seconds count
O_FLOWS=0 ' reset overflow counter
ENDIF

PIR1.0=0 ' clear timer1 overflow flag
T1CON.0 = 0 ' stop timer1

TMR1H = T1HI ' Reload values
TMR1L = T1LO

T1CON.0=1 ' re-start timer1

ENDIF

if difalt>=89 and difalt<10000 then KILL_MOTOR_ALT 'Check if 100mALT
'(in adc samples) reached!!
if sec_count<=0 then KILL_MOTOR_TMR

goto main


' SUBROUTINES
'************************************************* *****************************
'************************************************* *****************************
GetADC: 'Read MAX187 12bit ADC value

low ADC_CS
PAUSEUS 10
shiftin ADC_DATA,ADC_SCLK,msbpost,[advalue\12]
high ADC_CS


Average:' -=-=-=-=-=-= Average 6 X Analog values -=-=-=-=-=-=-=-=-=-=
IF Value = advalue Then NoChange

IF ABS (Value - advalue) > FAspread OR Value < AvgCount Then FastAvg
IF ABS (Value - advalue) < AvgCount Then RealClose

advalue = advalue - (advalue/AvgCount)
advalue = advalue + (Value/AvgCount)
GoTo AVGok

FastAvg:
advalue = Value
GoTo AVGok

RealClose:'If averaging more than 8 samples,change to (AvgCount/4)

advalue = advalue - (advalue/(AvgCount/2))
advalue = advalue + (Value/(AvgCount/2))

AVGok:
Value = advalue ' Put Average back into Value

NoChange:' -=-=-=-=-=-= End of Averageing -=-=-=-=-=-=-=-=-=-=

difalt=value-groundalt

return
END

'************************************************* *****************************
KILL_MOTOR_ALT:
low throttle
high led

LOOP1:
PULSOUT throttle, brake_pulse ; Kill motor - adjust this value. 4Mhz ->> 10uSec
pause 18
goto LOOP1

END
'************************************************* *****************************
KILL_MOTOR_TMR:
x = 0

LOOP2:

low throttle
PULSOUT throttle, brake_pulse ; Kill motor - adjust this value. 4Mhz ->> 10uSec

IF X = 0 THEN led = led ^ 1
x = ( x+1 ) // 18 ' Counter for led Blinking @ 1.5 Hz

pause 18
goto LOOP2

END
'************************************************* *****************************
'************************************************* *****************************



...

But did not try it ...


have fun

Alain

ScaleRobotics
- 19th January 2010, 17:52
Hey Bitmaniac,

You could try using a 20ms interrupt, and start your pulsout on interrupt. That would make things more consistent, and probably keep your motor controller happy.

ScaleRobotics
- 29th January 2010, 10:52
Hey Bitmaniac,

I was thinking this use of interrupts would probably keep things happy as far as motor controllers. It may need some more work though, and I still have to test it on a motor control.

http://www.picbasic.co.uk/forum/showthread.php?p=83834#post83834

Walter

bitmaniac
- 29th January 2010, 11:52
Well, Scalerobotics , Alain and others

May be we could give this aproach a try and see...

So let's sum up what I have tried so far:

1st just 12f683 -> 10bit ADC cannot do any MPX4115 useful calculations!

2nd 12f683 + LM358 op-amp for 'window-range' method -> clever idea but I think we may have erratic behavour as op-amp temp drift!

3rd 12f683 DT 14 bit oversampling method very good idea and increased resolution but delay issues with servo pass-through routines.

4th 12f683 + MAX187 12bit ADC (increased resolution-not as bad as internal 10bit and not as good as oversampling method) and interrupts for servo 'pass-trhough' LET's try it

Now I ended up in using a 12f683 internal osc (4MHz) + MAX187 so we have free interrupt sources and speed to try other methods.Also note that I have tried also with internal and external crystals and keep in-mind that I have already TMR1 running for the moment to keep track of 30sec. passing time.

Maybe I think somehow wrong / or weird for any of the above ideas ,please feel free to express your method / comments

Alain (Acetronics) some time ago , already gave a great idea for a completely different approach to the whole project, using an external DAC (NOT ADC!) to set the Vref of the pic internal 10bit adc so we 'narrow' the measurements of MPX to a resonable amount
This has also to be tried!!!

(P.S:For the moment I have a PIC ethernet project open.... in the same time)

ScaleRobotics
- 29th January 2010, 17:58
Also note that I have tried also with internal and external crystals and keep in-mind that I have already TMR1 running for the moment to keep track of 30sec. passing time.

Alain (Acetronics) some time ago , already gave a great idea for a completely different approach to the whole project, using an external DAC (NOT ADC!) to set the Vref of the pic internal 10bit adc so we 'narrow' the measurements of MPX to a resonable amount
This has also to be tried!!!


Hey Alexandros,

Certainly lots of methods to try. I am sure that Alain's method would work just fine. I just like the idea of interrupts, and using fewer components. And besides, I am learning a lot about interrupts and timers in the process, so that is good!

And for your 30 seconds: Since it is using a time base of 20ms on timer2, you could easily add a counter in that interrupt handler. And when it reached 1500, that is 30 seconds.

I will try adding the ADC oversample into it, and let you know how it goes. But my motor controller is taking kindly to it, and accepting it's pulses.

bitmaniac
- 31st January 2010, 16:40
Well a little bit of experiment with my last hardware : 12f683 , max187 12bit ADC , 4 Mhz Int osc. Servo attached instead of SC working ok (a little bit jerky -but acceptable) BUT when I connect SC it works only once at the begining when you plug the battery in.
So, after a little notice THE OBVIOUS THING CAME IN MY MIND!!

Of course there is a problem meanwhile with the SC , as soon as I 'break' for the first time just to to jump to my motor pre-check routine afterwards SC accepts no pulses at all for a period of time. So when I come back to re-activate the motor last position SC does not arm . It must go to arm procedure first (throttle low) and then it accepts signals!

So, the only way we can go is WITH interrupts just to keep the pulsout routine alive!

So obvious ......

Acetronics2
- 31st January 2010, 16:48
Hi, Alex

Interrupts ... ok, nice idea, ... but it will surely interfere with your INPUT Pulsin ....

hé,hé ... you said " Aaaargh !!! " ???

Alain

ScaleRobotics
- 31st January 2010, 17:48
Interrupts ... ok, nice idea, ... but it will surely interfere with your INPUT Pulsin ....
Alain

If you go to interrupts, you will not need any pulsin, or pulsout. There are a couple ways to input multiple channels for pulse width measurement. You could either make an interrupt on change on GPIO port, then poll the pins for change, or ....

tie both outputs of the receiver together, and connect them to the CPP1 pin. Only one will pulse at a time (on most rc receivers), so you will be able to read one at a time, even though they are connected together.

One thing I am not sure about is if there is enough time between pulses to read adjacent channels. Have not tried that yet. But channels that are separated by one channel, like 1 and 3, etc would be easy. Hard part would be telling channels from each other. For this, you could place an input on one of the in between channels to mark which pulse width you would be measuring next.

Or, make a multiplexing switch that switches between the throttle, and the on/off switch, and have those go to the same CCP1 pin.

Acetronics2
- 31st January 2010, 17:53
Hi,

If you want to give a try ...

with " classical " receivers ( CMOS 4015/4017/HC164/NE5045 decoders ) you have ...

15 ns ... as a " mark pulse " ...

Alain

bitmaniac
- 1st February 2010, 06:51
... or maybe using HPWM for pulsout ? to keep SC alive all the time!

Acetronics2
- 2nd February 2010, 20:01
Hi, Alex

I spent some more time on your code ...

should work as I verified the timing and flow with MPSIM ...




'************************************************* ***************************
' (c)2009 Alexandros Zahariadis (E.A.TH.) Greece *
' Electric Glider electronic switch to be used in F3J-GR competitions.
' The device will cut-off motor if 200m ALT reached or 30seconds passed
' whichever comes first!
' There is also a status led option which idicates if you have reached 200m
' or not (may be because of luck of power!)
' steady led -> 200m ALT reached , blinking led -> 30 secs passed.
' NOTE: after a lot of experiments and because of code execution speed
' I use direct ADC raw sample values without converting them to meters first!
' :: thanks to Acetronics (Alain) and picbasic forum for codding ideas ::
'************************************************* ***************************

'@ DEVICE FCMEN_OFF
'@ DEVICE IESO_OFF
'@ DEVICE BOD_ON
'@ DEVICE CPD_OFF
'@ DEVICE PROTECT_OFF
'@ DEVICE MCLR_OFF
'@ DEVICE PWRT_OFF
'@ DEVICE WDT_OFF
'@ DEVICE INTRC_OSC

@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOD_ON

INCLUDE "modedefs.bas"


DEFINE OSC 4
DEFINE PULSIN_MAX 2500

;DEFINE DEBUG_REG GPIO
;DEFINE DEBUG_BIT 2
;DEFINE DEBUG_BAUD 9600
;DEFINE DEBUG_MODE 1

OSCCON = $60 ' $60:4 Mhz $70:8 Mhz int.

CMCON0 = 7 'TURN COMPARATORS OFF
TRISIO = %00001010 'Set GPIO1 and GPIO3 0 INPUTS, others to OUTPUT
ANSEL = %00000100 'Set AN2 , Fosc/32
ADCON0 = %00000000 'AN2 select & Right Justify for 10-bit

;---------------------------------------------------------------------------
'
THROTTLE VAR GPIO.0 'Outputs to throttle servo
RADIO VAR GPIO.1 'Input from receiver
LED VAR GPIO.2 'status indicator
ADC_DATA VAR GPIO.3 ' adc serial data
ADC_SCLK VAR GPIO.5 ' adc serial clock
ADC_CS VAR GPIO.4 ' adc chip select

;---------------------------------------------------------------------------

advalue VAR word ' value read from adc
groundALT VAR word
difalt VAR word
P VAR WORD ' This stores the PULSIN value
x VAR byte ' general var
y VAR byte ' general var
Dummy VAR word
SEC_COUNT VAR BYTE ' seconds counter
O_FLOWS VAR BYTE ' holds the number of timer1 overflows
BRAKE_PULSE VAR word ' servo pulse to STOP (brake on) THR servo

CLEAR

'BRAKE_PULSE = 100

'-= vars for averaging routine =-
AvgCount CON 6 ' = Number of samples to average
FAspread CON 1000 ' = Fast Average threshold +/-
Value VAR WORD
'-= end of vars for averaging routine =-

'************************************************* *****************************
' TIMER1 Cycle MUST be longer than a R/C frame duration to be sure not to miss any ticks.
' 50 ms is a good value for timing precision.
' PL = 15543 @ 4Mhz ( reload = 7 cycle )
'************************************************* *****************************

T1LO CON $49 'timer1 preload values
T1HI CON $C3 '$C349 -> -15543

LOW throttle

INTCON = 0 ' disable interrupts
T1CON = %00010000 ' 1:2 prescale (1uS per tick), timer1 off (max 1:8!)
' 11 = 1:8 ,10 = 1:4, 01 = 1:2, 00 = 1:1 Prescale Value
TMR1H = T1HI ' 65,536-15536 = 50.000
TMR1L = T1LO ' 50.000 ticks * 1uS =50.000usec.=100msec
' 1 second= 100*10
' every 10 timer1 overflows = 1 second 1uS=
'---------------------------------------------------------------------------
pause 3'000

for x=1 to 4
high led
pause 2'00
low led
pause 1'00
next x



'************************************************* *****************************
CAL_BP: ' CALIBRATING Brake_Pulse ( P )
' Controller must see Brake Pulse to Unlock ...
'************************************************* *****************************

Pause 50
LOW led
Brake_Pulse = 0

For x = 1 TO 16

PULSIN radio,1,P

IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1
GoTo CAL_BP
EndIF


IF Brake_Pulse = $00 Then prems

IF ( P < (Brake_Pulse -1)) OR ( P > (Brake_Pulse +1)) THEN
Led = 1
GoTo CAL_BP
ENDIF

prems: Brake_Pulse = P

Next x

LOW Throttle

'************************************************* ****************************
precheck: 'leave some seconds to do a motor test
'then motor brake is ON for some seconds

for y=1 to 3

for x=1 to 255
PULSIN RADIO,1,P

IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1
GoTo Precheck
EndIF

Led = 0
LOW Throttle
PULSOUT THROTTLE, p

next x

next y

'************************************************* *****************************
' GroundAlt measure : Motor is Locked, But Brake_Pulse lenght must be sent ...
'************************************************* *****************************

for x=1 to 160 '160 x 22ms =

LOW Throttle
PULSOUT THROTTLE, brake_pulse
pause 19

next x

low THROTTLE

GOSUB GetAdc 'Get ground ALT
groundalt = value

'************************************************* *****************************
armcheck: '20.9 ms ' Now, we can launch the beast ...

PULSIN RADIO,1,P
IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1 ' Show Problem !!!
LOW Throttle
PULSOUT THROTTLE, brake_pulse ' Not to lock Controller
GoTo Armcheck
ENDIF

Led = 0
low throttle
PULSOUT THROTTLE, p

GOSUB GetAdc 'Get ALT

if difalt < 2 OR difalt > 10000 then Armcheck 'Arm if>=5mALT (in adc samples) reached!!


'************************************************* *****************************
'************************************************* *****************************
start: ' We are flying , now ... preset timer1

SEC_COUNT=28 ' load for 30 to 0 seconds countdown
O_FLOWS=0 ' clear overflow count
PIR1.0=0 ' clear timer1 overflow flag
T1CON.0=1 ' start timer1

low throttle ' to be sure ...

'************************************************* *****************************
main:

gosub GetADC

PULSIN RADIO,1,P
pauseUS 10

pULSOUT THROTTLE, p

' Note: Timer1 overflows every 0.050 seconds

IF PIR1.0 THEN ' if timer1 overflow then
O_FLOWS = O_FLOWS + 1 ' inc oveflow counter

IF O_FLOWS = 20 THEN ' if 1 second elapsed
SEC_COUNT = SEC_COUNT - 1 ' decrement seconds count
O_FLOWS=0 ' reset overflow counter
ENDIF

PIR1.0=0 ' clear timer1 overflow flag
T1CON.0 = 0 ' stop timer1

TMR1H = T1HI ' Reload values
TMR1L = T1LO

T1CON.0=1 ' re-start timer1

ENDIF

if difalt>=89 and difalt<10000 then KILL_MOTOR_ALT 'Check if 100mALT
'(in adc samples) reached!!
if sec_count < 1 then KILL_MOTOR_TMR

goto main


' SUBROUTINES


'************************************************* *****************************
'************************************************* *****************************
GetADC: 'Read MAX187 12bit ADC value - Take 9.25 ms

low ADC_CS
PAUSEUS 10




Average:' -=-=-=-=-=-= Average 16 X Analog values -=-=-=-=-=-=-=-=-=-=

For x = 0 to 15 ' 16 Samples MAXI !!!

shiftin ADC_DATA,ADC_SCLK,msbpost,[advalue\12] '337 µs

value = value + advalue

PAUSEUS 200

NEXT x

Value = Value / 16


difalt = groundalt - value

high ADC_CS

RETURN

END

'************************************************* *****************************

KILL_MOTOR_ALT:

low throttle
high led

LOOP1:
PULSOUT throttle, brake_pulse ' Kill motor - adjust this value. 4Mhz ->> 10uSec
pause 19
goto LOOP1

END
'************************************************* *****************************

KILL_MOTOR_TMR:

x = 0
T1CON.0 = 0 ' Stop the Timer

LOOP2:

low throttle
PULSOUT throttle, brake_pulse ' Kill motor - adjust this value. 4Mhz ->> 10uSec

IF X = 0 THEN led = led ^ 1
x = ( x+1 ) // 18 ' Counter for led Blinking @ 1.5 Hz

pause 19
goto LOOP2

END
'************************************************* *****************************
'************************************************* *****************************


Fond some " strange " things and corrected them ...

Alain

bitmaniac
- 2nd February 2010, 20:55
(SO....I have to see both codes side by side so I can learn for my mistakes :) )

You 've done excellent coding ...I'll give it a try although I had problems with averaging routines -keep sending '0' as result!

Darrel Taylor
- 2nd February 2010, 22:02
I agree with Walter.
All this "Software Timed" stuff just doesn't work well together.

Everything, should be Interrupt driven.

Capture (CCP) the received pulses.
Use A/D interrupt to OverSample the Altitude. (oversampling does not have to be "Blocking")
Timer interrupt to drive the servo.

No PULSIN's, no PULSOUT's, no SHIFTIN/OUT.

These PIC chips are extremely fast. (As long as the program isn't sitting in a loop somewhere waisting 90% of it's time.)
And with the Hardware doing most of the work, they "Scream".

Even if you don't use Interrupts ... Use the hardware.
<br>

Acetronics2
- 3rd February 2010, 09:32
Hi, Alex ...

just two little "bugs" of mine ...


'---------------------------------------------------------------------------
pause 3000

for x=1 to 4
high led
pause 200
low led
pause 100
next x



... I only forgot to clear the comments for shortening delays when using MPSIM ...

Here is the good sequence ...

AND




Average:' -=-=-=-=-=-= Average 16 X Analog values -=-=-=-=-=-=-=-=-=-=

Value = 0

For x = 0 to 15 ' 16 Samples MAXI !!!

shiftin ADC_DATA,ADC_SCLK,msbpost,[advalue\12] '337 µs

value = value + advalue



Forgot resetting "value" ... Boooo.


But ... you of course had noticed it !

Alain

PS for Darrel ...



Everything, should be Interrupt driven.


You really sure ??? ... not me, here for R/C Gadgets ...

flotulopex
- 3rd June 2010, 06:48
Hi All,

Just a question about DEFINEs.

In Darrel's code, I can see

DEFINE ADC_BITS 16 '10 BIT A/D CONVERSION RESULT
What does it mean?

I'm using a 12F683 that can only do a 10 bits resolution son what do I not understand? Why 16?

bitmaniac
- 3rd June 2010, 07:41
Hi All,
....
I'm using a 12F683 that can only do a 10 bits resolution son what do I not understand? Why 16?

Well my friend if you read carefully you would notice that Darell uses a method called 'Oversampling technique' to increase the resolution by software trick.
more info at : http://www.darreltaylor.com/DT_Analog/

So the actual hardware used is the onboard f683 10bit but with 'oversampling' by software you can archive 16 bit resolution result with speed penalty as a drawback.
By using define you can use 10 to 16 bit 'sampling' with the most common use be the 12 bit sampling as a matter of speed.

Have a nice day my friend!

flotulopex
- 3rd June 2010, 09:13
Thanks bitmaniac,

I have read Alain's explanation about "oversampling" and "rolling mean value" in a previous post but I'm still not clear why it is necessary to declare a DEFINE to do so.

I think, I don't understand what the DEFINE does.

Any clue for me?

mark_s
- 3rd June 2010, 15:37
Thanks bitmaniac,

I have read Alain's explanation about "oversampling" and "rolling mean value" in a previous post but I'm still not clear why it is necessary to declare a DEFINE to do so.

I think, I don't understand what the DEFINE does.

Any clue for me?

Hello,
You are correct you should set the pic to 10 bits:
DEFINE ADC_BITS 10

http://www.darreltaylor.com/DT_Analog/

If you study Darrel's example in the above link, bottom of the article.
You set your oversampling resolution in this line:


ADbits = 12 ; set to 12-bit resolution

Regards
Mark

Acetronics2
- 3rd June 2010, 16:41
I think, I don't understand what the DEFINE does.

Any clue for me?

Hello, Roger

DEFINE only set a constant ... used to DEFINE some processor module or macros configs.

the value is tested, and relevant settings are chosen by the compiler ( sort of conditionnal assembly - if you prefer ... sort of !!! )

just look at the difference ( in the asm listing) between DEFINE ADC_BITS 8 and ADC_BITS 10 ...

Should be little differences in the ADCONx setting values ... don't you think ???

Alain

flotulopex
- 3rd June 2010, 21:34
Thanks Alain,

I was confused because of the value (16) in Darrel's code example.

I now understand what this particular DEFINE does ;)

flotulopex
- 3rd March 2011, 09:44
Hi Darrel,

I'm a little confused about how to convert the ADC "pressure" result in an altitude (from 0.2V...4.8V to n meters or feets).

I've read lots of posts, but it is still unclear to me :(

Darrel Taylor
- 3rd March 2011, 15:04
Hi Roger,

Me too.
All I did was convert to kPa, PSI or BAR as shown in this calculator.
http://www.pbpgroup.com/Calculators/MPX4115A/MPX4115A.htm

Walter did a project for an altimeter using a lookup table ...
http://www.picbasic.co.uk/forum/content.php?r=184-MPX4115A-picbasic-code


.

ScaleRobotics
- 3rd March 2011, 17:25
I need to work at this a little to explain it well. But here is a shot at explaining it generally. I am still looking for the excel spreadsheet I did to make my lookup table ... but in the mean time...

Using an excel spread sheet, put a formula for calculating altitude from pressure. Add the formula for your pressure sensor to convert its voltage to pressure. Add in the part that converts your A/D reading to a voltage. Once you get to a point where you can say a reading of xxx of your a/d conversion gives you x feet or meters, you can find some evenly spaced a/d readings, and input the corresponding feet or meters into a lookup table. I know this explanation kind of stinks, because you need some examples here. I will try to elaborate on this later.

Anyway, once you have your lookup table, you need to divide your a/d reading by a number. If you look at my lookup table, you see that I am dividing by 1000 and subtracting 15. This is for a 16 bit A/D result. (In my code, even if you decide to use 12 bit resolution, it is shifted up to 16 bits so it can use the same lookup table). The subtract 15 lets you lower the start of your max altitude. Normal folks might just want to go up to 12,000 feet, or maybe even lower, so they would have a bigger subtraction number, and a different lookup table, that started at a lower altitude.

You may notice that I am looking up two values. This is because the value from the adc will be between two of the lookup table values. The lookup values in my table are about 400 feet or so apart. To make this somewhat accurate, we need to lookup both readings in the lookup table, find the difference in feet, then take our remainder from divide by 1000 and multiply the fraction to the difference in feet. Then I subtract this from my TempAlt to get a final altitude. For this to work, my lookup table had to be made at Analog to digital steps of 1000. That makes the math a little easier.

I am pretty sure I used Alain's spreadsheet as a base to calculate my lookup table. You can find his spreadsheet in Post 33 and another one of his previous. Also BitManiac has a spreadsheet in there as well. Here are my values, calculating for even 1000 steps for the A/D value. Table step number is shown, as is feet of altitude, and pressure in Pa.

<table frame="VOID" rules="NONE" border="0" cellspacing="0" cols="4"> <colgroup><col width="83"><col width="93"><col width="107"><col width="107"></colgroup> <tbody> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20" width="83">A/D Value</td> <td align="CENTER" bgcolor="#E6E6E6" width="93">Table step </td> <td align="CENTER" bgcolor="#E6E6E6" width="107">Feet</td> <td align="CENTER" bgcolor="#E6E6E6" width="107">Pa</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">54000</td> <td align="CENTER" bgcolor="#E6E6E6">39</td> <td align="CENTER" bgcolor="#E6E6E6">-237</td> <td align="CENTER" bgcolor="#E6E6E6">102.2</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">53000</td> <td align="CENTER" bgcolor="#E6E6E6">38</td> <td align="CENTER" bgcolor="#E6E6E6">226</td> <td align="CENTER" bgcolor="#E6E6E6">100.5</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">52000</td> <td align="CENTER" bgcolor="#E6E6E6">37</td> <td align="CENTER" bgcolor="#E6E6E6">696</td> <td align="CENTER" bgcolor="#E6E6E6">98.8</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">51000</td> <td align="CENTER" bgcolor="#E6E6E6">36</td> <td align="CENTER" bgcolor="#E6E6E6">1172</td> <td align="CENTER" bgcolor="#E6E6E6">97.11</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">50000</td> <td align="CENTER" bgcolor="#E6E6E6">35</td> <td align="CENTER" bgcolor="#E6E6E6">1655</td> <td align="CENTER" bgcolor="#E6E6E6">95.41</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">49000</td> <td align="CENTER" bgcolor="#E6E6E6">34</td> <td align="CENTER" bgcolor="#E6E6E6">2145</td> <td align="CENTER" bgcolor="#E6E6E6">93.71</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">48000</td> <td align="CENTER" bgcolor="#E6E6E6">33</td> <td align="CENTER" bgcolor="#E6E6E6">2643</td> <td align="CENTER" bgcolor="#E6E6E6">92.02</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">47000</td> <td align="CENTER" bgcolor="#E6E6E6">32</td> <td align="CENTER" bgcolor="#E6E6E6">3148</td> <td align="CENTER" bgcolor="#E6E6E6">90.32</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">46000</td> <td align="CENTER" bgcolor="#E6E6E6">31</td> <td align="CENTER" bgcolor="#E6E6E6">3660</td> <td align="CENTER" bgcolor="#E6E6E6">88.62</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">45000</td> <td align="CENTER" bgcolor="#E6E6E6">30</td> <td align="CENTER" bgcolor="#E6E6E6">4181</td> <td align="CENTER" bgcolor="#E6E6E6">86.92</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">44000</td> <td align="CENTER" bgcolor="#E6E6E6">29</td> <td align="CENTER" bgcolor="#E6E6E6">4710</td> <td align="CENTER" bgcolor="#E6E6E6">85.23</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">43000</td> <td align="CENTER" bgcolor="#E6E6E6">28</td> <td align="CENTER" bgcolor="#E6E6E6">5247</td> <td align="CENTER" bgcolor="#E6E6E6">83.53</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">42000</td> <td align="CENTER" bgcolor="#E6E6E6">27</td> <td align="CENTER" bgcolor="#E6E6E6">5794</td> <td align="CENTER" bgcolor="#E6E6E6">81.83</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">41000</td> <td align="CENTER" bgcolor="#E6E6E6">26</td> <td align="CENTER" bgcolor="#E6E6E6">6349</td> <td align="CENTER" bgcolor="#E6E6E6">80.14</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">40000</td> <td align="CENTER" bgcolor="#E6E6E6">25</td> <td align="CENTER" bgcolor="#E6E6E6">6915</td> <td align="CENTER" bgcolor="#E6E6E6">78.44</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">39000</td> <td align="CENTER" bgcolor="#E6E6E6">24</td> <td align="CENTER" bgcolor="#E6E6E6">7490</td> <td align="CENTER" bgcolor="#E6E6E6">76.74</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">38000</td> <td align="CENTER" bgcolor="#E6E6E6">23</td> <td align="CENTER" bgcolor="#E6E6E6">8076</td> <td align="CENTER" bgcolor="#E6E6E6">75.04</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">37000</td> <td align="CENTER" bgcolor="#E6E6E6">22</td> <td align="CENTER" bgcolor="#E6E6E6">8672</td> <td align="CENTER" bgcolor="#E6E6E6">73.35</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">36000</td> <td align="CENTER" bgcolor="#E6E6E6">21</td> <td align="CENTER" bgcolor="#E6E6E6">9280</td> <td align="CENTER" bgcolor="#E6E6E6">71.65</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">35000</td> <td align="CENTER" bgcolor="#E6E6E6">20</td> <td align="CENTER" bgcolor="#E6E6E6">9900</td> <td align="CENTER" bgcolor="#E6E6E6">69.95</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">34000</td> <td align="CENTER" bgcolor="#E6E6E6">19</td> <td align="CENTER" bgcolor="#E6E6E6">10532</td> <td align="CENTER" bgcolor="#E6E6E6">68.26</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">33000</td> <td align="CENTER" bgcolor="#E6E6E6">18</td> <td align="CENTER" bgcolor="#E6E6E6">11176</td> <td align="CENTER" bgcolor="#E6E6E6">66.56</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">32000</td> <td align="CENTER" bgcolor="#E6E6E6">17</td> <td align="CENTER" bgcolor="#E6E6E6">11834</td> <td align="CENTER" bgcolor="#E6E6E6">64.86</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">31000</td> <td align="CENTER" bgcolor="#E6E6E6">16</td> <td align="CENTER" bgcolor="#E6E6E6">12507</td> <td align="CENTER" bgcolor="#E6E6E6">63.16</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">30000</td> <td align="CENTER" bgcolor="#E6E6E6">15</td> <td align="CENTER" bgcolor="#E6E6E6">13194</td> <td align="CENTER" bgcolor="#E6E6E6">61.47</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">29000</td> <td align="CENTER" bgcolor="#E6E6E6">14</td> <td align="CENTER" bgcolor="#E6E6E6">13896</td> <td align="CENTER" bgcolor="#E6E6E6">59.77</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">28000</td> <td align="CENTER" bgcolor="#E6E6E6">13</td> <td align="CENTER" bgcolor="#E6E6E6">14615</td> <td align="CENTER" bgcolor="#E6E6E6">58.07</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">27000</td> <td align="CENTER" bgcolor="#E6E6E6">12</td> <td align="CENTER" bgcolor="#E6E6E6">15351</td> <td align="CENTER" bgcolor="#E6E6E6">56.38</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">26000</td> <td align="CENTER" bgcolor="#E6E6E6">11</td> <td align="CENTER" bgcolor="#E6E6E6">16106</td> <td align="CENTER" bgcolor="#E6E6E6">54.68</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">25000</td> <td align="CENTER" bgcolor="#E6E6E6">10</td> <td align="CENTER" bgcolor="#E6E6E6">16879</td> <td align="CENTER" bgcolor="#E6E6E6">52.98</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">24000</td> <td align="CENTER" bgcolor="#E6E6E6">9</td> <td align="CENTER" bgcolor="#E6E6E6">17673</td> <td align="CENTER" bgcolor="#E6E6E6">51.29</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">23000</td> <td align="CENTER" bgcolor="#E6E6E6">8</td> <td align="CENTER" bgcolor="#E6E6E6">18489</td> <td align="CENTER" bgcolor="#E6E6E6">49.59</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">22000</td> <td align="CENTER" bgcolor="#E6E6E6">7</td> <td align="CENTER" bgcolor="#E6E6E6">19327</td> <td align="CENTER" bgcolor="#E6E6E6">47.89</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">21000</td> <td align="CENTER" bgcolor="#E6E6E6">6</td> <td align="CENTER" bgcolor="#E6E6E6">20190</td> <td align="CENTER" bgcolor="#E6E6E6">46.19</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">20000</td> <td align="CENTER" bgcolor="#E6E6E6">5</td> <td align="CENTER" bgcolor="#E6E6E6">21078</td> <td align="CENTER" bgcolor="#E6E6E6">44.5</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">19000</td> <td align="CENTER" bgcolor="#E6E6E6">4</td> <td align="CENTER" bgcolor="#E6E6E6">21995</td> <td align="CENTER" bgcolor="#E6E6E6">42.8</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">18000</td> <td align="CENTER" bgcolor="#E6E6E6">3</td> <td align="CENTER" bgcolor="#E6E6E6">22942</td> <td align="CENTER" bgcolor="#E6E6E6">41.1</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">17000</td> <td align="CENTER" bgcolor="#E6E6E6">2</td> <td align="CENTER" bgcolor="#E6E6E6">23921</td> <td align="CENTER" bgcolor="#E6E6E6">39.41</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">16000</td> <td align="CENTER" bgcolor="#E6E6E6">1</td> <td align="CENTER" bgcolor="#E6E6E6">24934</td> <td align="CENTER" bgcolor="#E6E6E6">37.71</td> </tr> <tr> <td align="CENTER" bgcolor="#E6E6E6" height="20">15000</td> <td align="CENTER" bgcolor="#E6E6E6">0</td> <td align="CENTER" bgcolor="#E6E6E6">25985</td> <td align="CENTER" bgcolor="#E6E6E6">36.01</td> </tr> </tbody> </table>

I have attached one interesting pdf. It is not the formula I used for my lookup table, but it is interesting.

Walter