giovedì 9 febbraio 2017

Geological compass for Micro:bit (2)

In questo post viene aggiornato il programma Geocompass per Micro:Bit visto qui aggiungendo la possibilita' di salvare i dati sulla memoria non volatile di Micro:Bit



Geocompass in uso di campagna




E la bussola meccanica per confronto


prima di tutto per accedere al file system di Microbit e' necessario installare microfs mediante
pip install microfs

per listare il file si usa
ufs list

per copiare i file da Microbit al pc si usa
ufs get nomefile.ext

i dati di strike e dip vengono salvati in un file testo nel formato nr.progr strike/dip
2 197/32
3 116/41
4 17/34

5 153/26

e' presente anche un file last_data.txt che contiene il progressivo dell'ultima misura.

MicroPython ha alcune limitazione rispetto a Python normale.
Le piu' evidenti nella gestione dei file sono:

- non esiste l'append in scrittura file ..si deve quindi leggere tutto il file, metterlo in un buffer, aggiungere una stringa in coda al buffer e poi si riscrive sulla memoria non volatile. Il comando write semplicemente cancella il file se gia' presente

- per verificare su un file e' gia' presente non si puo' usare os.path.isfile(fname) ma si usa il costrutto try..except per la gestione delle ecccezioni

- non e' possibile scorrere un file di testo riga per riga con una sintassi classica
Attenzione : ogni volta che viene flashato il programma, i dati vengono cancellati

-----------------------
from microbit import display
import microbit
import math

display.scroll("GEOCOMPASS")

cc = 180/math.pi
teta = 0
dip = 0
buffer = ""
ls = 0  # contatore progressivo delle misure

# guarda se ci sono misure gia' presenti e prende l'ultimo 
# dato progressivo dal file nel variabile ls
try:
    with open("last_data.txt") as ll2:
        ls = int(ll2.read())
except:
    ls = 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
        ss = (sigma + hd) % 360
        display.scroll("Str " + str(int(ss)) + "/Dip " + str(int(teta)), 300)
        # controlla se c'e' il file su disco
        try:
            with open("geodata.txt") as ll:
                buffer = ll.read()
        except:
            buffer = ""
        # scrive i dati sul disco ultima misura
        ls = ls + 1   # incrementa contatore
        with open("geodata.txt", 'w') as out:
            aa = str(ls) + " " + str(int(ss)) + "/" + str(int(teta)) + "\n"
            out.write(buffer + aa)
        with open("last_data.txt", "w") as out2:
            out2.write(str(ls))
        microbit.sleep(500)
    if microbit.button_b.is_pressed():
        # the B button repeat the last measure
        display.scroll("Str " + str(int(ss)) + "/Dip " + str(int(teta)), 300)