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..
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..
Hi Alexandros
I had committed that from what you wrote ...
...Code:'**************************************************************************** ' (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
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
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.
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/show...3834#post83834
Walter
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)
Last edited by bitmaniac; - 29th January 2010 at 11:58.
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.
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 ......
Hi, Alex
Interrupts ... ok, nice idea, ... but it will surely interfere with your INPUT Pulsin ....
hé,hé ... you said " Aaaargh !!! " ???
Alain
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
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.
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
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
... or maybe using HPWM for pulsout ? to keep SC alive all the time!
Hi, Alex
I spent some more time on your code ...
should work as I verified the timing and flow with MPSIM ...
Fond some " strange " things and corrected them ...Code:'**************************************************************************** ' (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 '****************************************************************************** '******************************************************************************
Alain
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
(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!
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>
DT
Hi, Alex ...
just two little "bugs" of mine ...
Code:'--------------------------------------------------------------------------- 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
Forgot resetting "value" ... Boooo.Code: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
But ... you of course had noticed it !
Alain
PS for Darrel ...
You really sure ??? ... not me, here for R/C Gadgets ...Everything, should be Interrupt driven.
Last edited by Acetronics2; - 3rd February 2010 at 09:44.
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
Hi All,
Just a question about DEFINEs.
In Darrel's code, I can see
What does it mean?Code:DEFINE ADC_BITS 16 '10 BIT A/D CONVERSION RESULT
I'm using a 12F683 that can only do a 10 bits resolution son what do I not understand? Why 16?
Roger
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!
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?
Roger
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
Last edited by mark_s; - 3rd June 2010 at 15:45. Reason: add link
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
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
Thanks Alain,
I was confused because of the value (16) in Darrel's code example.
I now understand what this particular DEFINE does![]()
Roger
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![]()
Roger
Hi Roger,
Me too.
All I did was convert to kPa, PSI or BAR as shown in this calculator.
http://www.pbpgroup.com/Calculators/...A/MPX4115A.htm
Walter did a project for an altimeter using a lookup table ...
http://www.picbasic.co.uk/forum/cont...-picbasic-code
.
Last edited by Darrel Taylor; - 3rd March 2011 at 15:07.
DT
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
Last edited by ScaleRobotics; - 4th March 2011 at 14:35.
Bookmarks