mercoledì 30 settembre 2015

6 anni di Arduino


Sono passati 6 anni dal primo utilizzo di Arduino durante il dottorato di ricerca
Forse questo "Lego per adulti" mi ha un po' preso la mano a vedere quanto hardware ho a giro per casa

Scatola Arduino

Sensori/Accessori


Sensori/Accessori 2

Cavi




martedì 29 settembre 2015

Time Lapse con Xiaomi Yi

Questo time lapse e' stato creato nella notte tra sabato 26 e domenica 27 settembre come prova per filmare l'eclisse lunare del 28 settembre con l'action cam Xiaomi Yi (ero malato e non potendo lasciare casa mi sono dovuto adattare, per la ripresa, al terrazzo di casa nonostante la pessima esposizione verso Sud....la ripresa dell'eclisse e' stata annullata a priori a causa della copertura nuvolosa del giorno successivo)


Per alimentare la camera e' stato adottato un powerbank da 10000 mA (dopo 8 ore era ancora disponibile 1/4 di energia). Un'altra accortezza e' stata quella di coprire i led del Wifi e del pulsante di accensione perche' sono talmente luminosi da influenzare la ripresa nell'oscurita' della notte

I fotogrammi (uno al minuto) eseguiti alla massima risoluzione della camera sono stati montati e riscalati in formato hd720 mediante avconv con la seguente  stringa

avconv -f image2 -r 24 -i Y0020%04d.JPG -codec:v libx264 -s:v hd720 timelapse.mp4

venerdì 11 settembre 2015

Fritzing: da idea a PCB

Fritzing non e' solo un programma che permette di trascrivere in modo ordinato i collegamenti di una breadboard ma puo' essere utilizzato anche per crearsi un PCB (circuito stampato) da mettere poi in produzione


Partendo dallo schema sopra riportato, cliccando sul tab PCB. Si puo' fare in modo che il programma cerchi in modo autonomo quale sia la migliore disposizione delle piste del PCB mediante la funzione Routing/Autoinstrada. Questa e' una procedura automatica ma non e' esente da errori. Si devono spostare/routare i componenti fino a che ci si trova nella condizione si non avere piste incrociate e non sia necessario usare dei cavi esterni al di sopra del PCB (si possono creare PCB a due facce od una faccia, per uso amatoriale e' meglio a faccia singola)


Una volta ottenuto un autoinstradamento che puo' sembrare corretto, si clicca su Routing/Design Rule Check (DRC) che effettivamente effettua il controllo sulla correttezza del circuito (ci possono essere casi in cui le piste non ci incrociano ma sono comunque troppo vicine da creare interferenza)
E' un lavoro piuttosto noioso e fatto di tentativi ed errori

Alla fine, se non ci sono errori, si puo' stampare su carta il risultato
Come indicato sul sito di Fritzing e' molto utile incollare la stampa del circuito appena creato su una base di polistirolo dove inserire i componenti reali. Cio' permette di verificare direttamente l'ingombro dei componenti fisici ed eventuali errori 


giovedì 10 settembre 2015

DIY HomeKit con Android Wear e Raspberry

Questo e' un tentativo di realizzare un homekit, un sistema di domotica, che permetta di accendere dei dispositivi con un sensore di prossimita' (tipo il lampadario quando si entra in una stanza)

I componenti di questo kit sono
1) un orologio con Android Wear
2) un Raspberry (qualsiasi modello) con un dongle Bluetooth LE
3) un rele



L'orologio e' stato programmato come emettitore di beacon (e' possibile modificare il valore del minor in modo da personalizzarlo)


Di seguito il codice Android

--------------------------------------
apply plugin: 'com.android.application'

android {
    compileSdkVersion 21    buildToolsVersion "21.1.2"
    defaultConfig {
        applicationId "luca_innocenti.beacontrasmitter"        minSdkVersion 21        targetSdkVersion 21        versionCode 1        versionName "1.0"    }
    buildTypes {
        release {
            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }
    }
}

final def var = repositories {
    jcenter{
        url "http://jcenter.bintray.com/"    }
}
var

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.support:wearable:1.2.0'    compile 'com.google.android.gms:play-services-wearable:7.5.0'}
dependencies {
    compile 'org.altbeacon:android-beacon-library:2+'
} 

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

--------------------------------------
package luca_innocenti.beacontrasmitter;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.pm.PackageManager;

import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.BeaconTransmitter;
import org.altbeacon.beacon.Identifier;

import java.util.Arrays;


@TargetApi(21)
public class MainActivity extends Activity {

    private BeaconTransmitter mBeaconTransmitter;
    private TextView testo;
    private SeekBar barra;
    private Button pulsante;
    private int stato;
    private TextView testo2;
    private TextView testo3;


    private void trasmetti(){
        if (checkPrerequisites()) {
            //            //mBeaconTransmitter = new BeaconTransmitter(this, new BeaconParser().setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));            mBeaconTransmitter = new BeaconTransmitter(this, new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
            //beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));  // iBeacons
            //beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));      // Estimotes
            //beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=a7ae2eb7,i:4-19,i:20-21,i:22-23,p:24-24"));  // easiBeacons
            // uuid estimote B9407F30-F5F8-466E-AFF9-25556B57FE6D
            Beacon beacon = new Beacon.Builder()
                    .setId1("B9407F30-F5F8-466E-AFF9-25556B57FE6D")
                    .setId2("999")
                    .setId3(testo.getText().toString())
                    .setManufacturer(0x015D) // Simula Estimote                    .setTxPower(-59)
                    .setDataFields(Arrays.asList(new Long[]{0l}))
                    .build();

            mBeaconTransmitter.startAdvertising(beacon);
            stato = 1;
        }

    }

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override            public void onLayoutInflated(WatchViewStub stub) {
                barra = (SeekBar) stub.findViewById(R.id.seekBar);
                testo = (TextView) stub.findViewById(R.id.textView);
                testo2 = (TextView) stub.findViewById(R.id.textView2);
                testo3 = (TextView) stub.findViewById(R.id.textView3);
                pulsante = (Button) stub.findViewById(R.id.button);


                barra.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                                                     @Override                                                     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                                                         testo.setText(String.valueOf(new Integer(progress)));
                                                     }

                                                     @Override                                                     public void onStartTrackingTouch(SeekBar seekBar) {

                                                     }

                                                     @Override                                                     public void onStopTrackingTouch(SeekBar seekBar) {

                                                     }
                                                 }
                );

                pulsante.setOnClickListener(new View.OnClickListener() {
                    @Override                    public void onClick(View v) {
                        testo2.setText("Trasmitter ON");
                        testo3.setText("B9407F30-F5F8-466E-AF\nF9-25556B-57FE6D-999-"+testo.getText());
                        pulsante.setEnabled(false);
                        barra.setEnabled(false);
                        trasmetti();
                    }
                });
            }
        });
    }


    @Override    protected void onDestroy() {
        super.onDestroy();
        if (stato == 1) {
            mBeaconTransmitter.stopAdvertising();
        }
    }

    @TargetApi(21)
    private boolean checkPrerequisites() {

        if (android.os.Build.VERSION.SDK_INT < 18) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Bluetooth LE not supported by this device's operating system");
            builder.setMessage("You will not be able to transmit as a Beacon");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                @Override                public void onDismiss(DialogInterface dialog) {
                    finish();
                }

            });
            builder.show();
            return false;
        }
        if (!getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Bluetooth LE not supported by this device");
            builder.setMessage("You will not be able to transmit as a Beacon");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                @Override                public void onDismiss(DialogInterface dialog) {
                    finish();
                }

            });
            builder.show();
            return false;
        }
        if (!((BluetoothManager) getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter().isEnabled()){
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Bluetooth not enabled");
            builder.setMessage("Please enable Bluetooth and restart this app.");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                @Override                public void onDismiss(DialogInterface dialog) {
                    finish();
                }

            });
            builder.show();
            return false;

        }

        try {
            // Check to see if the getBluetoothLeAdvertiser is available.  If not, this will throw an exception indicating we are not running Android L            ((BluetoothManager) this.getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter().getBluetoothLeAdvertiser();
        }
        catch (Exception e) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Bluetooth LE advertising unavailable");
            builder.setMessage("Sorry, the operating system on this device does not support Bluetooth LE advertising.  As of July 2014, only the Android L preview OS supports this feature in user-installed apps.");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override                public void onDismiss(DialogInterface dialog) {
                    finish();
                }

            });
            builder.show();
            return false;

        }

        return true;
    }
}

--------------------------------------
Per leggere la prossimita' dell'orologio ho montato sulla Raspberry un dongle Broadcome (gia' visto qui) ed il programma in Python iBeacon-Scanner (Github) leggermente modificato

Il programma cicla fino quando non vede un dispositivo con minor=1, allora controlla l'Rssi e stima la distanza. Se la distanza e' inferiore ad un determinato valore si puo' agire sulle porte GPIO ed attivare il rele' (funzione da implementare ma di facilissima realizzazione)

--------------------------------------
import blescan
import sys

import bluetooth._bluetooth as bluez

dev_id = 0
try:
    sock = bluez.hci_open_dev(dev_id)
    #print "ble thread started"

except:
    print "error accessing bluetooth device..."
        sys.exit(1)

blescan.hci_le_set_scan_parameters(sock)
blescan.hci_enable_le_scan(sock)

while True:
    returnedList = blescan.parse_events(sock, 10)
    #print "----------"
    for beacon in returnedList:
        #print beacon
        valori = beacon.split(",")
        mac = valori[0]
        uuid = valori[1]
        major = valori[2]
        minor = valori[3]
        rssi = valori[4]
        rssi2 = valori[5]
        #print minor
        if (minor == "1"):
            #print minor+" "+rssi2
            if (int(rssi2) > -75):
                print "vicino"
            else:
                print "lontano"
--------------------------------------

Samsung Xpress M2022W su Debian

Avevo gia' provato ad installare una stampante Samsung su Debian ma in questo caso e' stato ancora piu' semplice


E' stato sufficiente installare CUPS (l'installazione Debian era un po' minimale), scarica il file tgz deo driver della stampante, scompattalo e lanciare install-printer.sh
Fatto cio' si apre il browser a http://localhost:631 (il configuratore web di Cups), si aggiunge la stampante e tutto funziona in nemmeno 10 minuti

Non ho avuto modo di provare il collegamento wireless perche' non era disponibile una rete locale WiFi

ps: la stampante e' dotata di cavetto USB al contrario del modello precedente

mercoledì 9 settembre 2015

Cisco Pix 501 - Resettare la password

Mi e' stato prestato un Cisco PIX 501 (che oramai prendeva polvere in un rack) per imparare un po' ad usare la configurazione via Cisco IOS, l'interfaccia a linea di comando al posto di quella tradizionale via web che si trova oramai su praticamente tutti i dispositivi di rete
Si tratta di un dispositivo molto vecchio (nato nel 2001 ed uscito di produzione nel 2008) che si trova su Ebay a 15 euro





Il primo problema e' che il dispositivo era protetto da password (ed oramai chi me lo ha prestato) non ricorda quindi e' stato necessario prima resettare la password di amministratore del dispositivo

Per fare si procede trovando il cavo di Consolle Cisco. Si tratta di un cavo seriale che ad una estremita' ha un comune DB-9 mentre all'altra' riporta un connettore RJ-45 ..tanto per fare le cose semplici





-----------------------------------------------------------------------
                               ||        ||
                               ||        ||
                              ||||      ||||
                          ..:||||||:..:||||||:..
                         c i s c o S y s t e m s
                        Private Internet eXchange
  -----------------------------------------------------------------------

Fortunatamente qualche anno fa ne avevo tenuto uno preso da una scatola che stava per essere gettata.

Si inizia quindi connettendo il dispositivo al PC (connessione seriale 9600 8N1) e si attende il boot del PIX senza premere nessun tasto. Si deve prendere nota della versione del sistema operativo (evidenziato in giallo nel listato sottostante)
---------------------------------------------------------------------
Cisco PIX Firewall Version 6.3(5)
Cisco PIX Device Manager Version 3.0(4)

Compiled on Thu 04-Aug-05 21:40 by morlee

local up 35 mins 15 secs

Hardware:   PIX-501, 16 MB RAM, CPU Am5x86 133 MHz
Flash E28F640J3 @ 0x3000000, 8MB
BIOS Flash E28F640J3 @ 0xfffd8000, 128KB

0: ethernet0: address is 0016.c836.xxxx, irq 9
1: ethernet1: address is 0016.c836.xxxx, irq 10
Licensed Features:
Failover:                    Disabled
VPN-DES:                     Enabled
VPN-3DES-AES:                Enabled
Maximum Physical Interfaces: 2
Maximum Interfaces:          2
Cut-through Proxy:           Enabled
Guards:                      Enabled
URL-filtering:               Enabled
Inside Hosts:                Unlimited
Throughput:                  Unlimited
IKE peers:                   10

This PIX has a Restricted (R) license.
---------------------------------------------------------------------

A questo punto si va sul sito CISCO e si scarica il firmware corrispondente esattamente alla versione installata e si crea un file server SFTP su una macchina di riserva dove depositare il file (diciamo che questa macchina ha come indirizzo 192.168.1.1, per impostare il server si puo' leggere questo post)

Si collega il Cisco spento con il cavo seriale alla macchina di riserva e ci si mette in ascolto sulla porta seriale (il cavo di rete si inserisce nell'hub a 4 porte e non alla Wan)
Il boot del Pix si interrompe per qualche secondo durante il quale si deve premere un tasto in modo da entrare in funzione monitor

Si digitano quindi i seguenti comandi
interface 1 (si selezionano le porte dell'hub, la zero e' la Wan)
address 192.168.1.2 (ip del PIX sul lato interno)
server 192.168.1.1 (ip del server TFTP)
file pix63.bin (nome del file di firmware prima scaricato)
ping 192.168.1.1 (verifica che il Pix riesce a pingare il PC)
tftp (inizia il trasferimento del file)

Do you want to enter a new activation key? [n] n

al riavvio successivo si trova che le configurazioni del PIX sono rimaste identiche (e' stata resettata solo la password). Se si digita il comando enable (ovvero quando si entra nel profilo amministratore) viene richiesta la password e cio' e' un po' fuorviante. Basta digitare Invio e il prompt si modifica dal segno maggiore a cancelletto per indicare che si e' entrata nella shell di amministratore

Per vedere come sono configurati gli indirizzi del terminale (in modo da abbandonare il cavo di console e mettersi in collegamento via cavo di rete si puo' usare il comando

show ip

Ci si puo' quindi connettere via telnet con password cisco

Per configurare il terminale si digita

configure terminal

in questo modo si puo' attivare l'interfaccia web con iil comando
http xx.xxx.xxx.xxx (mettere l'ip interno al posto delle x)
http server enable

Ci si connette quindi via https al Cisco. Curiosamente Firefox non permette di connettersi per un problema sulle chiavi SSL (e' un bug attuale di Firefox)

Su Chrome si arriva alla pagina di autenticazione (si devono lasciare bianchi il campo user/password e premere invio in quanto e' stata resettata la password) e si arriva ad una pagina con l'immagine di Cisco PIX Device Manager 3.0 senza pero' poter far niente. Da Midori invece l'immagine e' cliccabile e porta sul sito della CISCO dove si trova che il prodotto e' End-of-Support e non si puo' scaricare il controllo via web 

Immagine ripresa dal web di come si presentava il Device Manager

anche per quanto riguarda SSH ci sono un po' di problemi (le istruzioni dettagliate sono qui)


configure terminal
ca generate rsa key 2048
ca save all
ssh xx.xxx.xxx.x 255.255.255.255 inside (ip interno del router al posto delle x)
ssh timeout 60
enable password xxxxxx 
passwd xxxxx
se si cerca di connettersi con un client "moderno" si scopre che il protocollo SSH in uso e' la versione 1 (tutti i client moderni usano solo il protocollo versione 2 e quindi rifiutano la connessione)

rimane quindi la configurazione da linea di comando che puo' essere fatta in modo speditivo con il comando 
setup che permette una configurazione veloce degli IP interni ed esterni
per riportarlo allo stato di fabbrica configure factory-default

In buona sostanza un bel giocattolino ma adesso non puo' essere usato come macchina di produzione

Analisi di due backup battery solari

Premessa : entrambi gli oggetti in  foto non funzionano completamente e comunque hanno dei limiti di progettazione
Si tratta di due batteria di backup rispettiavamente da 5000 mAh e 10000 mAh


il problema di progettazione e' che in nessuno dei due casi il pannello solare puo' ricaricare la batteria interna in modo efficiente. Entrambi hanno un pannello solare da 1.5W e su quello giallo e' dichiarato che in alimentazione solare eroga 200 mA. Quindi, tenendo conto che anche per il modello nero le prestazioni siano simili, sono necessarie rispettivamente 25 ore e 50 ore di esposizione a pieno sole per la ricarica della batteria (e non e' una buona idea lasciare 25/50 ore sotto l'insolazione diretta delle batterie Lipo con il conseguente surriscaldamento e probabilita' di esplosione....il costruttore lo sa e per questo motivo nelle specifiche indica come massima temperatura di esercizio 45°C

Modello 1 (Giallo e verde)
Questo dispositivo si ricarica normalmente via microUsb da alimentatore di rete. Il problema e' che il pannello solare non ricarica la batteria. Collegando un tester si vede anche che, esposto alla luce solare, non solo non carica la batteria ma non manda nemmeno tensione sulla porta USB di uscita


per capirci qualcosa ho provato ad aprilo. Non ci sono viti a vista ma alzando la gomma verde si vedono delle clip automatiche in plastica (sono 8 in tutto)


Una volta guadagnato l'accesso all'interno si vede che il pannello solare e' fissato con clip al coperchio superiore ed ha una tensione di uscita di 3.7V. E' saldato piuttosto male ed e' stato sufficiente una piccola torsione del filo per staccarlo da circuito integrato di ricarica

Modello 2 (Nero)

E' molto piu' semplice da aprire tramite 8 viti che aprono due semigusci.
Da una verifica sui contatti interni si vede che il circuito di carica funziona, la batteria interna effettivamente e' carica ma non eroga corrente sulle porte Usb in nessuna condizione. Il pulsante di accensione funziona correttamente quindi il problema sembra risiedere nel circuito di erogazione della corrente (fondamentalmente non riparabile)
Al contrario del modello precedente se si mette il pannello solare (in pieno luce, diretta, senza un minimo di penombra altrimenti non funziona) sulla porta Usb si ha corrente (5.,4 V) quindi non si puo' usare la batteria ma si puo' usare il pannello solare per alimentare qualcosa di piccolo e poco esoso di corrente come una Arduino

In estrema sintesi non vale la pena di spendere soldi su questi dispositivi poco costosi ed a pannello solare (le soluzioni a pannello solare "serie" hanno costi dell'ordine di 150 euro, questi pacchi batteria possono essere acquistati per 15 euro....

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