L'accelerometro è uno strumento di input continuo (nel senso che l'input si presenta come flusso ininterrotto di informazioni in cui la variazione tra una lettura e la successiva è molto ridotta) estremamente intuitivo.
Come dice il nome stesso, l'accelerometro misura non lo spostamento del device, quanto la sua accelerazione lungo le tre dimensioni (X, Y e Z), ossia, genericamente, il rapporto tra la variazione di velocità e l'intervallo di tempo considerato. L'orientamento degli assi è ben esemplificato nell'immagine seguente:
Lo svantaggio nell'uso dell'accelerometro in connessione con il touch panel è dato dalla perdita di precisione dei tocchi. Ciò induce una "dicotomia" di controllo:
- Controllo preciso basato esclusivamente su tocchi su tutto lo schermo
- Controllo veloce usando l'accelerometro (veloce perché suscettibile di leggere la benché minima variazione nel flusso continuo di dati), ma poco preciso con i tocchi (si presuppone dei soli pollici, perché le altre dita saranno impegnate a reggere il device ?)
- Una variante intermedia tra le due
Prepariamoci dunque a leggere i valori dell'accelerometro. Per prima cosa includiamo nel nostro progetto la reference alla dll Microsoft.Devices.Sensors e la relativa inclusione del namespace apposito tramite la direttiva using. Adesso possiamo dichiarare il nostro sensore e inizializzarlo come segue:
Accelerometer accelerometerSensor = new Accelerometer();
Per completezza, è opportuno tenere presente come la classe Accelerometer esponga anche una proprietà State di tipo SensorState che, come si può intuire dal nome, indica lo stato dell'accelometro:
public enum SensorState
{
NotSupported = 0,
Ready = 1,
Initializing = 2,
NoData = 3,
NoPermissions = 4,
Disabled = 5,
}
Per avviare l'accelerometro è sufficiente a questo punto invocare il metodo Start, opportunamente incluso in un blocco try/catch nel caso in cui il sensore non sia, per una ragione qualunque, disponibile:
try
{
accelerometerSensor.Start();
}
catch (Exception ex)
{
// Gestire l'eccezione
}
Una volta avviato il sensore, possiamo metterci in ascolto dell'evento ReadingChanged nel seguente modo:
accelerometerSensor.ReadingChanged += new EventHandler< AccelerometerReadingEventArgs>(accelerometerSensor_ReadingChanged);
L'evento verrà così sollevato ogni qual volta il sensore registrerà nuovi dati e la callback riceverà un valore di tipo AccelerometerReadingEventArgs, contenente i valori di accelerazione misurati lungo i tre assi X
, Y
e Z
(espressi con un double
), più un TimeStamp indicante il momento in cui la lettura è avvenuta:
DateTimeOffset Timestamp { get; }
double X { get; }
double Y { get; }
double Z { get; }
È importante sottolineare che, anche quando il device è completamente immobile (ad esempio perché appoggiato sul tavolo), è comunque sottoposto alla forza di gravità, nonché alla rotazione terrestre, per cui in realtà l'accelerazione non sarà mai pari a 0
, variando continuamente in base alle forze di cui sopra (ad esempio, sull'asse Z riceveremo sempre un valore vicino a -1
, che rappresenta la resistenza alla forza di gravità, suscettibile peraltro di variazione in base alla collocazione geografica e all'altezza rispetto al livello del mare). Il risultato sarà dunque un flusso praticamente continuo di dati proveniente dal sensore.