Un piccolo riassunto sulle applicazioni che ho pubblicato sul Play Store
Di queste Geocompass, Soil Color Chart e Well Drawdown Test non sono state pubblicizzate in nessun modo ma in ogni caso sono state individuate dagli utenti e sono anche (diciamo) gradite
Nel periodo di maggior interesse il rapporto tra numero di installazioni e numero di download era di circa il 40-50% ovvero circa la meta' degli utenti che la aveva provata continuava ad utilizzarla. Con il tempo, dato che le applicazioni non sono mantenute ed aggiornate, sono arrivate nuove app piu' interessanti e gli utenti si sono spostati su altri sviluppatori
mercoledì 10 luglio 2013
martedì 9 luglio 2013
Mandelbrot in Go
Era da un po' di tempo che mi stuzzicava l'idea di provare il linguaggio Go di Google (vedi precedente post) e questa volta ci ho riprovato scrivendo il codice per Mandelbrot da solo senza utilizzare script gia' fatti
Come si puo' vedere ci sono riuscito ma ci sono un paio di considerazioni
al di la' del fatto se Go sia destinato all'oblio (come alcuni progetti di Google) o diventera' lo standard del futuro (personalmente propendo per la prima ipotesi .. ma di solito sbaglio) il linguaggio e' particolarmente ostico per un principiante
---------------------------------------------------------------
package main
import (
"image"
"image/png"
"image/color"
"log"
"os"
)
func main() {
var SCREEN_WIDTH int = 400
var SCREEN_HEIGHT int = 400
var re_min float32 = -2.0
var im_min float32 = -1.2
var re_max float32 = 1.0
var im_max float32 = 1.2
var iterazioni int = 1024
var a,b float32
var x,y,x_new,y_new,somma float32
var k,i,j int
var re_factor float32 = (re_max-re_min)
var im_factor float32 = (im_max-im_min)
m := image.NewRGBA(image.Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT))
for i=0;i<SCREEN_HEIGHT;i++ {
for j=0;j<SCREEN_WIDTH;j++ {
a = re_min+(float32(j)*re_factor/float32(SCREEN_WIDTH))
b = im_min+(float32(i)*im_factor/float32(SCREEN_HEIGHT))
x = 0
y = 0
for k=0;k<iterazioni;k++ {
x_new = (float32(x)*float32(x))-(float32(y)*float32(y))+float32(a)
y_new = (float32(2)*float32(x)*float32(y))+float32(b)
somma = (x_new*x_new)+(y_new*y_new)
if somma > 4 {
if k%2 == 0 {
m.Set(j, i, color.RGBA{0, 0, 0, 255})
} else {
m.Set(j, i, color.RGBA{255, 255, 255, 255})
}
break
}
x = x_new;
y = y_new;
}
}
}
f, err := os.OpenFile("mandelbrot.png", os.O_CREATE | os.O_WRONLY, 0666)
if(err != nil) {
log.Fatal(err)
}
if err = png.Encode(f, m); err != nil {
log.Fatal(err)
}
}
Come si puo' vedere ci sono riuscito ma ci sono un paio di considerazioni
al di la' del fatto se Go sia destinato all'oblio (come alcuni progetti di Google) o diventera' lo standard del futuro (personalmente propendo per la prima ipotesi .. ma di solito sbaglio) il linguaggio e' particolarmente ostico per un principiante
- non si possono eseguire operazioni tra tipi di variabile differenti (pena un errore mismatched types int float32 invalid operation) a meno di un esplicito cast
- l'assegnazione di un valore ad una variale mediante il segno "=" e' differente da ":=". In pratica usando := non solo si assegna ma si definisce anche una variabile. Se non si comprende questo meccanisco e si dichiara per esempio var s = "Luca" e subito dopo s:="Luca" si avra' l'errore variable declared and not used a causa di una doppia dichiarazione della variabile s
- il linguaggio non e' a formattazione libera e la posizione della parentesi graffa (per esempio) deve essere posizionato in posti precisi pena un errore di compilazione
- in generale la filosofia del compilatore e': tutti warnings sono errori. Il che puo' essere fastidioso ma mi ha permesso di eliminare una variabile che di fatto non utilizzavo mai (e' la variabile test dei precedenti esempi). In questo senso se si importa una libreria che non viene utilizzata il compilatore genera un errore e non esegue il programma
---------------------------------------------------------------
package main
import (
"image"
"image/png"
"image/color"
"log"
"os"
)
func main() {
var SCREEN_WIDTH int = 400
var SCREEN_HEIGHT int = 400
var re_min float32 = -2.0
var im_min float32 = -1.2
var re_max float32 = 1.0
var im_max float32 = 1.2
var iterazioni int = 1024
var a,b float32
var x,y,x_new,y_new,somma float32
var k,i,j int
var re_factor float32 = (re_max-re_min)
var im_factor float32 = (im_max-im_min)
m := image.NewRGBA(image.Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT))
for i=0;i<SCREEN_HEIGHT;i++ {
for j=0;j<SCREEN_WIDTH;j++ {
a = re_min+(float32(j)*re_factor/float32(SCREEN_WIDTH))
b = im_min+(float32(i)*im_factor/float32(SCREEN_HEIGHT))
x = 0
y = 0
for k=0;k<iterazioni;k++ {
x_new = (float32(x)*float32(x))-(float32(y)*float32(y))+float32(a)
y_new = (float32(2)*float32(x)*float32(y))+float32(b)
somma = (x_new*x_new)+(y_new*y_new)
if somma > 4 {
if k%2 == 0 {
m.Set(j, i, color.RGBA{0, 0, 0, 255})
} else {
m.Set(j, i, color.RGBA{255, 255, 255, 255})
}
break
}
x = x_new;
y = y_new;
}
}
}
f, err := os.OpenFile("mandelbrot.png", os.O_CREATE | os.O_WRONLY, 0666)
if(err != nil) {
log.Fatal(err)
}
if err = png.Encode(f, m); err != nil {
log.Fatal(err)
}
}
lunedì 8 luglio 2013
Raspberry Rev.1 e Rev.2
Mi e' stata gentilmente prestata una Raspberry Ver.2 da affiancare alla Rev.1
Le differenze, ad esclusione del case in plastica che e' stato aggiunto successivamente e si acquista a parte, sono a colpo d'occhio:
Le differenze, ad esclusione del case in plastica che e' stato aggiunto successivamente e si acquista a parte, sono a colpo d'occhio:
- la presenza dei fori di montaggio nella Rev.2 non presenti nel precedente modello
- l'assenza dei connettori alla sinistra (in foto) al connettore (giallo) del segnale video composito nella Rev.2 (ci sono i fori nella basetta ma non i pin di connessione)
- Piccoli spostamenti sulla circuiteria per fare posto a fori di montaggio
In alto Rev.1, in basso Rev.2 |
Display Nokia 5110 su Raspberry
Per utilizzare il display Nokia 5110 su Raspberry la via piu' semplice e' quella di utilizzare la libreria PCD8544 presente a questo sito
Prima pero' deve essere soddisfatta la dipendenza dalla libreria WiringPi che si puo' scaricare da questo sito
La compilazione di WiringPi e' semplice in quanto, dopo aver spacchettato l'archivio. e' sufficiente da root digitare ./build
A questo punto si puo' spacchettare la libreria PCD8544 e procedere alla sua compilazione.
Una volta spacchettato l'archivio se si tenta di lanciare la compilazione con i comandi proposti dal sito
cc -o pcd8544_test pcd8544_test.c ../PCD8544.c -L/usr/local/lib -lwiringPi
cc -o pcd8544_test2 pcd8544_test2.c ../PCD8544.c -L/usr/local/lib -lwiringPi
cc -o pcd8544_rpi pcd8544_rpi.c ../PCD8544.c -L/usr/local/lib -lwiringPi
questa fallisce
La cosa da fare e' modificare leggermente i file contenuti nella cartella samples modificando la riga dell'include da
#include "PCD8544.h"
a
#include "../PCD8544.h"
a questo punto si puo' compilare con successo
Attenzione: i collegamenti sono validi solo per la Raspberry Ver.2. Nei commenti del sito originario e' presente lo schema di collegamento per la Raspberry Ver.1 a cui devono essere accoppiate anche delle leggere modifiche al codice
Le connessione sono le seguenti
LCD pins Raspberry Pi
LCD2 - VCC P01 - 3.3V
LCD3 - CLK P11 - GPIO0
LCD4 - Din P12 - GPIO1
LCD5 - D/C P13 - GPIO2
LCD6 - CS P15 - GPIO3
LCD7 - RST P16 - GPIO4
LCD8 - LED P01 - 3.3V
in piu' per avere il led della retroilluminazione acceso si puo' collegare il pin BL del display all'alimentazione a 3.3 V della Raspberry
Prima pero' deve essere soddisfatta la dipendenza dalla libreria WiringPi che si puo' scaricare da questo sito
La compilazione di WiringPi e' semplice in quanto, dopo aver spacchettato l'archivio. e' sufficiente da root digitare ./build
A questo punto si puo' spacchettare la libreria PCD8544 e procedere alla sua compilazione.
Una volta spacchettato l'archivio se si tenta di lanciare la compilazione con i comandi proposti dal sito
cc -o pcd8544_test2 pcd8544_test2.c ../PCD8544.c -L/usr/local/lib -lwiringPi
cc -o pcd8544_rpi pcd8544_rpi.c ../PCD8544.c -L/usr/local/lib -lwiringPi
questa fallisce
La cosa da fare e' modificare leggermente i file contenuti nella cartella samples modificando la riga dell'include da
#include "PCD8544.h"
a
#include "../PCD8544.h"
a questo punto si puo' compilare con successo
Attenzione: i collegamenti sono validi solo per la Raspberry Ver.2. Nei commenti del sito originario e' presente lo schema di collegamento per la Raspberry Ver.1 a cui devono essere accoppiate anche delle leggere modifiche al codice
Le connessione sono le seguenti
LCD pins Raspberry Pi
---------------------------------------
LCD1 - GND P06 - GNDLCD2 - VCC P01 - 3.3V
LCD3 - CLK P11 - GPIO0
LCD4 - Din P12 - GPIO1
LCD5 - D/C P13 - GPIO2
LCD6 - CS P15 - GPIO3
LCD7 - RST P16 - GPIO4
LCD8 - LED P01 - 3.3V
in piu' per avere il led della retroilluminazione acceso si puo' collegare il pin BL del display all'alimentazione a 3.3 V della Raspberry
Dettaglio dei collegamenti |
L'esempio test2 in esecuzione |
Quadro completo |
Backup SD Card Raspbian
Una delle cose piu' fastidiose della Raspberry e' la necessita' di effettuare uno shutdown corretto pena la compromissione della SD Card ed il non riavvio del sistema operativo (abituati alle Arduino questo e' decisamente un problema)
Una soluzione puo' essere quella di creare una copia della SD Card in modo da salvare le impostazione e le personalizzazioni alla Raspbian
Per fare cio' in Linux,avendo la SD Card montata su sdb, si puo' digitare (da root)
Una soluzione puo' essere quella di creare una copia della SD Card in modo da salvare le impostazione e le personalizzazioni alla Raspbian
Per fare cio' in Linux,avendo la SD Card montata su sdb, si puo' digitare (da root)
dd if=/dev/sdb of=./copia.img
tar cvfj copia.tgz copia.img
venerdì 5 luglio 2013
Easter Egg su Amministrazione Google AdSense
Stavo consultando l'amministrazione di AdSense di questo blog (come si puo' vedere in un anno ha fatto 2.9 euro di guadagno..) quando ho lasciato il mouse sull'immagine in basso a destra, il numero 10 che festeggia il compleanno di questa piattaforma
In maniera non prevedibile e' apparsa un barra verde che progressivamente aumentava
Al termine e' comparso il gioco di Pong
La cosa divertente e' che non sapevo della presenza dell'Easter Egg ed e' stato abbastanza sorprendente...per la cronaca e' piuttosto facile vincere
In maniera non prevedibile e' apparsa un barra verde che progressivamente aumentava
Al termine e' comparso il gioco di Pong
Porta seriale in Qt
Per leggere e scrivere i valori per la porta seriale si possono utilizzare varie librerie. In questo caso viene presentato un esempio relativo alla libreria Qt Serial Port che si trova sul sito ufficiale Qt
La libreria e' valida sia per Qt4 che Qt5
Una volta scaricato il pacchetto si entra nella directory e si digita
qmake
make
make install
a questo punto si puo' creare un nuovo progetto Qt4
la prima cosa da modificare e' il file .pro aggiungendo la serialport
--------------------------------
dopo di cio' si modifica il file header aggiungendo l'include all'header della libreria, uno slot privato per la funzione di lettura della porta ed una nuova variabile che identifica la porta seriale
--------------------------------
il programma vero e proprio puo' essere cosi' scritto
In questo caso viene letta la porta /dev/ttyUSB0 con parametri 2400 8N1
--------------------------------
La libreria e' valida sia per Qt4 che Qt5
Una volta scaricato il pacchetto si entra nella directory e si digita
qmake
make
make install
a questo punto si puo' creare un nuovo progetto Qt4
la prima cosa da modificare e' il file .pro aggiungendo la serialport
--------------------------------
QT += core gui
CONFIG += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = seri
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui--------------------------------
dopo di cio' si modifica il file header aggiungendo l'include all'header della libreria, uno slot privato per la funzione di lettura della porta ed una nuova variabile che identifica la porta seriale
--------------------------------
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtSerialPort/QSerialPort>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void readData();
private:
Ui::MainWindow *ui;
QSerialPort *serial;
};
#endif // MAINWINDOW_H
--------------------------------
il programma vero e proprio puo' essere cosi' scritto
In questo caso viene letta la porta /dev/ttyUSB0 con parametri 2400 8N1
--------------------------------
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtSerialPort/QSerialPort>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
serial = new QSerialPort(this);
serial->setPortName("/dev/ttyUSB0");
if (serial->open((QIODevice::ReadWrite)))
{
serial->setBaudRate(QSerialPort::Baud2400);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
}
connect(serial,SIGNAL(readyRead()),this,SLOT(readData()));
}
void MainWindow::readData()
{
QByteArray data = serial->readAll();
qDebug() << data;
}
MainWindow::~MainWindow()
{
delete ui;
}--------------------------------
Iscriviti a:
Post (Atom)
Change Detection with structural similarity
L'idea di base e' quella di cercare le differenze tra le due immagini sottostanti Non e' immediatamente visibile ma ci sono dei ...
-
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...
-
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...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...