Pular para o conteúdo principal

Arduino + Sun Spot + Controle Remoto

Finalizamos nesta semana um incrível projeto de integração do Sun Spot com Arduino. Costumo dizer que o Sun Spot é o primo rico do Arduino e como não conseguimos encontrar acelerômetros em estoque nas lojas dos Estados Unidos, acabamos por topar o desafio de fazer o Arduino pegar os dados do acelerometro do Sun Spot, um tipo de "mashup" de hardware, ou no clássico termo: um hacking.

Para ter uma "implementação de referência" de uso do Sun Spot com Arduino, pegamos um controle de remoto infravermelho de um bicho bem esquisito que trouxemos da Maker Faire: o Mechamo.

O resultado esta no vídeo abaixo onde controlamos esta aranha usando o acelerômetro do Sun Spot:



Com o mesmo conceito você pode usar qualquer recurso do Sun Spot no Arduino e vice-versa. Vamos avançar agora transformando o código em bibliotecas para o Arduino com C++ e Jars para o Sun Spot.

O projeto contou com inúmeras colaborações do Paulos Carlos Ferreira dos Santos e Benedicto Franco Junior. Dois grandes mentores e parceiros Globalcode.

A seguir o descritivo completo incluindo código-fonte do projeto.

Etapa 1: abrindo e interceptando o controle remoto

Abrimos o controle remoto dela e para nossa sorte seu controle é o mais básico possível: com 4 botões comuns. Com isso usando o multimetro descobrimos qual era o pino de sinal de cada botão e soldamos 5 fios: 1 no terra e 1 para cada botão, esquerda, direita, frente e traz. Feito.

Etapa 2: testando o controle remoto com Arduino

Logo que terminamos testamos controlar o controle remoto puramente com Arduino e funcionou bem tranquilo o que nos deu uma segurança para prosseguir para a próxima fase: integrar o Arduino com Sun Spot, transferir dados do acelerometro do Sun Spot e depois comandar o controle remoto.

Etapa 3: integrando Arduino com Sun Spot método 1

A primeira solução que implementamos foi a mais ansiosa, diria assim. Foi com a técnica de polling, usamos 3 digitais: uma para dados, uma para polling e uma para acknowledge. Polling é basicamente ficar laço infinito lendo o sinal e assim que mudar de estado, 0 para 1 ou inverso, você reage e inicia a leitura dos dados. Funcinou! Mas deu um trabalhão para sincronizar os hardwares, na real tivemos que ir tentando o melhor delay após mudar o estado de uma porta digital. Enfim, mas funcionou gastando processamento de polling e também com custo de delays bem alto.

Etapa 4: mudando para usar interrupções no Arduino

Apresentando a engenhoca para o real engenheiro Paulo Carlos Ferreira dos Santos, tivemos uma mudança siginificativa na técnica: usar uma das 2 interrupções disponíveis do Arduino. UAU. Show de técnica. Basicamente mantivemos o uso de 3 digitais, porém uma das digitais ligamos do Sun Spot no Arduino Digital 2 que representa a interrupção 0, a digital 3 a interrupção 1. O que muda radicalmente é o código, pois fica assíncrono e a programação de serviços de interrupção (IRS) requer algumas práticas.

Se você é programador Java como eu, logo vai querer pensar com Threads, o que não acontece com Arduino pois ele é real-time. Xii, e as váriáveis que são alteradas pelos serviços de interrupção? Se temos duas interrupções? Pois é, a boa prática é quando entrar em uma interrupção, bloquear a outra, que no caso de só termos duas fica tranquilo. Bem, viagens a parte, seguimos adiante com a implementação de interrupção, que requer o uso das seguintes funções do Arduino:

attachInterrupt(0, suaFuncaoDeInterrupcao, RISING);

Esta função esta vinculando na interrupção 0, porta digital 2, a função "suaFuncaoDeInterrupcao", quando o sinal mudar de 0 para 1, e apenas de 0 para 1. Poderia ser falling (contrário), CHANGE qualquer mudança ou ainda LOW, ou seja, sempre que 0. Enfim, fácil de usar.

Aprendemos também que devemos fazer o mínimo necessário dentro da função de serviço de interrupção, pois em primeiro tentar interromper uma vez e transferir um byte por vez, não deu. Ai mostramos novamente a engenhoca para o engenheiro que diagnosticou com precisão: tem que ser uma interrupção por bit... Dito e feito e sincronizado.

Outro detalhe é que as variáveis que alteramos nas função de serviço de interrupção devem ser volatile (se lembram deste nome no Java??) volatile é uma diretiva de compilação que faz o Arduino alocar esta variável na RAM e não na stack e seu único uso é realmente para funções de interrupção.

Sei que ficou grande o post mas foram muitos aprendizados que queremos documentar e compartilhar com todos. Vejam o código completo do Arduino:

int SUN_SPOT = 9;
int SUN_SPOT_ACK = 10;
int SUN_SPOT_INTERRUPT = 0; //PORTA digital 2

int FORWARD=7; //fio branco
int BACKWARD=6; //fio laranja
int LEFT=4; //azul
int RIGHT=5; //verde

int interrupt=0;
volatile int data;
volatile boolean bit_array[16];
volatile int contador;
volatile int x;
volatile int y;

void setup() {
setupSunSpot();
//Setup do controle remoto da Aranha
setupMechamo();

attachInterrupt(0, receiveSunSpot, RISING);
Serial.begin(9600);
}
void setupSunSpot() {
pinMode(SUN_SPOT,INPUT);
pinMode(SUN_SPOT_ACK,OUTPUT);
}
void setupMechamo() {
pinMode(FORWARD, OUTPUT);
pinMode(BACKWARD, OUTPUT);
pinMode(LEFT, OUTPUT);
pinMode(RIGHT, OUTPUT);
digitalWrite(SUN_SPOT_ACK,LOW);
digitalWrite(FORWARD,HIGH);
digitalWrite(BACKWARD,HIGH);
digitalWrite(LEFT,HIGH);
digitalWrite(RIGHT,HIGH);
}
void receiveSunSpot() {
digitalWrite(SUN_SPOT_ACK,LOW);
bit_array[contador++]=digitalRead(SUN_SPOT);
if(contador==16) {
contador=0;
x = BtoI(0,7,bit_array);
y = BtoI(8,15,bit_array);
}
digitalWrite(SUN_SPOT_ACK,HIGH);
}

int BtoI(int start,int end, volatile boolean bits[]){
boolean negative=bits[start];
start++;
unsigned long integer=0;
unsigned long mask=1;
int r;
for (int i = end; i >= start; i--) {
if(negative) {
if (!bits[i]) integer |= mask;
}
else {
if (bits[i]) integer |= mask;
}
mask = mask << 1;
}
r = (int) integer;
if(negative) r= ~r;
return r;
}

void loop() {
digitalWrite(RIGHT, !(x>30 && x<90));
digitalWrite(LEFT, !(x<-30 && x>-90));
digitalWrite(FORWARD, !(y>30 && y<90));
digitalWrite(BACKWARD, !(y<-30 && y>-90));

Serial.print("x = ");
Serial.println(x);
Serial.print("y = ");
Serial.println(y);
delay(300);
}




Podemos perceber que o método loop fica totalmente independente da recepção dos dados do Sun Spot. Isso acontece assincronamente pela interrupção. Lembrando que apesar de termos apenas 2 no Arduino convencional, o Arduino Mega oferece 4 interrupções. Se fossemos criar um sistema de threads com para ATMega sem dúvida metade do caminho esta andado com este projeto.

Bem, vamos analisar agora o lado do Sun Spot. Lá é nossa praia (pelo menos minha), pois é Java. Programamos o Sun Spot com NetBeans e Midlets e uma agradável API no leva para os objetos que representam componentes do Sun Spot, como acelerômetro e portas digitais / analógicas.

Com este código obtemos as portas digitais de comunicação com Arduino:
 private IIOPin arduinoData = EDemoBoard.getInstance().getIOPins()[EDemoBoard.D0];
private IIOPin arduinoStrobe = EDemoBoard.getInstance().getIOPins()[EDemoBoard.D2];
private IIOPin arduinoAck = EDemoBoard.getInstance().getIOPins()[EDemoBoard.D1];



Aqui configuramos no startup se as portas serão de input ou output além do estado inicial delas:

  protected void startApp() throws MIDletStateChangeException {
arduinoData.setAsOutput(true);
arduinoStrobe.setAsOutput(true);
arduinoAck.setAsOutput(false);
arduinoData.setHigh(false);
arduinoStrobe.setHigh(false);
arduinoLoop();
}



O código completo ficou assim:

package br.com.globalcode.arduino;

import com.sun.spot.sensorboard.io.IIOPin;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ITriColorLED;
import com.sun.spot.sensorboard.peripheral.LEDColor;
import com.sun.spot.sensorboard.peripheral.IAccelerometer3D;
import com.sun.spot.util.Utils;

import java.io.IOException;

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/*
* ArduinoIntegration.java
*
* This simple Sun Spot Midlet reads accelerometer X and Y axis and send
* to Arduino using interruption.
*
* author: Vinicius Senger - vinicius@globalcode.com.br
* Paulo Carlos dos Santos - paulosantos@globalcode.com.br
* date: July, 2009
*/
public class ArduinoIntegration extends MIDlet {

private IAccelerometer3D accel = EDemoBoard.getInstance().getAccelerometer();
private ITriColorLED[] leds = EDemoBoard.getInstance().getLEDs();
private IIOPin arduinoData = EDemoBoard.getInstance().getIOPins()[EDemoBoard.D0];
private IIOPin arduinoStrobe = EDemoBoard.getInstance().getIOPins()[EDemoBoard.D2];
private IIOPin arduinoAck = EDemoBoard.getInstance().getIOPins()[EDemoBoard.D1];

public void arduinoLoop() {
for (int i = 0; i < 8; i++) {
leds[i].setOff(); // turn off all LEDs
leds[i].setColor(LEDColor.BLUE); // set them to be blue when lit
}
int oldX = 0;
int oldY = 0;
while (true) {
try {
int tiltX = (int) Math.toDegrees(accel.getTiltX()); // returns [-90, +90]
int tiltY = (int) Math.toDegrees(accel.getTiltY()); // returns [-90, +90]
if (tiltX != oldX || tiltY != oldY) {
sendBitsToIO(getBits((byte) tiltX), getBits((byte) tiltY));
oldX = tiltX;
oldY = tiltY;
}
changeLeds(tiltX);
} catch (IOException ex) {
System.out.println("Error reading accelerometer: " + ex);
}
}
}
private void sendBitsToIO(boolean bitsX[], boolean bitsY[]) {
for (int x = 0; x < bitsX.length; x++) {
send(bitsX[x]);
}
for (int y = 0; y < bitsY.length; y++) {
send(bitsY[y]);
}
}

private void send(boolean bit) {
arduinoData.setHigh(bit);
arduinoStrobe.setHigh();
arduinoStrobe.setLow();
while (arduinoAck.isLow());
}

private boolean[] getBits(byte value) {
//Depois de escrever o método minha
//querida esposa lembrou to Integer.toBinaryString :)
// Agora fica assim mesmo.
boolean result[] = new boolean[8];
byte displayMask = (byte) (1 << 7);
for (int c = 0; c < 8; c++) {
result[c] = (value & displayMask) != 0;
value <<= 1;
}
return result;
}

private void changeLeds(int tiltX) {
int offset = -tiltX / 15;
if (offset < -3) {
offset = -3;
}
if (offset > 3) {
offset = 3;
}
leds[3 + offset].setOn();
leds[4 + offset].setOn();
Utils.sleep(20);
leds[3 + offset].setOff();
leds[4 + offset].setOff();
}


protected void startApp() throws MIDletStateChangeException {
arduinoData.setAsOutput(true);
arduinoStrobe.setAsOutput(true);

arduinoAck.setAsOutput(false);
arduinoData.setHigh(false);
arduinoStrobe.setHigh(false);
arduinoLoop();
}

protected void pauseApp() {
}

protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
for (int i = 0; i < 8; i++) {
leds[i].setOff();
}
}
}

Comentários

Dr. Spock disse…
Ficou show de bola essa video montagem ... Só acho que faltou colocar o SyntaxHighlighter para mostrar o código fonte formatado e colorido como aparece em alguns outros blog ...

Dica: http://developertips.blogspot.com/2007/08/syntaxhighlighter-on-blogger.html
Hey Vinicius,

Qual irá ser o seu próximo desafio? Que tal integrar o SunSpot com esta aranha?
Unknown disse…
Detalhe pra taça de vinho em cima da mesa =P
Wagner Santos disse…
Bem loko heim Vinicius, parabéns !!! =)

Quero um brinquedinho desses para mim hehe..

Alguém já pensou em fazer experiências com o Lego Mindstorms e o Arduino, ou o Sun Spot,, deve ser no minimo interessante ..

Abraço,
Unknown disse…
@Wagnão: logo você poderá ter o seu pois nesta semana chegam os Program-ME. Lego MindStorms rola normal com Arduino, ja tem bastante gente fazendo com a versão mais recente da Lego. Mas o mais legal do hacking é fazer coisas com o que você tem na mão.

Agora estou neste mesmo projeto integrando o GPS Garmin que eu tenho para fazer a Aranha andar em rotas traçadas por GPS. Minha idéia é fazer ela aprender a chegar na praia sozinha, afinal de contas, é a inteligência mais digna de um robô filho de peixe.RS.

O mais legal disso é poder ver a eletrônica no baixo nível e praticar deslocamento de bits como nunca.

Isso é muito bom pois todos os fundamentos de lógica e algoritmos são praticados.

[]s
Vinicius
Unknown disse…
@Bene, meu próximo é usar o GPS para guiar ela por latitude e longitude. A comunicação Garmin X Arduino não demorou 15 minutos. Agora comprei DB9 e estou montando um hacking cable serial para facilitar. O que esta dificil nesta etapa é que o GPS só pega fora de casa e por conta das árvores, só com tempo bom. Como esta chovendo muito por aqui, esta integração esta parada. RSRSS. Desculpão hein?
Vinícius,

Lembre-se que o GPS comum, nas melhores condições, tem precisão variando em torno dos 15 metros. Com o serviço de correção WAAS disponível apenas na América do Norte, a precisão melhora para algo em torno de 3 metros.

[]s,

Bene.
Paulo Siqueira disse…
Muito legal mesmo! Mas concordo com o Spock, faltou um Sintax Highlight aí ;)
Anônimo disse…
Muito legal a integração de hardwares.

Postagens mais visitadas deste blog

Você já pensou em ser palestrante em algum evento ?

Você já deve ter participado de algum evento e pensado como deve ser legal ser palestrante... E para falar a verdade, é muito bom mesmo. Eu adoro, o Vinicius adora e conheço muitas pessoas que curtem cada minuto da participação no evento como palestrante. Com certeza é uma responsabilidade a mais. Você sente medo, adrenalina, tem que se preparar. Literalmente coloca a cara a tapa para qualquer pessoa te avaliar em todos os sentidos. Qual o seu tom de voz?  Seus slides são legais? Você manja mesmo ?  Seu português está ok?  E as palavras em inglês ?  Teve algum deslize técnico? E MUITO mais.  Mas é claro que a exposição tem dois lados... e os resultados podem ser ótimos. Normalmente conhecemos mais pessoas como palestrantes e podem surgir boas oportunidades de negócio. É sempre positivo ter uma nova referência positiva quando as pessoas buscam nosso nome no Google, podemos fazer a diferença para quem está assistindo a palestra e muito mais.  No The Developer's

TDC INNOVATION lança University Pass

Modalidade de ingresso tem como objetivo ajudar na capacitação dos universitários Uma pesquisa realizada em 2020 pela Associação Brasileira das Empresas de Tecnologia da Informação e Comunicação (Brasscom) diz que até o ano de 2024 o Brasil precisará de cerca de 420 mil profissionais na área de Tecnologia da Informação. Porém, por ano, a mesma pesquisa diz que o país forma apenas 46 mil profissionais capacitados no nicho. Pensando nisso, para ajudar na formação e capacitação desses jovens profissionais, o TDC INNOVATION, segunda edição do ano do The Developer's Conference, lança o University Pass, modalidade de ingresso que possibilita aceso digital gratuito a todas as palestras do evento, ou com 50% de desconto para quem preferir ir pessoalmente. Com o tema central “Desafios para a criação do futuro Digital”, o TDC INNOVATION ocorrerá entre 1 e 3 de junho, de forma híbrida: presencialmente no Centro de Convenções CentroSul, em Florianópolis, e com transmissão simultaneamente pela

Inscrever sua equipe em eventos de TI vale a pena? Entenda aqui

Os eventos de TI são importantes para o aprendizado contínuo, especialmente em uma área tão dinâmica, como a de tecnologia. A necessidade de estar sempre por dentro das tendências pode esbarrar em algumas objeções, como investir em especializações pouco práticas ou opções pulverizadas de mercado. Por isso, participar de conferências e assistir palestras de especialistas é uma excelente oportunidade para sua equipe se desenvolver. O melhor de participar de eventos de TI é expandir os conhecimentos e habilidades independentemente da experiência específica, seja um desenvolvedor web ou full stack, por exemplo, as conferências de tecnologia podem ajudar o profissional a se aperfeiçoar. Isso ocorre devido ao contato com outros especialistas e colegas da mesma área. Além disso, é possível descobrir novas soluções e fazer networking . Neste artigo, você conhecerá as vantagens da sua equipe participar em eventos de TI. Aproveite a leitura! Vantagens de participar de eventos de TI Se o seu ob

Entendendo como funciona a programação de computadores: linguagens de programação, lógica, banco de dados

Nesse post, diferente dos últimos que foram mais enfáticos nas experiências com tecnologias, vou focar um pouco mais nos profissionais que estão começando, ou pretendem ingressar na área de desenvolvimento de software, falando sobre conceitos fundamentais relacionados a programação em geral . Mercado de trabalho para programação Conforme já sabemos, o mercado de desenvolvimento de software, especialmente no Brasil, continua em franca expansão, sendo que cada vez mais as empresas buscam desenvolver seus próprios sistemas usando as mais diferentes e novas tecnologias. Algumas matérias interessantes: As seis profissões mais valorizadas em 2010 no IDG Now! Muitas vagas e sensação de reaquecimento da economia Por isso, a área de desenvolvimento de software tem despertado interesse em muitos profissionais de outras áreas que desejam mudar de profissão, já que as oportunidades de trabalho tendem a ser maiores. Esse é um perfil presente em muitos dos clientes da Globalcode que acabou m

Segurança da informação no alvo: o que esperar do futuro?

A segurança da informação não se trata apenas de proteger os dados contra acesso não autorizado. Na prática, refere-se aos recursos que impedem: uso; registro; inspeção; divulgação; interrupção; modificação; destruição de dados. O uso de dados pode abranger desde um perfil nas redes sociais a detalhes financeiros, biometrias ou novos projetos. Por isso, a preocupação com a proteção dos dados é crescente, tanto para empresas quanto clientes. Para muitas pessoas, a coleta de dados é considerada invasão de privacidade, criando desconfiança do titular dos dados, pois o uso dos dados pode ser facilmente corrompido, utilizado para fins não declarados. Apesar de o uso dos dados terem impulsionado os avanços tecnológicos na última década, as organizações lidam com o desafio de distinguir dados de informações pessoais de modo a proteger a privacidade e as preferências dos clientes. Neste artigo, abordaremos o impacto da segurança da informação e o que esperar do futuro. Confira casos conhecido

TDC ONLINE: SUA PLATAFORMA DE PALESTRAS GRAVADAS DO TDC DISPONÍVEL

Além do conteúdo ao vivo transmitido online nas edições do TDC, agora você pode ter acesso à centenas de palestras gravadas, através da nossa nova plataforma de vídeos - o TDC Online, que reúne todas as Trilhas premium, Stadium e Salas dos Patrocinadores das edições anteriores de 2022, TDC Innovation e TDC Connections.  Para acessar, basta clicar na edição em que você participou ( TDC Innovation ou TDC Connections ); Fazer o mesmo login (com e-mail e senha) cadastrados na hora de adquirir ou resgatar o seu ingresso no TDC; E clicar na Trilha de sua opção, e de acordo com a modalidade do seu ingresso. Logo em seguida, você será direcionado para a seguinte página com a lista de todas as palestras por Trilha: Pronto! Agora você tem acesso à centenas de palestras gravadas da sua área de interesse, para assistir como e quando quiser! Caso tenha esquecido a senha, clique na opção "Esqueci a senha" , insira o e-mail que você realizou para o cadastro no evento, e aparecerá a op