Preparativos (ou ajustando servos)
Como dito anteriormente, você não pode colocar os servos de qualquer jeito, ou poderá correr o risco de ter movimentos limitados. Portanto, neste post aprenderemos como “centralizá-los” a fim de não termos esse tipo de problema. Digo “centralizar” (entre aspas) porque não necessariamente esta posição será o centro absoluto, mas sim porque teremos o livre movimento para ambos os lados. E sim, neste post, vamos começar a parte divertida: códigos! Daqui pra frente, assumo que você já saiba pelo menos o básico da programação em Arduino. Caso negativo, comece com uma boa lida no site oficial do Arduino: https://www.arduino.cc/en/Guide/HomePage
Você pode usar o código na Arduino IDE ou no Visual Micro do Visual Studio. Não acontece com todo mundo, mas caso a Arduino IDE leve vários minutos para compilar, recomendo instalar o Visual Micro. Aqui tem um ótimo link para instruções de como instalá-lo: https://www.hackster.io/shakram02/arduino-visual-studio-fast-dev-683414
Para usar o controlador de servos você precisará instalar a Adafruit PWM Servo Driver Library, o que você pode fazer através da própria Arduino iDE em “Sketch -> Include Library -> Manage Libraries…” (o que vale também para o Visual Micro, já que ele usa a Arduino IDE).
(Atualização em 27/05/2016) Atenção: para usar esta biblioteca na Linkit ONE será necessário fazer uma pequena alteração no código-fonte da mesma. Localize o arquivo “Adafruit_PWMServoDriver.cpp” na pasta “Arduino\libraries\Adafruit_PWM_Servo_Driver_Library” que provavelmente está dentro da sua pasta Documentos e retire o “1” do “Wire1” no seguinte trecho (bem no começo do código) ficando:
#else // Arduino Due #define WIRE Wire
Isso é necessário porque esta biblioteca diferencia as placas usadas e considera qualquer outra como se fosse a Arduino Due, que deve usar o objeto Wire1, porém na Linkit ONE é mesmo o Wire.
Usarei neste exemplo um Arduino Uno, mas o código funcionará em qualquer outro modelo (Nano, Micro, etc.), inclusive na Linkit ONE.
O que você precisará:
- Um Arduino (Uno, Nano, Mega, Micro, etc.) ou a MediaTek Labs Linkit ONE;
- O controlador de servos/LED PCA9685;
- Um servo-motor, como o Tower (ou Towards) Pro MG996, MG946 ou MG995;
- Uma fonte de energia com 5V ou 6V;
- Fios do tipo Dupont macho-macho e macho-fêmea.
Preciso mesmo do controlador de servos? Não, não precisaria porque você pode controlar servos diretamente do Arduino, porém como queremos deixá-los já ajustados para configurações que usaremos depois o ideal é usar o mesmo controlador que usaremos posteriormente. Existem dois valores, são os pulsos mínimo e máximo, que controlam o começo e o fim da rotação do servo. Esses valores variam de um servo para outro, talvez pela qualidade de construção deles. É difícil achar valores que sejam comuns a todos eles, mas você encontrará valores que servirão para a maioria. Quebrei muita a cabeça com isso no começo, já que a cada novo servo que colocava, eu reparava que ele ficava chiando quando na posição 0 ou 180. Isso acontece porque se o pulso mínimo for menor que o esperado, o servo fica “tentando” atingir uma posição a qual não deveria, e o mesmo ocorre para o pulso máximo. Deixá-los muito tempo fazendo isso com certeza irá destruí-los. Por essa razão, você deve ajustar estes valores de maneira que, tanto no começo ou no fim do curso, ele não fique “forçando”.
Um servo gira aproximadamente 180 graus, e sim, digo aproximadamente porque isso também varia de um para o outro. Portanto, para efeito de “centralizá-lo” vamos ajustá-lo para 90 graus. Todos os movimentos dos servos serão baseados de 0 a 180. Vejamos então o código:
#include <Wire.h> #include <Adafruit_PWMServoDriver.h> Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); #define SERVOMIN 173 #define SERVOMAX 540 void setup() { Serial.begin(9600); Serial.println("Ajuste de servo!"); Serial.println("[A-P][0-180], OFF"); pwm.begin(); pwm.setPWMFreq(60); } void loop() { char data[5]; int numero; if (Serial.available() > 0) { numero = Serial.readBytesUntil (13,data,5); data[numero] = 0; if (strcmp(data, "OFF")==0) { Serial.println("ALL OFF"); for (int i=0; i<16; i++) { offServo(i); } } else { playServo(data); } } } int getValue(char *data) { char ndata[4]; int j=0; for (int i=1;i<5;i++) { ndata[j]=data[i]; j++; } int valor = atoi(ndata); return valor; } int playServo(char *data) { int servonum = (int)data[0]; servonum -= 65; int angulo = getValue(data); //int angulo = atoi(data); Serial.print(servonum); Serial.print(": "); Serial.println(angulo); moveServo(servonum, angulo); } int moveServo(int servonum, int pos) { int pulselength = map(pos, 0, 180, SERVOMIN, SERVOMAX); pwm.setPWM(servonum, 0, pulselength); return pulselength; } int offServo(int servonum) { pwm.setPWM(servonum, 0, 0); return 0; }
Repare que os pulsos mínimo (SERVOMIN) e máximo (SERVOMAX) são definidos como fixos neste código. Isso é apenas a título de teste e para ajuste inicial dos servos. No código atual do Jarvis, estes valores são definidos através de instruções enviadas (por uma conexão TCP ou por um arquivo na memória flash da Linkit ONE), o que nos permite configurá-los sem ter que recompilar. A título de aprendizado, neste caso, você terá que recompilar várias e várias vezes. 🙂
O que este código basicamente faz é ler uma informação de entrada pela serial do Arduino, que é a posição onde o servo está conectado (de 0 a 15, representado de “A” até “P”) e a posição (ângulo) desejado (de 0 a 180); ou a palavra “OFF” para desligar. Utilize sempre maiúsculas!
Para experimentar o código acima, você precisará fazer as ligações entre o Arduino, o controlador de servos, o servo e a fonte de energia. Vejamos:
PCA9685 | Arduino |
---|---|
VCC | 5V |
GND | GND |
SCL | A5 |
SDA | A4 |
V+ (Borne verde) | + da fonte de energia |
GND (Borne verde) | - da fonte de energia |
NEM PENSE em usar os 5V do Arduino para alimentar o(s) servo(s). A corrente (amperagem) necessária para movimentar e manter a posição dos servos vai ser muito superior a disponível através do regulador do Arduino. Eu queimei um Arduino Nano fazendo um teste com 2 servos. Como fonte de energia você pode usar pilhas ou baterias do tipo 18650. Estes servos toleram tensões maiores que 6V, pois já usei com 7,4V sem problemas, pelo menos em poucos intervalos de uso. Portanto, se quiser usar duas baterias 18650 de 3,7V ligadas em série, você pode tranquilamente. Outras alternativas seriam fontes como de switches/roteadores ou a fonte ATX do seu computador, qualquer coisa que disponibilize de 5V a 7,4V deve servir. Se você já possuir o UBEC, descrito no primeiro post, poderá utilizá-lo com uma bateria ou qualquer outra fonte de energia (de corrente contínua) até 12,6V. Se já tiver a bateria LiPo também, então você nem precisava ter lido esse parágrafo todo, rsrsrsrs.
Faça as ligações (além das especificadas acima, conecte o servo na posição 0, conforme as cores do cabo), compile o código e abra o Monitor Serial. Você deverá ver a tela com a informação abaixo:
Caso não veja, cheque se a velocidade de comunicação é mesmo de 9600 Bauds no canto inferior direito do Monitor Serial.
Supondo que até foi tudo bem, digite “A90” (sem as aspas e com o A maiúsculo) e tecle ENTER. Você deverá ver o servo se mexer para atingir a posição desejada. Caso isso não aconteça, verifique novamente as conexões. Caso dê certo, experimente outros valores (de 0 a 180) como “A50”, “A120”, etc.
Agora vamos aos ajustes. Como dito anteriormente, o pulso mínimo e máximo definem o percurso do servo, estabelecendo o início e o fim. Os valores que coloquei no código, 173 e 540, podem servir ou não para o seu servo e você saberá isso testando a posições mínima e máxima do mesmo. Repare que “A” é a indicação de qual servo queremos mover, no caso, o primeiro (0). Se fosse o segundo usaríamos B (que é a posição 1 na PCA9685). Como são 16 servos, podemos usar de A até P. E como são aproximadamente 180 graus, podemos usar de 0 até 180.
Então, para testarmos a posição mínima, usaremos “A0” e para a máxima “A180”. Todavia, isso não impede de usarmos valores maiores ou menores que estes. Para testar o pulso mínimo do servo digite “A0” e tecle ENTER. Se o servo se mover e parar, e *não* ficar chiando ou trepidando como se estivesse ainda tentando se mover, significa que ou você já está com o valor mínimo certo ou que ainda não o atingiu. Se for este o caso, digite “OFF” e tecle ENTER para desligar o servo, uma vez que ele ficará travado na posição que informamos. Após ele desligar, mova com a mão (esqueci de mencionar, mas na foto acima você verá que acoplei um dos acessórios que vem com ele) na mesma direção em que ele se moveu e veja se ainda tem mais percurso até ele travar. Caso tenha, tente usar “A-10”, sim, um valor negativo; isso fará com que ele se mova 10 “passos” além do mínimo. Novamente veja se ele não fica forçando, desligue (com “OFF”) e veja se ainda há mais movimento até travar. Faça isso até descobrir o valor que faça ele chegar no início do percurso, sem que fique forçando. Você pode ir incrementando de -1 em -1, de -2 em -2, etc. Supondo que você achou o valor de -15, subtraia esse valor de SERVOMIN, ou seja, 173 – 15 = 158 e este será o seu novo SERVOMIN. Troque o valor no código, recompile e faça o teste novamente com o “A0”, que deverá parar no início do curso sem forçar.
Se logo no primeiro teste com “A0” ele ficou forçando, você deverá tentar valores positivos, como “A10”, “A15”, etc. Quando encontrar o valor que faça ele não forçar no início, você então somará ao valor de SERVOMIN.
A mesma idéia serve para ajustar o SERVOMAX, usando “A180”. Se o movimento extrapolar, diminua, se terminar antes, some. A intenção aqui é que qualquer valor entre 0 e 180 fique dentro dos limites do servo.
Pronto, agora você achou os valores mínimos e máximos e consegue movê-lo entre 0 e 180 sem problemas, certo? Pois bem, se você tem todos os servos da mesma marca e modelo, ligue mais alguns e verifique se estes valores são os mesmos para todos. É possível que sejam ou não, você só saberá testando. Se forem de marcas e modelos diferentes a possibilidade de serem diferentes é bem maior. Neste caso, aconselho a anotar em algum lugar (uma etiqueta neles?) quais os mínimos e máximos de cada um para não ter problema. Na versão final do código do Jarvis você poderá definir os pulsos mínimos e máximos de cada servo independentemente, o que facilita tê-los registrados em algum lugar.
O importante no final é deixar todos aproximadamente centralizados, que seria o valor de 90 (metade do percurso) de forma que ele tenha movimento para ambos os lados. Teremos alguns ajustes finos depois, mas isso vem depois da montagem. Agora que você já sabe como ajustá-los, utilize a informação deste post com a do anterior para começar a montá-lo!
2 thoughts on “Preparativos (ou ajustando servos)”