Shop OBEX P1 Docs P2 Docs Learn Events
BMP085 Revisited... — Parallax Forums

BMP085 Revisited...

zlantzzlantz Posts: 136
edited 2014-02-12 16:38 in Propeller 1
So I have purchased a few BMP180 Module's (the new version of the BMP085), which have the same exact coding structure as the BMP085. I had problems before with i2c and have since gotten other i2c devices working. I can obtain the address of the BMP from an i2cscan and if I try to get the EEPROM values with the wrong address, the data comes back as -1. With the correct address it returns set values for the eeprom, which I understand is what it should do.

When I try to get pressure or temp data from it, I have to read to the write address $EE, which gives a bouncy reading that "appears" correct, at first glance. But is not. And if you use the address the Datasheet says (0xEF (read) and 0xEE (write)) the returned data is -1.

The pressure data changes, but not to pressure changes (blowing onto sensor).
The temp data changes, it climbs, but gets to a point then starts back over at 1, gets to that point again & repeats. (holding the sensor in my hand)

neither data's really settle at a consistent point.

This is what I am using to test the sensor with:
CON
  _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
  _xinfreq = 5_000_000

  ' $AA = 1010_1010
  ' $77 = 0111_0111
  ' $EE = 1110_1110  
   
  'BMP_Addr  = $EE    
  'BMP_Addr = $77
  'BMP_Addr = %1110_1110
  'BMP_Addr = %1110_1111
  'BMP_Addr = 10_1110
  
  ' BMP-085 / BMP-180 Datasheet:  0xEF (read) and 0xEE (write)
  

  
  BMP_Read  = $EE
  'BMP_Write = $77
  BMP_Write = $EE
  'BMP_Write = $EF
    
  
  BMPSCL   = 12   
  BMPSDA   = 13  

   
Var
  word AC1,AC2,AC3,AC4,AC5,AC6,B1,B2,MB,MC,MD             'E2Prom variables from BMP085

  long UT, UP

OBj
  I2C : "Basic_I2C_Driver_1.3"      'By Michael Green
  PST : "Parallax Serial Terminal"  'By Jeff Martin, Andy Lindsay, Chip Gracey
   
PUB Main | mode, MSB, LSB, XLSB
  PST.Start(115_200)        'Sets BaudRate for PST.
  PST.Clear                 'Clears PST Screen.
   
  I2C.Initialize(BMPSCL)
  I2C.Start(BMPSCL)
    
  repeat
     
    'I2C.ReadWord(BMPSCL, BMP_Addr, I2C#OneAddr|$AA)
     
    AC1 := I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$AA)
    AC2 := I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$AC)
    ac3 := I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$AE)
    ac4 := I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$B0)
    ac5 := I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$B2)
    ac6 := I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$B4)
    b1 :=  I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$B6)
    b2 :=  I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$B8)
    mb :=  I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$BA)
    mc :=  I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$BC) 
    md :=  I2C.ReadWord(BMPSCL, BMP_Read, I2C#OneAddr|$BE)

    ' // Read Temperature
    I2C.WriteByte(BMPSCL, BMP_Write, $F4|I2C#OneAddr, $2E)
    waitcnt ((clkfreq / 220) + cnt)                  ' Pause 4.5 mS
    UT := I2C.ReadWord(BMPSCL, BMP_Read, $F6|I2C#OneAddr)

    ' // Read Pressure
    mode := 3
    I2C.WriteByte(BMPSCL, BMP_Write, $F4|I2C#OneAddr, $34|(mode<<6))     
    waitcnt ((clkfreq / 38) + cnt)                   ' Pause 26 mS
    MSB  := I2C.ReadByte(BMPSCL, BMP_Read, $F6|I2C#OneAddr)         
    LSB  := I2C.ReadByte(BMPSCL, BMP_Read, $F7|I2C#OneAddr)
    XLSB := I2C.ReadByte(BMPSCL, BMP_Read, $F8|I2C#OneAddr)      
    UP := (MSB<<16 + LSB<<8 + XLSB)>> (8 - mode)
        
    PST.NewLine
    PST.Dec(UT)
    PST.NewLine
    PST.Dec(UP)      
    PST.NewLine
    PST.Dec(AC1)
    PST.NewLine
    PST.Dec(AC2)
    PST.NewLine
    PST.Dec(AC3)
    PST.NewLine
    PST.Dec(AC4)
    PST.NewLine
    PST.Dec(AC5)
    PST.NewLine
    PST.Dec(AC6)
    PST.NewLine
    PST.Dec(B1)
    PST.NewLine
    PST.Dec(B2)
    PST.NewLine
    PST.Dec(MB)
    PST.NewLine
    PST.Dec(MC)
    PST.NewLine
    PST.Dec(MD)
    PST.NewLine
    PST.Dec(AC2)
    PST.NewLine    

    waitcnt(clkfreq + cnt)

Which I have had similar luck with:
CON
   
  _clkmode = xtal1 + pll16x                  ' System clock &#8594; 80 MHz
  _xinfreq = 5_000_000

  

  CR = 13

  ' i2c bus contants
  _i2cNAK         = 1
  _i2cACK         = 0                                                                                                       
  
  BMPSCL   = 12   
  BMPSDA   = 13

  Baro_Addr = $EE  'i2c address of baro sensor    
                  
{

    ' UT & UP Are Calculated by BMP Object.

    ' // Calculate True Temperature
    X1 := (UT - AC6) * AC5 / 2^15
    X2 := MC * 2^11 / (X1 + MD)
    B5 := X1 + X2
    T := (B5 + 8) / 2^4

    T := Temp in 0.1 deg C
    
    ' // Calculate True Pressure
    B6 := B5 - 4000
    X1 := (B2 * (B6 * B6 / 2^12)) / 2^11
    X2 := AC2 * B6 / 2^11
    X3 := X1 + X2
    B3 := (((AC1 * 4 + X3) << oss) + 2) / 4
    X1 := AC3 * B6 / 2^13
    X2 := (B1 * (B6 * B6 / 2^12)) / 2^16
    X3 := ((X1 + X2) + 2) / 2^2
    B4 := AC4 * (X3 + 32768) / 2^15
    B7 := (UP - B3) * (50000 >> oss)
    if B7 < $8000_0000          ' might need to be if B7 & $8000_0000  (B7 = -B7) else (B7 = +B7)
      p := (B7 * 2) / B4
    else
      p := (B7 / B4) * 2
    X1 := (p / 2^8) * (p / 2^8)
    X1 := (X1 * 3808) / 2^16
    X2 := (-7357 * p) / 2^16
    p := p + (X1 + X2 + 3791) / 2^4

    'p = Pressure in Pa 
    
}


VAR
   
  byte Baro_Data_f6
  byte Baro_Data_f7
  byte Baro_Data_f8
  byte Baro_Data_f9
  byte Baro_Data_fa
  byte Baro_Data_fb
  byte Baro_Data_fc
  byte Baro_Data_fd
  byte Baro_Data_fe
  byte Baro_Data_ff
  byte Baro_Data_AA
  byte Baro_Data_AB
  byte Baro_Data_AC
  byte Baro_Data_AD
  byte Baro_Data_AE
  byte Baro_Data_AF
  byte Baro_Data_B0
  byte Baro_Data_B1
  byte Baro_Data_B2
  byte Baro_Data_B3
  byte Baro_Data_B4
  byte Baro_Data_B5
  byte Baro_Data_B6
  byte Baro_Data_B7   
  byte Baro_Data_B8
  byte Baro_Data_B9
  byte Baro_Data_BA
  byte Baro_Data_BB
  byte Baro_Data_BC
  byte Baro_Data_BD
  byte Baro_Data_BE
  byte Baro_Data_BF
   
  byte  i2cSDA, i2cSCL

  word UP,UT,ac1,ac2,ac3,ac4,ac5,ac6, MB,MC,MD, B1, B2

  long tTemp, tPressure, tAltitude, tAirSpeed
         
OBJ
  'umath :       "umath"                                 '0 Cog       
  Debug      :  "FullDuplexSerialPlus"              ' Use with Parallax Serial Terminal to

  
Pub Start 
  Debug.Start(31, 30, 0, 115200) 

  ' // Baro.init:
  i2cSCL := BMPSCL
  i2cSDA := BMPSDA
  Init_i2c(i2cSDA, i2cSCL)
    
  repeat
     
    Debug.Str(String(13, "BMP-180 Demo")) 

    ' // Read Pressure
    start_adcPres                            ' start the adc then
    readBaro                                 ' read data via i2c bus
    UP :=  baro_f6 * 256 + baro_f7           ' raw 16 bit pressure data put in UP

    waitcnt(clkfreq/100 + cnt)

    ' // Read Temperature
    start_adcTemp                            ' start the adc then
    readBaro                                 ' read data via i2c bus
    UT :=  baro_f6 * 256 + baro_f7           ' raw 16 bit pressure data in UT
    
    ' // Update Values 
    AC1 :=  baro_AA * 256 + baro_AB      
    AC2 :=  baro_AC * 256 + baro_AD
    AC3 :=  baro_AE * 256 + baro_AF
    AC4 :=  baro_B0 * 256 + baro_B1     
    AC5 :=  baro_B2 * 256 + baro_B3
    AC6 :=  baro_B4 * 256 + baro_B5
    B1 :=   baro_B6 * 256 + baro_B7
    B2 :=   baro_B8 * 256 + baro_B9
    MB :=   baro_BA * 256 + baro_BB
    MC :=   baro_BC * 256 + baro_BD
    MD :=   baro_BE * 256 + baro_BF        

    ' // Calculate Ailtutude
    'Convert(3, tTemp, tPressure)
     
    ' // Display Results     
    Debug.Str(String(13, "Temperature = "))
    Debug.Dec(tTemp)
     
    Debug.Str(String(13, "Pressure = "))
    Debug.Dec(tPressure)
     
    Debug.Str(String(13, "Altitude = "))
    Debug.Dec(tAltitude)
     
    Debug.Str(String(13, "Air Speed = "))
    Debug.Dec(tAirSpeed)
                       
    Debug.Str(String(13, "UP = "))
    Debug.Dec(UP)
     
    Debug.Str(String(13, "UT = "))
    Debug.Dec(UT)
     
    Debug.Str(String(13, "AC1 = "))
    Debug.Dec(AC1)
     
    Debug.Str(String(13, "AC2 = "))
    Debug.Dec(AC2)
     
    Debug.Str(String(13, "AC3 = "))
    Debug.Dec(AC3)
     
    Debug.Str(String(13, "AC4 = "))
    Debug.Dec(AC4)
     
    Debug.Str(String(13, "AC5 = "))
    Debug.Dec(AC5)
     
    Debug.Str(String(13, "AC6 = "))
    Debug.Dec(AC6)
     
    Debug.Str(String(13, "B1 = "))
    Debug.Dec(B1)
     
    Debug.Str(String(13, "B2 = "))
    Debug.Dec(B2)
     
    Debug.Str(String(13, "MB = "))
    Debug.Dec(MB)
     
    Debug.Str(String(13, "MC = "))
    Debug.Dec(MC)
     
    Debug.Str(String(13, "MD = "))
    Debug.Dec(MD)
     
    'waitcnt(clkfreq + cnt)


' // Return Calculated Altitude
Pub Altitude

  ' Calculate Altitude

  return tAltitude

' // Return Calculated Temperature  (Obtained via Convert)
Pub Temperature
  return tTemp

' // Return Calculated Pressure     (Obtained via Convert)
Pub Pressure
  return tPressure

Pub Baro_UT
   return UT

Pub Baro_UP
   return UP   

Pub Baro_AC1
   return AC1   

Pub Baro_AC2
   return AC2   

Pub Baro_AC3
   return AC3   

Pub Baro_AC4
   return AC4   

Pub Baro_AC5
   return AC5

Pub Baro_AC6
   return AC6   

Pub Baro_MB
   return MB   

Pub Baro_MC
   return MC   

Pub Baro_MD
   return MD   

Pub Baro_B1a
   return B1   

Pub Baro_B2a
   return B2   
  
' // Convert to Calculated Values
Pri Convert(mode, TempPtr, PressurePtr) | th, x1, x2, b5, b6, x3, b3, p, b4, b7

  {
    ' // Calculate True Temperature
    X1 := (UT - AC6) * AC5 / 2^15
    X2 := MC * 2^11 / (X1 + MD)
    B5 := X1 + X2
    T := (B5 + 8) / 2^4
  
    T := Temp in 0.1 deg C
  }
  
  X1 := ((UT - AC6) * AC5) ~> 15
  'x2 := (mc << 11) / (x1 + md)
  X2 := (MC ~> 11) / (x1 + MD)  
  B5 := X1 + X2
  long[TempPtr] := (B5 + 8) ~> 4

{
    ' // Calculate True Pressure
    B6 := B5 - 4000
    X1 := (B2 * (B6 * B6 / 2^12)) / 2^11
    X2 := AC2 * B6 / 2^11
    X3 := X1 + X2
    B3 := (((AC1 * 4 + X3) << oss) + 2) / 4
    X1 := AC3 * B6 / 2^13
    X2 := (B1 * (B6 * B6 / 2^12)) / 2^16
    X3 := ((X1 + X2) + 2) / 2^2
    B4 := AC4 * (X3 + 32768) / 2^15
    B7 := (UP - B3) * (50000 >> oss)
    if B7 < $8000_0000          ' might need to be if B7 & $8000_0000  (B7 = -B7) else (B7 = +B7)
      p := (B7 * 2) / B4
    else
      p := (B7 / B4) * 2
    X1 := (p / 2^8) * (p / 2^8)
    X1 := (X1 * 3808) / 2^16
    X2 := (-7357 * p) / 2^16
    p := p + (X1 + X2 + 3791) / 2^4

    'p = Pressure in Pa 
} 
  
  B6 := B5 - 4000
  X1 := (B2 * ((B6 * B6) ~> 12)) ~> 11
  'x2 := (AC2 * B6) ~> 11
  X2 := AC2 * B6 ~> 11  
  X3 := X1 + X2
  'B3 := ((((AC1 << 2) + X3) << mode) + 2) ~> 2
  B3 := (((AC1 * 4 + X3) << mode) + 2) ~> 2  

  'X1 := (AC3 * B6) ~> 13
  X1 := AC3 * B6 ~> 13  
  X2 := (B1 * ((B6 * B6) ~> 12)) ~> 16
  X3 := ((X1 + X2) + 2) ~> 2

  B4 := AC4 * (X3 + 32768) ~> 15  
  'B4 := (AC4 * (X3 + 32768)) >> 15                                             'unsigned 32 bit multiple
  'B4 := umath.multdiv(AC4, (X3 + 32768), 32768)

  B7 := (UP - B3) * (50000 >> mode)                                            'unsigned 32 bit multiple
  'if B7 < $8000_0000
  if B7 & $8000_0000
    'p := (B7 / B4) << 1
    p := (B7 * 2) / B4    
  else
    'p := (B7 * 2) / B4
    p := (B7 * B4) * 2
  'p := umath.multdiv((UP - B3), (100000 >> mode), B4)

  'th := p ~> 8 
  'X1 := th * th
  X1 := (p ~> 8) * (p ~> 8)
  X1 := (X1 * 3038) ~> 16
  X2 := (-7357 * p) ~> 16
  long[PressurePtr] := p + (X1 + X2 + 3791) ~> 4


' // EC_i2c_readbaro:
Pri start_adcTemp
   i2cStart
   i2cWrite(Baro_Addr)         'write 0xEE to i2c bus
   i2cWrite($F4)               'write 0xF4 to i2c bus
   i2cWrite($EE)               'write 0xEE sequence to start temp conversion   
   i2cStop

Pri start_adcPres
   i2cStart
   i2cWrite(Baro_Addr)         'write 0xEE to i2c bus
   i2cWrite($F4)               'write 0xF4 to i2c bus
   i2cWrite($F4 )              'write 0xF4 sequence to start pressure conversion   
   i2cStop
  
Pri readbaro

   i2cStart
   i2cWrite(Baro_Addr)         'write 0xEE to i2c bus sensor write address
   i2cWrite($F6)               'write 0xF6 to i2c bus sensor starting register
   i2cStart                    'do a restart
   i2cWrite(Baro_Addr|1)       'write 0xEF (read cmd) to i2c bus sensor read address   

   Baro_Data_f6 := (i2cRead(0))         'i2c read 12 BYTES with ack bit
   Baro_Data_f7 := (i2cRead(0))         '           V
   Baro_Data_f8 := (i2cRead(0))         '           V
   Baro_Data_f9 := (i2cRead(0))         '           V
   Baro_Data_fa := (i2cRead(0))         '           V
   Baro_Data_fb := (i2cRead(0))         '           V
   Baro_Data_fc := (i2cRead(0))         '           V
   Baro_Data_fd := (i2cRead(0))         '           V
   Baro_Data_fe := (i2cRead(0))         '           V
   Baro_Data_ff := (i2cRead(1))         '           V
   i2cStop

   i2cStart
   i2cWrite(Baro_Addr)         'write 0xEE to i2c bus sensor write address
   i2cWrite($AA)               'write 0xF6 to i2c bus sensor starting register
   i2cStart                    'do a restart
   i2cWrite(Baro_Addr|1)       'write 0xEF (read cmd) to i2c bus sensor read address   

   Baro_Data_AA := (i2cRead(0))         'i2c read 12 BYTES with ack bit
   Baro_Data_AB := (i2cRead(0))         '           V
   Baro_Data_AC := (i2cRead(0))         '           V
   Baro_Data_AD := (i2cRead(0))         '           V
   Baro_Data_AE := (i2cRead(0))         '           V
   Baro_Data_AF := (i2cRead(1))         '           V
   i2cStop
   
   i2cStart
   i2cWrite(Baro_Addr)         'write 0xEE to i2c bus sensor write address
   i2cWrite($B0)               'write 0xF6 to i2c bus sensor starting register
   i2cStart                    'do a restart
   i2cWrite(Baro_Addr|1)       'write 0xEF (read cmd) to i2c bus sensor read address   

   Baro_Data_B0 := (i2cRead(0))         'i2c read 12 BYTES with ack bit
   Baro_Data_B1 := (i2cRead(0))         '           V
   Baro_Data_B2 := (i2cRead(0))         '           V
   Baro_Data_B3 := (i2cRead(0))         '           V
   Baro_Data_B4 := (i2cRead(0))         '           V
   Baro_Data_B5 := (i2cRead(0))         '           V
   Baro_Data_B6 := (i2cRead(0))         '           V
   Baro_Data_B7 := (i2cRead(0))         '           V
   Baro_Data_B8 := (i2cRead(0))         '           V
   Baro_Data_B9 := (i2cRead(1))         '           V
   i2cStop

   i2cStart
   i2cWrite(Baro_Addr)         'write 0xEE to i2c bus sensor write address
   i2cWrite($BA)               'write 0xF6 to i2c bus sensor starting register
   i2cStart                    'do a restart
   i2cWrite(Baro_Addr|1)       'write 0xEF (read cmd) to i2c bus sensor read address   

   Baro_Data_BA := (i2cRead(0))         'i2c read 12 BYTES with ack bit
   Baro_Data_BB := (i2cRead(0))         '           V
   Baro_Data_BC := (i2cRead(0))         '           V
   Baro_Data_BD := (i2cRead(0))         '           V
   Baro_Data_BE := (i2cRead(0))         '           V
   Baro_Data_BF := (i2cRead(1))         '           V
   i2cStop

PUB Baro_f6
   return Baro_Data_f6

PUB Baro_f7
   return Baro_Data_f7

PUB Baro_f8
   return Baro_Data_f8

PUB Baro_f9
   return Baro_Data_f9

PUB Baro_fa
   return Baro_Data_fa

PUB Baro_fb
   return Baro_Data_fb

PUB Baro_fc
   return Baro_Data_fc

PUB Baro_fd
   return Baro_Data_fd

PUB Baro_fe
   return Baro_Data_fe

PUB Baro_ff
   return Baro_Data_ff
      
PUB Baro_AA
   return Baro_Data_AA

PUB Baro_AB
   return Baro_Data_AB

PUB Baro_AC
   return Baro_Data_AC

PUB Baro_AD
   return Baro_Data_AD

PUB Baro_AE
   return Baro_Data_AE

PUB Baro_AF
   return Baro_Data_AF
   
PUB Baro_B0
   return Baro_Data_B0

PUB Baro_B1
   return Baro_Data_B1

PUB Baro_B2
   return Baro_Data_B2

PUB Baro_B3
   return Baro_Data_B3

PUB Baro_B4
   return Baro_Data_B4

PUB Baro_B5
   return Baro_Data_B5

PUB Baro_B6
   return Baro_Data_B6

PUB Baro_B7
   return Baro_Data_B7

PUB Baro_B8
   return Baro_Data_B8

PUB Baro_B9
   return Baro_Data_B9

PUB Baro_BA
   return Baro_Data_BA

PUB Baro_BB
   return Baro_Data_BB

PUB Baro_BC
   return Baro_Data_BC

PUB Baro_BD
   return Baro_Data_BD

PUB Baro_BE
   return Baro_Data_BE

PUB Baro_BF
   return Baro_Data_BF
     

  ' // I2C Control
Pri init_i2c(_i2cSDA, _i2cSCL)
    i2cSDA := _i2cSDA  'referances passed from main file for pin numbers
    i2cSCL := _i2cSCL
    outa[i2cSDA] := 0  'as inputs to start
    outa[i2cSCL] := 0

Pri readLocation(deviceAddress, deviceRegister) : i2cData | ackbit
  ' do a standard i2c address, then read
  ' read a device's register
  ackbit := _i2cACK

  i2cStart
  ackbit := (ackbit << 1) | i2cWrite(deviceAddress)   
  ackbit := (ackbit << 1) | i2cWrite(deviceRegister)   
    
  i2cStart
  ackbit := (ackbit << 1) | i2cWrite(deviceAddress | 1)   ' repeat with read bit now set
  i2cData := i2cRead(_i2cNAK)
  i2cStop

  ' return the data      
  return i2cData

    
Pri writeLocation(deviceAddress, deviceRegister, i2cDataValue) : ackbit
  ' do a standard i2c address, then write
  ' return the ACK bit from the device address
  ackbit := _i2cACK
  i2cstart
  ackbit := (ackbit << 1) | i2cWrite(deviceAddress)
  ackbit := (ackbit << 1) | i2cWrite(deviceRegister)
  ackbit := (ackbit << 1) | i2cWrite(i2cDataValue)
  i2cStop
  return ackbit

Pri i2cStop
  ' i2c stop sequence - the SDA goes LOW to HIGH while SCL is HIGH
  dira[i2cSCL] ~
  dira[i2cSDA] ~

    
Pri i2cStart

       dira[i2cSDA] ~  
       dira[i2cSCL] ~
       dira[i2cSDA] ~~       
       
       repeat until ina[i2cSCL] == 1  

Pri i2cWrite(i2cData) : ackbit
    
    i2cData <<=24  

    ' init the clock line                             
    dira[i2cSCL] := 1 
 
    repeat 8
      ' set the SDA while the SCL is LOW 
      dira[i2cSDA] := (!(i2cData <-= 1) & 1)
      ' toggle SCL HIGH
      dira[i2cSCL] := 0
      ' toogle SCL LOW
      dira[i2cSCL] := 1

   ' setup for ACK - pin to input'    
    dira[i2cSDA] := 0
                  
    ' read in the ACK
    dira[i2cSCL] := 0
    ackbit := ina[i2cSDA]
    dira[i2cSCL] := 1

    ' leave the SDA pin LOW 
    dira[i2cSDA] := 1    

   return ackbit  


Pri i2cRead(ackbit): i2cData

    ' set the SCL to output and the SDA to input
    dira[i2cSDA] := 0
    dira[i2cSCL] := 1
     
    ' clock in the byte
    i2cData := 0
    repeat 8
      dira[i2cSCL] := 0
      i2cData := (i2cData << 1) | ina[i2cSDA]
      dira[i2cSCL] := 1
      
    ' send the ACK or NAK
    dira[i2cSDA] ~~
    dira[i2cSCL] := 0
    dira[i2cSDA] := !ackbit
    dira[i2cSCL] := 1

    ' return the data
    return i2cData

However, of these 2 codes, I should get the same resulting values, but I dont, as you can see below.
bmp180 code 1.jpg
bmp180 code 2.jpg
1024 x 757 - 51K
1024 x 757 - 59K

Comments

  • T ChapT Chap Posts: 4,223
    edited 2014-01-25 09:44
    Have you tried testing out a single read of some sort, versus the complete program just to see if you can establish communication? Typically, you would use an I2CSTART, I2C WRITE, followed by a READ to see some data and then STOP. Trying to test with the entire code is tough when you do not know that you have actually established communication with the device at a simpler level.
  • zlantzzlantz Posts: 136
    edited 2014-01-25 12:10
    T Chap wrote: »
    Have you tried testing out a single read of some sort, versus the complete program just to see if you can establish communication? Typically, you would use an I2CSTART, I2C WRITE, followed by a READ to see some data and then STOP. Trying to test with the entire code is tough when you do not know that you have actually established communication with the device at a simpler level.

    If you give it the wrong BMP Address say $A5 instead of $EE the result you will see is -1. The numbers only show up when i use $EE, which was discovered by i2cscan.
  • T ChapT Chap Posts: 4,223
    edited 2014-01-25 12:50
    Do you have pullups on 12/13? Have you tried 28/29? If no pullups on 12 and 13, have you verified that the i2c communication will work without them?
  • zlantzzlantz Posts: 136
    edited 2014-02-08 08:50
    Pullup's are built into the module, i have tested on an i2c port that has 2 resistors on it as well. Since none of the example code works, I have attempted to write my own code. I can get the Chip's ID 0x55 correct, so I assume the Calibration coefficients are coming back right (ac1, ac2, etc) but when it comes to the temperature & pressure, i know they are not right as they are only 3 digits long! expecting 5.

    Here is my code that kinda works:
    Con
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      CLK_FREQ = ((_clkmode-xtal1)>>6)*_xinfreq
      MS_001 = CLK_FREQ / 1_000  
    
      ' // Propeller Pinout
    
      Misc1 = 0
      Misc2 = 1
      Misc3 = 2
      Misc4 = 3
    
      MCPCLK  = 4
      MCPDOut = 5
      MCPDIn  = 5
      MCPCS   = 6      
    
      NC1 = 7
     
      MPUsda  = 8       ' All I2C Sensors on SAME Bus
      MPUscl  = 9
      
      RPitx  = 10        
      RPirx  = 11
      
      GPSrx   = 12  ' SCL
      GPStx   = 13  ' SDA
    
      BMPSCL   = 12   
      BMPSDA   = 13
                      
      WiFitx   = 14       ' White
      WiFirx   = 15       ' Green     
    
      Misc5 = 16    
      Misc6 = 17
      Misc7 = 18
                  
      LED   = 19
      Piezo = 20
    
      Servo6 = 21        ' Left Side Airlerons
      Servo5 = 22        ' Gyro Select
      Servo4 = 23        ' Gyro / Rudder
    
      NC2 = 24
                         
      Servo3 = 25        ' Motor Speed / Power
      Servo2 = 26        ' Elevator
      Servo1 = 27        ' Right Side Airlerons
    
      EEPROMscl   = 28
      EEPROMsda   = 29
    
      DEBUGSERtx  = 30
      DEBUGSERrx  = 31
    
    
      SCL = 12
      alt_address = %1110_1110
    
      ' // BMP-180 Settings
      bmpAddr  = %1110_1110
      
      bmpAddrR = %1110_1110
      bmpAddrW = %1110_1111
      
      OSS1 = 0      ' Ultra Low Power
      OSS2 = 1      ' Standard
      OSS3 = 2      ' High Resolution
      OSS4 = 3      ' Ultra High Resolution
    
    
      ' EEPROM data base address - i.e 32K (assumes a 64kb eeprom installed!!)
      EEPROM_Base   = $8000  
      EEPROMAddr    = %1010_0000  
    
      i2cSCL        = 28
    '  i2cSDA        = 29   
    
    OBJ
    
      i2cObject     :       "basic_i2c_driver_1.3"
      Ser           :       "FullDuplexSerial" 
    
    
    Var
      long ac1, ac2, ac3, ac4, ac5, ac6, b1, b2, mb, mc, md, id
      long UT, UP
      
    
      long T, P
      long i2cAddress, i2cSlaveCounter
    
      long oss
    
    Pub Start
      ser.start(31,30,0,115200)
    
      i2cObject.Initialize(bmpSCL)
    
      oss := OSS2
      
      repeat
    
        if i2cObject.devicePresent(bmpSCL, alt_address) == True
          ser.str(string("Device Located!"))
          ser.tx(13)
          waitcnt(clkfreq + cnt)
          GetBMP
        else
          ser.str(string("Device Not Found"))
          ser.tx(13)
          waitcnt(clkfreq + cnt)
        
    
    Pub GetBMP | v1, v2, v3, up1, up2, up3, ut1, ut2
      repeat
        
          {
          Table 5: Calibration Coefficients
                      BMP180 reg adr
          Parameter   MSB        LSB
            AC1       0xAA       0xAB
            AC2       0xAC       0xAD
            AC3       0xAE       0xAF
            AC4       0xB0       0xB1
            AC5       0xB2       0xB3
            AC6       0xB4       0xB5
            B1        0xB6       0xB7
            B2        0xB8       0xB9
            MB        0xBA       0xBB
            MC        0xBC       0xBD
            MD        0xBE       0xBF
          }
    
        ' i2cObject.readLocation(SCL,device_address, register)
    
        ' // Read Calibration Coefficients
        ac1 := i2cObject.readLocation(bmpSCL, bmpAddr, $AA)  ' 1B
        ac2 := i2cObject.readLocation(bmpSCL, bmpAddr, $AC)  ' FB
        ac3 := i2cObject.readLocation(bmpSCL, bmpAddr, $AE)  ' C7
        ac4 := i2cObject.readLocation(bmpSCL, bmpAddr, $B0)  ' 84
        ac5 := i2cObject.readLocation(bmpSCL, bmpAddr, $B2)  ' 61
        ac6 := i2cObject.readLocation(bmpSCL, bmpAddr, $B4)  ' 49
    
        b1 := i2cObject.readLocation(bmpSCL, bmpAddr, $B6)   ' 19
        b2 := i2cObject.readLocation(bmpSCL, bmpAddr, $B8)   ' 00
    
        mb := i2cObject.readLocation(bmpSCL, bmpAddr, $BA)   ' 80
        mc := i2cObject.readLocation(bmpSCL, bmpAddr, $BC)   ' D1
        md := i2cObject.readLocation(bmpSCL, bmpAddr, $BE)   ' 0A
    
        id := i2cObject.readLocation(bmpSCL, bmpAddr, $D0)   ' 55     *** Should = 0x55
         
        waitcnt((clkfreq / 4) + cnt)
    
        ser.str(string("AC1: "))
        ser.hex(ac1, 2)
        ser.str(string("  "))
        ser.dec(ac1)
        ser.tx(13)
        ser.str(string("AC2: "))
        ser.hex(ac2, 2)
        ser.str(string("  "))
        ser.dec(ac2)    
        ser.tx(13)
        ser.str(string("AC3: "))
        ser.hex(ac3, 2)
        ser.str(string("  "))
        ser.dec(ac3)    
        ser.tx(13)
        ser.str(string("AC4: "))
        ser.hex(ac4, 2)
        ser.str(string("  "))
        ser.dec(ac4)    
        ser.tx(13)
        ser.str(string("AC5: "))
        ser.hex(ac5, 2)
        ser.str(string("  "))
        ser.dec(ac5)    
        ser.tx(13)
        ser.str(string("AC6: "))
        ser.hex(ac6, 2)
        ser.str(string("  "))
        ser.dec(ac6)    
        ser.tx(13)                    
    
        ser.str(string("B1: "))
        ser.hex(b1, 2)
        ser.str(string("  "))
        ser.dec(b1)    
        ser.tx(13)
        ser.str(string("B2: "))
        ser.hex(b2, 2)
        ser.str(string("  "))
        ser.dec(b2)    
        ser.tx(13)
    
        ser.str(string("MB: "))
        ser.hex(mb, 2)
        ser.str(string("  "))
        ser.dec(mb)    
        ser.tx(13)
        ser.str(string("MC: "))
        ser.hex(mc, 2)
        ser.str(string("  "))
        ser.dec(mc)    
        ser.tx(13)
        ser.str(string("MD: "))
        ser.hex(md, 2)
        ser.str(string("  "))
        ser.dec(md)
        ser.tx(13)        
    
        ser.str(string("ID: "))
        ser.hex(id, 2)
        ser.str(string("  "))
        ser.dec(id)    
        ser.tx(13)
        
        'ser.str(string("bmpAddr: "))
        'ser.hex(bmpAddr | 1, 2)        ' 0 = EE, 1 = EF
        'ser.tx(13)
        
        ' // Read Uncompressed Temperature Value
        ' Write 0x2E into reg 0xF4, wait 4.5ms
        ' Read reg 0xF6 (MSB), 0xF7 (LSB)
    
        i2cObject.writeLocation(bmpSCL, bmpAddrW, $F4, $2E)       ' Temperature  0x2E  4.5
        waitcnt((clkfreq / 222) + cnt)             ' 4.5ms
        ut1 := i2cObject.readLocation(bmpSCL, bmpAddr, i2cObject#OneAddr|$F6)
        ut2 := i2cObject.readLocation(bmpSCL, bmpAddr, i2cObject#OneAddr|$F7) 
    
        'UT := i2cObject.readLocation16(bmpSCL, bmpAddr, i2cObject#OneAddr|$F6)
    
        ser.str(string("UT: "))
        ser.hex(ut1, 2)
        ser.str(string("  "))
        ser.hex(ut2, 2)
        ser.str(string("  "))    
        ser.dec(ut1 + ut2)
        ser.tx(13)
        
        ' // Read Uncompressed Pressure Value
        ' Write 0x34+(oss<<6) into reg 0xF4, wait #.#ms
        ' Read reg 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB)
    
        'i2cObject.writeLocation(bmpSCL, bmpAddr, $F4, $34 + (oss<<6))
    
        ' i2cObject.readLocation(SCL,device_address, register)
        ' i2cObject.writeLocation(SCL,device_address, register, value) 
        
        if oss == 0
          i2cObject.writeLocation(bmpSCL, bmpAddrW, $F4, $34)     ' Pressure (oss = 0)  0x34  4.5
          waitcnt((clkfreq / 222) + cnt)                         ' 4.5ms    
        elseif oss == 1
          i2cObject.writeLocation(bmpSCL, bmpAddrW, $F4, $74)     ' Pressure (oss = 1)  0x74  7.5
          waitcnt((clkfreq / 133) + cnt)                         ' 7.5ms    
        elseif oss == 2
          i2cObject.writeLocation(bmpSCL, bmpAddrW, $F4, $B4)     ' Pressure (oss = 2)  0xB4  13.5
          waitcnt((clkfreq / 74) + cnt)                          ' 13.5ms   
        elseif oss == 3
          i2cObject.writeLocation(bmpSCL, bmpAddrW, $F4, $F4)     ' Pressure (oss = 3)  0xF4  25.5
          waitcnt((clkfreq / 39) + cnt)                          ' 25.5ms
    
        up1 := i2cObject.readLocation(bmpSCL, bmpAddr, $F6)
        up2 := i2cObject.readLocation(bmpSCL, bmpAddr, $F7)
        up3 := i2cObject.readLocation(bmpSCL, bmpAddr, $F8)         
        
        ser.str(string("UP: "))
        ser.hex(up1 + up2 + up3, 6)
        ser.str(string("  "))
        ser.dec(up1 + up2 + up3)    
        ser.tx(13)
        ser.str(string("UP 123 Hex: "))  
        ser.hex(up1, 2)
        ser.str(string("  "))
        ser.hex(up2, 2)
        ser.str(string("  "))
        ser.hex(up3, 2)
        ser.tx(13)        
        ser.str(string("UP 123 Dec: "))  
        ser.dec(up1)
        ser.str(string("  "))
        ser.dec(up2)
        ser.str(string("  "))
        ser.dec(up3)
        ser.tx(13)        
    
    
        ' // Calculate True Temperature
    
        ' // Calculate True Pressure
    
    
        waitcnt(clkfreq + cnt)
    
    '' Basic I2C Routines  Version 1.3
    '' Written by Michael Green and copyright (c) 2009
    '' Permission is given to use this in any program for the Parallax
    '' Propeller processor as long as this copyright notice is included.
    
    '' Version: 1.0 - Initial version
    ''          1.1 - Corrected some comments
    ''          1.2 - Corrected example, added this list
    ''          1.3 - Added logic for non-memory devices
    
    '' This is a minimal version of an I2C driver in SPIN.  It assumes
    '' that the SDA pin is one higher than the SCL pin.  It assumes that
    '' neither the SDA nor the SCL pins have pullups, so drives both.
    
    '' These routines are primarily intended for reading and writing EEPROMs.
    '' The low level I2C are provided for use with other devices, but the
    '' read/write byte routines assume a standard I2C serial EEPROM with a
    '' 16 bit device address register, paged writes, and acknowledge polling.
    
    '' All of these read/write routines accept an EEPROM address up to 19
    '' bits (512K) even though the EEPROM addressing scheme normally allows
    '' for only 16 bits of addressing.  The upper 3 bits are used as part of
    '' the device select code and these routines will take the upper 3 bits
    '' of the address and "or" it with the supplied device select code bits
    '' 3-1 which are used to select a particular EEPROM on an I2C bus.  There
    '' are two schemes for selecting 64K "banks" in 128Kx8 EEPROMs.  Atmel's
    '' 24LC1024 EEPROMs allow simple linear addressing up to 256Kx8 ($00000
    '' to $3FFFF).  Microchip's 24LC1025 allows for up to 512Kx8, but in two
    '' areas: $00000 to $3FFFF and $40000 to $7FFFF.  Each EEPROM provides
    '' a 64K "bank" in each area.  See the device datasheets for details.
    
    '' If bit 21 of the address value is non-zero, then bit 20 indicates how
    '' many address bytes are to be sent to the device.  If bit 20 is zero,
    '' no address is sent.  If bit 20 is a one, then a single address byte
    '' is sent.
             
    '' This will work with the boot EEPROM and does not require a pull-up
    '' resistor on the SCL line (but does on the SDA line ... about 4.7K to
    '' +3.3V).  According to the Philips I2C specification, both pull-ups
    '' are required.  Many devices will tolerate the absence of a pull-up
    '' on SCL.  Some may tolerate the absence of a pull-up on SDA as well.
    
    '' Initialize may have to be called once at the beginning of your
    '' program.  Sometimes an I2C device is left in an invalid state.  This
    '' will reset the device to a known state so it will respond to the I2C
    '' start transition (sent out by the i2cStart routine).
    
    '' To read from or write to an EEPROM on pins 28/29 like the boot EEPROM:
    
    '' CON
    ''   eepromAddress = $7000
    
    '' VAR
    ''   byte buffer[32]
    
    '' OBJ
    ''   i2c : "Basic_I2C_Driver"
    
    '' PRI readIt
    ''   if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
    ''     abort ' an error occurred during the read
    
    '' PRI writeIt | startTime
    ''   if i2c.WritePage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
    ''     abort ' an error occured during the write
    ''   startTime := cnt ' prepare to check for a timeout
    ''   repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, eepromAddress)
    ''     if cnt - startTime > clkfreq / 10
    ''       abort ' waited more than a 1/10 second for the write to finish
    
    '' Note that the read and write use something called paged reads/writes.
    '' This means that any read using ReadPage must fit entirely in one
    '' EEPROM if you have several attached to one set of pins.  For writes,
    '' any write using i2cWritePage must fit entirely within a page of the
    '' EEPROM.  Usually these pages are either 32, 64, 128 or 256 bytes in
    '' size depending on the manufacturer and device type.  32 bytes is a
    '' good limit for the number of bytes to be written at a time if you
    '' don't know the specific page size (and the write must fit completely
    '' within a multiple of the page size).  The WriteWait waits for the
    '' write operation to complete.  Alternatively, you could wait for 5ms
    '' since currently produced EEPROMs will finish within that time.
    
    '' To read from an I2C device that uses a single register address byte,
    '' you could use any of these methods and supply a device address as
    '' follows:
    
    '' i2c.ReadByte( <SCL pin #>, <device code>, <register> | i2c#OneAddr)
    
    '' Similarly, to write to a device that doesn't use an address byte,
    '' you'd use:
    
    '' i2c.WriteByte( <SCL pin #>, <device code>, i2c#NoAddr)
    
    CON
       ACK      = 0                        ' I2C Acknowledge
       NAK      = 1                        ' I2C No Acknowledge
       Xmit     = 0                        ' I2C Direction Transmit
       Recv     = 1                        ' I2C Direction Receive
       BootPin  = 28                       ' I2C Boot EEPROM SCL Pin
       EEPROM   = $A0                      ' I2C EEPROM Device Address
       NoAddr   = $200000                  ' I2C Don't use register address
       OneAddr  = $300000                  ' I2C Use 8-bit register address
    
    PUB Initialize(SCL) | SDA              ' An I2C device may be left in an
       SDA := SCL + 1                      '  invalid state and may need to be
       outa[SCL] := 1                       '   reinitialized.  Drive SCL high.
       dira[SCL] := 1
       dira[SDA] := 0                       ' Set SDA as input
       repeat 9
          outa[SCL] := 0                    ' Put out up to 9 clock pulses
          outa[SCL] := 1
          if ina[SDA]                      ' Repeat if SDA not driven high
             quit                          '  by the EEPROM
    
    PUB Start(SCL) | SDA                   ' SDA goes HIGH to LOW with SCL HIGH
       SDA := SCL + 1
       outa[SCL]~~                         ' Initially drive SCL HIGH
       dira[SCL]~~
       outa[SDA]~~                         ' Initially drive SDA HIGH
       dira[SDA]~~
       outa[SDA]~                          ' Now drive SDA LOW
       outa[SCL]~                          ' Leave SCL LOW
      
    PUB Stop(SCL) | SDA                    ' SDA goes LOW to HIGH with SCL High
       SDA := SCL + 1
       outa[SCL]~~                         ' Drive SCL HIGH
       outa[SDA]~~                         '  then SDA HIGH
       dira[SCL]~                          ' Now let them float
       dira[SDA]~                          ' If pullups present, they'll stay HIGH
    
    PUB Write(SCL, data) : ackbit | SDA
    '' Write i2c data.  Data byte is output MSB first, SDA data line is valid
    '' only while the SCL line is HIGH.  Data is always 8 bits (+ ACK/NAK).
    '' SDA is assumed LOW and SCL and SDA are both left in the LOW state.
       SDA := SCL + 1
       ackbit := 0 
       data <<= 24
       repeat 8                            ' Output data to SDA
          outa[SDA] := (data <-= 1) & 1
          outa[SCL]~~                      ' Toggle SCL from LOW to HIGH to LOW
          outa[SCL]~
       dira[SDA]~                          ' Set SDA to input for ACK/NAK
       outa[SCL]~~
       ackbit := ina[SDA]                  ' Sample SDA when SCL is HIGH
       outa[SCL]~
       outa[SDA]~                          ' Leave SDA driven LOW
       dira[SDA]~~
    
    PUB Read(SCL, ackbit): data | SDA
    '' Read in i2c data, Data byte is output MSB first, SDA data line is
    '' valid only while the SCL line is HIGH.  SCL and SDA left in LOW state.
       SDA := SCL + 1
       data := 0
       dira[SDA]~                          ' Make SDA an input
       repeat 8                            ' Receive data from SDA
          outa[SCL]~~                      ' Sample SDA when SCL is HIGH
          data := (data << 1) | ina[SDA]
          outa[SCL]~
       outa[SDA] := ackbit                 ' Output ACK/NAK to SDA
       dira[SDA]~~
       outa[SCL]~~                         ' Toggle SCL from LOW to HIGH to LOW
       outa[SCL]~
       outa[SDA]~                          ' Leave SDA driven LOW
    
    PUB ReadPage(SCL, devSel, addrReg, dataPtr, count) : ackbit
    '' Read in a block of i2c data.  Device select code is devSel.  Device starting
    '' address is addrReg.  Data address is at dataPtr.  Number of bytes is count.
    '' The device select code is modified using the upper 3 bits of the 19 bit addrReg.
    '' Return zero if no errors or the acknowledge bits if an error occurred.
       devSel |= addrReg >> 15 & %1110
       if addrReg & $300000 <> $200000     ' One or two byte address or memory?
          Start(SCL)                       ' Select the device & send address
          ackbit := Write(SCL, devSel | Xmit)
          if addrReg & $300000 == $000000  ' Two byte address or memory device?
             ackbit := (ackbit << 1) | Write(SCL, addrReg >> 8 & $FF)
          ackbit := (ackbit << 1) | Write(SCL, addrReg & $FF)          
       Start(SCL)                          ' Reselect the device for reading
       ackbit := (ackbit << 1) | Write(SCL, devSel | Recv)
       repeat count - 1
          byte[dataPtr++] := Read(SCL, ACK)
       byte[dataPtr++] := Read(SCL, NAK)
       Stop(SCL)
       return ackbit
    
    PUB ReadByte(SCL, devSel, addrReg) : data
    '' Read in a single byte of i2c data.  Device select code is devSel.  Device
    '' starting address is addrReg.  The device select code is modified using the
    '' upper 3 bits of the 19 bit addrReg.  This returns true if an error occurred.
       if ReadPage(SCL, devSel, addrReg, @data, 1)
          return -1
    
    PUB ReadWord(SCL, devSel, addrReg) : data
    '' Read in a single word of i2c data.  Device select code is devSel.  Device
    '' starting address is addrReg.  The device select code is modified using the
    '' upper 3 bits of the 19 bit addrReg.  This returns true if an error occurred.
       if ReadPage(SCL, devSel, addrReg, @data, 2)
          return -1
    
    PUB ReadLong(SCL, devSel, addrReg) : data
    '' Read in a single long of i2c data.  Device select code is devSel.  Device
    '' starting address is addrReg.  The device select code is modified using the
    '' upper 3 bits of the 19 bit addrReg.  This returns true if an error occurred.
    '' Note that you can't distinguish between a return value of -1 and true error.
       if ReadPage(SCL, devSel, addrReg, @data, 4)
          return -1
    
    PUB WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit
    '' Write out a block of i2c data.  Device select code is devSel.  Device starting
    '' address is addrReg.  Data address is at dataPtr.  Number of bytes is count.
    '' The device select code is modified using the upper 3 bits of the 19 bit addrReg.
    '' Most devices have a page size of at least 32 bytes, some as large as 256 bytes.
    '' Return zero if no errors or the acknowledge bits if an error occurred.  If
    '' more than 31 bytes are transmitted, the sign bit is "sticky" and is the
    '' logical "or" of the acknowledge bits of any bytes past the 31st.
       devSel |= addrReg >> 15 & %1110
       Start(SCL)                          ' Select the device & send address
       ackbit := Write(SCL, devSel | Xmit)
       if addrReg & $300000 <> $200000     ' One or two byte address or memory?
          if addrReg & $300000 == $000000  ' Two byte address or memory device?
             ackbit := (ackbit << 1) | Write(SCL, addrReg >> 8 & $FF)
          ackbit := (ackbit << 1) | Write(SCL, addrReg & $FF)          
       repeat count                        ' Now send the data
          ackbit := ackbit << 1 | ackbit & $80000000 ' "Sticky" sign bit         
          ackbit |= Write(SCL, byte[dataPtr++])
       Stop(SCL)
       return ackbit
    
    PUB WriteByte(SCL, devSel, addrReg, data)
    '' Write out a single byte of i2c data.  Device select code is devSel.  Device
    '' starting address is addrReg.  The device select code is modified using the
    '' upper 3 bits of the 19 bit addrReg.  This returns true if an error occurred.
       if WritePage(SCL, devSel, addrReg, @data, 1)
          return true
       return false
    
    PUB WriteWord(SCL, devSel, addrReg, data)
    '' Write out a single word of i2c data.  Device select code is devSel.  Device
    '' starting address is addrReg.  The device select code is modified using the
    '' upper 3 bits of the 19 bit addrReg.  This returns true if an error occurred.
    '' Note that the word value may not span an EEPROM page boundary.
       if WritePage(SCL, devSel, addrReg, @data, 2)
          return true
       return false
    
    PUB WriteLong(SCL, devSel, addrReg, data)
    '' Write out a single long of i2c data.  Device select code is devSel.  Device
    '' starting address is addrReg.  The device select code is modified using the
    '' upper 3 bits of the 19 bit addrReg.  This returns true if an error occurred.
    '' Note that the long word value may not span an EEPROM page boundary.
       if WritePage(SCL, devSel, addrReg, @data, 4)
          return true
       return false
    
    PUB WriteWait(SCL, devSel, addrReg) : ackbit
    '' Wait for a previous write to complete.  Device select code is devSel.  Device
    '' starting address is addrReg.  The device will not respond if it is busy.
    '' The device select code is modified using the upper 3 bits of the 18 bit addrReg.
    '' This returns zero if no error occurred or one if the device didn't respond.
       devSel |= addrReg >> 15 & %1110
       Start(SCL)
       ackbit := Write(SCL, devSel | Xmit)
       Stop(SCL)
       return ackbit
    
    
     ' ******************* Extra's ******************* 
    
     
    PUB ReStart(SCL) | SDA                 ' SDA goes HIGH to LOW with SCL HIGH
       SDA := SCL + 1
       outa[SDA]~~                         ' Initially drive SDA HIGH
       dira[SDA]~~
       outa[SCL]~~                         ' Initially drive SCL HIGH
       'waitcnt(clkfreq / I2CDelay + cnt)
       outa[SDA]~                          ' Now drive SDA LOW
       'waitcnt(clkfreq / I2CDelay + cnt)
       outa[SCL]~                          ' Leave SCL LOW
    
    PUB devicePresent(SCL,deviceAddress) : ackbit
      ' send the deviceAddress and listen for the ACK
       Start(SCL)
       ackbit := Write(SCL,deviceAddress | 0)
       Stop(SCL)
       if ackbit == ACK
         return true
       else
         return false
    
    PUB readLocation(SCL,device_address, register) : value
      start(SCL)
      write(SCL,device_address | 0)
      write(SCL,register)
      start(SCL)
      write(SCL,device_address | 1)  
      value := read(SCL,NAK)
      stop(SCL)
      return value
    
    PUB writeLocation(SCL,device_address, register, value)
      start(SCL)
      write(SCL,device_address)
      write(SCL,register)
      write(SCL,value)  
      stop (SCL)
           
    PUB readLocation16(SCL,device_address, register) : value
      start(SCL)
      write(SCL,device_address | 0)
      write(SCL,register)
      restart(SCL)
      write(SCL,device_address | 1)  
      value := read(SCL,ACK)
      value <<= 8
      value |= (read(SCL,NAK) & $ff)
      stop(SCL)
      return value
    
    PUB readLocation24(SCL,device_address, register) : value
      start(SCL)
      write(SCL,device_address | 0)
      write(SCL,register)
      restart(SCL)
      write(SCL,device_address | 1)  
      value := read(SCL,ACK)
      value <<= 8
      value |= (read(SCL,ACK) & $ff)
      value <<= 8
      value |= (read(SCL,NAK) & $ff)
      stop(SCL)
      return value
    
  • zlantzzlantz Posts: 136
    edited 2014-02-10 18:26
    Thanks to jonnyMac on another thread, I have come up with some code that "appears" to work. but clearly it is not. the coefficient's appear correct, UT appears correct (changes when i hold the sensor) but is a bit bouncy (hits extreme highs & lows at random), UP is just all over the place and has nothing to do with the air pressure surrounding the sensor. Finally, the results from the conversion math, gives values that do not change at all for temperature and pressure.

    in the same code I am testing my other sensor (mpu-9150) but with the mpu6050's driver (only way i can get it to work).

    I have ran this with both of them plugged in, and just one with the same results for the bmp.

    BMP i2c Test.zip

    tp.jpg
    tp walk.jpg
    810 x 1168 - 96K
    811 x 1172 - 96K
  • mhm21mhm21 Posts: 14
    edited 2014-02-12 16:38
    I have been using this sensor for quite a while for flight testing purposes. I have attached my code which was copied/stolen/rewritten from various sources. The pressure calculation from the raw UP value is something I wrote, following the data sheet to the letter. This might tell you if your sensor is alive and responding. Let me know how it goes..
Sign In or Register to comment.