• PicŪ Basic


  • MS5611 Pressure sensor

    The MS5611 is a 24bit digital absolute pressure sensor. It outputs both pressure and temperature via a i2c interface or 4 wire SPI interface. The following code utilizes a DOG 128x64 LCD which needs only 5 control pins to operate. Including the MS5611 only 7 pic pins are needed to provide a small compact device. I have used the PIC18f26K20 micro controller as its low power 3.3 volt operation is ideal for using with the DOG display and sensor which are both 3.3volts.
    Code:
    '****************************************************************'*  Name    : MS5611.BAS                                        *
    '*  Author  : [jeremy smith]                                    *
    '*  Notice  : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 8/8/2012                                          *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
       Device = 18F26K20
        XTAL = 8
        'Declare PLL_Req = True
        OSCCON  = 100000         'Internal 8 MHz clock select
        'OSCTUNE.6 = 1 ' Frequency Multiplier PLL for INTOSC Enable bit
        ALL_DIGITAL = True 
        Declare WATCHDOG = True
        FLOAT_DISPLAY_TYPE = LARGE
        
        ' Device Fuse configuration
        CONFIG_START
        FOSC = INTIO67 'type of main oscilator used(INTIO67 is internal 16MHz oscilator 
        FCMEN = OFF 'fail-safe clock monitor
        IESO = OFF 'internal/external oscilator switchover enable
        PWRT = On 'powerup timer enable(keep in reset until power is good)
        BOREN = OFF 'brown out reset enable
        BORV = 27 'brown out voltage(2.7v)
        WDTEN = OFF 'watchdog timer enable(can be disable in software if enabled here)
        WDTPS = 128 'watchdog timer postscale value
        PBADEN = OFF 'PORTB.0 to 4 digital on power up
        STVREN = OFF 'no reset on stack full
        LVP = OFF 'low voltage programming
        XINST = OFF 'extended instruction set
        Debug = OFF 'hardware debug module
        CCP2MX=PORTC 'alternative pin(RB3) for HPWM2
        MCLRE= off 'enable MCLRE pin as RE3(digital input pin only)
        HFOFST=On 'allow core to run before oscilator has stabilised on frequency
        LPT1OSC=OFF 'unused
        CP0=OFF 'code protection bits, all unused
        CP1=OFF
        CP2=OFF
        CP3=OFF
        CPB=OFF
        CPD=OFF
        WRT0=OFF
        WRT1=OFF
        WRT2=OFF
        WRT3=OFF
        WRTB=OFF
        WRTC=OFF
        WRTD=OFF
        EBTR0=OFF
        EBTR1=OFF
        EBTR2=OFF
        EBTR3=OFF
        EBTRB=OFF            
        CONFIG_END  
    
    
    ' ****************I2C declared pins for the MS5611 *****************************
     Declare SDA_PIN PORTC.2
     Declare SCL_PIN PORTC.3
     
    '****************** Variables to hold the MS5611 calculations ******************
    Dim PRESSURE As DWord
    Dim RAW_TEMP As DWord
    Dim TEMPC As Float
    Dim TEMPC1 As DWord
    Dim VAR_DT As DWord
    Dim VAR_OFF As Float
    Dim VAR_OFF1 As Float
    Dim VAR_OFF2 As Float
    Dim VAR_OFF3 As Float
    Dim VAR_OFF4 As Float
    Dim VAR_SENS As Float
    Dim VAR_SENS1 As Float
    Dim VAR_SENS2 As Float   
    Dim VAR_SENS3 As Float
    Dim VAR_SENS4 As Float
    Dim vario As DWord
    Dim P1 As Float
    Dim P2 As Float
    Dim P3 As Float
    '----------- MS5611 coeficients read from the eprom on the device --------------
    Symbol C1 = 60203 '$A2
    Symbol C2 = 52502 '$A4
    Symbol C3 = 37307 '$A6
    Symbol C4 = 32921 '$A8
    Symbol C5 = 32737 '$AA
    Symbol C6 = 27535 '$AC
    Symbol CRC = 40990' $AE
    
    
    
    
    '*************************** DOG displat text **********************************
    Dim index As Byte       'dim for column selecting
    Dim lcd_page As Byte    'dim for page increments
    Dim page_index As Byte  'to clear pages in clear screen routine
    Dim Col_MSB As Byte     'column MSB part
    Dim Col_LSB As Byte     'column LSB part
    Dim LCD_Row As Byte     'selects Row 
    Dim i As Byte
    Dim j As Word
    Dim k As Byte
    Dim LcdStr[26] As Byte
    Dim Lcd_Data As Byte
    Dim Lcd_column As Byte
    Dim LCD_COL As Byte
    Dim databyte As Byte
    Dim fontcash[6] As Byte 'font data 6 bits of data per chr ie "$E0,$E0,$E0,$00,$00,$00"
    Dim BIGfontcash[11] As Byte
    Dim INDEXROW As Byte
    
    
    '***************************Ring Buffer for pressure averaging Dims ************
    Symbol AvgCount = 8 ' = Number of samples to average
    Symbol FAspread = 400 ' = Fast Average threshold +/-
    Dim ADavg As Float
    Dim temp1 As Float
    Dim temp2 As Float
    ADavg = 0
    
    
    
    
    '****************************EADOG 128x64 LCD PINS******************************
    Symbol SI = PORTC.7   'pin 36 SI PIN
    Symbol CS = PORTC.4   'pin 40 cs
    Symbol A0 = PORTC.5   'pin 38 A0 PIN
    Symbol CLK = PORTC.6  'pin 37  clock
    High PORTB.0          'pin 39 reset pin hid high
    '*******************************************************************************
    
    
    
    
    GoSub  Init_LCD       'initilise the dislpay
    GoSub Clear_Screen    'clear the screen
    
    
     '---------------------------------------------------------------------------
     ' THIS SENDS 16 CLOCK PULSES TO THE MS5611 BEFORE THE RESET SEE DATA SHEET
     For index = 1 To 16
     PORTC.3 = PORTC.3 ^1
     DelayMS 1
     Next
     '--------------------------------------------------------
     ' RESETS THE MS5611 PRESSURE SENSOR
      BStart
      BusOut $EC      ' MS5611 CONTROL ADDRESS
      BusOut $1E      ' SEND RESTE COMMAND
      BStop
      DelayMS 5       ' LET IT RESET
    
    
    main:
    
    
    GoSub READ_PRESSURE
    GoSub READ_TEMP
    
    
        lcd_page = 177                 'selects the line 1 to 7,  176=page 1
        Lcd_column = 5                 'Selects column 0 - 128
        GoSub lcd_gotoxy
        Str LcdStr = "Hpa: ",0          'enter your text here
        GoSub Lcd_SentString           'goto string loading routine 
        lcd_page = 177
        Lcd_column = 30                'Selects column 0 - 128
        GoSub lcd_gotoxy
        Str LcdStr = Str$ (DEC2 P3)    'prints the pressure in Hpa
        GoSub Lcd_SentString          'goto string loading routine 
        
        lcd_page = 180                 'selects the line 1 to 7,  176=page 1
        Lcd_column = 5                 'Selects column 0 - 128
        GoSub lcd_gotoxy
        Str LcdStr = "Temp: ",0          'enter your text here
        GoSub Lcd_SentString           'goto string loading routine 
        
        lcd_page = 180
        Lcd_column = 30                 'Selects column 0 - 128
        GoSub lcd_gotoxy
        Str LcdStr = Str$ (DEC1 TEMPC)   'prints the temperature
        GoSub Lcd_SentString            'goto string loading routine 
          
    GoTo main
    
    
    '********************************CLEAR SCREEN ********************************** 
    'this function clears the screen by selecting each row in turn and setting each
    'pixel to zero in each row, then it selects the next row and so on  it also has  
    'reset the column number to 0 after each page increment.
    '******************************************************************************* 
    Clear_Screen:
    
    
    Low A0                                      'prepare LCD for command send                                    
    For page_index = 176 To 183                 ' 0 - 7 pages on screen or page rows
        Low CS
        SHOut SI,CLK, msbfirst, [page_index]    'page address
        High CS                                 'de select lcd
        
        
    '******* this sets the column back to zero after each page increment ***********  
      Col_MSB = 0 >>4                  ' shifts data in MSB 4 places to right
      Col_LSB = 0 <<4                  
      Col_LSB = Col_LSB >>4
      Col_MSB = Col_MSB + 16                    'need to add 16 as D4 is always 16
     Low A0                                     'pepare LCD for Command
     Low CS  
     SHOut SI,CLK, msbfirst, [Col_LSB,Col_MSB] 'page address is 100 col=9=(9=lsb+16=msb)
     High CS
     High A0                                    'prepare LCD for data send 
        For index = 0 To 127                    '128 columns
            Low CS                              'select lcd
            SHOut SI,CLK, msbfirst, [$00]       'turn each pixel off in column
            High CS                             'de select lcd
             Next 
        Low A0                                  'select command send
        DelayMS 100
    Next page_index                             'increment to next row
    Return                                      'go back to old kent road
    
    
    
    
    
    
    '************************GOTO X (Column),Y (Page) Pos on LCD *******************
    ' Two 8bit commands are req for col bit shifting ensures MSB and LSB are joined 
    '*******************************************************************************  
    lcd_gotoxy:
          Low A0
        Low CS
        SHOut SI,CLK, msbfirst, [lcd_page]      'page address
        High CS      
      Col_MSB = Lcd_column >>4                  'shifts data in MSB 4 places to right
      Col_LSB = Lcd_column <<4                  
      Col_LSB = Col_LSB >>4
      Col_MSB = Col_MSB + 16                    'need to add 16 as D4 is always 16
     Low A0                                     'pepare LCD for Command
     Low CS  
     SHOut SI,CLK, msbfirst, [Col_MSB, Col_LSB] 'page address is 100 col=9=(9=lsb+16=msb)
     High CS
     High A0
    Return
    '*******************************************************************************  
    Lcd_SentChar:
        j=databyte * 6                 ' does this increment through car cread line ???????
        For i=0 To 5                   ' five bytes in the character
          databyte=CRead Font+j+i      ' can not sus what j does butthink its incrementing through cread table
          fontcash[i] = databyte
          Next
      
          High A0
          Low CS
          SHOut SI,CLK, msbfirst, [fontcash[0],fontcash[1],fontcash[2],fontcash[3],fontcash[4],fontcash[5]]
          High CS
    Return
    '*****************************************************************************
    Lcd_SentString:
        For k=0 To 26                 ' this sets the max string lengh to equall LCD width
            databyte=LcdStr[k]       ' loads char into string
            If databyte=0 Then Break ' stops at end
            GoSub Lcd_SentChar       ' sends each char in turn to cread byte send routine
        Next
    Return
            
    '****************************Initialise the LCD ************************************
    ' This fuction sends the init commands for lcd  all in one SHOUT statement
    '***********************************************************************************          
    Init_LCD:
        Low A0              ' Prepare LCD for command send
        Low CS              ' select LCD
        SHOut SI,CLK, msbfirst, [$40,$A1,$C0,$A6,$A2,$2F,$F8,$00,$27,$81,$16,$AC,$00,$AF] 
        High CS             ' de selects LCD
    Return                  ' go back to old kent road
    '***********************************************************************************
    
    
    READ_PRESSURE:
      BStart
      BusOut $EC              ' MS5611 CONTROL ADDRESS   WRITE COMMAND
      BusOut $48              ' SEND THE PRESSURE CONVERSION COMMAND
      BStop
      
      DelayMS 9               ' SEE DATA SHEET NEED 9MS TO GET RESULT
      BStart
      BusOut $EC              ' MS5611 CONTROL ADDRESS
      BusOut $00              ' READ THE ADC CONVERSION 
      BStop
      
      BStart
      BusOut $ED              ' MS5611 CONTROL ADDRESS READ COMMAND
      PRESSURE  = BusIn       ' get the ADC result and put it in PRESSURE variable
      BStop
     
     PRESSURE = PRESSURE >>8  ' shift out the 8 unwanted bit to leave 24bit result 
    GoSub Av_reading
    
    
    'OFF = C2 * 65536 + (C4 * dT ) / 128; 
    ' i have divided by 100 to reduce the size of the ansew to fit 32bit variable
    VAR_OFF1 = (C2/100) * 655.36       '= (52502/100) * (65536/100)
    VAR_OFF2 = (C4/100)       
    VAR_OFF3 = VAR_OFF2 * (VAR_DT/100)   
    VAR_OFF4 = VAR_OFF3/128           
    VAR_OFF = (VAR_OFF1 + VAR_OFF4)   
    
    
    ' PROTON Gives 344079700   EXCEL Gives 3471975808
    
    
      
    
    
    'SENS = C1 * 32768 + (C3 * dT) / 256;
    ' will not store the result as it is to big,,need to dive by 100 to fit in var
     VAR_SENS1 = (C1/100)* 327.68
     VAR_SENS2 = (C3/100) 
     VAR_SENS3 = VAR_SENS2 * (VAR_DT/100)
     VAR_SENS4 = VAR_SENS3/256
     VAR_SENS =  (VAR_SENS1 +  VAR_SENS4)
    'PROTON Gives  197274662  EXCEL Gives 1990929851
    
    
    
    
      
     'P = (D1*SENS/2097152 - OFF)/32768;
     P1 = (PRESSURE/100) * VAR_SENS     '=  d1 * Var_SENS   = (7125836 *200721.2)
     P2 =  P1/20971.52 - VAR_OFF       
     P3 = (P2/327.68) 
     
    Return
       
     READ_TEMP:
      BStart
      BusOut $EC      ' MS5611 CONTROL ADDRESS   WRITE COMMAND
      BusOut $58      ' SEND THE TEMP CONVERSION COMMAND
      BStop
      
      DelayMS 9       ' SEE DATA SHEET NEED 9MS TO GET RESULT
      BStart
      BusOut $EC      ' MS5611 CONTROL ADDRESS
      BusOut $00      ' READ THE ADC CONVERSION 
      BStop
      
      BStart
      BusOut $ED     ' MS5611 CONTROL ADDRESS READ COMMAND
      RAW_TEMP  = BusIn
      BStop 
      RAW_TEMP =RAW_TEMP >>8  ' shift out the 8 unwanted bit to leave 24bit result
    
    
    
    
    'dT = D2-((long)C5*256);
    ' TEMP = 2000 + ((long long)dT * C6)/8388608;
    VAR_DT = RAW_TEMP -(C5 * 256)
    TEMPC1 = (VAR_DT * C6)/8388608 
    TEMPC = 2000 + TEMPC1
    TEMPC=TEMPC/100
    
    
    Return 
     
    '*****************  Ring Buffer type averaging on the hoof *********************
    Av_reading:
    If PRESSURE = ADavg Then NoChange
    If Abs (PRESSURE - ADavg) > FAspread Or PRESSURE < AvgCount Then FastAvg
    If Abs (PRESSURE - ADavg) < AvgCount Then RealClose
    ADavg = ADavg - (ADavg/AvgCount)
    ADavg = ADavg + (PRESSURE/AvgCount)
    GoTo AVGok
    FastAvg:
    ADavg = PRESSURE
    GoTo AVGok
    RealClose:
    temp1 =  (ADavg/(AvgCount/4))
    temp2 =(PRESSURE/(AvgCount/4))
        ADavg = ADavg - temp1
        ADavg = ADavg + temp2
    
    
    AVGok:
    PRESSURE = ADavg ' Put Average back into altim
    NoChange:
    Return
    
    
    
    
    
    
    
    
    Include "font.inc"
  • Recent Activity

    joesaliba-353

    ASM Error with USART PIC 16F15325

    Thread Starter: Robertux

    Hello, if i try Hserout or Hserout1 I have a ASM error : Symbol not previously defined (PP_TXIF) With Hserin or Hserin1 the ASM error is : Symbol...

    joesaliba Yesterday, 17:22 Go to last post
    RGV250-614

    Wrong loader version

    Thread Starter: RGV250

    Hi, I have just had to re-install PDS (thanks to the latest windows10 update wrecking my laptop), I have compiler 3.6.0.3 but the loader is 1.0.2.1...

    RGV250 Today, 10:11 Go to last post