257 lines
13 KiB
Arduino
257 lines
13 KiB
Arduino
|
//==================================================================================================================================================================================
|
||
|
// Autor...........: Cid Rodrigo Barcellos Filho
|
||
|
// Cliente.........: Laura Lima (Artista Plástica), Yoann Saura (Francês Art&Tech)
|
||
|
// Projeto.........: Obra-5_Bate-Bola - Arduino-1 (de Cima)
|
||
|
// Objetivo........: Movimentar 3 Motor de Passo sincronizados para animação da Obra-5_Bate-Bola
|
||
|
// O Eixo desses Motores estão conectados a carreteis para subir e descer a barra superior da Obra-5.
|
||
|
// Posição dos Motores na Obra: Motor-X -> "do Rabo" , Motor-Y -> "do Meio" e Motor-Z -> "da Cabeça".
|
||
|
// Arquivo.........: Ob5-Cima_V03.ino
|
||
|
// Data............: 09/03/2023
|
||
|
// ConfigArduinoIDE: Versão_Ide: 1.8.13 , Placa: "Arduino Uno"
|
||
|
// Hardware........: 1 Arduino Uno , 1 CNC Shield V3.0 com 3 Drivers, 3 Motores de Passo Nema-17,
|
||
|
// 3 Sensores de Fim de Curso (à definir),
|
||
|
//==================================================================================================================================================================================
|
||
|
|
||
|
//============================================================================================================================================
|
||
|
#define MODO_DEBUG //Deixar essa linha comentada para NÃO Debugar pela Serial.
|
||
|
//============================================================================================================================================
|
||
|
|
||
|
//=================================================================================================================================================================
|
||
|
// Bibliotecas Utilizadas e Declaração/Definição de Variáveis/Constantes Globais
|
||
|
//=================================================================================================================================================================
|
||
|
|
||
|
#define DELAY_INICIAL 30000 //Delay Inicial em mili-segundos antes de começar os movimentos [no setup()]
|
||
|
#define DELAY_ENTRE_MOVIMENTOS 1 //Delay em mili-segundos entre os movimentos.
|
||
|
#define QTD_PASSOS_POR_VOLTA 200 //Constante para o Nema-17 utilizado (Full-Step)
|
||
|
#define UMA_ITERACAO_FOR_US 90 //Tempo de uma Iteração do FOR em micro-segundos.
|
||
|
#define _H_ true //Direção Horária dos Ponteiros do Relógio (Visão de cima do Motor)
|
||
|
#define _A_ false //Direção Anti-Horária dos Ponteiros do Relógio (Visão de cima do Motor)
|
||
|
#define _P_ 0 //Motor Parado (Alimentado = Travado)
|
||
|
|
||
|
const int Pin_Enable = 8; //Pinos de controle dos 3 Motores
|
||
|
|
||
|
const int Pin_Dir_X = 5; //Pinos de controle do Motor-X
|
||
|
const int Pin_Step_X = 2 ;
|
||
|
|
||
|
const int Pin_Dir_Y = 6; //Pinos de controle do Motor-Y
|
||
|
const int Pin_Step_Y = 3;
|
||
|
|
||
|
const int Pin_Dir_Z = 7; //Pinos de controle do Motor-Z
|
||
|
const int Pin_Step_Z = 4;
|
||
|
|
||
|
unsigned long G_millis = 0; //Variável Global para Receber o millis()
|
||
|
|
||
|
|
||
|
|
||
|
//=================================================================================================================================================================
|
||
|
// Definição de Funções Gerais
|
||
|
//=================================================================================================================================================================
|
||
|
|
||
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||
|
// Função de ajuda para Obter o Maior Número entre três valores
|
||
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||
|
long fnc_GetMaiorNum(long num1, long num2, long num3) {
|
||
|
long Maior = num1; //Inicialmente considero que o maior é o num1
|
||
|
|
||
|
if (num2 > Maior) Maior = num2; //Salvo o maior número caso num2 seja maior
|
||
|
if (num3 > Maior) Maior = num3; //Salvo o maior número caso num3 seja maior
|
||
|
|
||
|
return Maior; //Retorna o maior número
|
||
|
}
|
||
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||
|
// Função principal para Ligar os Motores. Cada chamada executa um "Movimento do conjunto" para os 3 motores em um determinado tempo.
|
||
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||
|
void fnc_Liga_Motor(String Nome_Movimento, long Periodo_seg, bool Direcao_X, bool Direcao_Y, bool Direcao_Z, long Num_Voltas_X, long Num_Voltas_Y, long Num_Voltas_Z){
|
||
|
|
||
|
//--Cálculos Necessários apartir dos parâmetros Recebidos------------------------------------------------------------
|
||
|
long Maior_Num_Voltas = fnc_GetMaiorNum(Num_Voltas_X, Num_Voltas_Y, Num_Voltas_Z);
|
||
|
|
||
|
long Num_Passos = Maior_Num_Voltas * QTD_PASSOS_POR_VOLTA; //Maior Número de Passos entre os três
|
||
|
long Delay_us_For = round( ( ( ( (float)(Periodo_seg * 1000) / Num_Passos) * 1000) - UMA_ITERACAO_FOR_US ) / 2); //Delay para ajustar o Time dentro do For
|
||
|
|
||
|
long Num_Passos_x12 = Num_Passos * 12; //Variáveis utilizadas no FOR ao invés da Num_Passos e Delay_us_For
|
||
|
long Delay_us_For_d6 = Delay_us_For / 6;
|
||
|
|
||
|
long ChangeLevel_X = 0, ChangeLevel_Y = 0, ChangeLevel_Z = 0;
|
||
|
long Num_Voltas_REAL_X = 0, Num_Voltas_REAL_Y = 0, Num_Voltas_REAL_Z = 0; //
|
||
|
|
||
|
if (Num_Voltas_X == 0) {
|
||
|
ChangeLevel_X = -1; //-1 Nunca será alcançado no loop do For => Motor Parado
|
||
|
} else {
|
||
|
ChangeLevel_X = round(((float)Maior_Num_Voltas / Num_Voltas_X) * 6);
|
||
|
Num_Voltas_REAL_X = (6.0F / ChangeLevel_X) * Maior_Num_Voltas;
|
||
|
}
|
||
|
|
||
|
if (Num_Voltas_Y == 0) {
|
||
|
ChangeLevel_Y = -1; //-1 Nunca será alcançado no loop do For => Motor Parado
|
||
|
} else {
|
||
|
ChangeLevel_Y = round(((float)Maior_Num_Voltas / Num_Voltas_Y) * 6);
|
||
|
Num_Voltas_REAL_Y = (6.0F / ChangeLevel_Y) * Maior_Num_Voltas;
|
||
|
}
|
||
|
|
||
|
if (Num_Voltas_Z == 0) {
|
||
|
ChangeLevel_Z = -1; //-1 Nunca será alcançado no loop do For => Motor Parado
|
||
|
} else {
|
||
|
ChangeLevel_Z = round(((float)Maior_Num_Voltas / Num_Voltas_Z) * 6);
|
||
|
Num_Voltas_REAL_Z = (6.0F / ChangeLevel_Z) * Maior_Num_Voltas;
|
||
|
}
|
||
|
//----------------------------------------------------------------------------------------------------------------------
|
||
|
|
||
|
//--Variáveis para manter o Nível Lógico do Pino Step de cada motor (o toggle é feito dentro do FOR)
|
||
|
bool F_Nivel_X = false, F_Nivel_Y = false, F_Nivel_Z = false;
|
||
|
|
||
|
//--Variáveis para contagens dentro do FOR.
|
||
|
long F_iX = 0, F_iY = 0, F_iZ = 0;
|
||
|
|
||
|
long T_X = 0, T_Y = 0, T_Z = 0;
|
||
|
|
||
|
#ifdef MODO_DEBUG
|
||
|
Serial.println("-------------------------------------------------------");
|
||
|
Serial.println("---> " + Nome_Movimento);
|
||
|
Serial.println("-------------------------------------------------------");
|
||
|
Serial.println("Periodo_seg = " + String(Periodo_seg));
|
||
|
Serial.println("Direcao_X = " + String(Direcao_X) + " , Num_Voltas_X = " + String(Num_Voltas_X) + " , ChangeLevel_X = " + String(ChangeLevel_X) + " , Num_Voltas_REAL_X = " + String(Num_Voltas_REAL_X));
|
||
|
Serial.println("Direcao_Y = " + String(Direcao_Y) + " , Num_Voltas_Y = " + String(Num_Voltas_Y) + " , ChangeLevel_Y = " + String(ChangeLevel_Y) + " , Num_Voltas_REAL_Y = " + String(Num_Voltas_REAL_Y));
|
||
|
Serial.println("Direcao_Z = " + String(Direcao_Z) + " , Num_Voltas_Z = " + String(Num_Voltas_Z) + " , ChangeLevel_Z = " + String(ChangeLevel_Z) + " , Num_Voltas_REAL_Z = " + String(Num_Voltas_REAL_Z));
|
||
|
Serial.println("Num_Passos = " + String(Num_Passos));
|
||
|
Serial.println("Delay_us_For = " + String(Delay_us_For));
|
||
|
Serial.println("Num_Passos_x12 = " + String(Num_Passos_x12) + " -> (Igual as Iterações do For)");
|
||
|
Serial.println("Delay_us_For_d6 = " + String(Delay_us_For_d6) + " -> (Delay Adicionado a cada Iteração do For)");
|
||
|
if (Delay_us_For_d6 < 60) {
|
||
|
Serial.println(">>> ATENÇÃO: VALOR MUITO BAIXO (<100uS) PARA NO DELAY ADICIONADO <<<");
|
||
|
}
|
||
|
Serial.println("Movimento Iniciado. Aguarde...");
|
||
|
#endif
|
||
|
|
||
|
digitalWrite(Pin_Dir_X, Direcao_X);
|
||
|
digitalWrite(Pin_Dir_Y, Direcao_Y);
|
||
|
digitalWrite(Pin_Dir_Z, Direcao_Z);
|
||
|
|
||
|
G_millis = millis(); //Início da Cronometragem do tempo de Execução do FOR
|
||
|
|
||
|
//----------------------------------------------------------------
|
||
|
// FOR a execução do movimento dos 3 motores com um tempo previsto de [Periodo_seg],
|
||
|
// Baseado no tempo de execução do Arduino Uno à 16MHz.
|
||
|
//----------------------------------------------------------------
|
||
|
for(long i = 0; i < Num_Passos_x12; i++) {
|
||
|
|
||
|
if (F_iX == 0) {
|
||
|
F_Nivel_X = !F_Nivel_X;
|
||
|
digitalWrite(Pin_Step_X, F_Nivel_X); //Inverte o Nivel Lógico do Pin_Step_X
|
||
|
T_X++;
|
||
|
}
|
||
|
if (F_iY == 0) {
|
||
|
F_Nivel_Y = !F_Nivel_Y;
|
||
|
digitalWrite(Pin_Step_Y, F_Nivel_Y); //Inverte o Nivel Lógico do Pin_Step_Y
|
||
|
T_Y++;
|
||
|
}
|
||
|
if (F_iZ == 0) {
|
||
|
F_Nivel_Z = !F_Nivel_Z;
|
||
|
digitalWrite(Pin_Step_Z, F_Nivel_Z); //Inverte o Nivel Lógico do Pin_Step_Z
|
||
|
T_Z++;
|
||
|
}
|
||
|
|
||
|
F_iX++; F_iY++; F_iZ++; //Incrementa os 3 Contadores e Zera ao Alcançar o seu Limite em ChangeLevel_
|
||
|
if (F_iX == ChangeLevel_X) F_iX = 0;
|
||
|
if (F_iY == ChangeLevel_Y) F_iY = 0;
|
||
|
if (F_iZ == ChangeLevel_Z) F_iZ = 0;
|
||
|
|
||
|
delayMicroseconds(Delay_us_For_d6); //Delay Adicionado a cada Iteração do FOR
|
||
|
|
||
|
}
|
||
|
//----------------------------------------------------------------
|
||
|
|
||
|
unsigned long Real_ms = millis() - G_millis; //Final da Cronometragem do tempo de Execução do FOR
|
||
|
|
||
|
#ifdef MODO_DEBUG
|
||
|
Serial.println("Periodo Real Cronometrado : " + String( float(Real_ms) / 1000 , 4 ) + " segundos.");
|
||
|
Serial.println("T_X = " + String(T_X) + " , T_Y = " + String(T_Y) + " , T_Z = " + String(T_Z));
|
||
|
Serial.println("VoltasContadas: X = " + String(T_X/400.0) + " , Y = " + String(T_Y/400.0) + " , Z = " + String(T_Z/400.0));
|
||
|
Serial.println("PassosContados: X = " + String(T_X/2) + " , Y = " + String(T_Y/2) + " , Z = " + String(T_Z/2));
|
||
|
Serial.println("");
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||
|
|
||
|
//=================================================================================================================================================================
|
||
|
|
||
|
|
||
|
|
||
|
//=================================================================================================================================================================
|
||
|
// Função SETUP
|
||
|
//=================================================================================================================================================================
|
||
|
void setup ( ) {
|
||
|
|
||
|
#ifdef MODO_DEBUG
|
||
|
Serial.begin(115200);
|
||
|
#endif
|
||
|
|
||
|
pinMode (Pin_Step_X, OUTPUT );
|
||
|
pinMode (Pin_Dir_X, OUTPUT );
|
||
|
|
||
|
pinMode (Pin_Step_Y, OUTPUT );
|
||
|
pinMode (Pin_Dir_Y, OUTPUT );
|
||
|
|
||
|
pinMode (Pin_Step_Z, OUTPUT );
|
||
|
pinMode (Pin_Dir_Z, OUTPUT );
|
||
|
|
||
|
pinMode (Pin_Enable, OUTPUT );
|
||
|
digitalWrite(Pin_Enable, LOW); //Habilita todos os Motores
|
||
|
|
||
|
#ifdef MODO_DEBUG
|
||
|
Serial.println("#############################################################");
|
||
|
Serial.println("# Obra-5_Bate-Bola - Arduino-1 (de Cima) # Ob5-Cima_V03.ino #");
|
||
|
Serial.println("#############################################################\n");
|
||
|
Serial.println("Aguarde o Delay Inicial no Setup = " + String(DELAY_INICIAL) + " ms.\n");
|
||
|
#endif
|
||
|
|
||
|
delay(DELAY_INICIAL);
|
||
|
}
|
||
|
//=================================================================================================================================================================
|
||
|
|
||
|
|
||
|
//=================================================================================================================================================================
|
||
|
// Função LOOP
|
||
|
//=================================================================================================================================================================
|
||
|
void loop() {
|
||
|
|
||
|
//Parâmetros da fnc_Liga_Motor: (Nome_Movimento, Periodo_seg, Direcao_X, Direcao_Y, Direcao_Z, Num_Voltas_X, Num_Voltas_Y, Num_Voltas_Z)
|
||
|
|
||
|
//Enquanto não tem sensor de fim de Curso, Será necessário Posicionar Manualmente todos os carreteis para o Início da apresentação, ou seja com a obra fechada.
|
||
|
|
||
|
fnc_Liga_Motor("Movimento 1", 90, _A_,_A_,_A_ , 274, 149, 274); //Movimento 1
|
||
|
delay(DELAY_ENTRE_MOVIMENTOS);
|
||
|
|
||
|
fnc_Liga_Motor("Movimento 2", 90, _H_,_A_,_H_ , 125, 125, 125); //Movimento 2
|
||
|
delay(DELAY_ENTRE_MOVIMENTOS);
|
||
|
|
||
|
fnc_Liga_Motor("Movimento 3", 90, _A_,_H_,_P_ , 125, 62, 0); //Movimento 3
|
||
|
delay(DELAY_ENTRE_MOVIMENTOS);
|
||
|
|
||
|
fnc_Liga_Motor("Movimento 4", 90, _H_,_P_,_A_ , 125, 0, 125); //Movimento 4
|
||
|
delay(DELAY_ENTRE_MOVIMENTOS);
|
||
|
|
||
|
fnc_Liga_Motor("Movimento 5", 90, _P_,_A_,_H_ , 0, 62, 125); //Movimento 5
|
||
|
delay(DELAY_ENTRE_MOVIMENTOS);
|
||
|
|
||
|
//Considerando Sentido AntiHorário como (-) e Sentido Horário como (+),
|
||
|
//após todos os 5 Movimentos, teremos o seguinte saldo de Voltas com valores AntiHorário:
|
||
|
//Motor-X ("Rabo")..: -274 +125 -125 +125 +0 = -149
|
||
|
//Motor-Y ("Meio")..: -149 -125 +62 +0 -62 = -274
|
||
|
//Motor-Z ("Cabeça"): -274 +125 +0 -125 +125 = -149
|
||
|
//Enquanto não tem sensor de fim de Curso, Segue abaixo duas chamadas da fnc_Liga_Motor para Zerar as Posições, ou seja,
|
||
|
//voltar para o Ínicio com a obra fechada para permitir o Loop.
|
||
|
|
||
|
fnc_Liga_Motor("Movimento Retorno 1/2", 45, _P_,_H_,_P_ , 0, 125, 0); //Movimento de Retorno
|
||
|
fnc_Liga_Motor("Movimento Retorno 2/2", 45, _H_,_H_,_H_ , 149, 149, 149);
|
||
|
delay(DELAY_ENTRE_MOVIMENTOS);
|
||
|
|
||
|
}
|
||
|
//==================================================================================================================================
|
||
|
|
||
|
|