venerdì 30 ottobre 2015

Pseudo ologramma con Android


Questa cosa e' stata ripostata mille volte su Internet nell'ultimo mese ma vale la pena provarlo direttamente perche':

  1. L'effetto e' decisamente piu' divertente visto dal reale che dai video di Youtube
  2. E' da fare insieme con i bambini




Si parte costruendo un tronco di piramide con le facce trasparenti e senza basi come nelle istruzioni riportate a questo link usando la copertina trasparente di un CD


Un po' di attenzione: c'e' la seria possibilita' di farsi male. Per tagliare la copertina del CD si deve fare molta forza sul taglierino e la superficie e' insospettatamente scivoloso. Basta poco a farsi scappare la mano. E' anche abbastanza difficile fare tagli dritti

Il tronco di piramide deve essere posto al centro dello schermo del telefono



Si deve scegliere su Internet un video Youtube che permetta di visualizzare l'ologramma. Ho trovato questo video (anche perche' e' il piu' vario)


e qui si capisce il trucco. Ci sono 4 animazioni contemporanee, una per ogni angolo di vista
Per una migliore visione si deve scegliere una stanza buia e mettere la luminosita' dello schermo al massimo

A questo punto, per omaggiare Guerre Stellari, e' necessario provare un ologramma della Morte Nera (Death Star) come e' stato visto nel primo film della serie

Immagine dal film
La qualita' e' quella che e' (ovvero pessima) ma quando ero bambino non mi sarei mai sognato di poterlo fare in casa



giovedì 29 ottobre 2015

Wine su Mac con Homebrew

Ho la necessita' di utilizzare un programma sviluppato da un collega in Visual Basic (Visual Studio 2010) ma normalmente non ho con me una macchina Windows.
Non avendo voglia di installare una intera macchina virtuale Windows XP per far girare un programma da pochi Mb ho scelto la strada di Wine ed in particolare Wine su Mac





Per prima cosa si deve agire da superutente
sudo su

L'installazione di Wine e' stata fatta mediante Homebrew (esistono soluzioni gia' preconfezionate di Wine su Mac tipo WineBottler e PlayOnMac ma entrambe mi hanno generato errori senza che io avessi la possibilita' di capire dove era il problema per cui ho rinunciato...per la verita' esiste anche una soluzione a pagamento con una trial da 14 giorni CrossOver)

poi, lavorando dietro ad un proxy, devo istruire Homebrew
export http_proxy=http://proxy.xxxxxx.it:8080 export ALL_PROXY=$http_proxy

si inizia installando Wine ma prima si deve aggiornare Brew per evitare problemi di dipendenze (a me e' successo con libpng)..c'e' anche una dipendenza da XQuartz ma io la installo sempre
Attenzione ... munirsi di pazienza

brew update
brew upgrade


brew fetch -deps wine
brew install wine

a questo punto dovrebbe essere possibile digitare
winefile
per aprire il file manager di Wine

Se si clicca pero' l'eseguibile Visual Basic questo non parte perche' mancano le librerie di base di DotNet....pero' DotNet non si installa se prima non e' installata la msxml3. Per rendere le cose semplici si usa winetricks (e' uno script di shell)

wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
(oppure wget http://kegel.com/wine/winetricks)
chmod +x winetricks

winetricks msxml3
winetricks dotnet40

Non basta. Cercando di aprire l'eseguibile compare il seguente errore. 

Queste librerie non sono incluse in winetricks, si scarica quindi l'installer e si esegue con il comando

wine VisualBasicPowerPacksSetup.exe

alla fine siamo pronti ad aprire l'eseguibile in Visual Basic (con il doppio clic da winefile oppure direttamente lanciandolo da riga di comando)

mercoledì 28 ottobre 2015

Sharp ElsiMate EL-5809 e regolo calcolatore

Per la modica cifra di 10 euro il mio museo di strumenti di calcolo ha avuto due nuovi ingressi
Una Sharp ElsiMate EL-5809 in condizioni perfette con scatola, libretto e custodia (si parla di un oggetto del 1978)


ed un regolo calcolatore tascabile con manuale di istruzione in cui e' riportato l'utilizzo per rilievi tachiometrici (il libro e' del 1940, il regolo dovrebbe essere degli anni 60)



lunedì 26 ottobre 2015

Lighttable editor

Sono stato un utente di CODA, fino a quando ho potuto usarlo licenziato. Adesso pero' sono costretto a trovare un degno sostituto



Per aprire file in modo rapido (ovvero non usando la combinazione Cmd+Shift+O) si puo' usare il Workspace. Per abilitare tale modalita' si preme CTRL+SPACE) e si seleziona Workspace: Toggle Workspace Tree, a questo punto si apre un pannello sulla destra in cui clicccando destro si puo' selezionare
la directory in cui sono contenuti i file del progetto HTML
Un'altra soluzione e' quella di usare CTRL+SPACE e digitare Navigate: Open Navigate


Una volta aperto il sorgente si puo' splittare lo schermo in due porzioni con la combinazione CTRL+SPACE e selezionando Tabset:Add tabset. A questo punto lo schermo si divide in due lasciando una porzione libera a destra. Per visualizzare il browser della pagina html aperta si clicca CTRL+SHIFT+ENTER


Il browser si apre nel settore sinistro..basta prendere il tab dal titolo (nella parte superiore dove compare il nome del file) e trascinarlo a destra. Si avra' cosi' la visione affiancata tra il sorgente ed il browser

Se si modifica la pagina sorgente a sinistra e' sufficiente premere CTRL+ENTER per vedere l'aggiornamento nella parte sinistra

Puo' essere utile aprire nella parte bassa la console in modo da visualizzare eventuali errori. Questa operazione si effettua con CTRL+SPACE e Console: Toogle Console

Altri comandi
CTRL+SEGNO MENO : Zoom out
CTRL+F : Find
CTRL+SHIFT+TAB : cicla fra i tab di uno stesso tabset
CTRL+W : chiude il tab attuale
CTRL+numero : vari al tab numero..


Attenzione : su Mac la combinazione Command (CTRL+SPACE) e' gia' mappata per aprire Spotlight. Dato che non la uso mai ho disattivato lo shortcut dalle Impostazione di Mac/Tastiera/Abbreviazioni


GPS : L1, L1+WAAS, L1+Raw, L1+L2

In questo post vengono riassunte un po' di esperienze su vari tipi di posizionamento GPS con antenne di costo medio e basso (dove per antenna si intende l'accoppiamento della ricevente piu' l'orologio interno al sensore)


(nella figura i risultati di una prova; in giallo i due punti medi di una acquisizione con Garmin 12 XL in modalita' Raw con la sua area di errore in rosso, in blu i dati del Garmin 12 XL in modalita' NMEA e in verde l'area di un MTK3339 in modalita' non WAAS; l'andamento a griglia deriva da una interpolazione delle cifre significative del dato)

Antenna L1 : i ricevitori con antenna L1 (1575.42 MHz) si trovano comunemente per cifre comprese tra i 10 ed i 20 euro. Hanno una connessione seriale con in uscita stringhe in protocollo NMEA e non hanno nessun tipo di correzione. I dati non possono essere post-processati perche' il dato NMEA puro non puo' essere post-processsato in quanto gia' derivante da un algoritmo di calcolo interno al ricevitore che varia da antenna ad antenna e da produttore a produttore. Il sensore MTK3339 senza la correzzione WAAS attivata ha una ellisse degli errori (espressa come standard deviation) pari a circa 3.5 m in Latitudine e 7.5 m in Longitudine (vedi paragrafo successivo per confronto)

Antenna L1 + WAAS : una versione migliorata di un sensore L1 (ma sempre con i limite della non possibilita' di fare post-processing) e' quella che implementa la ricezione dei segnali di correzione (EGNOS per noi europei, WAAS per il Nord America). In caso di funzione WAAS attivata il sensore MTK3339 (Adafruit GPS Breakout) mostra una ellisse degli errori pari a 1.88 m in Latitudine e 0.61 m in Longitudine. Il costo sale verso circa 50 euro. Attenzione : questo dato viene espresso come standard deviation attorno al punto medio e non come nel caso successivo come Sigma95%. Se si osserva la nuvola dei punti la dispersione dei punti e' molto ampia al pari del caso precedente





Antenna L1 + Raw data: in questo caso l'acquisizione non prevede solo la trasmissione delle stringhe NMEA ma anche i dati di pseudorange. Tali dati possono essere post processati e si ha un incremento notevole della precisione. Lo stesso sensore (Garmin 12 XL) fatto lavorare in modalita' NMEA ha mostrato una ellisse degli errori di circa 7 m per asse. In modalita' raw data, con acquisizione corta ovvero inferiore ai 10 minuti non si ha un reale miglioramento della distribuzione dell'errore con assi dell'ellisse intorno a 5-6 m; passando ad acquisizioni piu' lunghe, ovvero oltre l'ora, sono stati misurati errori di 1.2 e 1.1 m rispettivamente su Latitudine e Longitudine. Il costo di un ricevitore L1 con possibilita' di Raw Data parte da 80 euro per andare su qualche centinario di euro

Antenna L1+L2 : e qui, come ho trovato scritto su un forum, bisogna vendersi un rene per fare misure GPS in doppia banda L1 + L2 (1227.60 MHz) perche' i costi vanno verso le migliaia di euro (diciamo a partire da 5000 euro). Il posizionamento e' pero' di estrema di precisione ovvero al centimetro con tempi di acquisizione di qualche decina di secondi

A costi ragionevoli l'unica strada percorribile sembra essere quella di usare un sistema L1+Raw con post processing:

Ho fatto una prova eseguendo in due giorni differenti con lo stesso ricevitore una acquisizione di circa un'ora e 20 minuti

I risultati sono stati
Acquisizione 1 : Lat 43°50'0.5968" +- 2.195 m  Lon 11°18'37.9074" +-1.248 m
Acquisizione 2 : Lat 43°50'0.6584" +- 1.219 m  Lon 11°18'37.7559" +-1.149 m

Si vede che l'area dell'errore (calcolato come 95% Sigma) e' molto modesta. Andando a calcolare pero' la distanza in metri tra i due punti si osserva che e' di circa 4. Considerando l'ellisse dell'errore le due misure, peraltro vicine, non si sovrappongono. Quindi il metodo tende ad essere preciso ma non necessariamente accurato (non ho una antenna L1+L2 per verificare la posizione al centimetro)

venerdì 23 ottobre 2015

NodeMcu Lua ESP8266 ESP-12E WIFI Development Board

Questo dispositivo e' un microcontrollore con abbinato capacita' WiFi a basso costo simile ad Arduino, che si puo' programmare con Arduino....ma non e' Arduino (ha piu' o meno le dimensioni di una Arduino Nano)



Il costo di ogni kit e' di circa 7 Euro (sui vari ecommerce cinesi per esempio Banggood)
Per la programmazione su Windows Xp e' necessario prima scaricare il driver della porta CP210x da questo link


In seguito e' conveniente flashare il modulo mediante il programma (senza questa operazione non riuscivo a comunicare con la scheda) che puo' essere reperito a questo link (cartella WIN32/Realease/ESP8266Flasher.exe) .

La scheda mi e' arrivata con questo firmware
NodeMcu 0.9.2 build 20141207  powered by Lua 5.1.4
ed e' stata aggiornata a 
NodeMCU 0.9.5 build 20150318  powered by Lua 5.1.4

(i firmware di sviluppo si scaricano da questo indirizzo)

Con il primo firmware c'era sempre un errore sul comando tmr, con il secondo firmware tutti gli script che si trovano su internet funzionano correttamente

L'uso e' molto semplice, basta selezionare la porta COM e lanciare l'operazione che dura un paio di minuti


Come dice il nome il metodo di programmazione della scheda e' in LUA e si puo' utilizzare il programma LuaLoader


Per connettersi con la scheda si deve andare nel menu Settings/COMM Port Settings e selezionare la porta virtuale (nel mio caso la Comm37) e poi effettuare il Connect. In caso di connessione diventa verde il box in alto a sinistra.

Esiste anche un'altro ambiente di sviluppo ESPlorer (non e' stato impiegato durante la scrittura di questo post)



Per caricare i programmi questi si scrivono in un editor di testo ed poi effettuato l'upload con il comando Upload File. Per mandare in esecuzione il programma si seleziona dal menu a tendina lo script desiderato e si lancia dofile

Attenzione : tutti i file di cui si fa l'upload rimangono in memoria. Per rimuoverli si devono selezionare dal menu a tendina e poi eseguire remove. Per visualizzare la memoria libera si puo' cliccare sul pulsante Heap

Per mandare in esecuzione automatica un programma all'accensione si deve nominare come init.lua. Questo espone ad un rischio ovvero che se il programma va in loop inifinito non c'e' modo di  riprendere il controllo della scheda (i file sopravvivono ad un flash della scheda) . Conviene scrivere un init.lua che comprenda righe del tipo

-----------------------------------------
tmr.alarm(0, 1000000, 0, function()
dofile("mioprogramma.lua")
end)
--------------------------------------------------
in modo da ritardare la partenza di mioprogramma.lua di 10 secondi e poter nel frattempo premere il comando tmr.stop per interrompere l'esecuzione automatica


Il pinout della scheda e' il seguente


Per modificare lo stato dei pin digitali si puo' eseguire le seguenti chiamate
In questo caso si setta a 1 il pin GPIO 1 ovvero D10
pin=1 
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.HIGH)

e per invece settare 0 sul pin 1
gpio.write(pin, gpio.LOW)

La scheda ha una tensione di lavoro di 3.3 V per cui lo stato 1 vale 3.3 V

Ovviamente avendo una scheda WiFi e' interessante sfruttare la connessione di rete
Con questo script la scheda diventa un web server
-------------------------------------------------------------
-- Simple NodeMCU web server (done is a not so nodeie fashion :-)
--
-- Written by Scott Beasley 2015
-- Open and free to change and use. Enjoy.
--

-- Your Wifi connection data
local SSID = "XT1032 3365"
local SSID_PASSWORD = "XXXXXXXX"

local function connect (conn, data)
   local query_data

   conn:on ("receive",
      function (cn, req_data)
         query_data = get_http_req (req_data)
         print (query_data["METHOD"] .. " " .. " " .. query_data["User-Agent"])
         cn:send ("Hello World from ESP8266 and NodeMCU!!")
         -- Close the connection for the request
         cn:close ( )
      end)
end

function wait_for_wifi_conn ( )
   tmr.alarm (1, 1000, 1, function ( )
      if wifi.sta.getip ( ) == nil then
         print ("Waiting for Wifi connection")
      else
         tmr.stop (1)
         print ("ESP8266 mode is: " .. wifi.getmode ( ))
         print ("The module MAC address is: " .. wifi.ap.getmac ( ))
         print ("Config done, IP is " .. wifi.sta.getip ( ))
      end
   end)
end

-- Build and return a table of the http request data
function get_http_req (instr)
   local t = {}
   local first = nil
   local key, v, strt_ndx, end_ndx

   for str in string.gmatch (instr, "([^\n]+)") do
      -- First line in the method and path
      if (first == nil) then
         first = 1
         strt_ndx, end_ndx = string.find (str, "([^ ]+)")
         v = trim (string.sub (str, end_ndx + 2))
         key = trim (string.sub (str, strt_ndx, end_ndx))
         t["METHOD"] = key
         t["REQUEST"] = v
      else -- Process and reamaining ":" fields
         strt_ndx, end_ndx = string.find (str, "([^:]+)")
         if (end_ndx ~= nil) then
            v = trim (string.sub (str, end_ndx + 2))
            key = trim (string.sub (str, strt_ndx, end_ndx))
            t[key] = v
         end
      end
   end

   return t
end

-- String trim left and right
function trim (s)
  return (s:gsub ("^%s*(.-)%s*$", "%1"))
end

-- Configure the ESP as a station (client)
wifi.setmode (wifi.STATION)
wifi.sta.config (SSID, SSID_PASSWORD)
wifi.sta.autoconnect (1)

-- Hang out until we get a wifi connection before the httpd server is started.
wait_for_wifi_conn ( )

-- Create the httpd server
svr = net.createServer (net.TCP, 30)

-- Server listening on port 80, call connect function if a request is received
svr:listen (80, connect)
-------------------------------------------------------------

Un altro aspetto e' quello di settare l'ESP8266 come un Access Point con i comandi
-------------------------------------------------------------
cfg={}
 cfg.ssid="LucaInno"
 cfg.pwd="xxxxxxxxxxxxxi"
 wifi.ap.config(cfg)
 wifi.setmode(wifi.SOFTAP)
-------------------------------------------------------------

mercoledì 21 ottobre 2015

Garmin 12 XL e GPS Differenziale

A lavoro utilizzo un vecchio Garmin 12 XL, un modello piuttosto datato visto che risale circa al 1998 con un modesto ricevitore a 12 canali


Lo ho sempre usato come sistema di campagna speditivo ma ho scoperto che e' possibile ottenere i dati raw delle acquisizione (non quindi le semplici stringhe NMEA) mediante dei comandi non documentati.
Per fare cio' si puo' utilizzare il programma descritto a questo link e che puo' essere scarica da qui (il programma e' piuttosto vecchio, datato 2000, ma e' ancora funzionante su Linux ...ps il programmatore e' ancora contattabile per mail ma risponde che non mantiene piu' il programma quindi bisogna arrangiarsi da soli)

Il dispositivo deve essere collegato al PC mediante il cavo seriale con un connettore proprietario di Garmin (dato che l'altro lato ha un connettore DB9 attualmente e' necessario usare un cavo USB2Serial ma non sono stati riscontrati problemi)

Sul GPS deve essere impostato nel Menu Principale/ Menu Setup/Interfaccia in modalita' GRMN/GRMN.

Per iniziare l'acquisizione si collega il GPS al PC e si lancia il comando
./async_1_23 -a -r -rinex -t 1200 -p ttyUSB1

il parametro -t 1200 indica il tempo di acquisizione in secondi (20 minuti)
il parametro -p ttyUSB1 indica la porta seriale

viene quindi creato un file binario con estensione .g12
Per passare dal formato binario al formato RINEX si digita

,/gar2rnx_1_48 file.g12 -area FIRE -f

viene quindi creato un file con estensione .15O il cui nome inizia per la sigla FIRE (puo' essere modificata)
Il contenuto di questo file e' in formato RINEX
-----------------------------------------------------------------------
     2              OBSERVATION FILE    GPS NAVSTAR         RINEX VERSION / TYPE
GAR2RNX 1.48        Any GPS12 Owner     Wed Oct 21 10:20:44 PGM / RUN BY / DATE 
** gar2rnx (Garmin to Rinex) generates Rinex2 files         COMMENT             
** from a GPS12 (or XL) (Copyright Antonio Tabernero)       COMMENT             
** Generated from G12 data file: 286475.g12                 COMMENT             
** Options: -area FIRE -f                                 COMMENT             
Garmin                                                      MARKER NAME         
Number of Antenna marker                                    MARKER NUMBER       
Your name here      Your boss here                          OBSERVER / AGENCY   
096                 GPS 12XL SOFTWARE   4.58                REC # / TYPE / VERS 
0                   GPS12 Internal Antenna                  ANT # / TYPE        
** Position from first 3D fix of the receiver               COMMENT             
  4523901.4321   898264.7768  4390920.8765                  APPROX POSITION XYZ 
        0.0000        0.0000        0.0000                  ANTENNA: DELTA H/E/N
     1     0                                                WAVELENGTH FACT L1/2
     2    C1    L1                                          # / TYPES OF OBSERV 
  2015    10    21     7    35    0.002589      GPS         TIME OF FIRST OBS   
     1                                                      INTERVAL            
                                                            END OF HEADER       
 15 10 21 07 35  0.0025890  0  6G16G20G21G26G27G29                  
  22487277.418 7   3534097.662 7
  23082055.829 7   3802321.421 7
  21737892.870 8   3820190.731 8
  21215257.724 9   3725662.773 9
  24786222.492 7   3158539.883 7
  22957023.360 7   4097166.888 7
 15 10 21 07 35  1.0026085  0  6G16G20G21G26G27G29                  
  22493017.729 7   3564265.832 7
  23088238.244 7   3834813.615 7
  21744098.021 8   3852799.017 8
  21221310.975 9   3757472.446 9
..............................................
-----------------------------------------------------------------------

A questo punto si puo' utilizzare il file per inviarlo a qualche servizio gratuito di postprocessing per ottenere il DGPS. Ed a questo punto sorge un problema. Molti dei servizi (come OPUS e Trimble) richiedono che sia presenti nel file RINEX anche le informazioni di L2 mentre il ricevitore Garmin riporta solo quelle L1 (peraltro non ci sono nemmeno limiti minimi del tempo di acquisizione come su Trimble).
Per fortuna il servizio National Resource Canada non ha questa limitazione ed invia per mail il risultato dell'elaborazione (esiste il limite che e' disponibile solo il datum NAD83 che si ritrova anche sul Garmin 12XL)



Aumentando il tempo di acquisizione il valore del Sigma95% si riduce sensibilmente anche se la precisione e' ben lontana dal valore centimetrico (cio nonostante la precisione ottenuta e' nettamente migliore di quella derivante dall'analisi dei dati NMEA del medesimo ricevitore)



martedì 20 ottobre 2015

IBeacon con AC-BT-V4

Il modulo AC-BT-V4, visto nel precedente post, conosciuto anche come HM-10 e basato su CC2540 puo' funzionare non solo come scanner di beacon ma effettuare anche il broadcast come IBeacon (attenzione, io ho usato la versione V540, il firmware puo' essere richiesto con il comando AT+VERR?)

In questo caso non e' necessario utilizzarlo come una Arduino ma puo' essere utilizzato un semplice cavo FTDI-USB


Per effettuare il broadcast del beacon basta cambiare il ruolo

AT+ROLE0

si puo' modificare sia l'UUID che il Major ed il Minor. Per esempio con i due comandi sottostanti si imposta sia il Major che il Minor a 255

AT+MARJ0x00FF
AT+MINO0x00FF

Il primo beacon osservato e' il dispositivo AC-BT-V4

Le impostazioni permangono anche se si toglie l'alimentazione. Al successivo riavvio si troveranno impostati i propri valori di Major e Minor ed il dispositivo iniziera' ad effettuare subito broadcast senza necessita' di ulteriori comandi

lunedì 19 ottobre 2015

DIY Homekit con Arduino

Dopo un primo esperimento con DIY HomeKit (a questo post) non ero particolarmente contento perche' comunque i costi di Raspberry e la gestione in generale non erano ottimali ed ho provato a replicare la cosa su Arduino


Per il modulo Bluetooth ho usato un modulo Bluetooth LE HM-10 del costo di circa 5 euro (qui). Attenzione, non tutti i moduli BT per Arduino supportano BT4 LE. Il modulo riporta sul retro la scritta AC-BT-V4 ed al comando AT+NAME? risponde con HMSoft

Il modulo si comanda tramite stringhe AT (per l'elenco completo dei comandi si puo' leggere qui il manuale di istruzioni)

Cio' che interessa e' la sequenza di comando
AT+ROLE1
AT+IMME1
AT+DISI?

all'ultimo comando il dispositivo risponde in questo modo
---------------------------------------------------------
OK+DISIS
OK+DISC:4C000215:B9407F30F5F8466EAFF925556B57FE6D:71884DF6B6:F1A84DF67188:-086
OK+DISC:00000000:00000000000000000000000000000000:0000000000:C493974F69E2:-084
OK+DISC:4C000215:B9407F30F5F8466EAFF925556B57FE6D:DB2A91AEB6:D81691AEDB2A:-084
OK+DISCE
---------------------------------------------------------
Sono stati avvistati 3 beacons (due Estimote ed un Eddystone riconoscibile da tutti zeri perche' il protocollo non e' riconosciuto)

Prendendo la riga evidenziata in giallo
iBeacon ID = B9407F30F5F8466EAFF925556B57FE6D
Major = 7188
Minor = 4DF6
Measured power (182 decimale) =B6
Mac Address = F1A84DF67188
RSSI = -86

Passando quindi ad Arduino

I collegamenti sono banali (verra' usata la Seriale Software di Arduino)
BT VCC +3.3V Arduino
BT GND GND Arduino
BT RXD D2 Arduino
BT TXD D3 Arduino

Nello sketch seguente se viene individuato il beacon con minor AEB6 viene attivato il pin D13 in modo da aprire il contatto su un rele'; se per piu' di 50 secondi non viene piu' messo in lista il beacon con minor AEB6 il pin D13 va Low e si chiude il rele (il codice si commenta da solo)

--------------------------------------------------------------------------------------
#include <SoftwareSerial.h>

SoftwareSerial mySerial(3, 2); 
char risposta[115];
int conta;
int rele = 13;
long tempo;

void setup()  
{
  Serial.begin(9600);
  mySerial.begin(9600);
  mySerial.write("AT+ROLE1");
  mySerial.write("AT+IMME1");
  if (mySerial.available())
     {
       while (mySerial.available()>0){
       }
     }
     
  pinMode(rele, OUTPUT);
  tempo = 0; 
}

void loop() 
{
  mySerial.write("AT+DISI?");
  if (mySerial.available())
     {
       conta = 0;
       while (mySerial.available()>0){
         risposta[conta] = mySerial.read();
         conta = conta + 1;
       }
     }   
  if ((risposta[56] == 'A') && (risposta[57] == 'E') && (risposta[58] == 'B') && (risposta[59] == '6')) 
    {
      //Serial.println("ATTENZIONE");
      digitalWrite(rele, HIGH);
      tempo = 0;
    }
  delay(500);
  tempo = tempo + 1;
  if (tempo > 100)
        {
          digitalWrite(rele, LOW);
          tempo = 101;
        }
  
}

venerdì 9 ottobre 2015

Confronto tra moduli GPS per Arduino

Per riprendere il discorso che avevo iniziato qui con Android, mi sono comprato un paio di moduli GPS Breakout da interfacciare ad Arduino

Avevo quindi la necessita' di comprare due moduli GPS uguali e mi sono orientato sul GPS Breakout di Adafruit. Ho fatto l'errore pero' di comprarne un modulo su Aliexpress ed uno su RobotItaly



Indicativamente i due moduli sembrano identici ma si osservi  che quello acquistato da RobotItaly riporta sulla faccia la sigla Adafruit mentre quello comprato in Cina non ha la sigla sul davanti mentre sul retro riporta Deek-Robot. A parte cio' la disposizione dei componenti e' simile a parte il fatto che il led del Fix e' rosso su Adafruit e' rosso mentre e' verde su Deek-Robot (a livello di prezzo sono quasi simili, 40 Euro per Adafruit contro circa 25 Euro per Deek-Robot)

Entrambi sono dichiarati avere in chipset MTK3339 (22 satelliti su 66 canali) abilitati a ricevere correzione SBAS/WAAS

Oltre  al livello hardware, ho potuto notare alcune differenze penso a livello di firmware. Il modello DeekRobot e' estremamente veloce nel fare il fix del punto ed ad acquisire il fix del DPGS oltre a ricevere un elevato numero di satelliti al contrario del modello Adafruit  a cui occorrono anche minuti per fare il fix normale ed il fix DGPS. Peraltro quando il componente DeekRoboto ha ottenuto il fix GPS non lampeggia il led mentre quello Adafruit continua ad accendere il led anche a fix acquisito

Messi a confronto con una acquisizione in parallelo in condizioni ottimali di visibilita' del cielo (da 7 a 8 satelliti visibili) si osserva il comportamento completamente differente dei dati registrati


I dati di Adafruit (in blu) sono molto raggruppati attorno a quello che e' il punto vero di misura (peraltro il valore medio della misura corrisponde alla posizione reale) mentre i dati di Deek-Robot (in verde) mostrano una deriva del segnale anche molto lontano dal punto reale di misure (i due GPS erano ubicati affiancati a distanza di 40 cm con un tempo di acquisizione di oltre 15 minuti)

I due punti gialli sono il baricentro delle due serie di misura. Il baricentro della serie verde e' esterno alla nuvola dei punti mentre quello della serie blu si trova al centro della propria nuvola dei punti

Da questa prova i risultati dei due componenti sono totalmente differenti e non correlabili.

La stessa prova e' stata fatta anche in ambiente urbano con una visibilita' del cielo limitata dalla presenza di alti palazzi (in genere erano visibili solo 5 satelliti)


In questo caso la distribuzione dei dati e' molto piu' spargliata (come prevedibile). C'e' pero da osservare un dettaglio; plottando Lat_GPS1 contro Lat_GPS2 e Lon_GPS1 contro Lon_GPS2 si osserva un tracciato che mostra una curiosa similarita' (i punti di medesimo colore sono relativi allo stesso minuto di acquisizione)

Correlazione Latitudine
Correlazione Longitudine
Plottando la distanza tra i punti dei due GPS (mettendo insieme dati ad uguale orario) si continua ad osservare una correlazione (seppure variabile nel tempo)


In conclusione, nonostante la somiglianza dei due componenti, questi si comportano in modo differenti e non e'stato possibile ripetere l'esperienza fatta con i due telefoni Android. Da un punto di vista della scelta, il componente Adafruit, nonostante la lentezza nell'effettuare il fix gps ed il fix dgps e nonostante la difficolta' ad agganciare un alto numero di satelliti sembra ottenere le prestazioni migliori in condizioni di cielo aperto e prestazioni simili ad Deek Robot in ambiente urbano




mercoledì 7 ottobre 2015

Copia ricorsiva con Bash

In alcuni casi, per esempio copiare tutti i file mp3 da una collezione, puo' essere utile un comando che cerchi in automatico tutti i file con una determinata estensione e li metta tutti in una directory senza rispettare l'albero delle directory originario.
Tale operazione puo' essere fatta con un solo comando


find . -name "*.mp3" -type f -exec cp {} ../destinazione/ \;

(attenzione allo spazio tra l'ultima slash e backslah)

martedì 6 ottobre 2015

Ibernazione Xbee


In questo esempio viene mostrato come impostare la modalita' di ibernazione di un modulo Xbee utilizzando un pin comandato da Arduino


Per prima cosa si deve procedere ad una modifica hardware sullo shield Xbee saldando un connettore da piedino 9 dello Xbee e portandolo dentro la porta D9 di Arduino
Se il pin 9 di Xbee si trova nello stato low (ground) viene abilitata la trasmissione/ricezione del modulo, se il pin 9 si trova nello stato high (che per Xbee vuol dire 3.3 V !!) la radio viene spenta

Visto che su Arduino le uscite digitali sono a 5 V (e contrariamente a quello che viene citato qui che non ci sono problemi ad alimentare un piedino a 3.3V con un tensione da 5V) lo sketch Arduino utilizza la modalita' PWM del pin D9 di Arduino per impostare un corrente di 3.3 V

Dal punto di vista software bisogna configurare XBee con XCTU a funzionare come End Device (si puo' fare questa modificando solo modificando il firmware mediante Update Firmware) e modificando i valori di Serial Interfacing/D7 DIO7 Configuration su 0 Disable ed impostando SM ad 1 (Pin Wake Mode)


----------------------------------------------------------------------
#define XBEE_SLEEP 9

void setup() {
  //setta il pin 9 come controllo dello sleep di XBEE
  pinMode(XBEE_SLEEP,OUTPUT);
  analogWrite(XBEE_SLEEP,0);
}

void loop() { 
analogWrite(XBEE_SLEEP,168); //spenge XBEE, 3.3V PWM  
delay(sleep_time); //tempo di standby
analogWrite(XBEE_SLEEP,0); //risveglia XBEE
}
----------------------------------------------------------------------

In trasmissione l'assorbimento di corrente arriva fino a 50 mA (compreso il microcontrollore Arduino) mentre a radio spenta si hanno valori intorno ai 10 mA

lunedì 5 ottobre 2015

Configurazione moduli XBee

Per impostare un modulo Xbee si possono utilizzare vari dispositivi.
Il primo passo e' pero' trovare un socket che permetta di connettere il modulo Xbee. A causa della distanza dei piedini non e' possibile inserire Xbee su una breadboard standard

Utilizzo di Arduino
Si puo' utilizzare una Arduino come programmatore di XBee ponticellando i pin RST e GND (cio' esclude il collegamento del processore a bordo dell'Arduino) e collegando i pin TX-TX ed RX-RX tra Arduino e Xbee (di solito si usa collegare incrociando TX ed RX ma in questo caso e' giusto cosi')




FOCA Board
Una soluzione a basso costo (meno di 10 euro) e' quello di utilizzare una FOCA Board . Da notare l'orientamento del modulo con l'antenna in direzione della USB (sulla schedina non sono riportate indicazioni molto chiari su quale sia la numerazione dei pin). Importante: prima di connettere la corrente sincerarsi che l'interruttore/selettore bianco sulla Foca Board sia impostato su 3.3 V


XBee Explorer Usb
Simile alla FOCA Board ma decisamente piu' costosa (circa 30 euro) c'e' la XBee Explorer. Le indicazioni dei pin sono molto chiare

Funduino Xbee
Per terminare c'e' il modulo Xbee di Funduino (che sul mercato cinese si trova anche a 5 euro)
Per orientare la Xbee basta seguire il disegno stampato sulla piastra (l'antenna e' dalla parte opposta alla porta USB)


Leggere la porta seriale da Linux

Alcune volte puo' essere utile leggere il flusso da una porta seriale in Linux direttamente da shell senza passare da Minicom o simili

Per esempio si puo' leggere il flusso seriale da una Arduino (che di solito e'configurata come 9600 8N1)
Per prima cosa si devono impostare le giuste configurazione per la porta seriale (una Arduino collegata via USB ad una Linux Box di solito si presenta su /dev/ttyACM0

stty -F /dev/ttyACM0 raw ispeed 9600 ospeed 9600 cs8 -ignpar -cstopb -echo
dopo di cio' e' sufficiente 

cat /dev/ttyACM0

per vedere il flusso dati

venerdì 2 ottobre 2015

Soddisfazioni

Quando un amico/cliente ti manda un SMS come quello sotto riportato ti rendi conto che il tuo lavoro non e' proprio inutile (sorvoliamo sull'italiano....)


giovedì 1 ottobre 2015

Ricevitore GPS per Arduino

Sto lavorando per interfacciare Arduino con un ricevitori GPS e ne ho presi un paio, di prezzo nettamente differente, per delle prove

GY-NEO6MV2per un costo di circa una decina di euro si puo' acquistare il ricevitore GY-NEO6MV2.

Si tratta di un semplice dispositivo con 4 connessioni (VCC 2.7-5V, GND, TX ed RX). Non e' di fatto programmabile ed il modulo trasmette dati sulla seriale (9600, 8N1) in formato NMEA ad 1Hz


Per l'uso con Arduino si puo' usare la libreria TinyGPS

Avendo un cavo FTDI si puo' collegare direttamente il dispositivo al PC leggendo i dati NMEA direttamente in un emulatore di terminale





Adafruit GPS Breakout

Ad un costo di circa 4 volte superiore (40 euro) si puo' trovare il modulo GPS Breakout di Adafruit che risulta essere di un'altra classe rispetto a GY-NEO6MV2.



E' disponibile un piedino per accendere o spengere il dispositivo, e' abilitata la ricezione dei segnali SBAS/EGNOS per il posizionamento DPGS, e' possibile variare il tipo di sentenze ricevute e la velocita' con cui vengono generate (da 100 milliHz a 10 Hz) e la velocita' della seriale.

Per l'uso con Arduino si puo' usare la libreria Adafruit-GPS-Library in cui sono contenuti vari esempi

C'e' da notare un bug nel firmware. Caricando lo sketch echo (che rimanda sulla seriale le stringhe NMEA del dispositivo) compaiono dei caratteri anomali
$PGTOP,11,2*6E
$PGTOP,11,2*6E
questi sono codici di programmazione del modulo MTK3339 e non dovrebbero essere presenti nel flusso NMEA (peraltro non c'e' modo di sopprimerli, si possono eliminare solo in postprocessing)

Il modulo viene riportato per avere una assorbimento di 20 mA in modalita' operativa e dalle mie prove tale valore risulta conforme al teorico

Di seguito il codice Arduino da poter usare con Gps Adafruit con impostata la richiesta della modalita' DPGS

----------------------------------------------------------------------
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>

unsigned long delaytime=250;


SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPS(&mySerial);
#define GPSECHO  true
boolean usingInterrupt = false;
void useInterrupt(boolean);



void setup() {

  Serial.begin(9600);
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
  GPS.sendCommand(PGCMD_ANTENNA);
  //enable DPGS
  GPS.sendCommand(PMTK_ENABLE_SBAS);
  GPS.sendCommand(PMTK_ENABLE_WAAS);

  useInterrupt(true);
  delay(1000);
  mySerial.println(PMTK_Q_RELEASE);
}

SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
#ifdef UDR0
  //if (GPSECHO)
    //if (c) UDR0 = c;
#endif
}

void useInterrupt(boolean v) {
  if (v) {
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();



void loop() {
  if (! usingInterrupt) {
    char c = GPS.read();
    //if (GPSECHO)
      //if (c) Serial.print(c);
  }
  if (GPS.newNMEAreceived()) {
    if (!GPS.parse(GPS.lastNMEA()))
      return;
  }

  if (timer > millis())  timer = millis();

  if (millis() - timer > 1000) {
    timer = millis(); // reset the timer
    //NOME DELLA STAZIONE
    Serial.print("ST01-");
      
    //GPS
    Serial.print(GPS.hour,DEC);
    Serial.print(":");
    Serial.print(GPS.minute,DEC);
    Serial.print(":");
    Serial.print(GPS.seconds,DEC);
    //Serial.print(".");
    //Serial.print(GPS.milliseconds,DEC);
    Serial.print(" ");
    Serial.print(GPS.day, DEC); Serial.print('/');
    Serial.print(GPS.month, DEC); Serial.print("/20");
    Serial.print(GPS.year, DEC);
if (GPS.fix)
    {
    Serial.print("-");
    Serial.print(GPS.latitude,4);
    Serial.print("-");
    Serial.print(GPS.lat);
    Serial.print("-");
    Serial.print(GPS.longitude,4);
    Serial.print("-");
    Serial.print(GPS.lon);
    Serial.print("-");
    Serial.print(GPS.HDOP,4);
    Serial.print("-");
    Serial.print((int)GPS.fixquality);

    Serial.print("-");
    Serial.print((int)GPS.satellites);
    }
    Serial.println();
  }
}

-------------------------------------------
Il modulo puo' essere messo in stato di ibernazione con i comandi
GPS.standby()
GPS.wakeup()

Una Arduino Uno con il modulo GPS attivo consuma circa 20 mA mentre la stessa configurazione con il GPS in ibernazione scende al di sotto dei 10 mA
Ovviamente dopo aver riacceso il modulo, il sistema deve effettuare da zero il Fix GPS (e' quindi consigliabile inserire la batteria tampone per le effemeridi)

Arduino con batteria Lipo e pannello solare


Gia' in precedenza avevo provato ad usare un pannello solare per alimentare Arduino ma stavolta per un progetto piu' serio avevo necessita' di un sistema di alimentazione a batteria ricaricabile a sua volta ricaricata da un pannello solare. La batteria permette di mantenere l'operativita' quando l'irraggiamento solare e' scarso od assente


Ho quindi impiegato un solar charger shield 2.2 (di Seedstudio) accoppiato ad una batteria Lipo da 3000 mAh ed un pannello solare da 100x80 mm da 1 W. Le connessioni sono tutte con JST 2.0
La batteria puo' essere ricaricata sia dal pannello solare che da una connessione microUsb

Lo shield ha anche la possibilita' di connettere il pin A0 per misurare la quantita' di energia residua nella batteria. Cio' si ottiene cortocircuitando due connettori R7 sulla scheda (vicino ad R8 e con a destra la sigla A0)
Piu' semplice a dirsi che a farsi....come si puo' vedere c'e' stata la necessita' di fare un ponticello con un cavo extra (in verde nella foto)


per ottenere il valore in Volt della carica istantanea della batteria si procede con il seguente codice. Da notare che il calcolo del voltaggio sul pin A0 non e' quello standard per passare dal Digital Number al voltaggio per i pin analogici su Arduino (viene inserito un fattore 2 di correzione); questo non  e' un errore ed e' dovuto alla caratteristica dello shield

--------------------------------------------------
const int analogInPin = A0; 
int BatteryValue = 0;
float outputValue = 0; 

void setup() { 
    Serial.begin(9600); 

 void loop() { 
 BatteryValue = analogRead(analogInPin); 
outputValue = (float(BatteryValue)*5)/1023*2; 
Serial.print(" voltage = "); 
Serial.println(outputValue); 
Serial.println("V \n"); 
delay(1000); 
}

--------------------------------------------------
Un breve calcolo per calcolare il tempo di ricarica (dati il pannello solare da 1W/5V e la batteria da 3000 mAh, ovvero 3Ah)

Il pannello eroga 1W/5V = 0.2 A. Per la ricarica si divide 3Ah/0.2A e si ottiene il tempo di ricarica di 15  ore