MS5837-30BA on ODROID via USBIO

We have a BAR30 attached to an Odroid USB IO board.

http://www.hardkernel.com/main/products/prdt_info.php?g_code=G135390529643

This has an I2C capability described here:

two files that are key are:

(the interface code)

(an example I2C interface)

So I think what i need to do is get a version of the code here:

translated so it communicates via the USBIO/I2C rather than the SMBUS.

For example:

self._bus.read_word_data(self._MS5837_ADDR, self._MS5837_PROM_READ + 2*i)

I assume reads something (a single byte?) from the I2C,

The functions I need to translate are:

self._bus.write_byte(self._MS5837_ADDR, self._MS5837_CONVERT_D1_256 + 2oversampling)
self._bus.read_word_data(self._MS5837_ADDR, self._MS5837_PROM_READ + 2
i)
self._bus.read_i2c_block_data(self._MS5837_ADDR, self._MS5837_ADC_READ, 3)

What is the equivalent call from the HK library? (all the calls available are below)

I think I’m pretty close on this (from a theoretical point of view) but I am completely out of my depth (ha!) from an I2C standpoint.

Any help would be greatly appreciated!!!


def i2c_init(dev):			# init i2c
	dev.write(1,[u_i2c_init], 100)
def i2c_idle(dev):			# i2c idle
	dev.write(1,[u_i2c_idle], 100)
def i2c_start(dev, cval):		# i2c start
	a = array('B',[0,0,0,0,0,0,0,0,0,0,0,0,0,0])
	a[0] = u_i2c_strt
	a[1] = cval
	dev.write(1, a, 100)
def i2c_stop(dev):			# i2c stop
	dev.write(1,[u_i2c_stop], 100)
def i2c_slave_ack(dev):			# i2c slave ack
	dev.write(1,[u_i2c_slak], 100)
	ret = dev.read(0x81, 64, 100)
	return ret[1]			# 1=no ack, 0=ack
def i2c_write(dev, cval):		# i2c write
	a = array('B',[0,0,0,0,0,0,0,0,0,0,0,0,0,0])
	a[0] = u_i2c_writ
	a[1] = cval
	dev.write(1, a, 100)
def i2c_master_ack(dev, cval):		# 1=nack, 0=ack
	a = array('B',[0,0,0,0,0,0,0,0,0,0,0,0,0,0])
	a[0] = u_i2c_mack
	a[1] = cval
	dev.write(1, a, 100)
def i2c_read(dev):			# i2c read
	dev.write(1,[u_i2c_read], 100)
	ret = dev.read(0x81, 64, 100)
	return ret[1]			# i2c_read char
def i2c_isdatardy(dev):			# check if i2c char avail
	dev.write(1,[u_i2c_dtrd], 100)
	ret = dev.read(0x81, 64, 100)
	return ret[1]			# i2c_read char


def writeRegister(dev_addr, addr, value):
	i2c_start(usb, I2C_START_CMD)
	i2c_write(usb, (dev_addr << 1 | I2C_WRITE_CMD))
	while (i2c_slave_ack(usb)):
		time.sleep(0.1)
	# select the register to write to 
	i2c_write(usb, addr)
	while (i2c_slave_ack(usb)):
		time.sleep(0.1)
	# write the value to the previously selected reg
	i2c_write(usb, value)
	while (i2c_slave_ack(usb)):
		time.sleep(0.1)
	i2c_stop(usb)
def readRegister(dev_addr, addr):
	i2c_start(usb, I2C_START_CMD)
	i2c_write(usb, (dev_addr << 1 | I2C_WRITE_CMD))
	while (i2c_slave_ack(usb)):	# wait for slave ack
		time.sleep(0.1)
	# select the register address to read
	i2c_write(usb, addr)
	while (i2c_slave_ack(usb)):	# wait for slave ack
		time.sleep(0.1)
	i2c_start(usb, I2C_REP_START_CMD)
	i2c_write(usb, (dev_addr << 1 | I2C_READ_CMD))
	# read the value from the register
	while (i2c_slave_ack(usb)):	# wait for slave ack
		time.sleep(0.1)
	a = i2c_read(usb)
	# ack the byte
	i2c_master_ack(usb, I2C_DATA_NOACK)
	i2c_stop(usb)
	return a

The documentation for the smbus calls is here. Reading a word reads two bytes.

You can use the read, write, readRegister and writeRegister commands to do the same thing. The difference between the three smbus calls you pointed out is just how many bytes are being transfered at a time between the start and stop conditions.

Thanks for the info: So this:

bus.read_word_data(self._MS5837_ADDR, self._MS5837_PROM_READ + 2i)
becomes: bus.read_word_data(0x76 , 0xA0) (when i=0)

How would I use the i2c_* commands and the read/WriteRegister Commands to do the same thing.
Something like this:

readRegister(0x76,0xA0)

is this all I need to do to modify following 3 functions: (is it really this simple?)

read_word_data(ADDR,VAR) => readRegister(ADDR,VAR)
read_i2c_block_data(ADDR,VAR,NUM) = >[readRegister(ADDR,VAR1)+readRegister(ADDR,VAR2)…readRegister(ADDR,VARNUM)]
write_byte(ADDR,VAR) = > writeRegister(ADDR,VAR)

@subdriver It will be something like that, yes. You might want to modify the readregister and writeregister functions to transfer multiple bytes at a time.

I guess I’m confused about the difference between Addresses and Device Address.

This is the original:
self._bus.write_byte(self._MS5837_ADDR, self._MS5837_RESET)

With these definitions:
_MS5837_ADDR = 0x76
_MS5837_RESET = 0x1E
This means “write byte 0x1E to the location 0x76” right?

So if I translate this to the new functions, I have writeRegister(dev_addr,addr,value)

What is the difference between dev_addr and addr?

Or (maybe this is my problem) what’s the difference between writing to a register and writing a byte?

Each I2C device has an address on the I2C bus so that discrete pieces of hardware can be identified/addressed (0x76).

Then I2C slaves also have many internal memory registers that each have their own address. You tell the device which register (0x1E) you want to read or write (the data that you actually read or write could be any byte).

I suggest you look through some I2C documentation or tutorials if you are still confused about what you are trying to accomplish.

Thanks for all the help! Ive looked through i2c docs, tutorials and examples til I’m blue in the face. We got even simpler and used direct connections (using i2cdetect and similar) and it seems that we can’t even get access to the bus from the Odroid.

The result? We hooked up an arduino and used the arduino code sample you provided to broadcast depth on a serial interface to a USB line to the odroid.

Not ideal - but it works, and we now know how deep we are!

Thanks again!

Good. I don’t know about other computers, but on the RPI3 under raspbian, i2cdetect does not see the ms5837. i2cdump does.