Hi guys, i'm new to arduino, and this is my first sketch. I'm here because i know there is somethings that could be better in this code, and i want to know what and how! You guys could help me, plus, i didn't found anything related to controlling servos with encoders and show the actual microseconds that are being aplied to the servo. I need to know exactly what is the range of my servos, so i did this. Please feel free to give me some tips and tricks on these things.. thank you in advance!
PS. The comments are in portuguese, sorry for that.
PS2. IT WORKS, btw
/*############################################################################
*# Sketch para verificação de limites de um servomotor #
*# Utiliza um encoder rotativo para alterar o valor de microssegundos #
*# enviado ao servo para definir qual o limite de rotação do servo em #
*# microssegundos, pois cada servo tem o seu numero próprio devido as #
*# tolerâncias da fabricação. Envia o valor pelo monitor serial e/ou #
*# display LCD. Utilizei um LCD 16x2 comum, um encoder rotativo KEYES, #
*# e um servo TowerPro SG90. #
*# #
*# O valor mostrado e armazenado na variável 'counter' é o correspondente #
*# aos microssegundos de TON do PWM gerado para controle do servo. #
*# #
*# Desenvolvido por averaldofh@gmail.com AGO/2017 #
*# #
*# ALTAMENTE RECOMENDADO O USO DE ALIMENTAÇÃO EXTERNA P/ O SERVO #
*############################################################################*/
#include <Servo.h> //inclui os comandos da biblioteca servo.h
#include <LiquidCrystal.h> //inclui os comandos da biblioteca LiquidCrystal.h
Servo servo; //define o servo
int rotaryRead(int PinA, int PinB, int minV, int maxV); // função que lê o encoder
int rotaryBegin(int pinA, int PinB); // Inicializa o encoder
int aState, aLastState;
int counter=450,Lcounter=450; // Inicializar os valores aqui próximo do mínimo do servo (aprox. 400)
LiquidCrystal lcd(52,50,48,46,44,42); //RS, EN, D7, D6, D5, D4 comente esta linha para usar somente a serial
void setup()
{
lcd.begin(16,2); //Inicializa o LCD 16x2 comente esta linha para usar a serial
Serial.begin(9600); //Inicializa a Serial
rotaryBegin(2,3); //Inicializa o Rotary Encoder
analogWrite(9,70); //No meu caso uso o pino 9 em PWM para contraste do lcd, se utilizar um potenciometro ou somente a serial comente esta linha
lcd.print("Microssegundos:"); //Imprime a palavra "valor" no lcd se usar a serial comente esta linha
servo.attach(8, 400, 2500); //Adiciona o Servo no pino 8, define o minimo em 400 e maximo em 2600
servo.write(0); //posiciona o servo no menor angulo de acordo com o minimo definido acima
}
void loop()
{
rotaryRead(2,3,450,2500); //faz a leitura do encoder, bater esses valores com o do servo attach
if(counter != Lcounter){ //Se a leitura do encoder mudou
Serial.print("Microssegundos: "); //Imprime na serial
Serial.println(counter); // o Valor atual do encoder
lcd.setCursor(1,2); // Define o cursor na linha da baixo do lcd se usar serial comente esta linha
lcd.println(counter); //Imprime o valor do encoder no lcd se usar serial comente esta linha
servo.writeMicroseconds(counter); //Envia o valor para o servo
}
}
int rotaryBegin(int PinA, int PinB)
{
pinMode(PinA,INPUT);pinMode(PinB,INPUT); //seta os modos de pinos para entrada do encoder
aLastState = digitalRead(PinA); //salva no aLastState o estado do pino A
}
int rotaryRead(int PinA, int PinB, int minV, int maxV){
Lcounter = counter; //seta o ultimo valor do contador como sendo o atual
aState = digitalRead(PinA); //le o valor atual do pino A do encoder
if(aState != aLastState) //compara com o ultimo valor do pino A, caso seja diferente
{
if(digitalRead(PinB) != aState) //compara se o pino B é diferente, sentido horário
{
if(counter<maxV) // e ainda se o valor for menos que o valor maximo setado, incremmenta mais 5
counter = counter+5;
}
else //caso seja igual o pino B, sentido anti-horário
{
if(counter>minV) //decrementa 5 se for maior que o valor minimo
counter = counter -5;
}
}
aLastState = aState; //salva o novo estado do pino A
}
MyRotary.ino (4.26 KB)