Kamil používá elektronický kompas HMC5883L, který je připojen ke sběrnici I2C (SDA a SCL), k napájení 3.3V a GND. Brzy po instalaci jsem zjistil, jak je kompas citlivý na okolní magnetická pole. Musel jsem nahradit ocelové připevňovací šroubky plastovými, protože k zašroubování použitý nástroj byl zmagnetován a něco ze sebe předal šroubkům. Následně se mi nějakým záhadným způsobem zmagnetovaly připájené Dupont piny a ani propojovací vodiče s Dupont konektory nebyly bez viny, takže jsem musel přímo na destičku kompasu připájet měděné vodiče. V praxi pak máme problémy s některými dveřmi s ocelovými zárubněmi nebo různými železy v podlaze. Problém je to ale řešitelný. Před oblastí s magnetickou anomálií změříme azimut, hodnotu uložíme do registru, projedeme oblastí bez kompasu a poté se, pokud se při jízdě změnil, otočíme na uložený azimut.
Ještě musím upozornit na problém s označením na destičce kompasu. Existuje kompas HMC5883L a pak QMC5883L. Oba jsou na pohled stejné, na QMC ale není originální čip, liší se např. jinou adresací registrů, takže oba kompasy nejsou SW kompatibilní a níže uvedený pythonovský kód pro QMC nefunguje. Aby toho nebylo málo, jsou kompasy označeny shodně - HMC5883L. Spolehlivým rozpoznavatelem je buďto nápis na destičce kompasu "HW-127" (nebo bez nápisu) pro HMC a "GY-273" pro QMC, po zapojení pak I2C adresa. HMC má adresu 0x1e, zatímco QMC 0x0d.
#!/usr/bin/python
import smbus
import math
# KOMPAS - some MPU6050 Registers and their Address
Register_A = 0 # Address of Configuration register A
Register_B = 0x01 # Address of configuration register B
Register_mode = 0x02 # Address of mode register
X_axis_H = 0x03 # Address of X-axis MSB data register
Z_axis_H = 0x05 # Address of Z-axis MSB data register
Y_axis_H = 0x07 # Address of Y-axis MSB data register
deklinace = 0.00459 # 4°59' - magnetická deklinace pro Brno
pi = 3.14159265 # define pi value
def Magnetometer_Init():
# write to Configuration Register A
bus.write_byte_data(kompas_addr, Register_A, 0x70)
# Write to Configuration Register B for gain
bus.write_byte_data(kompas_addr, Register_B, 0xa0)
# Write to mode Register for selecting mode
bus.write_byte_data(kompas_addr, Register_mode, 0)
def read_raw_data(addr):
high = bus.read_byte_data(kompas_addr, addr) # Read raw 16-bit value
low = bus.read_byte_data(kompas_addr, addr+1)
value = ((high << 8) | low) # concatenate higher and lower value
if(value > 32768): # to get signed value from module
value = value - 65536
return value
def cti_kompas():
Magnetometer_Init() #
# Read Accelermeter raw value
x = read_raw_data(X_axis_H)
z = read_raw_data(Z_axis_H)
y = read_raw_data(Y_axis_H)
heading = math.atan2(y, x) + deklinace
if (heading > 2*pi): # Due to deklinace check for >360 degree
heading = heading - 2*pi
if (heading < 0): # check for sign
heading = heading + 2*pi
heading_angle = int(heading * 180/pi) # convert into angle
#
return heading_angle
kompas_addr = 0x1e # HMC5883L magnetometer device I2C address
bus = smbus.SMBus(1) # SMBus(0) for older version boards
print("azimut je ", cti_kompas())