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

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

Palestras do TDC Business Disponíveis Online

🚨 Atenção, TDC Lovers! O TDC Business em São Paulo acabou, mas os conteúdos mal começaram!  Não pô de aproveitar a STADIUM ao vivo? Não tem problema, porque trouxemos ela até você. Todas as palestras da STADIUM, palco principal do TDC, já estão no ar e liberadas para qualquer pessoa assistir. Essa Trilha incrível conta com palestras de Trilhas Premium e temas variados de forma GRATUITA para você poder maratonar de casa!  Aproveite para prestigiar seu evento de TI favorito com pipoca direto do seu sofá. 🎥 🍿 Gravação da STADIUM, 22 a 24 de Agosto de 2022, disponível aqui: https://www.globalcode.com.br/videos/tdc-2022-business/  Todas as demais trilhas do TDC Business serão publicadas gradualmente nas próximas semanas, fique atento aos nossos e-mails, você será notificado por lá quando sua Trilha estiver disponível. Acompanhe nossas redes sociais para não perder nada e ficar por dentro de todas as novidades do TDC!

Seja um Palestrante do TDC Connections 2022

A Equipe TDC está muito feliz e orgulhosa em começar mais uma jornada de eventos em 2022 e criar muitas oportunidades! Agora, chegou o momento para você que sempre quis ser palestrante mas não teve oportunidade, e também de quem já é palestrante experiente, e está ansioso para compartilhar aquela nova prática ou caso de sucesso fresquinho, submeter sua palestra para o TDC Connections e co-criar conosco o maior evento de desenvolvedores do Brasil.  Link de inscrição: https://cfp-conn.thedevconf.com.br/?_ga=2.103579840.1386204218.1643036190-1988609034.1631800014 Confira aqui o calendário do TDC 2022. Nesta edição teremos muitas novidades e você poderá palestrar de forma Online ou Presencial! Entenda como vai funcionar o TDC CONNECTIONS: Nesta edição, além de todo o conteúdo dividido em Trilhas transmitidas ao vivo (13 trilhas simultâneas) também teremos dois eventos híbridos em Recife e Belo Horizonte, que terão uma trilha por dia, ao vivo, para um público limitado, seguindo protocolo

Inspire a mudança com a liderança ágil

A liderança ágil é essencial para que uma organização realize mudanças de negócios significativas. Ser líder é uma tarefa desafiadora, especialmente em um cenário de constantes transformações, principalmente na forma de lidar com a relação empresa e pessoal. Pesquisas sobre liderança na era digital revelam que algumas soft skills têm sido substituídas por outras, o profundo conhecimento na área de negócio, ser referência nas tecnologias utilizadas, ter foco total no prazo e nas entregas e conhecer um arsenal de técnicas e ferramentas, têm dado espaço a habilidades, como: empatia; adaptabilidade; senso de equipe; visão e propósito; engajamento constante. A colaboração entre pessoas de todos os níveis hierárquicos são vitais, afinal, as equipes estão trabalhando para o mesmo objetivo: o encantamento e atendimento das necessidades do cliente que proporcionarão um crescimento sustentável da organização. Com propósito claro, estratégia e prioridades definidas, os times desfrutam de uma ma

TDC Digital: o que você precisa saber para transformar sua carreira em 2022

O TDC Digital é o maior evento de TI do mercado e proporciona crescimento profissional a partir de palestras com especialistas e oportunidades de networking com o mundo todo, direto da sua casa. Através da escolha individual de cada participante é possível obter experiências imersivas e transformadoras conforme o tema-chave de cada trilha.  O evento também é o lugar ideal para ajudar no desenvolvimento de carreiras, permitindo que qualquer pessoa com vontade — e um tema interessante — seja palestrante e compartilhe suas experiências e conhecimentos. Para aqueles que querem  participar como ouvinte a plataforma do TDC favorece conferências dinâmicas, e o encontro de diversas comunidades e ecossistemas de TI. E, após a escolha de uma trilha, fica mais fácil acompanhar especialistas para aprender e se inspirar. Em 2021 , o The Developer’s Conference (TDC) foi 100% digital e, em três dias de evento, contou com mais de 300 horas de conteúdos , incluindo: Agile; Testes; Design; Web e Mobile;

9 ESQUENTAS TDC ESPERANDO POR VOCÊ

O TDC nasceu do sonho de profissionais que valorizam o compartilhamento de conhecimento, experiências e oportunidades entre as comunidades de desenvolvedores.  Por isso, o crescimento do TDC nunca poderia ficar longe do crescimento das comunidades! Pensando nessa união, criamos um projeto quente: O ESQUENTA TDC ! Visando divulgar os meetups de comunidades que querem transformar e inspirar carreiras, foi co-criado este projeto lindo e cheio de apoio, onde o TDC abraça meetups de diversas comunidades espalhadas pelo Brasil e elas contribuem com a divulgação da edição regente.  O TDC Innovation vai rolar de 14 a 16 de JUNHO, mas até lá vão acontecer muitos encontros incríveis!  Fique por dentro das comunidades que vão participar, quais temas irão abordar e claro as datas e locais para você participar. 💥Esquentas TDC Innovation 2023: 24/05 - Esquenta TDC: Carreira e Desenvolvimento Presencial em Floripa das 19:00 as 21:30 com inscrição AQUI Comunidade: Google Developers Groups Nova