Processing - Controle interativo de Servos, e o bug na Standard Firmata
Autor: EGDA | Publicado: 2011-03-31T13:54:00-07:00

Olá, finalmente chegamos aqui em, para a alegria de muita gente que pediu controle de servos com o processing e para decepção de quem esperava poder fazer tudo com a firmata, afinal ela foi feita para se fazer tudo, mas de alguma forma... em fim falaremos sobre isso depois.

A propósito, para quem ainda não baixou, a ide Arduino está de versão nova v22 cheias de atualizações principalmente para usuários da versão UNO vale a pena conferir: http://arduino.cc/en/Main/Software

Agora sim vamos lá, faça o upload do exemplo Servo_firmata , presente na sessão da biblioteca Firmata , ele é uma versão do firmware específico para controle de servos, nenhuma outra forma de controle funcionará se sua placa estiver usando este firmata.

/*&nbsp;This&nbsp;firmware&nbsp;supports&nbsp;as&nbsp;many&nbsp;servos&nbsp;as&nbsp;possible&nbsp;using&nbsp;the&nbsp;Servo&nbsp;library&nbsp;
&nbsp;*&nbsp;included&nbsp;in&nbsp;Arduino&nbsp;0017
&nbsp;*
&nbsp;*&nbsp;TODO&nbsp;add&nbsp;message&nbsp;to&nbsp;configure&nbsp;minPulse/maxPulse/degrees
&nbsp;*
&nbsp;*&nbsp;This&nbsp;example&nbsp;code&nbsp;is&nbsp;in&nbsp;the&nbsp;public&nbsp;domain.
&nbsp;*/
&nbsp;
#include&nbsp;&lt;Servo.h&gt;
#include&nbsp;&lt;Firmata.h&gt;

Servo servos[MAX_SERVOS];

void analogWriteCallback(byte pin, int value)
{
&nbsp;&nbsp;&nbsp;&nbsp;if (IS_PIN_SERVO(pin)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;servos[PIN_TO_SERVO(pin)].write(value);
&nbsp;&nbsp;&nbsp;&nbsp;}
}

void setup() 
{
&nbsp;&nbsp;&nbsp;&nbsp;byte pin;

&nbsp;&nbsp;&nbsp;&nbsp;Firmata.setFirmwareVersion(0, 2);
&nbsp;&nbsp;&nbsp;&nbsp;Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);

&nbsp;&nbsp;&nbsp;&nbsp;for (pin=0; pin &lt; TOTAL_PINS; pin++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (IS_PIN_SERVO(pin)) {
 &nbsp;&nbsp;&nbsp;&nbsp;servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Firmata.begin(57600);
}

void loop() 
{
&nbsp;&nbsp;&nbsp;&nbsp;while(Firmata.available())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Firmata.processInput();
}

Depois de ter gravado o exemplo na sua placa, abra o processing e vamos ao trabalho.

OBS.: Este programa utiliza a biblioteca Arduino feita para o processing, caso já não tenha, faça o download da mesma e extraia na pasta Libraries dentro do processing.

processing-arduino-0017.zip

import processing.serial.*;

import cc.arduino.*;

Arduino&nbsp;meuArduino;&nbsp;//Inicializa placa 

void setup() {
&nbsp;&nbsp;size(500, 500);
&nbsp;&nbsp;meuArduino&nbsp;=&nbsp;new Arduino(this, Arduino.list()[1], 57600); 
&nbsp;&nbsp;meuArduino.pinMode(3,Arduino.SERVO);&nbsp;//Declara pino 3 como SERVO
&nbsp;&nbsp;meuArduino.pinMode(5,Arduino.SERVO);&nbsp;//Declara pino 5 como SERVO
}

void draw() {
&nbsp;&nbsp;//Muda a cor de fundo de acordo com a posição do mouse.
&nbsp;&nbsp;background(constrain(mouseX / 2, 0, 255));
&nbsp;&nbsp;//Mapeia e escreve a posiçãoX no servo do pino 3 
&nbsp;&nbsp;meuArduino.analogWrite(3,&nbsp;int(map(mouseX,0,500, 0, 180)));
&nbsp;&nbsp;//Mapeia e escreve a posiçãoX no servo do pino 3
&nbsp;&nbsp;meuArduino.analogWrite(5,&nbsp;int(map(mouseY,0,500, 0, 180)));
&nbsp;&nbsp;//Repare na função int, ela é necessaria para a conversão
&nbsp;&nbsp;//de float (resultado do mapeamento) para int.
}


Pronto, você poderá ligar quantos servos sua placa suportar, e controlar todos por aí.

Agora vem a parte RUIM...

O Standard Firmata foi criado realmente para fazer tudo... inclusive controlar servos, mas de alguma forma, mesmo que você defina seu pino como SERVO , e realmente o comando passado a placa seja o comando de escrever uma posição do servo, utilizando a própria biblioteca Servo nativa do arduino, a placa NÃO RESPONDE CORRETAMENTE, pois ela enviará um sinal PWM ao servo, o que faz ele se movimentar de forma um pouco semelhante (dependendo do servo) porem é totalmente impreciso. Já venho pesquisando e tentando fazer alterações na Standard Firmata para tentar solucionar este problema sem sucesso...

Caso algum de vocês consiga controlar um servo com precisão utilizando a Standard Firmata, por favor deixe me saber o/

Até mais.