Zitat von
Torrentula
Du benötigst immer noch ein Accelerometer, denn schließlich willst du ja für Neigung kompensieren. Das Magnetometer misst ja erstmal nur die Stärke eines Magnetfeldes auf 3 Achsen. Diese Werte werden in der Einheit Gauß angegeben, d.h. du musst sie, wie du es bereits machst im Code, miteinander verrechnen, sodass du einen Winkel zum magnetischen Nordpol bekommst (<besserwisser>und erst dann ist es ein Kompass</besserwisser> :P).
Diese simple Formel:
Code:
ang = 180+round(math.atan2(x, y)*(180/math.pi),0)
Ist eigentlich eine Vereinfachung, denn hier wird davon ausgegangen, dass das Magnetometer parallel zum Boden ausgerichtet ist (d.h. die Z-Achse senkrecht zur Erdoberfläche steht).
Mit Hilfe eines Acceleromters kannst du die Beschleunigung auf 3 Achsen messen, mit Hilfe dieser Werte kannst du dir deinen Winkel um alle drei Achsen ausrechnen, d.h. du kennst Pitch (X-Winkel), Yaw (Z-Winkel) und Roll (Y-Winkel) (alles im Bezug auf die Erdoberfläche).
Wenn du jetzt Pitch und Roll kennst, dann kannst du die Messung des Magnetometers für Neigung kompensieren (Pseudocode):
Code:
pitch = asin(ACC_X);
roll = asin(ACC_Y);
x = MAG_X * cos(pitch) + MAG_Z * sin(pitch);
y = MAG_X * sin(roll) * sin(pitch) + MAG_Y * cos(roll) - MAG_Z * sin(roll) * cos(pitch);
ang = atan2(y, x);
Alles nachzulesen auf
https://www.loveelectronics.co.uk/Tu...duino-tutorial
Code:
#!/usr/bin/env python3
import time
import random
import smbus
import math
import serial
bus = smbus.SMBus(1)
address = 0x1e
class SensorADXL345(object):
def __init__(self, bus_nr, addr):
self.bus = smbus.SMBus(bus_nr)
self.addr = addr
def read_data_beschl(self):
ax = self.bus.read_word_data(self.addr, 0x32)
ay = self.bus.read_word_data(self.addr, 0x34)
az = self.bus.read_word_data(self.addr, 0x36)
return (ax, ay, az)
bus = smbus.SMBus(1)
address = 0x1e
while True:
mitte = 0
bus.write_byte_data(address,0,80)
bus.write_byte_data(address,1,32)
bus.write_byte_data(address,2,1)
time.sleep(0.01)
x = y = z = 1.0
x = y = z = 1.0
x1=bus.read_byte_data(address,3)
x2=bus.read_byte_data(address,4)
x=x1*256.0+x2
if x>32767:
x-=65536
z1=bus.read_byte_data(address,5)
z2=bus.read_byte_data(address,6)
z=z1*256.0+z2
if z>32767:
z-=65536
y1=bus.read_byte_data(address,7)
y2=bus.read_byte_data(address,8)
y=y1*256.0+y2
if y>32767:
y-=65536
ang = 180+round(math.atan2(x, y)*(180/math.pi),0)
sensor = SensorADXL345(1, 0x53)
xm, ym, zm = sensor.read_data_beschl()
pitch = xm
roll = ym
x = x * math.cos(pitch) + z * math.sin(pitch);
y = x * math.sin(roll) * math.sin(pitch) + y * math.cos(roll) - z * math.sin(roll) * math.cos(pitch);
ang2 = 180+round(math.atan2(x, y)*(180/math.pi),0)
print "alt",ang, "neu",ang2
time.sleep(2)
die alten werte stimmen nur die neuen mit Zusatz sensor sind total falsch. Was is das prob?
wenn ich pitch und roll auf 0 setze kommt der richtige winkel raus...nur wenn ich die Accelerometer werte nehme nicht mehr...
Lesezeichen