Avendo preso un MacBook da 13 (soprattutto per problemi di peso e venendo dal 15) mi sono trovato ad avere uno schermo piu' piccolo dell'usuale.
Per questo motivo ho provato ad estendere il monitor provando i programmi che usano lo schermo dell'Ipad come estensione del portatile
Vi sono molte soluzioni a pagamento sia con connessione wifi che con connessione mediante cavo lightning (quest'ultima mi sembrava la migliore fino a quando non ho scoperto che l'Ipad non si ricarica mentre e' in modalita' dual monitor) ma a fronte di recensioni non tutte positive non ho voluto spendere una decina di euro per una prova
Mi sono orientato quindi verso l'unico software che permette una demo ovvero VtDisplay Lite.
Si devono montare sul portatile e sull'Ipad (che devono esssere agganciati alla stessa wifi) i rispettivi programmi e poi si effettua la connessione
Le impressioni d'uso non sono molto positive, c'e' un sensibile (e fastiidoso ritardo) del mouse quando ci si sposta sul monitor Ipad. Puo' essere una soluzione utile in caso di necessita' (vedi mancanza di secondo monitor fisico collegato via thunderbolt) e solo nel caso di tenere qualcosa da leggere sull'ipad (tipo un manuale) mentre si usa il portatile per lavorare ma diciamo che se avessi comprato il software me ne sarei sostanzialmente pentito
mercoledì 31 dicembre 2014
SismoArduino
Dopo i recenti terremoti vicino a Firenze mi e' tornata la voglia di lavorare ad un progetto che avevo in mente da tempo e che con somma fantasia ho denominato SismoArduino. Si tratta di un progetto da un giorno ovvero che non risolve in 10 minuti collegando 4 fili ma che non necessita comunque troppo impegno
Per questo progettino ho tirato fuori l'Arduino Uno (la scelta e' stata obbligata perche' Arduino Due non entra fisicamente nella scatola da esterni in cui alla fine deve essere alloggiato il tutto per metterlo in produzione), uno shield Ethernet originale Arduino e un accelerometro triassiale ADXL335
Per comodita' ho piegato il pin ST in modo da fare contatto ed ho poi inserito i pin Z,Y e X nelle porte A3,A4 ed A5 patchando poi al volo i cavi di alimentazione (collegati a 3.3V e GND)
Lo sketch montato su Arduino semplicemente legge i dati sulle porte analogiche e poi invia una stringa mediante UDP client ad un server
(Arduino e' 192.168.1.177 mentre il server e' 192.168.1.120 in ascolto su porta 5005)
-----------------------------------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
//Arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888;
//Server
byte remoteIP[4] = {192, 168, 1, 120};
int remotePort = 5005;
String dati;
char charBuf[1024];
EthernetUDP Udp;
void setup() {
Serial.begin(9600);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
}
void loop() {
int x = analogRead(A5);
delay(2);
int y = analogRead(A4);
delay(2);
int z = analogRead(A3);
delay(2);
dati = String(x)+","+String(y)+","+String(z);
Serial.println(dati);
dati.toCharArray(charBuf, 1024);
Udp.beginPacket(remoteIP, remotePort);
Udp.write(charBuf);
Udp.endPacket();
delay(10);
}
-----------------------------------------------------------------------
Sul server e' stato messo uno script Python che riceve i dati con un server UDP e li scrive su un database Mysql
-----------------------------------------------------------------------
import socket
import MySQLdb as mdb
import time
current_milli_time = lambda: int(round(time.time()*1000))
con = mdb.connect('localhost','root','chiara','sismoarduino')
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind(("192.168.1.120",5005))
while True:
data,addr=sock.recvfrom(1024)
with con:
cur = con.cursor()
cur.execute("INSERT INTO sisard (x1,y1,z1,milli,tempo) VALUES ("+data+","+str(current_milli_time())+",now())")
print data
Per la tabella Mysql c'e' un piccolo trucco. Mysql non accetta in modo semplice il formato tempo con i millisecondi. Per cui e' stato creato un campo milli come BIGINT dove e' registrato il tempo completo con i millisecondi ed un campo tempo come DATETIME per il lettore umano
-----------------------------------------------------------------------
CREATE TABLE `sisard` (
`x1` int(11) DEFAULT NULL,
`y1` int(11) DEFAULT NULL,
`z1` int(11) DEFAULT NULL,
`milli` bigint(20) DEFAULT NULL,
`tempo` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
------------------------------------------------------------------------
La presentazione dei dati e' effettuata in tempo reale mediante un lettore fatto con le librerie Dygraph
I dati per la presentazione a video vengono generati dal seguente scritp php (in pratica viene generato al volo un CSV che viene dato in pasto a DyGraph
------------------------------------------------------------------------
$output = fopen('php://output', 'w');
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'chiara';
$dbdb = 'sismoarduino';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbdb);
$result = mysql_query("SELECT * FROM sisard ORDER BY milli DESC LIMIT 1000");
while ($row = mysql_fetch_array($result)) {
$arr[0] = $row['milli'];
//$arr[0]=date("d-m-Y H:i:s",$row['milli']/1000);
$arr[1] = $row['x1'];
$arr[2] = $row['y1'];
$arr[3] = $row['z1'];
fputs($output,implode($arr,',')."\n");
}
mysql_close($conn);
?>
E questa e' la pagina html che ospita Dygraph con aggiornamento automatico ogni secondo (la finestra e' degli ultimi 1000 dati
------------------------------------------------------------------------
<head>
<script type="text/javascript"
src="http://localhost/dygraph-combined.js"></script>
</head>
<body>
<div id="graphdiv2"
style="width:500px; height:300px;"></div>
<br>
<script type="text/javascript">
g2 = new Dygraph(
document.getElementById("graphdiv2"),
"http://localhost/sismodati.php",
{title: 'SismoArduino'} // options
);
var update = function(){
g2.updateOptions({'file': 'http://localhost/sismodati.php'});
};
window.setInterval(update,1000);
</script>
</body>
</html>
------------------------------------------------------------------------
Per questo progettino ho tirato fuori l'Arduino Uno (la scelta e' stata obbligata perche' Arduino Due non entra fisicamente nella scatola da esterni in cui alla fine deve essere alloggiato il tutto per metterlo in produzione), uno shield Ethernet originale Arduino e un accelerometro triassiale ADXL335
Per comodita' ho piegato il pin ST in modo da fare contatto ed ho poi inserito i pin Z,Y e X nelle porte A3,A4 ed A5 patchando poi al volo i cavi di alimentazione (collegati a 3.3V e GND)
Lo sketch montato su Arduino semplicemente legge i dati sulle porte analogiche e poi invia una stringa mediante UDP client ad un server
(Arduino e' 192.168.1.177 mentre il server e' 192.168.1.120 in ascolto su porta 5005)
-----------------------------------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
//Arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888;
//Server
byte remoteIP[4] = {192, 168, 1, 120};
int remotePort = 5005;
String dati;
char charBuf[1024];
EthernetUDP Udp;
void setup() {
Serial.begin(9600);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
}
void loop() {
int x = analogRead(A5);
delay(2);
int y = analogRead(A4);
delay(2);
int z = analogRead(A3);
delay(2);
dati = String(x)+","+String(y)+","+String(z);
Serial.println(dati);
dati.toCharArray(charBuf, 1024);
Udp.beginPacket(remoteIP, remotePort);
Udp.write(charBuf);
Udp.endPacket();
delay(10);
}
-----------------------------------------------------------------------
-----------------------------------------------------------------------
#!/usr/bin/python
import socket
import MySQLdb as mdb
import time
current_milli_time = lambda: int(round(time.time()*1000))
con = mdb.connect('localhost','root','chiara','sismoarduino')
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind(("192.168.1.120",5005))
while True:
data,addr=sock.recvfrom(1024)
with con:
cur = con.cursor()
cur.execute("INSERT INTO sisard (x1,y1,z1,milli,tempo) VALUES ("+data+","+str(current_milli_time())+",now())")
print data
-----------------------------------------------------------------------
-----------------------------------------------------------------------
CREATE TABLE `sisard` (
`x1` int(11) DEFAULT NULL,
`y1` int(11) DEFAULT NULL,
`z1` int(11) DEFAULT NULL,
`milli` bigint(20) DEFAULT NULL,
`tempo` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
------------------------------------------------------------------------
La presentazione dei dati e' effettuata in tempo reale mediante un lettore fatto con le librerie Dygraph
I dati per la presentazione a video vengono generati dal seguente scritp php (in pratica viene generato al volo un CSV che viene dato in pasto a DyGraph
------------------------------------------------------------------------
<?php header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');$output = fopen('php://output', 'w');
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'chiara';
$dbdb = 'sismoarduino';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbdb);
$result = mysql_query("SELECT * FROM sisard ORDER BY milli DESC LIMIT 1000");
while ($row = mysql_fetch_array($result)) {
$arr[0] = $row['milli'];
//$arr[0]=date("d-m-Y H:i:s",$row['milli']/1000);
$arr[1] = $row['x1'];
$arr[2] = $row['y1'];
$arr[3] = $row['z1'];
fputs($output,implode($arr,',')."\n");
}
mysql_close($conn);
?>
------------------------------------------------------------------------
------------------------------------------------------------------------
<html>
<META HTTP-EQUIV="refresh" CONTENT="900"><head>
<script type="text/javascript"
src="http://localhost/dygraph-combined.js"></script>
</head>
<body>
<div id="graphdiv2"
style="width:500px; height:300px;"></div>
<br>
<script type="text/javascript">
g2 = new Dygraph(
document.getElementById("graphdiv2"),
"http://localhost/sismodati.php",
{title: 'SismoArduino'} // options
);
var update = function(){
g2.updateOptions({'file': 'http://localhost/sismodati.php'});
};
window.setInterval(update,1000);
</script>
</body>
</html>
------------------------------------------------------------------------
il passo di campionamento misurato e' stato di circa 15-16 campioni al secondo (15 Hz) che non sono assolutamente paragonabili a strumenti professionali (i sismografi reali hanno passi di campionamento che vanno da 50 a 100 Hz)
Qui il video della prova
Qui il video della prova
L'aspetto finale e' da sottolineare e' che il server (di recupero) impiegato e' stato un P3 a 700 Mhz con 128 Mb di ram con Debian Wheezy, Apache, Php, Mysql e Xwindow in funzione ed ha comunque funzionato dignitosamente
venerdì 26 dicembre 2014
IBeacon ed IOS8
In estate avevo scritto una piccola applicazione per IBeacon
E' passata l'estate e l'autunno ma sono rimasto fedele a IOS 7 e OS X 10.9 perche' i sistemi operativi troppo recenti sono sempre fonti di problemi; in questi giorni mi sono pero' convinto a passare ad IOS 8.1.2 sul telefono ed a OSX 10.10 sul portatile
La sorpresa e' venuta quando sono arrivato a compilare ed eseguire il codice per IBeacon che precedemente funzionava perfettamente. Nonostante non ci fossero errori di compilazione ne' errori di esecuzione il programma semplicemente aveva smesso di riconoscere i beacons vicini
Dopo un paio di giorni a battere il capo sul muro sono arrivato su questo link in cui si segnala che con l'arrivo di IOS 8 si devono aggiungere un paio di stringhe un info.plist del progetto
-----------------------------------------
<key>NSLocationAlwaysUsageDescription</key>
E' passata l'estate e l'autunno ma sono rimasto fedele a IOS 7 e OS X 10.9 perche' i sistemi operativi troppo recenti sono sempre fonti di problemi; in questi giorni mi sono pero' convinto a passare ad IOS 8.1.2 sul telefono ed a OSX 10.10 sul portatile
La sorpresa e' venuta quando sono arrivato a compilare ed eseguire il codice per IBeacon che precedemente funzionava perfettamente. Nonostante non ci fossero errori di compilazione ne' errori di esecuzione il programma semplicemente aveva smesso di riconoscere i beacons vicini
Dopo un paio di giorni a battere il capo sul muro sono arrivato su questo link in cui si segnala che con l'arrivo di IOS 8 si devono aggiungere un paio di stringhe un info.plist del progetto
-----------------------------------------
<key>NSLocationAlwaysUsageDescription</key>
<string>Messaggio Utente</string>
-----------------------------------------
oppure
-----------------------------------------
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your message goes here</string>
oppure
-----------------------------------------
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your message goes here</string>
-----------------------------------------
effettuate queste modifiche il programma ha ricominciato a funzionare (e' in questi momenti che amo la programmazione :<<<<
effettuate queste modifiche il programma ha ricominciato a funzionare (e' in questi momenti che amo la programmazione :<<<<
mercoledì 24 dicembre 2014
Fallita migrazione Mac2Mac con Assistente Migrazione
Ieri mi sono trovato per la prima volta a fare una migrazione di dati ed impostazioni tra un vecchio MacBook A1286 verso un nuovo A1278. Considerando che entrambi i sistemi montano 10.10 e che disponevo di un backup di Time Machine, ho sfoderato Assistente di Migrazione ed ho aspettato un paio di ore
sudo find / -type f -size +500M
i file sono stati effettivamente copiati in una directory temporanea /private/var/folders (piu' caratteri casuali)
Dopo tre prove fallite di Assistente di Migrazione la soluzione e' stata quella di cancellare tutti i file presenti e copiare a mano tutto quanto dal Finder (....just works :<<<)
Al termine della barra ho visto che l'indicatore era bloccato sulla scritta "Due minuti al termine"; fiducioso ho lasciato che il computer continuasse ma dopo altre due ore era tutto bloccato ed il led del disco esterno mi segnalava che non era piu' il caso di aspettare perche' non c'era attivita' di trasferimento dati
Riacceso il computer ho trovato che era stato creato il nuovo utente ma all'interno del profilo non c'erano le impostazione personalizzate e nemmeno i dati. Ma cosa aveva fatto per tutto il tempo il calcolatore?? Dopo un controllo sullo spazio disco era chiaro che i dati erano stati copiati da qualche parte ma non erano accessibili in modo semplice. Da terminale ho quindi cercato i file piu' grandi di 500 Mb (nelle cartelle copiate c'erano dei video)
Mandando un find su tutto il disco
Dopo tre prove fallite di Assistente di Migrazione la soluzione e' stata quella di cancellare tutti i file presenti e copiare a mano tutto quanto dal Finder (....just works :<<<)
TextToSpeech su Browser
Per una installazione didattica avevo bisogno di un lettore per un testo su una pagina web. Non considerando l'ipotesi di un lettore umano ho voluto provare i sistemi (sperimentali) di TextToSpeech che prendono un generico testo ed inviano l'audio di quanto letto in automatico
Il codice per generare e' il seguente (Il testo e' tratto dall'introduzione dalle Lecture on Physics di Feynman)
---------------------------------------------
<html>
<head>
<title>TTS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function() {
var u1 = new SpeechSynthesisUtterance();
u1.text = $('div').html();
u1.lang = 'en-US';
u1.pitch = 2;
u1.rate = 0.5;
u1.voiceURI = 'native';
u1.volume = 0.5;
speechSynthesis.speak(u1);
});
</script>
<div id="demo_div">
This two-year course in physics is presented from the point of view that you, the reader, are going to be a physicist. This is not necessarily the case of course, but that is what every professor in every subject assumes! If you are going to be a physicist, you will have a lot to study: two hundred years of the most rapidly developing field of knowledge that there is. So much knowledge, in fact, that you might think that you cannot learn all of it in four years, and truly you cannot; you will have to go to graduate school too!
</div>
con Chrome la lettura e' molto buona ma viene troncata a circa meta' testo (tutto il lavoro e' fatto in remoto dai server di Google che leggono il testo, lo processano e mandano indietro un file audio....ad occhio c'e' impostato un tempo limite) mentre in Safari e' decisamente ridicola
Un'altra soluzione, costosa ma non poi cosi' tanto visti i risultati, e' data da GSpeech, un plugin per Joomla e Wordpress che surclassa decisamente le Api di TTS con un testo senza limiti di tempo e con una intonazione non piatta ma basata sulla punteggiatura (atttenzione audio basso)
Il codice per generare e' il seguente (Il testo e' tratto dall'introduzione dalle Lecture on Physics di Feynman)
---------------------------------------------
<html>
<head>
<title>TTS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function() {
var u1 = new SpeechSynthesisUtterance();
u1.text = $('div').html();
u1.lang = 'en-US';
u1.pitch = 2;
u1.rate = 0.5;
u1.voiceURI = 'native';
u1.volume = 0.5;
speechSynthesis.speak(u1);
});
</script>
<div id="demo_div">
This two-year course in physics is presented from the point of view that you, the reader, are going to be a physicist. This is not necessarily the case of course, but that is what every professor in every subject assumes! If you are going to be a physicist, you will have a lot to study: two hundred years of the most rapidly developing field of knowledge that there is. So much knowledge, in fact, that you might think that you cannot learn all of it in four years, and truly you cannot; you will have to go to graduate school too!
</div>
---------------------------------------------
e di seguito il video del risultato
Un'altra soluzione, costosa ma non poi cosi' tanto visti i risultati, e' data da GSpeech, un plugin per Joomla e Wordpress che surclassa decisamente le Api di TTS con un testo senza limiti di tempo e con una intonazione non piatta ma basata sulla punteggiatura (atttenzione audio basso)
Firefox e Youtube. Plugin should be updated
Su Firefox del computer di mia moglie (Windows XP) e' comparso improvvisamente il messaggio che il plugin di Flash deve essere aggiornato
Considerando che questo plugin e' quello impiegato per visualizzare i video di Youtube, il bambino non poteva piu' vedere i suoi cartoni animati e cio' e' male
Tentando di aggiornare i plugin di Firefox sono andato in Strumenti/Componenti Aggiuntivi/Plugin in cui erano segnalati dei plugin obsoleti da aggiornare ma niente di relativo a Flash
Dopo una buona mezz'ora a cercare di capire dove era il problema ho trovato che l'unica soluzione possibile era l'aggiornamento manuale dal sito di Adobe all'indirizzo http://get.adobe.com/it/flashplayer/
Considerando che questo plugin e' quello impiegato per visualizzare i video di Youtube, il bambino non poteva piu' vedere i suoi cartoni animati e cio' e' male
Tentando di aggiornare i plugin di Firefox sono andato in Strumenti/Componenti Aggiuntivi/Plugin in cui erano segnalati dei plugin obsoleti da aggiornare ma niente di relativo a Flash
Dopo una buona mezz'ora a cercare di capire dove era il problema ho trovato che l'unica soluzione possibile era l'aggiornamento manuale dal sito di Adobe all'indirizzo http://get.adobe.com/it/flashplayer/
martedì 16 dicembre 2014
Evadere da un proxy server (3)
Questo post e' la continuazione dei due precedenti post (1 e 2)
il mio proxy server aziendale, oltre ad effettuare il vero e proprio lavoro di proxy, effettua anche una scansione dei contenuti ed evita la navigazione su una serie di siti che considera non adatti ad un ambiente lavorativo (ancora devo scoprire il motivo perche' fa passare Facebook ma lasciamo perdere......)
Il problema e' che nella rete del blocco del filtro cascano siti legittimi e legati all'attivita' lavorativa come per esempio il sito dell'Ordine dei Geologi della Toscana (viene classificato come Disease Vector anche se non e' vero)
Ho scoperto quasi per caso che il proxy server puo' essere attraversato dalle connessioni su reti TOR. Utilizzando il Tor Browser Bundle (configurato per utilizzare il proxy aziendale) si puo' raggiungere tranquillamente il sito filtrato (nella foto sopra si puo' osservare la pagina di Chrome con sovrapposta Firefox tramite TOR) visto che tutto il contenuto della connessione e' criptato e quindi non puo' essere analizzato
Quindi ancora una volta e' stato possibile evadere dal proxy, con mezzi peraltro banali
il mio proxy server aziendale, oltre ad effettuare il vero e proprio lavoro di proxy, effettua anche una scansione dei contenuti ed evita la navigazione su una serie di siti che considera non adatti ad un ambiente lavorativo (ancora devo scoprire il motivo perche' fa passare Facebook ma lasciamo perdere......)
Il problema e' che nella rete del blocco del filtro cascano siti legittimi e legati all'attivita' lavorativa come per esempio il sito dell'Ordine dei Geologi della Toscana (viene classificato come Disease Vector anche se non e' vero)
Quindi ancora una volta e' stato possibile evadere dal proxy, con mezzi peraltro banali
Iscriviti a:
Post (Atom)
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...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...