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

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:

  1. la presenza dei fori di montaggio nella Rev.2 non presenti nel precedente modello
  2. 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)
  3. Piccoli spostamenti sulla circuiteria per fare posto a fori di montaggio


In alto Rev.1, in basso Rev.2



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...