mercoledì 8 febbraio 2017

Geological compass for Micro:bit

Aggiornamento qui
Un semplice programma in MicroPython per usare l'accelerometro e la bussola di Micro:bit come bussola da rilevamento geologico


Premendo il pulsante A si acquisisce la misura (se la bussola non e' stata calibrata sara' necessario farlo ruotando il dispositivo fino a creare un cerchio sul display). Il pulsante B ripete la visualizzazione dell'ultima misura
Il costo finale, compreso di batterie, e' di circa 25 euro



Il calcolo matematico di pitch e roll partendo dai dati dell'accelerometro e' stato ripreso da qui

Mark Pedley, Tilt Sensing Using a Three-AxisAccelerometer. Freescale Semiconductor Document Number: AN3461 Application Note Rev. 6, 03/2013


Il calcolo di strike e dip partendo da pitch e roll e' stato ripreso da questo articolo

 R.N. Barbosa *,1 , J.B. Wilkerson2 , H.P. Denton3 and D.C. Yoder 2, Slope Gradient and Vehicle Attitude Definition Based on Pitch and Roll Angle Measurements: A Simplified ApproachThe Open Agriculture Journal, 2012, 6, 36-40

in questa immagine l'orientazione degli assi dell'accelerometro e della bussola rispetto alla scheda (da notare che l'accelerazione Gz e' negativa perche' all'accelerometro e' saldato sulla parte opposta della scheda)




(nota : i valori di accelerazione vengono mostrati come numeri interi e non come float (m/s2) o come frazioni dell'accelerazione di gravita' (come in Android)
----------------------
from microbit import display
import microbit
import math

display.scroll("GEOCOMPASS")

cc = 180/math.pi
teta = 0
dip = 0

while True:
    if microbit.button_a.is_pressed():
        # if necessary calibrate the compass
        if not microbit.compass.is_calibrated():
            display.scroll("Calibrate compass")
            microbit.compass.calibrate()
            microbit.sleep(2500)
        gx = microbit.accelerometer.get_x()
        gy = microbit.accelerometer.get_y()
        gz = microbit.accelerometer.get_z()
        hd = microbit.compass.heading()
        # change the sign to uniform to Android
        gx = - gx
        gz = - gz
        pitch = math.atan2(gy, math.sqrt((gx*gx)+(gz*gz)))
        roll = math.atan2(-gx, gz)
        # from pitch/roll to strike/dip
        p2 = math.sin(pitch)*math.sin(pitch)
        r2 = math.sin(roll)*math.sin(roll)
        t1 = math.sqrt(p2+r2)
        # ---
        teta = (cc * math.asin(t1))
        sigma = math.asin(math.sin(roll)/t1)
        sigma = (cc * sigma)
        # -----
        # primo quadrante
        if ((gy <= 0) and (gx < 0)):
            sigma = sigma
        # secondo quadrante
        if ((gy > 0) and (gx < 0)):
            sigma = 180 - sigma
        # terzo quadrante
        if ((gy > 0) and (gx >= 0)):
            sigma = 180 - sigma
        # quarto quadrante
        if ((gy <= 0) and (gx >= 0)):
            sigma = 360 + sigma
        dip = (sigma + hd) % 360
        display.scroll("Dip " + str(int(teta)) + "/Str " + str(int(dip)))
        microbit.sleep(500)
    if microbit.button_b.is_pressed():
        # the B button repeat the last measure
        display.scroll("Dip " + str(int(teta)) + "/Str " + str(int(dip)))
----------------------