lunedì 15 luglio 2013

Megatools

Attenzione:
al momento di scrivere di questo post sul sito dello sviluppatore e' comparso un messaggio in cui lo sviluppo di questo tool e' sospeso a causa di una modifica alle API di Mega e sono stati rimossi i link per il download degli eseguibili. Risulta tuttora disponibile il link a GitHub per i sorgenti. Per adesso il tool funziona ma non e' chiaro fino a quando le API continueranno a funzionare come adesso


Finalmente iniziano ad essere disponibili i clienti per il servizio Cloud di Mega in particolar modo quello ufficiale per Android e quello non ufficiale per Linux/Windows offerto da Megatools
E' infatti sostanzialemente inutile avere 50 Giga di spazio e dover effettuare tutte le operazioni da interfaccia Web senza la possibilita' di automatizzare l'upload



In Linux, una volta scompattato l'archivio e compilato i sorgenti mediante ./configure make, si hanno a disposizione i seguenti principali comandi (ne ho omessi alcuni di uso meno frequente)

megadf       come df mostra lo spazio disco a disposizione
megals       come ls (Linux)
megamkdir    come mkdir (Linux)
megarm       come rm (Linux)
megamv       come mv (Linux)
megaput      effettua l'upload di un file
megaget      effettua il download di un file
megasync     sincronizza una directory remota con una directory locale

in generale i comandi hanno tutti uno switch
-u nomeutente
-p password

una tipica sessione puo' essere

megadf -u lucainnoc@gmail.com -p password
megamkdir -u lucainnoc@gmail.com -p password Immagini
magesync -u lucainnoc@gmail.com -p password --local /home/luca/Immagini --remote /Root/Immagini

La directory di root del Cloud e' sempre Root 

Le velocita' di upload sono piuttosto modeste e popolare i 50 Gb sara' veramente un'impresa

venerdì 12 luglio 2013

Shutdown Raspberry via pulsante

Questo progetto e' stato copiato da questo link per evitare uno dei problemi piu' fastidiosi della Raspberry (ovvero di Linux) ovvero la corruzione del file system in caso di arresto brutale dell'elaboratore

In questo esempio viene implementato un pulsante fisico che permetta di eseguire (ove possibile) uno shutdown corretto della macchina

Sono possibili due schemi elettrici



Io ho usato il metodo del secondo schema perche' nel primo la porta GPIO e' sempre sottotensione (stato logico 1) mentre nel secondo esempio lo stato logico e' 0

il programma per gestire il pulsante e' il seguente: se il pin 17 acquisisce uno stato logico 1 viene lanciato il comando di shell per lo shtdown. Le resistenze, come nello schema, sono da 1 e 10 KOhm

------------------------------------------------------
import RPi.GPIO as GPIO
import time
import os
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN)
while True:
if (GPIO.input(17)):
os.system("sudo shutdown -h now")
break
time.sleep(1)
------------------------------------------------------

Nella foto il cavo rosso e' collegato al pin di 3.3 V, il cavo nero al GND mentre il cavo giallo e' collegato alla porta 17


vistodall'alto



Ed ecco un breve video


mercoledì 10 luglio 2013

GPIO su Raspberry (Led Blink)

In Raspberry e' presente una porta una porta GPIO (General Purpose Input Output) che puo' essere utilizzata come in Arduino per interfacciare la scheda con il mondo esterno (attenzione: ci sono controlli digitali e non analogici)

La prima fondamentale differenza rispetto al mondo Arduino e' che i pin sono spesso indicati con un doppio nome; il primo e' il numero ordinale  (da 1 a 26) mentre il secondo prende in considerazione a quale collegamento rispetto alla CPU siano associati

GPIO Pin Rev.1

ad aggiungere confuzione tra la prima e seconda revisione della Raspberry alcuni pin sono stati modificati per cui alcuni progetti girano su una versione e non sull'altra

GPIO Pin Rev.2
Attenzione : la tensione di riferimento della Raspberry e' di 3.3 V sui pin digitali (ad esclusione di una alimentazione a 5 V sul pin 2)

Per programmare in modo semplice l'accesso i/o ai pin e' disponibile una libreria Python (gia' installata di default nelle versioni attuali di Raspbian). Tutti i programmi che usano le porte devono essere eseguiti come super-utente (script python compresi)


Lo script seguente accende e spenge un led connesso al pin 11 (nome GPIO17)
-------------------------------------------------
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

# Set up #17 as an output
print "Setup #17"
GPIO.setup(17, GPIO.OUT)

var=1
print "Start loop"
while var==1:
 print "Set Output False"
 GPIO.output(17, False)
 time.sleep(1)
 print "Set Output True"
 GPIO.output(17, True)
 time.sleep(1)
-------------------------------------------------




Stringhe su Nokia 5110 da Raspberry

In questo esempio viene mostrato come scrivere stringhe sul display Nokia 5110 utilizzando Raspberry

Nel caso specifico la stringa viene ripresa dal primo parametro della linea di comando
Per la compilazione e maggiori dettagli si rimanda  a questo post




-------------------------------------------------
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include "../PCD8544.h"

// pin setup
int _din = 1;
int _sclk = 0;
int _dc = 2;
int _rst = 4;
int _cs = 3;
  
// lcd contrast 
int contrast = 50;
int i;
  
int main (int argc, char *argv[])
{
  if (wiringPiSetup() == -1)
  {
printf("wiringPi-Error\n");
    exit(1);
  }
  
  LCDInit(_sclk, _din, _dc, _cs, _rst, contrast);
  LCDclear();
  LCDdrawstring(1, 1, argv[1]);
  LCDdisplay();
  delay(2000);

  LCDclear();
  
  return 0;
}

Mandelbrot in Raspberry con display Nokia 5110

Mettendo insieme i precedenti post Display Nokia 5110 su RaspberryArduino Uno + Display Nokia 5110 = Mandelbrot 48x84 ho provato a ripetere la stessa cosa su Raspberry

il codice per generare l'immagine e' sempre il solito (che fortunatamente si ricicla in mille modi) e si compila con la seguente linea

cc -o mandel mandel.c ../PCD8544.c -L/usr/local/lib -lwiringPi


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

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include "../PCD8544.h"

#define SCREEN_WIDTH 84
#define SCREEN_HEIGHT 48

// pin setup
int _din = 1;
int _sclk = 0;
int _dc = 2;
int _rst = 4;
int _cs = 3;
// lcd contrast 
int contrast = 50;
  

float re_min = -2.0;
float im_min = -1.2;
float re_max = 1.0;
float im_max = 1.2;
int iterazioni = 1024;
float a,b;
float x,y,x_new,y_new;
int k,j,i;


int main (void)
{
  // check wiringPi setup
  if (wiringPiSetup() == -1)
  {
printf("wiringPi-Error\n");
    exit(1);
  }
  
  // init and clear lcd
  LCDInit(_sclk, _din, _dc, _cs, _rst, contrast);
  LCDclear();

  
  float re_factor = (re_max-re_min);
  float im_factor = (im_max-im_min);
    

for (i=0;i<SCREEN_HEIGHT;i++)
{
for (j=0;j<SCREEN_WIDTH;j++)
 {
 a = re_min+(j*re_factor/SCREEN_WIDTH); 
 b = im_min+(i*im_factor/SCREEN_HEIGHT);
 
 x = 0;
 y = 0;

 
 for (k=0;k<iterazioni;k++)
  {
  x_new = (x*x)-(y*y)+a;
  y_new = (2*x*y)+b;
  if (((x_new*x_new)+(y_new*y_new))>4)
{
test = k;
if (k%2 == 0)  LCDsetPixel(j, i, BLACK);
// LCDdisplay();    
break;
}
  x = x_new;
  y = y_new;
  }
 
 }

}
  
  
  LCDdisplay();
  delay(2000);
  return 0;

}

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

L'aspetto piu' interessante e' la differenza di velocita', su Raspberry l'immagine appare in modo praticamente istantaneo mentre su Arduino era necessario circa un minuto



Un riassunto di PlayStore (dopo oltre un anno)

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



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


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

Physics informed neural network Fukuzono

Visto che puro ML non funziona per le serie tempo di cui mi sto occupando ed le regressioni basate su formule analitiche mostrano dei limiti...