Lab_interaccio/2023/Baleliteral/Ob5-Cima_V03/Ob5-Cima_V03.ino

257 lines
13 KiB
Arduino
Raw Permalink Normal View History

2025-02-25 21:29:42 +01:00
//==================================================================================================================================================================================
// 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);
}
//==================================================================================================================================