// Declaração Global de constantes que representarão os pinos do Arduino
const byte INPUT_1 = 2; //Pinos de controle do L298N
const byte INPUT_2 = 3;
const byte INPUT_3 = 4;
const byte INPUT_4 = 5;
const byte EIXO = A7; // Potenciômetro do EIXO.
//Variáveis globais
int inc_dec = 1; //Valor usado como incremento e decremento da posição (Comandos + e -)
int retardo_entre_os_passos = 3; //constante que determinará a retardo entre os passos do ajuste do motor
int tolerancia = 1; //constante que determinará uma tolerância mínima para o ajuste
int leitura_comando = 510; // Variável que armazena o valor da leitura do COMANDO.
int leitura_eixo = 0; // Variável que armazena o valor da leitura do SENSOR DO EIXO.
int passo = 0; //Variável que armazena o passo atual.
int limite_inferior = 420; //limite inferior para o posicionamento
int limite_superior = 620; //limite superior para o posicionamento
String comando_recebido = ""; //String que armazena os dados recebido
boolean recepcao_completa = false; //sinalizador de dados aguardando leitura
void setup() {
// Ajustando os pinos do Arduino para operarem como saídas digitais
pinMode(INPUT_1, OUTPUT);
pinMode(INPUT_2, OUTPUT);
pinMode(INPUT_3, OUTPUT);
pinMode(INPUT_4, OUTPUT);
// Ajustando os pinos do Arduino resposáveis pela leitura do potenciômetro
pinMode(EIXO, INPUT);
//Inicia a comunicação serial
Serial.begin(9600);
// reserva 200 bytes de buffer para dados recebidos
comando_recebido.reserve(200);
// Determina sua posição inicial
leitura_eixo = analogRead(EIXO);
//envia uma mensagem de inicio pela serial
mensagem();
}
void loop() {
//leitura do potenciômetro de posição do eixo
leitura_eixo = analogRead(EIXO);
// verifica se há dados disponíveis
if (recepcao_completa == true)
{
//Envia o comando recebido para a função que interpretará o comando
interpretador(comando_recebido);
//reinicia as variáveis de recepção
comando_recebido = "";
recepcao_completa = false;
}
// Avaliação da direção do movimento
if (leitura_eixo < (leitura_comando - tolerancia))
{
girar(1); //Girar o EIXO no sentido de AUMENTAR a leitura do sensor
}
if (leitura_eixo > (leitura_comando + tolerancia))
{
girar(-1); //Girar o EIXO no sentido de REDUZIR a leitura do sensor
}
// Aguarde para repetir
delay(retardo_entre_os_passos);
}
void mensagem()
{
/*
Envia pela serial uma mensagem inicial com algumas
informações como ajustes do servo e comandos disponíveis.
Esta função é opcional. Pode ser retirada do programa sem
consequencias
*/
Serial.println("Servo com Motor de Passo e Controle Serial\n");
Serial.println("Ajustes atuais:");
interpretador("L");
Serial.println("");
Serial.println("Lista de comandos\n");
Serial.println("L - Ler as configuracoes atuais");
Serial.println("A# - Ajusta a posicao para #");
Serial.println("M# - Ajusta para a posicao MEDIA ");
Serial.println("R# - Ajusta a rapidez com que os passos sao dados");
Serial.println("S# - Ajusta o valor do limite superior");
Serial.println("I# - Ajusta o valor do limite inferior");
Serial.println("T# - Ajusta o valor de desvio toleravel");
Serial.println("+# - Incrementa o passo em #");
Serial.println("-# - Decrementa o passo em #");
}
void serialEvent()
{
/*
A função SerialEvent ocorre sempre que um novo byte
chegar na entrada RX, interrompendo a execução normal
do programa e retornando depois de executada
*/
while (Serial.available())
{
// captura o novo byte recebido e armazena como caracter
char caracter = (char)Serial.read();
// adiciona o novo caracter a variável comando_recebido:
comando_recebido += caracter;
// se o novo caracter recebido é um caracter de nova linha (\n),
//então muda o valor do sinalizador de recepção completa para que o
//possamos utilizar o comando recebido
if (caracter == '\n')
{
recepcao_completa = true;
}
}
}
//Esta função é responsável pela interpretação de cada comando
void interpretador(String comando)
{
if (comando.startsWith("L")) //LEITURA do estado atual
{
Serial.println("___________________________");
Serial.print("Posicao (und.): ");
Serial.println(leitura_eixo);
Serial.print("Retardo entre os passos (ms): ");
Serial.println(retardo_entre_os_passos);
Serial.print("Tolerancia (und.): ");
Serial.println(tolerancia);
Serial.print("Limite Inferior (und.): ");
Serial.println(limite_inferior);
Serial.print("Limite Superior (und.): ");
Serial.println(limite_superior);
Serial.println("___________________________");
Serial.flush();
}
//determina o valor da TOLERÂNCIA do ajuste
if (comando.startsWith("T"))
{
//obtém somente o valor do comando recebido e o converte para inteiro
tolerancia = comando.substring(1, comando.length()).toInt();
}
// Define o RETARDO entre cada mudança de passo
if (comando.startsWith("R"))
{
//obtém somente o valor do comando recebido e o converte para inteiro
retardo_entre_os_passos = comando.substring(1, comando.length()).toInt();
/*
Verifica se este valor é menor que 3ms. Se a mudança de passos for muito rápida
o motor pode não ser capaz de girar e pode perder passos. Se uma valor menor que 3
for recebido, este valor será ignorado e o valor 3 será atribuido.
*/
if(retardo_entre_os_passos < 3){retardo_entre_os_passos =3;}
}
//Define o limite INFERIOR para posicionamento.
if (comando.startsWith("I"))
{
//obtém somente o valor do comando recebido e o converte para inteiro
limite_inferior = comando.substring(1, comando.length()).toInt();
/*
Verifica se este valor é menor que 0. Como estamos utilizando diretamente a
leitura da porta analógica A0 (0 a 1023), este valor não pode ser negativo.
*/
if(limite_inferior < 0){limite_inferior = 0;}
}
//Define o limite SUPERIOR para posicionamento
if (comando.startsWith("S"))
{
//obtém somente o valor do comando recebido e o converte para inteiro
limite_superior = comando.substring(1, comando.length()).toInt();
/*
Verifica se este valor é maior que 1023. Como estamos utilizando diretamente a
leitura da porta analógica A0 (0 a 1023), este valor não pode ser maior que 1023.
*/
if(limite_superior > 1023){limite_superior = 1023;}
}
//Ajusta o servo para uma posição MÉDIA entre os LIMITES
if (comando.startsWith("M"))
{
//Calcula a posição MÉDIA
leitura_comando = (limite_superior + limite_inferior) / 2;
}
//INCREMENTA a posição um ajuste além da tolerância
if (comando.startsWith("+"))
{
//obtém somente o valor do comando recebido e o converte para inteiro
int temp = comando.substring(1, comando.length()).toInt();
// Verifica se o valor recebido é maior que 0
if(temp > 0){inc_dec = temp;}
//Calcula a nova posição
leitura_comando = leitura_eixo + inc_dec;
/*
Verifica se a posição solicitada está dentro do limite SUPERIOR.
Se for superado, o valor será ignorado e o valor limite será
tomado como novo valor.
*/
if (leitura_comando > limite_superior)
{
leitura_comando = limite_superior;
}
}
//DECREMENTA a posição um ajuste além da tolerância
if (comando.startsWith("-"))
{
//obtém somente o valor do comando recebido e o converte para inteiro
int temp = comando.substring(1, comando.length()).toInt();
// Verifica se o valor recebido é maior que 0
if(temp > 0){inc_dec = temp;}
//Calcula a nova posição
leitura_comando = leitura_eixo - inc_dec;
/*
Verifica se a posição solicitada está dentro do limite INFERIOR.
Se for superado, o valor será ignorado e o valor limite será
tomado como novo valor.
*/
if (leitura_comando < limite_inferior)
{
leitura_comando = limite_inferior;
}
}
//AJUSTA para a posição contida no comando
if (comando.startsWith("A"))
{
//obtém somente o valor do comando recebido e o converte para inteiro
leitura_comando = comando.substring(1, comando.length()).toInt();
/*
Verifica se a posição solicitada está entre os limites SUPERIOR e INFERIOR.
Se algum deles for superado, o valor será ignorado e o valor limite será
tomado como novo valor.
*/
if (leitura_comando > limite_superior) {
leitura_comando = limite_superior;
}
if (leitura_comando < limite_inferior) {
leitura_comando = limite_inferior;
}
}
}
//Função para girar o motor na direcao avaliada
void girar(int direcao)
{
// Girar INCREMENTANDO o PASSO
if (direcao > 0)
{
passo++;
if (passo > 3)
{
passo = 0;
}
}
//Girar DECREMENTANDO o passo
else {
passo--;
if (passo < 0 )
{
passo = 3;
}
}
//Atualiza o passo
ajustar_passo(passo);
}
//Função para atualização do passo
void ajustar_passo (int bobina)
{
switch (bobina) {
//PASSO 1
case 0:
digitalWrite(INPUT_1, HIGH);
digitalWrite(INPUT_2, LOW);
digitalWrite(INPUT_3, LOW);
digitalWrite(INPUT_4, LOW);
break;
///PASSO 2
case 1:
digitalWrite(INPUT_1, LOW);
digitalWrite(INPUT_2, HIGH);
digitalWrite(INPUT_3, LOW);
digitalWrite(INPUT_4, LOW);
break;
//PASSO 3
case 2:
digitalWrite(INPUT_1, LOW);
digitalWrite(INPUT_2, LOW);
digitalWrite(INPUT_3, HIGH);
digitalWrite(INPUT_4, LOW);
break;
//PASSO 4
case 3:
digitalWrite(INPUT_1, LOW);
digitalWrite(INPUT_2, LOW);
digitalWrite(INPUT_3, LOW);
digitalWrite(INPUT_4, HIGH);
break;
}
}