Visualizzazione post con etichetta Micro:bit. Mostra tutti i post
Visualizzazione post con etichetta Micro:bit. Mostra tutti i post

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)

mercoledì 8 febbraio 2017

Micro:Bit

Microbit e' un progetto promosso per introduzione all'informatica dei bambini nel Regno Unito. In estrema sintesi vengono regalati ai ragazzi di 11-12 anni delle piccole schede dotate di un processore Arm, Accelerometro, Bluetooth, un array di led 5x5, due pulsanti ..ed altre cose; con queste in classe fanno dei piccoli esperimenti

Questo esperimento non e' nuovo perche' agli inizi degli anni 80 era stato lanciato il progetto BBC Micro (basato su 6502)

Comfronto tra la scheda ed una moneta da 1 euro
In Italia la scheda si trova su Amazon a circa 25 euro nel kit con il cavo USB ed il pacco batterie



Quando si apre la confezione la cosa che salta piu' all'occhio e' l'assenza della scheda...e' talmente piccola che e' stata messa nel pacchetto di cartone sulla sinistra



Per programmare la scheda ci sono molte opzioni on line, dall'interfaccia tipo Blockly all'editor testuale. In alcuni casi e' presente anche un emulatore per provare il codice. Usare Python e' particolarmente fastidioso perche' non e' presente l'emulatore e non si puo' fare l'upload diretto del programma nella scheda (si deve compilare e scaricare il compilato e quindi trascinare il file dentro alla cartella di Micro:bit che si presenta come un disco USB)



Questa e' la IDE per Javascript con l'emulatore sulla sinistra ed il sistema di composizione dei comandi a blocchi sulla destra




Molto piu' comodo (anche se ha le sue idiosincrasie) e' usare Mu, un editor offline per MicroPython che effettua direttamente l'upload e permette alla riga di comando REPL di Python

La cosa un po' folle e' il sistema di debugging...l'errore scorre, carattere a carattere sul display...giusto per cronaca l'errore del video sottostante e'

Line 27 AttributeError module object has no attribute arcsin

sfido chiunque a capirlo al primo tentativo






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)))
----------------------

Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...