- Fri May 27, 2016 10:53 pm
#48142
OK< well for anyone else trying to do this, I'll post the results of my diagnostic efforts below; The i2c read/write routines I used almost unchanged from
this post of Sanchos for the pcf8591 adc - thank you Sancho, particularly since I will also be using that very device alongside the compass at a later stage!
I understand the compass needs some calibration for location, but I'll skip that for now.
The HMC5883L datasheet was hellish confusing, but what worked was just setting the mode to continuous read, a delay while the moded activated, and then reading all 6 registers (in auto-increment mode) at once. Hope this helps anyone trying to tame this beast. The code just reads the data registers every 10 secs, displaying hex and integer values.
Code: Select all -- read from reg_addr content of dev_addr
function read_reg(dev_addr, reg_addr)
i2c.start(id)
i2c.address(id, dev_addr ,i2c.TRANSMITTER)
i2c.write(id,reg_addr)
i2c.stop(id)
i2c.start(id)
i2c.address(id, dev_addr,i2c.RECEIVER)
c=i2c.read(id,6)
i2c.stop(id)
return c
end
-- write value into device dev_addr, register reg_addr
function write_reg(dev_addr, reg_addr, reg_val)
i2c.start(id)
i2c.address(id, dev_addr, i2c.TRANSMITTER)
i2c.write(id, reg_addr)
i2c.write(id, reg_val)
i2c.stop(id)
end
-- convert 2 hex bytes to 16 bit signed int
function reg2int(reg1, reg2)
num=bit.lshift(reg1,8)+reg2
if num>2047 then num=num-65536 end
return num
end
function read_compass()
-- get contents of all 6 data registers
result = read_reg(device, 0x03)
-- show contents in hex, convert to signed 16-bit integers
print("read:")
for i=1,6,1 do print(string.format("%02X",string.byte(result,i))) end
x=reg2int(string.byte(result, 1),string.byte(result, 2))
z=reg2int(string.byte(result, 3),string.byte(result, 4))
y=reg2int(string.byte(result, 5),string.byte(result, 6))
print("heading:"..x..";"..z..";"..y)
-- reread data every 10 secs
tmr.alarm( 1 , 10000 , 0 , read_compass )
end
-- start here
device=0x1E --HMC5883L
id=0 -- bus
sda=1 -- i2c data
scl=3 -- i2c clock
-- initialize i2c, set gpio0 as sda, gpio4 as scl
i2c.setup(id,sda,scl,i2c.SLOW)
-- set mode register to 00 = continuous update
write_reg(device,0x02,0x00)
-- wait 100ms before trying to read compass (min 67ms)
tmr.alarm( 1 , 100, 0 , read_compass )