Rotary Encoder + Servo, how to improve?

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)

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
}

You lied when you said that this function returns an int. It does not. The first thing you MUST do is fix that.

PaulS:

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
}



You lied when you said that this function returns an int. It does not. The first thing you MUST do is fix that.

Thank you for that, but can you explain better? Don't fix it for me but explain your point so i can figure out what i did wrong there. I've learned programming PICs in assembly language, and not that good.. C is new to me, and arduino is even more.. so i get a little confused abt functions type and miss some basic things.
Thanks man

The very first line quoted says that the function rotaryRead() is of type int. It's promising to return an integer. But there's no return statement anywhere in the function.

If it is not going to return anything, like loop() or setup() then you declare the function to be type void.

MorganS:
The very first line quoted says that the function rotaryRead() is of type int. It's promising to return an integer. But there's no return statement anywhere in the function.

If it is not going to return anything, like loop() or setup() then you declare the function to be type void.

Of course! How can I miss that! My bad, sorry. But it works this way :stuck_out_tongue: i'll fix that. Thanks.

But it works this way

It corrupts the stack, but you've gotten away with it so far is what you meant.