[Tutorial] Aprendendo a Mexer com o Sun SPOTS, parte 2: O Acelerômetro

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

To see a translation of this blog post in English, click here.

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

Continuando nosso tutorial sobre Sun Spots. Se você perdeu a primeira parte, confira-a aqui.

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

Conhecendo o Acelerômetro

Na página de documentação você encontra um PDF com informações sobre o acelerômetro. Antes de começar a programar freneticamente, vamos conhecê-lo um pouco melhor: trata-se de um acelerômetro de três eixos, conforme ilustrado abaixo:

Acelerômetro do SunSPOT

As setas e os sinais indicam em que sentido os valores serão negativos, e em qual direção eles serão positivos - por exemplo, ao inclinar o acelerômetro para cima, o valor do eixo Z será positivo.

Não entrarei em detalhes sobre as aspectos técnicos do acelerômetro já que eu não considero isso tão relevante para poder usá-lo. Para quem tiver interesse, porém, consulte o documento original na página do SunSpots, ou leia este PDF sobre o acelerômetro usado.

A biblioteca do SunSpot inclui a interface IAccelerometer3D, que possui todos os métodos comuns a acelerômetros em geral e a classe LIS3L02AQAccelerometer  que implementar a interface e adiciona alguns métodos exclusivos desse acelerômetro.

A API padrão possui métodos bastante simples para obter os valores de aceleração em cada eixo: getAccelX(), getAccelY() e getAccelZ(). Além disso, o método getAccel() serve para obter o módulo da soma dos vetores, ou seja, a raiz da soma dos quadrados de cada eixo. Ou seja: |a| = (|X|2 + |Y|2 + |Z|2)½.

Há um detalhe importante a ser observado: em repouso, o SunSPOT está sujeito a uma aceleração positiva de 1g no eixo Z como resposta à ação da gravidade. Ou seja, para verificar se o SunSPOT está em movimento, você teria um método como esse:

public boolean isMoving() throws IOException {
    double mag = acc.getAccel();
    return Math.abs(mag – 1.0) >= 0.1;
}

Onde você deve subtrair 1 justamente por causa desse 1g da gravidade. Além disso, como você pode perceber, a aceleração é medido em termos da força gravitacional da Terra. Ou seja, uma aceleração de 4,9 m/s2 corresponde a cerca de 0.5 para o SunSPOT.

Se você quiser medir a aceleração relativa a uma posição de repouso qualquer, você irá utilizar os métodos getRelativeAccelX(), getRelativeAccelY(), getRelativeAccelZ() e getRelativeAccel para obter as acelerações e o método setRestOffsets() para definir a posição de repouso. Neste caso, verificar se o Sun SPOT está em movimento envolveria apenas verificar se getRelativeAccel() retorna um valor maior do que 0.1, sem a necessidade de subtrair o 1g da gravidade, e definir um setRestOffsets() antes do loop para definir o repouso como posição de comparação.

Além desses métodos, temos também os métodos getTiltX(), getTiltY() e getTiltZ() na interface IAccelerometer3D. Eles servem para obter os valores de inclinação do acelerômetro, em relação a um nível e de acordo com a aceleração medida. Um esquema da relação entre essas variáveis é mostrado abaixo:

Sun SPOT - Tilt

O método getTiltX() retorna o ângulo, em radianos (em um intervalo de -pi/2 a +pi/2) do nível com a aceleração. No caso, vemos no triângulo menor que a hipotenusa deste ângulo é o módulo da aceleração total, e o cateto oposto é a aceleração no eixo X.

O documento do acelerômetro mostra um exemplo de uma aplicação bastante simples, que pisca os leds de acordo com a posição do acelerômetro.

Um Exemplo Simples Usando o Acelerômetro

Vamos analisar o código e testá-lo. Se você está em dúvida de como criar seu projeto ou de como testá-lo no emulador de Sun SPOT, consulte a primeira parte deste tutorial que possui essas instruções.

Certifique-se de que você possui essas importações no início de StartApplication:

import com.sun.spot.sensorboard.\*;
import com.sun.spot.sensorboard.peripheral.IAccelerometer3D;
import com.sun.spot.util.Utils;

O método startApp deve ser o seguinte:

//primeiro, vamos obter as instâncias dos leds e dos acelerômetros para que esses dispositivos possam ser manipulados e acessados.
private ITriColorLED [] leds = DemoBoard.getInstance().getLEDs();
IAccelerometer3D acc = EDemoBoard.getInstance().getAccelerometer();


protected void startApp() throws MIDletStateChangeException {         

for (int i = 0; i < 8; i++) {
        leds[i].setOff();                   // desliga todos os leds
        leds[i].setRGB(0,200,0);     // deixa os LEDs verdes quando acesos
}
while (true) {
        try {
            int tiltX = (int)Math.toDegrees(acc.getTiltX()); // retorna o valor, em graus, da inclinação no eixo X.
            int offset = -tiltX / 15;       // O valor negativo se deve ao fato de que o eixo X do Sun SPOT é invertido em relação ao que estamos habituados. Inverte-se a inclinação para que ela fique da maneira que estamos habituados: valores negativos à esquerda, valores positivos à direita. Divide-se por 15 para obter valores que possam ser utilizados como deslocamento dos LEDs ligados para a esquerda e para a direita.
            if (offset < -3) offset = -3;   // limita os valores no intervalo [3, -3]
            if (offset > 3) offset = 3;
            leds[3 + offset].setOn();       // usar dois LEDs
            leds[4 + offset].setOn();      //3 e 4 são os LEDs do meio, o offset é o deslocamento dos LEDs para a esquerda e para a direita
            Utils.sleep(50);                // atualiza 20 vezes por segundo
            leds[3 + offset].setOff();      // limpa o display, apagando os LEDs
            leds[4 + offset].setOff();
        } catch (IOException ex) {
            System.out.println("Error reading accelerometer: " + ex);
        }
    }
}

Após construir o projeto e rodar o jar criado no Sun SPOT virtual do Solarium, você pode clicar com o botão direito sobre o Sun SPOT, pedir para mostrar os valores dos sensores e, na aba do acelerômetro, brincar um pouco com o eixo X para ver o programa funcionando, como abaixo:

SunSPOT - Sun SPOT virtual no Solarium, com sensores

Mexendo o cursor do eixo X na direção dos valores negativos equivale a mexer o Sun SPOT real para a direita, como pode ser visto na figura. Você pode mexer e ver que os LEDs acompanham o movimento.

Esses são os métodos que você provavelmente irá usar em seu projeto, mas não são os únicos. A classe LIS3L02AQAccelerometer implementa alguns outros métodos específicos.

Por exemplo, você pode definir em qual escala deseja trabalhar: de -2g a +2g, ou de -6g a +6g. O padrão, como pode ser visto pelo screenshot acima, é de -2 a +2.

Para mudar a escala, você deve usar o método setScale(LIS3L02AQAccelerometer.SCALE_2G); onde SCALE_2G é a constante para a escala de 2G, e SCALE_6G é a constante para uma escala de 6G. Para usar esse método, você deve incluir a biblioteca com.sun.spot.sensorboard.LIS3L02AQAccelerometer  na sua classe. E para obter a escala sendo utilizada no momento, você possui o método getCurrentScale().

Além disso, caso você deseje desenvolver alguma aplicação que utilize o acelerômetro de maneira muito criativa, você provavelmente vai se interessar por métodos mais obscuros, como getRawX(), getRawY() e getRawZ(), que são os métodos que retornam os valores de tensão em cada eixo. Essa tensão é utilizada para calcular a aceleração em cada eixo, utilizando a fórmula a = (Raw - zeroOffset)/gain, onde zeroOffset é a tensão no repouso e possui valor nominal de 465.5 e o ganho possui valor nominal de 186.2 na escala 2G e 62 na escala 6G.

Para obter os valores de offset e o ganho, você possui os métodos getZeroOffsets(), getGains() e getRestOffsets() (esse último usado para calcular aceleração relativa). Esses métodos retornam, cada um, uma matriz [2][3], onde primeiro vem a escala e depois o eixo desejado. Por exemplo, zeroOffsets[scale][0] retorna zeroOffset na escala utilizada, no eixo X. Essas matrizes podem ser definidas pelos métodos setZeroOffsets, setGains e setRestOffsets.

O último método a ser mencionado nessa parte do tutorial é o reset(), que retorna a escala para os valores padrões e garante que o acelerômetro não está em modo de auto-teste.

Calibrando o Acelerômetro

Como cada acelerômetro é diferente, é necessário calibrar o Sun Spot. Isso é feito movimentando o acelerômetro para cima e para baixo. Uma aplicação para calibrar o Sun SPOT se encontra no Sun SPOT SDK, na pasta Demos/CalibrateAccelorometer.

Como não faz muito sentido calibrar um Sun SPOT virtual, vou deixar para examinar isso com mais cuidado quando estiver com um Sun SPOT em mãos.

E aqui nós terminamos a segunda parte do tutorial. Como eu estou estudando o Sun SPOT para um projeto, eu irei focar meus estudos no que eu pretendo usar, mas, se vocês tiverem interesse em alguma parte em especial, avisem que eu tento falar sobre isso aqui, ok?

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

Para continuar o tutorial, siga para a próxima parte, que mostra os Sun SPOTs que chegaram para mim, que se encontra aqui.

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


Comments:

Um post genial, justamente nesta sexta-feira meu professor de robótica nos contava alguns conceitos sobre acelerômetros. Mais ele ficou mais na parte de funcionamento, falando de capacitores de capacitância variável.

Posted by Arnie on Março 01, 2009 at 05:47 AM GMT+03:00 #

Excelente, Cindy! Gostei bastante!

:D

Posted by Bruna Campos on Março 25, 2009 at 02:37 PM GMT+03:00 #

Menina, vc é um gênio!!! Também estou estudando o sun SPOT pra desenvolver um projeto e seu post me ajudou bastante, valeu!

Posted by Joyce Aline on Agosto 19, 2009 at 10:08 PM GMT+03:00 #

Olá Cindy, como vai?

Gostei do artigo, ajudou muito!
Porém, gostaria de saber se pode me ajudar em outra coisa. Como eu faria para receber estes dados (do acelerômetro ou mesmo temperatura) e escrevê-los, por exemplo, em um arquivo texto. Pois consegui trabalhar para exibir apenas no console.

Muito Obrigado.

Posted by Henrique on Outubro 02, 2009 at 12:02 PM GMT+03:00 #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Blog com tutoriais relacionados a desenvolvimento de software, especialmente Java, e que conta com as experiências de desenvolvimento de uma menina maluquinha, digo, eu.

Search

Archives
« Abril 2014
SegTerQuaQuiSexSábDom
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today