I'm trying to use the Gyro sensor with ESP8266 and finding a trouble doing the calibration but first I used the mpu6050.py see below in order to get the position and temperature but all the values are wrong even when I keep my sensor without moving it, all the values keep changing and I don't know why , So I did some digging in this site on how to calibrate the Gyro sensor and I found many example but I didn't succeed in running them ,
the actual mpu6050.py is :
Code: Select all
import machine
class accel():
def __init__(self, i2c, addr=0x68):
self.iic = i2c
self.addr = addr
self.iic.start()
self.iic.writeto(self.addr, bytearray([107, 0]))
self.iic.stop()
def get_raw_values(self):
self.iic.start()
a = self.iic.readfrom_mem(self.addr, 0x3B, 14)
self.iic.stop()
return a
def get_ints(self):
b = self.get_raw_values()
c = []
for i in b:
c.append(i)
return c
def bytes_toint(self, firstbyte, secondbyte):
if not firstbyte & 0x80:
return firstbyte << 8 | secondbyte
return - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1)
def get_values(self):
raw_ints = self.get_raw_values()
vals = {}
vals["AcX"] = self.bytes_toint(raw_ints[0], raw_ints[1])
vals["AcY"] = self.bytes_toint(raw_ints[2], raw_ints[3])
vals["AcZ"] = self.bytes_toint(raw_ints[4], raw_ints[5])
vals["Tmp"] = self.bytes_toint(raw_ints[6], raw_ints[7]) / 340.00 + 36.53
vals["GyX"] = self.bytes_toint(raw_ints[8], raw_ints[9])
vals["GyY"] = self.bytes_toint(raw_ints[10], raw_ints[11])
vals["GyZ"] = self.bytes_toint(raw_ints[12], raw_ints[13])
return vals # returned in range of Int16
# -32768 to 32767
def val_test(self): # ONLY FOR TESTING! Also, fast reading sometimes crashes IIC
from time import sleep
while 1:
print(self.get_values())
sleep(0.05)
def calibrate(threshold=50, n_samples=100):
while True:
v1 = get_values(n_samples)
v2 = get_values(n_samples)
# Check all consecutive measurements are within
# the threshold. We use abs() so all calculated
# differences are positive.
if all(abs(v1[key] - v2[key]) < threshold for key in v1.keys()):
return v1 # Calibrated.
def get_smoothed_values(n_samples=10):
for _ in range(samples):
data = accel.get_values()
for key in data.keys():
# Add on value / samples (to generate an average)
# with default of 0 for first loop.
result[m] = result.get(m, 0) + (data[m] / samples)
return result
and for the calibration I followed this code :
Code: Select all
import pyb
import os
from struct import unpack as unp
from math import atan2,degrees,pi
class MPU6050():
mpu_addr = 0x68 # address of MPU6050
_I2Cerror = "I2C communication failure"
def __init__(self, side=1, disable_interrupts=False):
# create i2c object
self._timeout = 10
self.disable_interrupts = False
self._mpu_i2c = pyb.I2C(side, pyb.I2C.MASTER)
self.chip_id = int(unp('>h', self._read(1, 0x75, self.mpu_addr))[0])
# now apply user setting for interrupts
self.disable_interrupts = disable_interrupts
# wake it up
self.wake()
self.accel_range(1)
self._ar = self.accel_range()
self.gyro_range(0)
self._gr = self.gyro_range()
# read from device
def _read(self, count, memaddr, devaddr):
irq_state = True
if self.disable_interrupts:
irq_state = pyb.disable_irq()
result = self._mpu_i2c.mem_read(count,
devaddr,
memaddr,
timeout=self._timeout)
pyb.enable_irq(irq_state)
return result
# write to device
def _write(self, data, memaddr, devaddr):
irq_state = True
if self.disable_interrupts:
irq_state = pyb.disable_irq()
result = self._mpu_i2c.mem_write(data,
devaddr,
memaddr,
timeout=self._timeout)
pyb.enable_irq(irq_state)
return result
# wake
def wake(self):
try:
self._write(0x01, 0x6B, self.mpu_addr)
except OSError:
print(MPU6050._I2Cerror)
return 'awake'
# mode
def sleep(self):
try:
self._write(0x40, 0x6B, self.mpu_addr)
except OSError:
print(MPU6050._I2Cerror)
return 'asleep'
# sample rate
def sample_rate(self, rate=None):
gyro_rate = 8000 # Hz
# set rate
try:
if rate is not None:
rate_div = int( gyro_rate/rate - 1 )
if rate_div > 255:
rate_div = 255
self._write(rate_div, 0x19, self.mpu_addr)
# get rate
rate = gyro_rate/(unp('<H', self._read(1, 0x19, self.mpu_addr))[0]+1)
except OSError:
rate = None
return rate
# accelerometer range
def accel_range(self, accel_range=None):
# set range
try:
if accel_range is None:
pass
else:
ar = (0x00, 0x08, 0x10, 0x18)
try:
self._write(ar[accel_range], 0x1C, self.mpu_addr)
except IndexError:
print('accel_range can only be 0, 1, 2 or 3')
# get range
ari = int(unp('<H', self._read(1, 0x1C, self.mpu_addr))[0]/8)
except OSError:
ari = None
if ari is not None:
self._ar = ari
return ari
# gyroscope range
def gyro_range(self, gyro_range=None):
# set range
try:
if gyro_range is None:
pass
else:
gr = (0x00, 0x08, 0x10, 0x18)
try:
self._write(gr[gyro_range], 0x1B, self.mpu_addr)
except IndexError:
print('gyro_range can only be 0, 1, 2 or 3')
# get range
gri = int(unp('<H', self._read(1, 0x1B, self.mpu_addr))[0]/8)
except OSError:
gri = None
if gri is not None:
self._gr = gri
return gri
# get raw acceleration
def get_accel_raw(self):
try:
axyz = self._read(6, 0x3B, self.mpu_addr)
except OSError:
axyz = b'\x00\x00\x00\x00\x00\x00'
return axyz
# get acceleration
def get_acc(self, xyz=None):
if xyz is None:
xyz = 'xyz'
scale = (16384, 8192, 4096, 2048)
raw = self.get_accel_raw()
axyz = {'x': unp('>h', raw[0:2])[0]/scale[self._ar],
'y': unp('>h', raw[2:4])[0]/scale[self._ar],
'z': unp('>h', raw[4:6])[0]/scale[self._ar]}
aout = []
for char in xyz:
aout.append(axyz[char])
return aout
# get pitch
def pitch(self):
scale = (16384, 8192, 4096, 2048)
raw = self.get_accel_raw()
x = unp('>h', raw[0:2])[0]/scale[self._ar]
z = unp('>h', raw[4:6])[0]/scale[self._ar]
pitch = degrees(pi+atan2(-x,-z))
if (pitch>=180) and (pitch<=360):
pitch-=360
return -pitch
# get raw gyro
def get_gyro_raw(self):
try:
gxyz = self._read(6, 0x43, self.mpu_addr)
except OSError:
gxyz = b'\x00\x00\x00\x00\x00\x00'
return gxyz
# get gyro
def get_gyro(self, xyz=None, use_radians=False):
if xyz is None:
xyz = 'xyz'
if use_radians:
scale = (7150, 3755, 1877.5, 938.75)
else:
scale = (131.0, 65.5, 32.8, 16.4)
raw = self.get_gyro_raw()
gxyz = {'x': unp('>h', raw[0:2])[0]/scale[self._gr],
'y': unp('>h', raw[2:4])[0]/scale[self._gr],
'z': unp('>h', raw[4:6])[0]/scale[self._gr]}
gout = []
for char in xyz:
gout.append(gxyz[char])
return gout
# get gyro pitch - y - axis in degrees
def get_gy(self):
scale = (131.0, 65.5, 32.8, 16.4)
raw = self.get_gyro_raw()
gy = unp('>h', raw[2:4])[0]/scale[self._gr]
return gy
Code: Select all
from mpu6050 import MPU6050
Anyone have an idea how to calibrate Gyro sensor (mpu6050) , I also Tried to use mpu9250 9150 but I get the same error when using
Code: Select all
from mpu9150 import MPU9150
sensor : MPU -92/65_____GY 9250/9255/6500/6555
Anyidea is welcome ,
Best Regards,
Samerou