quinta-feira, 31 de março de 2011

Processing - Controle interativo de Servos, e o bug na Standard Firmata

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.

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

Servo servos[MAX_SERVOS];

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

void setup() 
{
    byte pin;

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

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

void loop() 
{
    while(Firmata.available())
        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 meuArduino; //Inicializa placa 

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

void draw() {
  //Muda a cor de fundo de acordo com a posição do mouse.
  background(constrain(mouseX / 2, 0, 255));
  //Mapeia e escreve a posiçãoX no servo do pino 3 
  meuArduino.analogWrite(3, int(map(mouseX,0,500, 0, 180)));
  //Mapeia e escreve a posiçãoX no servo do pino 3
  meuArduino.analogWrite(5, int(map(mouseY,0,500, 0, 180)));
  //Repare na função int, ela é necessaria para a conversão
  //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.

8 comentários:

  1. O meu dá o seguinte erro : Canonot find anything named "Arduino.Servo" O que pose ser? Poderia me ajuadar?

    ResponderExcluir
  2. Simples, nao existe Arduino.Servo, sim Arduino.SERVO , SERVO td maiusculo...

    ResponderExcluir
  3. Este comentário foi removido pelo autor.

    ResponderExcluir
  4. Desculpe-me pelo erro. Na hora de eu escrever aqui acabei esquecendo, todavia a IDE mostra: Cannot find anything named "Arduino.SERVO" -mesmo. Pode ser algo no ServoFirmata meu? Já tentei aqui alguns outros códigos e até mesmo outros métodos mas nada solucionou. Pois utilizo o da versão 0017, todavia o exemplo do ServoFirmata em que você menciona no tutorial também é o da versão 0017, logo então não creio ser isso. Pois ele dá como se o método SERVO nao existisse. Poderá ser o fato deu usar o Ubuntu e ele ser sensível à letras maiúsculas?

    ResponderExcluir
  5. Não creio que nada disso seja o problema, só um detalhe, isso aí vc ta colocando no processing n eh? Substitua a variável Arduino.SERVO por 0x04. Ficaria assim: "meuArduino.pinMode(3,0x04);" se não funcionar deve ser alguma coisa na biblioteca q vc importou. O firmata não tem nd a ver com isso pois ele está apenas no Arduino, isso é código do processing...

    ResponderExcluir
  6. Hummmmmmmmmmmm..... valeu piá! Deu certo sim aqui agora. Então... acharia incomodo se me explicasse o que aconteceu que não estava dando certo e agora deu? Abraços e muito obrigado

    ResponderExcluir
  7. Assim, de alguma forma a sua biblioteca nao tem a define SERVO, ou tem algum erro em algum lugar... acontece que o tipo SERVO é apenas um valor passado ao arduino pra dizer que se trata de um servo, se vc for se aprofundar um pouco na firmata vai ver que esse valor é 4 que em hexa fica 0x04.

    ResponderExcluir
  8. Da pra usar o servo junto com o photocell no processing? Alguém me salva ai rs

    ResponderExcluir