mercoledì 9 dicembre 2015

Mysql tunnel over SSH

Alcune volte, un po' per passare dati riservati, un po' per bucare firewall non particolarmente permissivi si puo' creare un tunnel SSH per far passare anche informazioni derivanti da altri server. In questo caso si puo' vedere come interagire direttamente con un database MySql nel caso in cui la porta 3306 del server sia filtrata mentre la porta 22 risulta accessibile

In pratica la connessione funziona in questo modo

server Mysql (3306 remota) <-> SSH remoto (22) <-> Internet <-> client locale ssh <->porta locale del tunnel

Linux
Nel caso Linux la procedura per creare un tunnel Mysql over SSH e' piuttosto banale e veloce
Si crea il tunnel con la seguente riga di comando

ssh login@server -L 3306:127.0.0.1:3306 -N &

login e server sono le credenziali del server SSH
in pratica ci si connette con la porta 3306 remota (passando dal tunnel SSH) ed creando una porta 3306 in ascolto. (Ovviamente sulla macchina client non deve essere presente nessun servizio che occupi la porta ... in caso contrario il numero della porta locale puo' essere modificato a piacere)

(importante la & finale per mandare il processo di tunnel in background...in caso si ometta si deve aprire un'altra shell per gestire il collegamento Mysql)

Fatto cio' ci si connette come se il server fosse installato in localhost

mysql -h 127.0.0.1 -p -u user_mysql
(ovviamente le credenziali di Mysql sono quelle dell'host remoto)

Windows
In questo caso il client SSH e' molto piu' spesso Putty. Per creare un tunnel SSH con Putty, dopo aver creato come di norma una sessione, 


si deve andare in Connection/SSH/Tunnels ed impostare 
Source port : 3306
Destination : 127.0.0.1:3306 
Anche in questo caso non deve esserci un altro servizio che occupa la porta 3306 ed in ogni caso la Destination port puo' essere modificata

Di preme Add e la schermata dovrebbe essere identica a quella sottostante


Fatto cio' si puo' aprire MysqlWorkbench e connettersi in localhost per creare una connessione con Mysql remoto

venerdì 4 dicembre 2015

ADXL335 Accelerometro come tiltmetro

In questo post del 2012  avevo usato il componente CMPS10 per avere le indicazione di Yaw, Pitch e Roll.
Con il solo accelerometro (quindi senza una bussola) e' possibile tuttavia avere le informazioni di inclinazione dell'accelerometro in Pitch e Roll (Yaw non e' possibile perche' il calcolo richiede la scomposizione del vettore di accelerazione di gravita' e quindi la rotazione sul piano ortogonale al vettore gravita' non e' registrabile)



Sfruttando questo post ho provato a fare la stessa cosa con un ADXL335

Nel post e' peraltro interessante l'uso di un filtro passa basso.Agendo  sul parametro alpha si puo' ottenere un filtraggio meno (con numeri vicini a 1) o piu' aggressivi (con numeri dell'ordine di 0.1)
A sensore fermo la misura oscilla con filtro a 0.4 di circa +/- 1°
---------------------------------------------------------------------------
const float alpha = 0.5;

double fXg = 0;
double fYg = 0;
double fZg = 0;

double Xg = 0;
double Yg = 0;
double Zg = 0;


void setup()
{
    Serial.begin(9600);
    delay(100);
}

void loop()
{
    double pitch, roll, Xg, Yg, Zg;
    Xg = (analogRead(A5)*(5.0/1023.0))-1.59;
    Yg = (analogRead(A4)*(5.0/1023.0))-1.60;
    Zg = (analogRead(A3)*(5.0/1023.0))-1.67;

    Xg = 9.8*(Xg/0.33);
    Yg = 9.8*(Yg/0.33);
    Zg = 9.8*(Zg/0.33);
   
  
    //Low Pass Filter
    fXg = Xg * alpha + (fXg * (1.0 - alpha));
    fYg = Yg * alpha + (fYg * (1.0 - alpha));
    fZg = Zg * alpha + (fZg * (1.0 - alpha));

    //Roll & Pitch Equations
    roll  = (atan2(-fYg, fZg)*180.0)/M_PI;
    pitch = (atan2(fXg, sqrt(fYg*fYg + fZg*fZg))*180.0)/M_PI;

    Serial.print(pitch);
    Serial.print(":");
    Serial.println(roll);

    delay(100);
}

---------------------------------------------------------------------------

Pi Zero: ne vale la pena??

Grazie ad un amico che la ha acquistata il giorno di uscita, sono riuscito a mettere le mani su una Raspberry Pi Zero. Ma, a parte il prezzo di 5 dollari (la spedizione costa circa 6 volte di piu' che non l'oggetto) vale veramente la pena usare una Pi Zero al posto di una Raspberry B+ per esempio??


Il consumo del dispositivo e' decisamente inferiore ad un Raspberry B (110 mA contro circa il doppio della B...si e' bruciato il punto decimale del misuratore di corrente..si deve leggere 0.11 A)

Sul prezzo c'e' poco da dire, non esistono confronto se non con il futuro Chip (adesso in preordine).
Il problema che per usare una Pi Zero ci si deve munire di almeno un cavo microUsb-USB possibilmente OTG, un HUB Usb per attaccarci tastiera e mouse e un eventuale dongle Ethernet o Wifi (quindi forse e' meglio prendere un HUB alimentato), un non comunissimo cavo HDMI con un connettore standard ed uno in formato miniHDMI

In conclusione un sacco di cavi e cavetti sul tavolo che rendono inutili le dimensioni estremamente ridotte della Pi Zero (avessero messo almeno un Bluetooth ....). Puo' essere interessante come schedina da saldare in un progetto IOT (Internet of Things)... anche se per queste cose preferisco i microcontrollori al posto dei microprocessori ... ma come computer e' molto meglio la PI B+ (anche se molto piu' costosa)

Io nel frattempo ho fatto un preordine per CHIP..........




lunedì 30 novembre 2015

Maratona di Firenze 2015

6° Maratona....stesso sudicio
Anche quest'anno sono stato ripreso in foto andate su giornali on line (firenze.repubblica.it)




Integrazioni dati da accelerometro ADXL335/GY-61

Ho provato ad usare, su suggerimento di un amico, l'accelerometro come misuratore di spostamento.
In estrema sintesi integrando i dati di accelerazione si puo' avere una stima, seppure un po' grossolana, di quanto e' stato spostato il sensore (ovviamente se il sensore viene spostato con velocita' costante questo sistema non funziona)

Il sistema che ho usato e' una schedina GY-61 su cui e' montato un ADXL335 gia' usato altre volte nella versione Sparkfun


Il problema maggiore e' cercare di gestire il rumore dello strumento e la deriva (su quello orginale Sparkfun il modulo non mostra deriva mentre su questo modello cinese la deriva e' presente)

Questo e' lo script per la gestione del calcolo dello spostamento su due assi (x,y); l'asse z ha una sensibilita' differente a quella su x ed y e diventa difficile fare misure accurate

Per prima cosa viene convertito il valore delle porte analogiche in accelerazione in m/s2 togliendo l'offset per avere una misura piu'possibile vicina a zero in condizioni statiche
Successivamente viene integrata la velocita' ed in seguito lo spostamento (vedi questo link per una spiegazione piu' dettagliata)
L'integrazione avviene mediando il valore della accelerazione tra il valore attuale e quello precedente e moltiplicando per il delta di tempo (qui impostato a 0.05 secondi)
Succesivamente si passa allo spostamento sui due assi e calcolando quindi la risultante dello spostamento sui due assi

Il calcolo viene effettuato solo se viene superato un valore di trigger in modo da evitare di registrare tutto il rumore
ATTENZIONE : questo calcolo funziona solo per moti su superfici orizzontali. In caso contrario viene registrata anche una componente della accelerazione di gravita' per cui i dati sono falsati
--------------------------------------------------------------------------
unsigned long time, old_time;
int x,y,z;
float xx,yy,zz,ax,ay;
float old_ax,old_ay,old_vx,old_vy; //
float vx,vy,av_ax,av_ay,av_vx,av_vy; //valori medi di acc e vel sui due assi
float dx,dy,old_dx,old_dy; //spostamento
float delta_time;
float risultante;

void setup() {
  Serial.begin(115200);
  old_ax=0;
  old_ay=0;
  old_vx=0;
  old_vy=0;
  old_dx=0;
  old_dy=0;
  av_ax=0;
  av_ay=0;
  av_vx=0;
  av_vy=0;
}

void loop() {
  //z = analogRead(A3);
  y = analogRead(A4);
  x = analogRead(A5);
  //zz = z * (5.0 / 1023.0);
  yy = y * (5.0 / 1023.0)-1.67;
  xx = x * (5.0 / 1023.0)-1.61;
 
  ax = 9.8*(xx/0.33);
  ay = 9.8*(yy/0.33);

  //toglie offset
  ax = ax + 0.06;
  ay = ay + 0.68 ;
 
if ((ax-old_ax) > 0.3)
  {
  //time = millis();
  //delta_time = (time - old_time)/1000;
  delta_time = 0.05;
 
  //calcolo dell'accelerazione media
  av_ax = (ax+old_ax)/2;
  av_ay = (ay+old_ay)/2;

  //calcolo della velocita'
  vx = old_vx + (av_ax * delta_time);
  vy = old_vy + (av_ay * delta_time);

  // calcolo della velocita' media
  av_vx = (vx+old_vx)/2;
  av_vy = (vy+old_vy)/2;

  // spostamento
  dx = old_dx + (av_vx * delta_time);
  dy = old_dy + (av_vy * delta_time);

  // risultante
  risultante = sqrt((dx*dx)+(dy*dy));

  Serial.print(ax);
  Serial.print(";");
  Serial.print(ay);
  Serial.print(";");
  Serial.print(vx);
  Serial.print(";");
  Serial.print(vy);
  Serial.print(";");
  Serial.print(dx);
  Serial.print(";");
  Serial.print(dy);
  Serial.print(";");
  Serial.println(risultante);
  }

  delay(50);
  //old_time = time;

  //scambio delle variabili
  old_dx = dx;
  old_dy = dy;
  old_vx = vx;
  old_vy = vy;
  old_ax = ax;
  old_ay = ay;
}

--------------------------------------------------------------------------

giovedì 26 novembre 2015

Primi passi con Octave

Durante il dottorato ho avuto il modo di utilizzare (a livello decisamente base) Matlab apprezzandone la sintassi compatta. Purtroppo non ho piu' disponibilita' della licenza universitaria e quindi ho deciso di provare Octave, una versione open source simile a Matlab (anche se chi lavora in modo serio con Matlab mi dice che Octave e' ancora ad anni luce di distanze per alcune funzionalita')

L'aspetto interessante e' che con la versione 3.8 e' stata implementata una GUI simile a Matlab (prima si lavorava praticamente a linea di comando da shell)

Il programma e' stato compilato da sorgenti su Centos 6
Le dipendenze sono
yum install gcc gcc-c++ kernel-devel make mercurial libtool libtool-ltdl-devel libtool-ltdl autoconf cmake lapack-devel \ lapack pcre-devel readline-devel readline fftw-devel glpk-devel suitesparse suitesparse-devel gnuplot libcurl-devel zlib-devel \ flex texlive gperf fltk-devel qhull-devel hdf5-devel gl2ps-devel qrupdate-devel arpack-devel qscintilla-devel llvm-devel qt-devel \ bison ghostscript-devel librsvg2-tools icoutils readline pcre
Dopo la compilazione (un po' lunghina per la verita' ...ma la mia macchina e' un po' vecchiotta) si lancia il programma con

octave --force-gui



Questo e' uno script base su Octave che dovrebbe funzionare senza troppi problemi su Octave
----------------------------------------------------------------------------
clear all
close all
echo off

function rad = radians(degree)
    rad = degree .* pi / 180;
end;

function [a,c,dlat,dlon]=haversine(lat1,lon1,lat2,lon2)
    dlat = radians(lat2-lat1);
    dlon = radians(lon2-lon1);
    lat1 = radians(lat1);
    lat2 = radians(lat2);
    a = (sin(dlat./2)).^2 + cos(lat1) .* cos(lat2) .* (sin(dlon./2)).^2;
    c = 2 .* asin(sqrt(a));
    #arrayfun(@(x) printf("distance: %.8f m\n",6372800 * x), c);
end;

[volt,lat,lon,quota]=textread("tetto_6_11_ridotto.csv", "%u;%u;%u;%u");
mlat = mean(lat);
mlon = mean(lon);
minlat = min(lat);
maxlat = max(lat);
minlon = min(lon);
maxlon = max(lon);
stdlat = std(lat);
stdlon = std(lon);
[r,c] = size(lat);
fprintf("Media Lat: %d\n",mean(lat));
fprintf("Media Lon: %d\n",mean(lon));
fprintf("Std Lat: %d\n",std(lat));
fprintf("Std Lon: %d\n",std(lon));
fig = figure;
plot(lat,lon);
axis([minlat maxlat minlon maxlon]);
title('Originali')
print(fig,'gps','-dpng');
centro = centroid(lat,lon);
fprintf("Centroide %d %d\n",centro);
#plot(volt)
#print(fig,'volt','-dpng')
disp ("-----------------")
mlat = double(mlat)/10000000.0
mlon = double(mlon)/10000000.0
#fprintf("MLat: %f\n",mlat);

ripuliti = zeros(r,2);
indice = 1;

for n = 1:r
  #fprintf("MLat: %f\n",mlat);
  #fprintf("MLon: %f\n",mlon);
  #fprintf("Lat: %f\n",double(lat(n))/10000000.0);
  #fprintf("Lon: %f\n",double(lon(n))/10000000.0);
  [a,c,dlat,dlon] = haversine(mlat,mlon,double(lat(n))/10000000.0,double(lon(n))/10000000.0);
  #fprintf("Distanza %i :%f\n",n,double(c)*6378160.0);
  if (c*6378160.0) < 5.0
        ripuliti(indice,1) = double(lat(n))/10000000.0;
        ripuliti(indice,2) = double(lon(n))/10000000.0;
        indice = indice + 1;
        end
end

fig2 = figure;
plot(ripuliti(1:indice-1,1),ripuliti(1:indice-1,2))
axis([double(minlat)/10000000.0 double(maxlat)/10000000.0 double(minlon)/10000000.0 double(maxlon)/10000000.0]);
title("Filtrati")
mflat = mean(ripuliti(1:indice-1,1));
mflon = mean(ripuliti(1:indice-1,2));
devflat = std(ripuliti(1:indice-1,1));
devflon = std(ripuliti(1:indice-1,2));

fprintf("Media Filtrata Lat: %.7f\n",mflat);
fprintf("Media Filtrata Lon: %.7f\n",mflon);
fprintf("DevSt Filtrata Lat: %.7f\n",devflat);
fprintf("DevSt Filtrata Lon: %.7f\n",devflon);
----------------------------------------------------------------------------


Octave ha un corrispettivo dei toolbox di Matlab, ovvero di pacchetti di estensioni dei comandi che possono essere scaricati, a seconda delle necessita' da Octave Forge
Se per esempio si vuole leggere/scrivere una porta seriale si deve scaricare il pacchetto instrument control in formato tar.gz e si installa con il comando

pkg install instrument-control-0.2.1.tar.gz

Di seguito un semplice esempio per leggere i dati seriali (da Arduino). Per far utilizzare la porta seriale ad un normale utente, quest'ultimo deve essere aggiunto al gruppo dialout (adduser luca dialout)
----------------------------------------------------------------------------
#! /usr/local/bin/octave -qf
pkg load instrument-control
s1 = serial("/dev/ttyACM0");
srl_flush(s1);
get(s1);
set(s1,"baudrate",9600);
set(s1,"bytesize",8);
set(s1,"parity",'N');
set(s1,"stopbits",1);
get(s1);
while true
   valore = srl_read(s1,6);
   char(valore)
   pause(1);
endwhile
srl_close(s1)



----------------------------------------------------------------------------

Per quanto riguarda la connettivita' con i database la versione attuale si interfaccia solo con PostgreSql mediante il pacchetto database 

pkg install database-2.3.2.tar.gz
(deve essere installato il pacchetto devel di postgresql, esempio ripreso da qui. Prima di arrivare ad una connessioni con Postgres c'e' un post da smanettare con la configurazione del server, in particolare con il file pg_hba.conf)

----------------------------------------------------------------------------
pkg load database
conn = pq_connect (setdbopts ("dbname", "test")); 
pq_exec_params (conn, "create table testtable (t text, i int2, b bytea);") 
pq_exec_params (conn, "insert into testtable values ($1, $2, $3);", {"name1", 1, uint8([2, 4, 5])}) 
 pq_exec_params (conn, "select * from testtable;")
 pq_exec_params (conn, "drop table testtable;")
 pq_close (conn);
----------------------------------------------------------------------------


I programmi in Octave possono essere lanciati anche all'esterno dell'ambiente di sviluppo rendendo eseguibile il file .m ed inserendo il testa al file .m la riga
#!/usr/local/bin/octave -qf


Newrez su Centos 6

Un po' per pigrizia utilizzo lo script newrez (gia' descritto qui) per avere una risoluzione personalizzata su portatili un po' vecchiotti (1024x768 oramai e' un po' troppo riduttiva come risoluzione

Attualmente ho montato una Centos 6 su un ToughBook ed ho scoperto che lo script non funziona.
La cosa e' facilmente risolvibile eseguendo il comando xrandr
Newrez si aspetta di dover gestire LVDS1 e VGA1 mentre su Centos lo schermo del portatile viene chiamato LVDS-0

-------------------------------------------------------------------------
Screen 0: minimum 320 x 200, current 1600 x 1000, maximum 4096 x 4096
LVDS-0 connected 1600x1000+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
   1024x768       60.0*+
   800x600        60.3     56.2 
   640x480        59.9 
VGA-0 disconnected (normal left inverted right x axis y axis)
   1600x1000      59.9 
TV-0 unknown connection (normal left inverted right x axis y axis)
   848x480        59.9 +
   640x480        59.9 +
   1024x768       59.9 
   800x600        59.9 
-----------------------------------------------------------------------------

basta modificare lo script e tutto torna a funzionare (certo che 1600x1000 su uno schermo da 10 pollici e' un po' troppo per gli occhi)
------------------------------------------------------------
#!/bin/bash

# newrez

# Marc Brumlik, Tailored Software Inc, tsi-inc@comcast.net

# up to v 0.8
# use 'xrandr' to scale video output to the display

# v 0.9
# Wed Jan  2 05:23:54 CST 2013
# rewrite to handle mouse boundaries when scaled (mouse confined)
# by setting requested resolution to the unused VGA-0 device
# then scaling that for display on the LVDS-0 device

# v 1.1
# Fri Dec 20 08:28:08 CST 2013
# fixed issue where setting to "default" after some other resulution
# left mouse-area at prior resolution

umask 000

# resolution can optionally be specified on command line
newrez=$1

# we MUST be running xrandr 1.3 or higher
if xrandr -v | grep "RandR version 1.[012]"
    then    zenity --info --title="XRandR version is too old" --text="You must be running Xrandr
version 1.3 or newer!
Time to upgrade your system  :-)"
        exit 0
fi

# find the currently connected devices, make a list
devices=`xrandr -q | grep connected | grep -v disconnected | cut -d"(" -f1`

# there MUST be a "connected" LVDS-0 and a "disconnected" VGA-0
current=`xrandr -q`

if echo "$current" | grep "LVDS-0 connected" >/dev/null
    then    : OK
    else    zenity --info --title="PROBLEM" --text="Current display must be LVDS-0"; exit 0
fi
if echo "$current" | grep "VGA-0 disconnected" >/dev/null
    then    : OK
    else    zenity --info --title="IMPORTANT" --text="The VGA-0 display resolution may be affected by this change"
fi

default=`echo "$current" | grep -A 1 "^LVDS-0" | tail -1 | awk '{print $1}'`
H=`echo $default | cut -d'x' -f1`
V=`echo $default | cut -d'x' -f2`
HZ=`echo $default | awk '{print $2}' | tr -d '[*+]'`

# echo DEFAULT: $default $H $V

if [ -z "$newrez" ]
    then    while true
        do
            newrez=`zenity --entry --title="Set New Resolution" \
                --text="Default Resolution: $default\n\nNew size (eg 1280x750 or 1450x1000)\n   -or- \"default\""` || exit 0
            case $newrez in
                default|[0-9]*x[0-9]*)    break ;;
            esac
        done
fi

case $newrez in
    default)    xrandr --output LVDS-0 --mode $default --scale 1x1
            xrandr --addmode VGA-0 $default
            xrandr --newmode $default $newmode
            xrandr --output VGA-0 --mode $default --scale 1x1
            exit 0 ;;
esac

newH=`echo $newrez | cut -d'x' -f1`
newV=`echo $newrez | cut -d'x' -f2`
modeline=`cvt $newH $newV $HZ | grep Modeline`
newmode=`echo "$modeline" | sed 's/^.*"//'`
cvtrez=`echo "$modeline" | sed -e 's/_.*//' -e 's/^.*"//'`

if [ "$newrez" != "$cvtrez" ]
    then    newrez=$cvtrez
        newH=`echo $newrez | cut -d'x' -f1`
        newV=`echo $newrez | cut -d'x' -f2`
fi

scaleH=`echo -e "scale=10\n$newH / $H\nquit" | bc`
scaleV=`echo -e "scale=10\n$newV / $V\nquit" | bc`

if echo "$current" | grep -A 100 "^VGA-0" | grep $newrez >/dev/null
    then    : already there
    else    xrandr --newmode "$newrez" $newmode
        xrandr --addmode VGA-0 $newrez
fi

if xrandr --output VGA-0 --mode $newrez --output LVDS-0 --fb $newrez --scale $scaleH"x"$scaleV 2>&1 | tee -a /tmp/xrandr.err
    then    : success
    else    zenity --info --title="Xrandr produced this error" --text="`cat /tmp/xrandr.err`"

The problem could be that Your video driver
does not support xrandr version 1.3
        rm -f /tmp/xrandr.err
fi

Aruco Tag e filtri Kalman

Usando gli Aruco tag in ambiente esterno con illuminazione solare a diverse ore e in diversi periodi dell'anno ho trovato un errore nell...