The compass needs to be calibrated in order to report values that are centered and equalized. This is needed because there are magnetic fields all around; by calibrating the sensor, we can cancel out the effect of any localized fields.
By measuring the readings of the compass on all axes, we can determine the minimum
and maximum values for each axis. This will allow us to calculate the mid-point of the readings, and also the scaling, so that each axis will read the same value whenever it is facing the same way.
Add the following code at the top of the file (after the import statements):
CAL=100 #take CAL samples
Add the following code to __init__(self) of the compass class:
self.offset,self.scaling=self.calibrateCompass() if DEBUG:print("offset:%s scaling:%s"%(str(self.offset), str(self.scaling)))
Add a new function named calibrateCompass() within the compass class, as follows:
def calibrateCompass(self,samples=CAL): MAXS16=32768 SCALE=1000.0 avg=[0,0,0] min=[MAXS16,MAXS16,MAXS16];max=[-MAXS16,-MAXS16,-MAXS16] print("Rotate sensor around axis (start in 5 sec)") time.sleep(5) for calibrate in range(samples): for idx,value in enumerate(self.readCompassRaw()): avg[idx]+=value avg[idx]/=2 if(value>max[idx]): max[idx]=value if(value<min[idx]): min[idx]=value time.sleep(0.1) if DEBUG:print("#%d min=[%+06d,%+06d,%+06d]" %(calibrate,min[0],min[1],min[2]) +" avg[%+06d,%+06d,%+06d]" %(avg[0],avg[1],avg[2]) +" max=[%+06d,%+06d,%+06d]" %(max[0],max[1],max[2])) offset=[] scaling=[] for idx, value in enumerate(min): magRange=max[idx]-min[idx] offset.append((magRange/2)+min[idx]) scaling.append(SCALE/magRange) return offset,scaling
Add another new function named readCompass() in the compass class, as follows:
def readCompass(self): raw = self.readCompassRaw() if DEBUG:print("mX = %+06d, mY = %+06d, mZ = %+06d" % (raw[0],raw[1],raw[2])) read=[] for idx,value in enumerate(raw): adj=value-self.offset[idx] read.append(adj*self.scaling[idx]) return read
If you look closely at the readings (if you use readCompass()), you will now find that all of the readings have the same range and are centered around the same values.