PDA

View Full Version : Manometer project continued.



aajgss
- 9th June 2011, 07:38
OK, I have the math to a point where it is calculating somewhere near the number I want.

I have connected the hardware. A MPXV4006 pressure sensor which is connected to a MCP3201 ADC which in turn goes via SPI to a 18F14K50 PIC.

Attached is the setup.


' Variables
SCK VAR PORTB.6 'Clock pin
CS VAR PORTC.1 'Chip Select Active low
SDI VAR PORTB.4 'Data In pin

COUNTS var word
lbit var COUNTS.byte0
hbit var COUNTS.byte1
'-------------------------------------------------------------------------------
Define LOADER_USED 1
INCLUDE "MODEDEFS.BAS"
DEFINE OSC 12
DEFINE SHIFT_PAUSEUS 10 'gives a 50KHZ clock pulse
TRISB.4 =1 ' set PortB 4 as an input
TRISB.6 =0 ' set PortB 6 as an output

TRISC =%00000000
knots var long
knotsRem var long
HIGH CS
START:

LOW CS
PAUSEUS 50 'delay after CS goes low for conversion to start. Probably not needed
SHIFTIN SDI,SCK,2,[counts\14] ' using mode 2 for SPI
high cs

'knots = ((SQR(counts*100))*1563)/10000
'knotsRem = (SQR(counts*100)*1563)//10000
'serout2 portb.7,396,[ #Knots,".",dec3 knotsRem," ",#counts,","," Knots",13,10]
serout2 portb.7,396,[ #lbit," ",#hbit,13] ' Just send out ADC value to start
GOTO START:
END

I can see the data coming in on the scope. If I move the plunger of the syringe, I get the data changing, but always get a Zero when I send it out to the serial port.

I havent used the shiftin command before. It looks right so I'm not sure where I am going wrong.

Any help would be appreciated.

TIA
aajgss

Ioannis
- 10th June 2011, 08:43
If your data to see on terminal is in the counts variable, you have this line commented out.

Ioannis

aajgss
- 10th June 2011, 12:14
Thanks Ioannis,

I changed it to counts, Unfortunatly no difference, but at least if it was working I wouldn't have seen it anyway. Thanks for the tip.

I also Added

ANSELH.2 = 0

This then worked, however I must say when I read the datasheet for the 18F14K22 I interpret it that it should be digital so it wouldnt be necessary to add this statement so I am a bit confused. Maybe another 40 or 50 reads and it might sink in!!!

regards
aajgss

aajgss
- 19th June 2011, 12:14
I now have everything working and calculating air speed

I used "DEC1" to only print out to one decimal point.

Running the program gave some strange results. On occasion the count would increase, but the Knots value woud reduce.

By printing out all of the remainder, I could see what was going on.
eg for 2577 counts, the value would be 110.7 and for 2579 counts the value would be 110.1. The problem being in the true value

2577 counts is 110.457 and 110.501. The "DEC1" would give the digit either the 1 or 7 and not the 4 or the 5 as I expected (read hoped)

How can I get the first digit?

thanks
aajgss

mackrackit
- 19th June 2011, 13:46
What does your code look like now?

aajgss
- 20th June 2011, 00:59
Hi Dave,

Code is attached. Thanks for looking


Define LOADER_USED 1
INCLUDE "MODEDEFS.BAS"
DEFINE OSC 12
DEFINE SHIFT_PAUSEUS 10
TRISB.4 =1 ' set PortB 4 as an input
TRISB.6 =0 ' set PortB 6 as an output
ANSELH.2 =0
DEFINE ADC_BITS 8
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
ANSEL =%10000000 ' Enable ADC channel-AN2
ANSELH =%0000
OSCCON=%01100000
TRISA =%00001111 ' Set ports A3-A2-A1-A0 as inputs

TRISC =%01001000
knots var long
knotsRem var long
zero var word
zeroSw var portc.6
i var byte
avg var word
HIGH CS
START:
for i = 1 to 10
LOW CS
PAUSEUS 150 'delay after CS goes low for conversion to start. Probably not needed
SHIFTIN SDI,SCK,2,[counts\14] ' using mode 2 for SPI
high cs
avg = counts + avg
next
counts = avg/10
avg=0
if zeroSw then zero = counts 'Get value at zero pressure
if zeroSw then high portc.2
counts = counts -zero 'set zero point
if counts >65000 then counts= 0 'in case of underflow
knots = (((SQR(counts*10000))*65500)/301)/10000
knotsRem = ((SQR(counts*10000)*65500)/301)//10000
serout2 portb.7,396,[ #Knots,".",Dec1 knotsRem," Knots ",#counts," ",#zero,10,13]
GOTO START:
END

Thanks
aajgss

mackrackit
- 20th June 2011, 14:12
Try DEC2 then try DEC3 to see what the command does.
Then take a look at DIG

4.17.7. DIG

DIG returns the value of a decimal digit. Simply tell it the digit number (0 - 4 with 0 being the rightmost digit) you would like the value of, and voila.

B0 = 123 ' Set B0 to 123
B1 = B0 DIG 1 ' Sets B1 to 2 (digit 1 of 123)

Add a DIG statement to your code to "pull" the DIGit you want.

aajgss
- 20th June 2011, 22:08
Thanks Dave,

I looked at both as you suggested. These are the results

Number 40.8914

DEC2 returns the value 1
DEC4 RETURNS
Number 50.143

aajgss
- 20th June 2011, 23:01
Hit the end button before finished.

Results

DEC 1
47.6 Knots 686
46.8 Knots 9598
46.7 Knots 8727
46.2 Knots 9162
47.6 Knots 686
46.4 Knots 8074
46.2 Knots 9162
46.7 Knots 8727
46.2 Knots 9162
46.8 Knots 9598
DEC 2
46.28 Knots 5028
46.69 Knots 3069
46.28 Knots 5028
46.81 Knots 5681
46.93 Knots 893
46.39 Knots 7639
46.62 Knots 9162
46.16 Knots 6116
46.81 Knots 5681
46.04 Knots 7204
DIG 1
43.1 Knots 3910
42.4 Knots 6946
43.7 Knots 3475
43.8 Knots 6086
44.3 Knots 438
43.6 Knots 4563
43.5 Knots 5651
43.5 Knots 5651
43.8 Knots 6086
43.8 Knots 6086
DIG 2
49.0 Knots 7016
49.5 Knots 8539
49.0 Knots 5058
49.9 Knots 8975
50.4 Knots 498
50.4 Knots 498
49.0 Knots 5058
49.4 Knots 7451
49.6 Knots 4622
49.0 Knots 5058


The value before Knots is what is the result of whether I have used DEC 1or 2 and DIG 1 or 2. The value fi=ollowing is the knotsRem variable.

The DEC1 and 2 seem to make sense, although not displaying the first digit but the DIG 1 and 2 look to return the 2nd digit for DIG1 and 3rd digit for DIG2

Before I was confused - now I'm way past that!!
Looking at the manual there doesn't seem to be anywhere that left justifies a number.

Thanks
aajgss

mackrackit
- 21st June 2011, 01:19
NUM VAR WORD
NUM = 12345
NUM_DIG VAR BYTE

BOOT:
SEROUT2 TX,BAUD,[$d,$a]
'RETURNS 12345
SEROUT2 TX,BAUD,["NUM= ",DEC NUM,$d ,$a]
'RETURNS 345
SEROUT2 TX,BAUD,["NUM= ",DEC3 NUM,$d ,$a]
NUM_DIG = NUM DIG 4 'RETURNS 1
SEROUT2 TX,BAUD,["NUM_DIG4= ",DEC NUM_DIG,$d ,$a]
NUM_DIG = NUM DIG 3 'RETURNS 2
SEROUT2 TX,BAUD,["NUM_DIG3= ",DEC NUM_DIG,$d ,$a]
NUM_DIG = NUM DIG 2 'RETURNS 3
SEROUT2 TX,BAUD,["NUM_DIG2= ",DEC NUM_DIG,$d ,$a]
GOTO BOOT

aajgss
- 24th June 2011, 09:47
Hi Dave,

I think I understand where your heading with this.

Where I can see a problem with what I am doing is I dont have a constant number of digits in the remainder. It could be 1,2,3 or 4 characters long, So DIG2 would pick the right number if the remainder was in the hundreds, but the wrong number if the result was in the thousands.

If I remember back to Q Basic days there was a Left$ or Right$ and number of characters command, but I cant see anything like that in PBP.

Am I seeing this right or not?

aajgss

mackrackit
- 24th June 2011, 12:16
If I remember back to Q Basic days there was a Left$ or Right$ and number of characters command, but I cant see anything like that in PBP.

Nope...

Try something like this.
IF NUM_REM >= 9999 and <= 1000 THEN
DIG3 NUM_REM

IF NUM_REM >= 999 and <= 100 THEN
DIG2 NUM_REM

aajgss
- 24th June 2011, 22:59
Ah Yes,

A good solution, thanks. Using that method I could also now look at the second digit and if >= 5 round up to the next value.

aajgss