code for reading a single i2c device

Benjie

Senior Member
Hi there,
I need a code for 8M2 to read from a GY-63 MS5611 pressure sensor module (see attached spec). The sensor address should be 1110111x. The SCL and SDA outputs have a pull-up of 22K. The CSB pin is at GND while the PS pin is at +5V.
The test code I copied from the manuals is:

hi2csetup i2cmaster, %11101100, i2cslow, i2cbyte
main: do
hi2cin %11101100, (b0,b1,b2,b3,b4,b5,b6,b7)
debug b0
pause 2000
loop

From that code the debug give me 255 (%11111111) for all b0 to b7.
In my opinion only b0-b1 should be read.
Am I wrong?
thanks
 

Attachments

Hemi345

Senior Member
After hi2cin, send a command byte instead of the device address
Code:
hi2cin %10100110, (b0,b1,b2)
This should read the first few bytes of prom (page 12).
 

Benjie

Senior Member
Thank you Hemi345. I need however to extract the least word (the two last bytes) of the 24 bit pressure reading. I am not interested on the conversion to altitude, just the pressure small variations around the 102,3 KPascal.
 

Benjie

Senior Member
I modified the code to read the first 3 byte of the PROM: the debug shows a value ov 255 on all 3 bytes.
What about reading the memory bytes of pag. 12 of MS5611 data sheet? Which code before the debug?
Attached is the code and the circuit schematic.

Code:
hi2csetup i2cmaster, %11101100, i2cslow,i2cbyte
main: do
    hi2cin %10100110, (b0,b1,b2)
    debug
    pause 2000
loop
[\code]
 

Attachments

hippy

Technical Support
Staff member
Your I2C Device Address (%11101100) appears to be correct for when CS is tied to ground, and PS is correctly tied to 5V for I2C mode, so the likely possibilities for reading all 255 ($FF) values are -

The pull-ups are too high value to allow correct operation
SCL and SDA signal lines have been transposed
SCL and/or SDA are connected to the wrong PICAXE pins
The PICAXE board has other pull-ups or pull-downs on those pins

Finally the data could actually be all 255 values due to needing some initialisation or configuration before valid data is available for reading.

I am not familiar with the MS6511 but looking at the datasheet that suggests a command must be sent to tell the chip what to do as Hemi345 noted in post #3. It seems you may need to send a $A0 command to read the first two bytes of PROM but what you have would seem expected to return other than 255 results.

I would suggest using what Hemi345 suggests to see if you get results other than 256 before moving on to read the data you want to obtain. If that doesn't work, only returns 256 values, then there is some issue which will need resolving before you will be able to read the data you want.
 

Benjie

Senior Member
Hello hippy,
The pull-up resistors have been changed to 4.7Kohm. Attached is the debug result.
How can I send a $A0 command?
 

Attachments

Benjie

Senior Member
Hippy,
have checked all connection and tested the voltages at various pin: all look ok. FYI the module GY63 MS5611 is similar to more popular BMP180 which uses the same i2C communication.
 

hippy

Technical Support
Staff member
More people might look at your debug output if you didn't make it a PDF file. Just sayin'.
And just saying the result is the same, all 255's, would do.

How can I send a $A0 command?
This is what I would suggest ...
Code:
#Picaxe 08M2
hi2csetup i2cmaster, %11101100, i2cslow, i2cbyte
main:
  do
    hi2cin $A0, (b1,b0)
    debug
    pause 2000
  loop
That should read the first two bytes of PROM. Note the return values are two bytes at a time, 16-bit, MSB first, LSB second, but that doesn't really matter here as we're only looking for non-255 results.
 

Benjie

Senior Member
Hippy, here is the code that I run where I put first the command $A0 that you suggested and then the one I had before.
You will see the debug result. How should I interprete this?
Code:
#Picaxe 08M2
hi2csetup i2cmaster, %11101100, i2cslow, i2cbyte
  do until b0=3
    hi2cin $A0, (b1,b0)
    debug
    pause 2000
    b0=b0+1
  loop
hi2csetup i2cmaster, %11101100, i2cslow,i2cbyte'hi2cout , %11101100 , $A0
main: do until b0=5
    hi2cin %1100110, (b0,b1,b2)
    debug

    pause 2000
    b0=b0+1
loop
[\code]
 

Attachments

lbenson

Senior Member
In this statement: hi2cin %1100110, (b0,b1,b2)

Did you intend hi2cin $66, because that's what you have with %1100110--only 7 binary digits when you perhaps meant 8?
 

hippy

Technical Support
Staff member
Hippy, here is the code that I run where I put first the command $A0 that you suggested and then the one I had before.
You will see the debug result. How should I interprete this?
Hard to say as it's not possible to tell if the DEBUG data shown is for reading the PROM or for reading something else.

Just test with the code in Post #10 with nothing more added.

If it's reading 255 in b0 and b1 then it's not working, there's probably an error as described in Post #6.
 

Benjie

Senior Member
I rewired my board and double checked the connections. All looks ok but results does not change. I am unable to identify the address of the 16bit pressure data to i2cin on pag. 12-13 of the MS5611 data sheet.
 

Hemi345

Senior Member
Did you solder this sensor yourself or did it come on a breakout board? I soldered a similar pressure sensor on my AXEtimeter project and had a tiny solder blob touching the metal lid on the sensor that I needed to wick up. Check that you don't have something similar like that on yours.

Page 13 says you can do a read ADC request, like:
Code:
hi2cin 0,(b0,b1,b2,b3,b4)
Give that a try
 

Hemi345

Senior Member
This might initiate a D1 pressure conversion:
Code:
hi2cout 0,(%01001000)
D2 temperature conversion:
Code:
hi2cout 0,(%01011000)
So final code would be something like:
Code:
#Picaxe 08M2
main:
    hi2csetup i2cmaster, %11101100, i2cslow, i2cbyte
    hi2cout 0,(%01011000)
    pause 20 'give it time to do conversion (needs only 10ms at OSR=4096)
    hi2cin 0,(b0,b1,b2,b3,b4)
    debug
    pause 1000
    goto main
^untested
 

Benjie

Senior Member
Did you solder this sensor yourself or did it come on a breakout board? I soldered a similar pressure sensor on my AXEtimeter project and had a tiny solder blob touching the metal lid on the sensor that I needed to wick up. Check that you don't have something similar like that on yours.

Page 13 says you can do a read ADC request, like:
Code:
hi2cin 0,(b0,b1,b2,b3,b4)
Give that a try[/QUOTE
 

Hemi345

Senior Member
I would assume so, but impossible to know without a schematic if the SDA and SCL logic levels are converted to work with your 5V.

Try running the PICAXE at 3.3V. The sensor itself will work down to 1.8V, so as long as the LDO on the breakout board will function when fed only 3.3V. Sensor may only get like 2.0V, but should be okay.
 
Last edited:

marks

Senior Member
Hi Benjie,
like others have said receiving 255,255,255 its not talking with the gy-63 module
the ebay pics look like they have 2200 ohm pullups with level shifting so 3 or 5v should work
it looks like PE6 wont except the low default address of %1110 1101
so try with CSB pin high hardware address %1110 1110 which is the same as $EE
because of the voltages differences it may be best to pullup ps and csb pins with 1k resistors!
Code:
#terminal 9600
SETFREQ M8                                   ' to select I2C mode pullup PS pin high to VDD
HI2CSETUP I2CMASTER, $EE, I2Cslow_8, I2CBYTE '' pullup CSB pin high to VDD
pause 100
main:
Hi2Cout $0,($48)            ' start conversion Up
pause 100
Hi2Cin  $0,(b3,b2,b1)       ' Read ADC
pause 100
sertxd(#b3,",",#b2,",",#b1,cr,lf)

goto main
 
Last edited:

Benjie

Senior Member
I replaced the sertxd with debug: the result is 0,0,0. Using 11101100 on the addressing hi2csetup returns all 255. the CS pin is tied to +V.

The MS5611 data sheet are not very exhaustive like the BMP180.
 

hippy

Technical Support
Staff member
The MS5611 data sheet are not very exhaustive like the BMP180.
The MS5611 datasheet seems to have everything one needs included in it. It is the GY-63 modules which are not well documented. It appears that the /CS for the MS5611 is inverted to become an actual CS on the GY-63.

That is probably because there's a voltage translation transistor to convert the 5V input to a 3V3 /CS which goes to the chip, which also inverts that signal.

That is sort of implied by using "CS" instead of "/CS" on the module but it's fairly common to drop the "/" on silk-screening.

So it seems you have two options; connect CS to V+ rather than 0V and use %11101100 as the Device Address, or leave CS connected to 0V and use %11101110. Both should work and reading 0,0,0 suggests you now have I2C comms working.

It would now be worth reading the PROM which should return something which isn't 0,0,0 or 255,255,255. That would confirm genuine data can be read and the 0,0,0, is just an issue of having not triggered a temperature/pressure read and conversion.
 

marks

Senior Member
Hi Benjie,
as yourve already dicovered and hippy's quick at correcting things...
I misread the datasheet quickly and was thinking adjacent bits

MS5611-01BA address is 111011Cx, where C is the complementary value of the pin CSB.

, but really the x bit means doesn't matter and if C bit is 1 then the CSB pin needs to be low or vice versa.

The pin CSB shall be connected to VDD or GND (do not leave unconnected!).

another look at the pic of the gy-63
PS and CSB already has 2.2k resistors in series so can be jumpered to VCC direct.
HI2CSETUP I2CMASTER, $EE, I2Cslow_8, I2CBYTE '' pulldown CSB pin low (default)
HI2CSETUP I2CMASTER, $EC, I2Cslow_8, I2CBYTE '' pullup CSB pin high to VDD
 
Last edited:

hippy

Technical Support
Staff member
I found this schematic of the GY-63 though I don't know how correct it is for any particular module which is for sale -

https://ae01.alicdn.com/kf/HTB1iAliiVuWBuNjSszbq6AS7FXaX.jpg

From that it seems I could be wrong about inverting CS with a transistor. In fact it seems PS and CSB are internally tied via resistors to 3V3 and 0V respectively.

I don't know if that is the case for the module you have but that indicates PS and CSB should only be connected to 3V3 or 0V. Connection to 5V could damage the MS5611.

I would remove both PS and CSB (CS) connections and see which Device Address the CY-63 has and just use that.
 

hippy

Technical Support
Staff member
Mystery solved as marks notes in post #28. Page 6 of the MS5611 datasheet, "I2C Mode" -

"In I2C-Mode the complement of the pin CSB (Chip Select) represents the LSB of the I2C address."

So the inversion is internal to the chip.

When CSB is 0 the Device Address is %11101110

When CSB is 1 the Device Address is %11101100
 

Benjie

Senior Member
By connecting the board CSB to +V and this code
Code:
#Picaxe 08M2

main:
    hi2csetup i2cmaster, %11101100, i2cslow, i2cbyte
    hi2cout 0,(%01001000)
    pause 40 'give it time to do conversion (needs only 10ms at OSR=4096)
 hi2cin 0, (b0,b1,b2,b3,b4)
    debug
    pause 1000
    goto main
I get on the debug:
b0=0
b1=0
b2=0
b3=63 or $3F
b4=255 or $FF
 

Benjie

Senior Member
there is something wrong because I reconnected CSB to V+ and the result is all bytes at $FF.
I am looking why I cannot get again
b0=0
b1=0
b2=0
b3=63 or $3F
b4=255 or $FF
 

Benjie

Senior Member
I t that a kind of reset of the PROM has to be performed: the first run gives hi2cin 0, (b0,b1,b2,b3,b4) while switching off and on the power and reloading the code it gives all 255.
 

hippy

Technical Support
Staff member
From the datasheet -

"The Reset sequence shall be sent once after power-on to make sure that the calibration PROM gets loaded into the internal register".

"The conversion command is used to initiate uncompensated pressure (D1) or uncompensated temperature (D2) conversion."

"After the conversion, using ADC read command the result is clocked out with the MSB first."

The datasheet also describes how zeroes will be returned if other than this procedure is followed, and also the requirement for the PROM to be read after Reset.

Untested but the code I would use to read the PROM and raw pressure and temperature values is -
Code:
#Picaxe 08M2
#Terminal 4800
#No_Data

Symbol C1 = w1  : Symbol C1.msb = b3  : Symbol C1.lsb = b2
Symbol C2 = w2  : Symbol C2.msb = b5  : Symbol C2.lsb = b4
Symbol C3 = w3  : Symbol C3.msb = b7  : Symbol C3.lsb = b6
Symbol C4 = w4  : Symbol C4.msb = b9  : Symbol C4.lsb = b8
Symbol C5 = w5  : Symbol C5.msb = b11 : Symbol C5.lsb = b10
Symbol C6 = w6  : Symbol C6.msb = b13 : Symbol C6.lsb = b12

Symbol Pl = w7  : Symbol Pl.msb = b15 : Symbol Pl.lsb = b14
Symbol Ph = w8  : Symbol Ph.msb = b17 : Symbol Ph.lsb = b16

Symbol Tl = w9  : Symbol Tl.msb = b19 : Symbol Tl.lsb = b18
Symbol Th = w10 : Symbol Th.msb = b21 : Symbol Th.lsb = b20

Symbol CMD_RESET   = $1E
Symbol CMD_D1_256  = $40
Symbol CMD_D1_512  = $42
Symbol CMD_D1_1024 = $44
Symbol CMD_D1_2048 = $46
Symbol CMD_D1_4096 = $48
Symbol CMD_D2_256  = $50
Symbol CMD_D2_512  = $52
Symbol CMD_D2_1024 = $54
Symbol CMD_D2_2048 = $56
Symbol CMD_D2_4096 = $58
Symbol CMD_ADC     = $00
Symbol CMD_PROM_0  = $A0
Symbol CMD_PROM_1  = $A2
Symbol CMD_PROM_2  = $A4
Symbol CMD_PROM_3  = $A6
Symbol CMD_PROM_4  = $A8
Symbol CMD_PROM_5  = $AA
Symbol CMD_PROM_6  = $AC
Symbol CMD_PROM_7  = $AE

PowerOnReset:

  HI2cSetup I2CMASTER, %11101110, I2CSLOW, I2CBYTE

  HI2cOut ( CMD_RESET )
  Pause 10

  HI2cOut ( CMD_PROM_1 ) : HI2cIn ( C1.msb, C1.lsb )
  HI2cOut ( CMD_PROM_2 ) : HI2cIn ( C2.msb, C2.lsb )
  HI2cOut ( CMD_PROM_3 ) : HI2cIn ( C3.msb, C3.lsb )
  HI2cOut ( CMD_PROM_4 ) : HI2cIn ( C4.msb, C4.lsb )
  HI2cOut ( CMD_PROM_5 ) : HI2cIn ( C5.msb, C5.lsb )
  HI2cOut ( CMD_PROM_6 ) : HI2cIn ( C6.msb, C6.lsb )

MainLoop:
  Do

    HI2cOut ( CMD_D1_4096 )
    Pause 10
    HI2cOut ( CMD_ADC )
    Pause 10
    HI2cIn ( Ph.msb, Ph.lsb, Pl.msb ) : Pl.lsb = 0

    HI2cOut ( CMD_D2_4096 )
    Pause 10
    HI2cOut ( CMD_ADC )
    Pause 10
    HI2cIn ( Th.msb, Th.lsb, Tl.msb ) : Tl.lsb = 0

    SerTxd( "Pressure    = $" )
    b0 = Ph.msb : Gosub ShowHex
    b0 = Ph.lsb : Gosub ShowHex
    b0 = Pl.msb : Gosub ShowHex
    SerTxd( CR, LF )

    SerTxd( "Temperature = $" )
    b0 = Th.msb : Gosub ShowHex
    b0 = Th.lsb : Gosub ShowHex
    b0 = Tl.msb : Gosub ShowHex
    SerTxd( CR, LF )

    Pause 1000
  Loop

ShowHex:
  b1 = b0 / $10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
  b0 = b0 & $0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
  SerTxd( b1, b0 )
  Return
That stores 24-bit raw pressure and temperature values in two word variables each, the msb's in the 'Ph' and 'Th' words, lsb's in the 'Pl' and 'Tl' words, with their lsb's zeroed.

So a raw D1 pressure reading of 1193046 ($123456) would be Ph = $1234, Pl = $5600. That should make maths easier but it's easy enough to adjust if it doesn't. Adjusting the OSR value for D1 and D2 readings would hopefully put an integer value in the 'Ph' and 'Th' words allowing the 'Pl' and 'Tl' values ignored.

Edit: Added PAUSE 10 after CMD_ADC. It's not clear where the delay needs to be.
Edit: Added PAUSE 10 after CMD_RESET.
 
Last edited:

Benjie

Senior Member
Hippy, I confess my ignorance in front of your code. I don’t know if it is correct, I will run it, but as usual it denote your deep knowledge on this matter.
 

Benjie

Senior Member
Hippy, the code looks working. I have a problem: on line two you specify #terminal 4800 which, together with sertxd should display the values. I am using the AXE027 cable but the PC does not show the results even removing the terminal directive.
How can I solve it ?
PS: I do not need to convert tho actual KPa and Degrees because what is needed in a variometer is only a high resolution pressure variation.
 
Top