Reputation: 11
I am making a wireless device to measure a magnetic field based on the HMC5983 magneto-resistive sensor and an ESP8266 (NodeMCU ESP-12e module).
The sensor is connected to the ESP8266 on the I2C interface. The ESP8266 polls the sensor and sends this to a data collector (Raspberry Pi).
It is extremely important to me to achieve the greatest possible number of computation in a second, as quality of the obtained data for later processing depends on it.
HMC5983 supports the I2C interface in Standard, Fast and High-speed modes. But the NodeMCU I2C Module only supports i2c.SLOW speed.
common I²C bus speeds are the 100 kbit/s standard mode and the 10 kbit/s low-speed mode https://en.wikipedia.org/wiki/I%C2%B2C
Then I connected the HMC5983 directly to the Raspberry Pi via I2C. I could achieve about 500 measurements per second (by monitoring the DRDY interrupt pin) in single-measurement mode and 200 measurements per second in continous-measurement mode (with Data Output Rate at 220 Hz - all right). The programm was written in Python, here is the code:
#!/usr/bin/python
import smbus #for i2c use
import time
import os
bus = smbus.SMBus(1) #use i2c port 1 on Rasspberry Pi
addr = 0x1e #address HMC5983 0x1E
bus.write_byte_data(addr,0x00,0b00011100) #Write to CRA Speed 220Hz
bus.write_byte_data(addr,0x01,0b00100000) #Write to CRB Gain 660 +-2.5Ga 1.52mG/Lsb
print "Start measuring.....
while True: #if we need infinity cycle
bus.write_byte_data(addr,0x02,0b00000001) #Write to Mode single-measurement mode
while bus.read_byte_data(addr,0x09) == 0b11: #Wait RDY in Status Register
()
#DATA READY
data = bus.read_i2c_block_data(addr,0x03,6)#Take data from data registers
#convert three 16-bit 2`s compliment hex value to dec values and assign x,y,z
x = data[0]*256+data[1]
if x > 32767 :
x -= 65536
y = data[2]*256+data[3]
if y > 32767 :
y -= 65536
z = data[4]*256+data[5]
if z > 32767 :
z -= 65536
print "X=",x, "\tY=",y, "\tZ=",z
When I connected the HMC5983 to the ESP8266, I could achieve only about 140 computations a second in single-computation mode.
----------THIS IS FOR SINGLE-MEASUREMENT MODE-------------
--init i2c
function H_init(sda,scl)
i2c.setup(id, sda, scl, i2c.SLOW)
print("I2C started...")
end
-- reads 6byte from the sensor
function read_axis()
i2c.start(id)
i2c.address(id, dev_addr, i2c.RECEIVER)
data = i2c.read(id, 6)
i2c.stop(id)
return data
end
--set register
function set_reg(reg_addr,val)
i2c.start(id)
i2c.address(id, dev_addr, i2c.TRANSMITTER)
i2c.write(id,reg_addr)
i2c.write(id,val)
i2c.stop(id)
end
--------GPIO INITILIZATION-------
drdyn_pin=3
gpio.mode(drdyn_pin, gpio.INPUT)
-------I2C INITILIZATION-------
id = 0
i2c = i2c
local i=0
dev_addr = 0x1e
H_init(1,2)
set_reg(0x00,0x1c) --set speed 220Hz
set_reg(0x01,0x20) --set gain
print("Start measurement...")
while true do
set_reg(0x02,0x01) --single-measurement mode
while(gpio.read(drdyn_pin) == 1) do
end
data = read_axis()
tmr.wdclr()
end
After that I configured the sensor to continous-measurement mode and received the same 200 measurements per second.
Is operation of the I2C interface in NodeMCU at high speeds possible? Can somebody tell me how to try to accelerate sensor polling?
Upvotes: 1
Views: 2378
Reputation: 718
Of course it is possible, ESP8266 is faster than Pentium :-) Just a few thousands or even just a few ten thousands measurements per second would be really disappointing for such tremendous processing power. Here you are the link to ESP8266 I2C library written in assembly and tested with Arduino toolchain. That way you can communicate at the rate of 800000
messages per second @80 MHz or one million messages per second @160 MHz. I believe that would be more than enough for the project you have described, at 80 kHz I2C speed you can have a few ten thousands measurements per second - if a slave device can handle such speed.
For any future doubts if something could or couldn't be done with ESP8266, I'd say this is more than enough to get a picture - and in this case I mean it literally :-)
Upvotes: 1