lunedì 13 gennaio 2014

Batteria bruciata su JIAYU G3T

Il telefono in questione, uno JIAYU G3T (in breve le caratteristiche 4.5 pollici HD IPS Gorillla Quad Core 1.5Ghz MTK6589T Android 4.2 Dual SIM WIFI GPS 8MP) durante la carica ha segnalato, tramite sistema operativo, un surriscaldamento della batteria

Il possessore, un amico, ha spento il telefono (lasciandolo pero' in carica). Al mattino successivo la pessima sorpresa: batteria fusa, parte della scocca fusa ed ovviamente telefono che non parte
Piccola nota: acquistato da circa un mese




Mandelbrot su Arduino con TvOut

Un metodo veloce per visualizzare dati derivanti da una Arduino senza utilizzare display appositi ed impiegando solo due uscite digitali puo' essere quella di ricorrere alla libreria TvOut ed inviando il segnale all'uscita SVideo di un comune televisore


In questo modo, usando un semplice connettore S-Video ed un paio di resistenze, si puo' avere una visualizzazione senza troppi problemi
Lo schema delle resistenza e' il seguente


Alcuni riportano che' obbligatoria una resistenza da 75 Ohm anche sul GND. Per quanto mi riguarda il tutto ha funzionato anche senza (ho avuto difficolta' a trovare questo taglio di resistenza)
Importante: sul sito e' indicato che per la Arduino Uno i pin digitali da collegare sono D7 (Video), D9 (Sync) e GND ma nel mio caso hanno funzionato D8 (Video), D9 (Sync) e GND

La risoluzione di base e' sostanzialmente pessima, un misero 128x98, ma per un sistema cosi' semplice non e' male
Ovviamente non potevo esimermi dal provare a disegnare l'insieme di Mandelbrot




-----------------------------------------------------------------------------
#include <TVout.h>
TVout TV;


int SCREEN_WIDTH = 0;
int SCREEN_HEIGHT = 0;

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


void setup(void) {
  TV.start_render(_PAL);
  TV.delay_frame(50);

  TV.clear_screen();
  SCREEN_WIDTH = TV.horz_res();
  SCREEN_HEIGHT = TV.vert_res();

  //---------------------------------
  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;
      test = 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)
          {
            TV.set_pixel(j,i,1); 
         }     
        break;
        }
       x = x_new;
       y = y_new;
       }
      }
     }
}

void loop(void) {
  while (1) {}
}

venerdì 10 gennaio 2014

74HC4050 Level Shifter con Arduino

Il 74HC4050 permette di cambiare il voltaggio di una porta digitale Arduino da 5 V ad un valore differente (tipicamente 3.3V, molti componenti moderni funzionano a questa tensione) senza alternarne lo stato logico

In pratica in pin del 4050 sono a coppie AY. Quando sul pin A si ha una tensione di 5V sul corrispondente pin Y si avra' la tensione di 3.3V



ed ecco la versione reale
il cavo giallo e' l'uscita del pin D13 dopo essere passata per il level shifter
il cavo nero e' il gnd (in realta' sono due cavi perche' su uno e' montato il voltmetro)
il cavo bianco e rosso e' l'uscita del pin D13 senza conversione


Montando sull'Arduino il semplice sketch Blink il risultato e' il seguente (prima viene misurata l'uscita pura dal pin D13 e poi quella modificata dal level shifter)


giovedì 9 gennaio 2014

GPS Tracking e batteria in Android

Sto sviluppando una applicazione per effettuare il tracciamento di escursionisti (a piedi ed in ambiente di montagna) per cui una delle caratteristiche richieste e' la lunga durata della batteria
Normalmente un cellulare Android con batteria completamente carica non riesce a tracciare piu' di 5 ore di percorso, un tempo scarsino per una escursione dato che mediamente di parla di 6-9 ore

Una soluzione che sto valutando e' quello di non tracciare con continuita' ma di accendere l'antenna GPS per un minuto (tempi inferiori non garantiscono che ci sia il fix del punto Gps) e che rimanga spenta un tempo prestabilito (diciamo 4-5 minuti che a piedi con velocita' uguale od inferiore a 5 Km/h corrisponde ad un punto ogni 400 m). In tale modo non si ha la traccia del sentiero ma si ha sempre la posizione  sul percorso
(l'applicazione nella versione definitiva dovrebbe una applicaizone orientata al soccorso)

Una prima prova e' stata effettuata con il programma riportato al termine del post: i punti sono stati acquisiti ogni 4 minuti (durante la prova lo spostamento e' stato effettuato in macchina quindi le acquisizioni sono molto distanziate)
In giallo i punti acquisiti
ed ecco la tabella delle acquisizioni con i tempi



Il programma implementa un Timer (che scatta ogni minuto) ed un Location Manager.
Quando il numero di cicli del timer (variabile contatore) e' un multiplo di 5 viene attivato il Location Manager altrimenti vengono disattivate le update dallo stesso manager (e viene spenta l'antenna)
Semplice ma funzionale
----------------------------------------------------------
package com.test.tempo;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.WindowManager;

public class MainActivity extends Activity {

private Timer t;
private TimerTask task;
private LocationManager mlocManager;
private MyLocationListener mlocListener;
private double contatore;
public String tempo_gps;
public double latitudine;
public double longitudine;
public long old_time;
public boolean gps_fix;
public long tempo;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//mantiene lo schermo attivo 
   getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

contatore = 0;

//GESTIONE DEL GPS
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
        mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
        // se il GPS non e' abilitato richiede l'intervento dell'utente
        if (!mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
        }

//GESTIONE DEL TIMER
        t = new Timer();     
   task = new TimerTask() {  
   @Override  
     public void run() {  
    runOnUiThread(new Runnable() {  
   @Override  
   public void run() {  
    //nella variabile contatore ci sono i minuti trascorsi
    contatore = contatore+1;
    //se i minuti sono divisibili per 5 allora si acquisisce per un minuto la posizione
    //acquisisce anche al primo ciclo per inizializzare il GPS
    if (((contatore % 5) == 0) || (contatore == 0))
    {
    //abilita GPS
       mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
    }
    else
    {
    //disabilita GPS
    mlocManager.removeUpdates(mlocListener);
    }
         
     }  //fine run
    });  
   }  
  };
  //il timer scatta una volta ogni 60 secondi
  t.scheduleAtFixedRate(task, 0, 60000);
  // FINE DELLA GESTIONE DEL TIMER
}

public class MyLocationListener implements LocationListener
    {


@Override
    public void onLocationChanged(Location loc)
    {
    latitudine = loc.getLatitude();
    longitudine = loc.getLongitude();
    tempo = loc.getTime();
    
    // e' considerato di avere il fix gps se non ci sono piu' di 5 secondi
    // tra due letture consecutive
    if ((tempo-old_time < 5000) && (old_time > 0))
    {
            gps_fix = true;
            Date date = new Date(tempo);
            SimpleDateFormat format = new SimpleDateFormat("dd/MM/yy HH:mm:ss zzz a");
            format.setTimeZone(TimeZone.getTimeZone("GMT"));
            tempo_gps = format.format(date);
            salva();
    }
    old_time = tempo;
    }


    @Override
    public void onProviderDisabled(String provider)
    {
    gps_fix = false;
    }


    @Override
    public void onProviderEnabled(String provider)
    {
    gps_fix = false;
    }


@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub

}
  }



//all'uscita dall'applicazione spenge il timer ed il GPS
protected void onDetroy()
{
super.onDestroy();
t.cancel();  
   t.purge();  
        mlocManager.removeUpdates(mlocListener);
}


private void salva()
// salva i dati su file
   {
            try {
                   File root = Environment.getExternalStorageDirectory();
                   if (root.canWrite()){
                       File data_file = new File(root, "sart.txt");
                       FileWriter data_file_writer= new FileWriter(data_file,true);
                       BufferedWriter out = new BufferedWriter(data_file_writer);
                            out.write(Double.toString(latitudine)+";"+Double.toString(longitudine)+";"+tempo_gps+"\n");
                            out.close();        
                   }
               } catch (IOException e) {
               }

           
   }


}

-------------------------------------------------------------
Manifest
-------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.tempo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.test.tempo.MainActivity"
            android:label="@string/app_name" 
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>


</manifest>


EasyPeasy su EEEPC 1001 PXD

Mi e' stato chiesto un consiglio per rendere operativo un EEEPC 1001 PXD comprato oltre due anni fa e che giaceva chiuso in un cassetto da oltre un anno perche' la macchina era oggettivamente non usabile.
Dato che il proprietario lo vuole usare solo per archiviare e sentire la musica e vedere le foto non me la sono sentita di fare una installazione di Debian (piu' che altro per il tempo necessario)


Mi sono ricordato che sul mio Samsung N150 avevo installato in un primo momento una Ubuntu specifica per netbook ma da una ricerca su internet ho verificato che la distribuzione non e' piu mantenuta.
Sono cosi' incappato in EasyPeasy, una distribuzione basata su Ubuntu che sembra aver raccolto il testimone di Ubuntu per Netbook
Il kernel e' rimasto alla serie 2.6 ed e' stato mantenuta l'interfaccia originale di Ubunti per netbook
L'EEEPC non e' decollato (ha un Atom 550 con un giga di memoria) ma quanto meno l'installazione ha riconosciuto tutte le periferiche ed il computer e' usabile

mercoledì 8 gennaio 2014

Sonda Effetto Hall (KY-003 Clone cinese)

Ho comprato su DealExtreme questa sonda di Hall giusto per fare qualche esperimento (per dettagli su cosa sia effettivamente l'effetto Hall si puo' leggere la relativa pagina di Wikipedia)
Il costo era ridicolo (meno di due euro spedizione compresa)


Si tratta di un piccolo componente elettronico (44E938) montato su una basetta con i reofori ed un piccolo led. Il componente di per se non e' niente di speciale: ha solo lo stato On/Off e necessita di un discreto campo magnetico per attivarsi. Lo stato e' normalmente On e la schedina e' dotata di un led rosso che si attiva alla prossimita' del magnete (in linea di principio non e' richiesta l'Arduino ma basta l'alimentazione)

La pedinatura dell'integrato e' (con la scritta rivolta verso l'alto)
Sinistra : VCC 5V
Centro GND
Destra : Segnale

mentre quella della schedina e'
Sinistra : GND
Centro VCC 5V
Destra : Segnale

L'utilizzo di questo sensore puo' essere come interruttore (accoppiato ad un piccolo magnete) per verificare l'apertura di una porta o per contare i giri di un disco


(il magnete e' nascosto all'interno del tessuto. Ho usato il fermaglio magnetico del case del tablet)

Ps: un utente ha segnalato nei commenti di DealtExtreme che la pedinatura scritta sulla scheda non e' corretta. Per quanto mi riguarda i collegamenti sono corretti
--------------------------------------------------------------
int val = 0; 
void setup()
{
pinMode(2, INPUT); // segnale del sensore
pinMode(13, OUTPUT); 
Serial.begin(9600); 
}

void loop()
{

val = digitalRead( 2 );
Serial.println(val); 

if ( val == HIGH )
digitalWrite ( 13, HIGH ); 
else
digitalWrite ( 13, LOW ); .
delay(1000);
}

martedì 7 gennaio 2014

Controllo batteria su Android

Un semplice snippet per monitorare via Api il livello della batteria su Android

--------------------------------------------------------
import android.os.Bundle;
import android.widget.TextView;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;


public class MainActivity extends Activity {


private TextView battery;

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

battery=(TextView)findViewById(R.id.batteria);

this.registerReceiver(this.batteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
private BroadcastReceiver batteryInfoReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
             
            int  level= intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0);
            battery.setText("Livello : " + Integer.toString(level));
        }
    };

}

Geologi

  E so anche espatriare senza praticamente toccare strada asfaltata