/* By Ismael.B.S.S ~Tenniko
Posição de Pinos da placa de controle:
[J][I]
[H][G]
[F][E] Exp1
[D][C]
[B][A]
[T][S]
[R][Q]
[P][O] Exp2
[N][M]
[L][K]
//configuração / Pinos microcontorlador
A = P1.30 -> HB_PWM 2
B = P0.28 -> HE0_PWM 3
C = P1.18 -> HE1_PWM 4
D = P1.19 -> XSTP 5
E = P1.20 -> YSTP 6
F = P1.21 -> ZSTP 7
G = P1.22 -> XDIR 8
H = P1.23 -> YDIR 9
I = GND GND
J = 5v OUT 5v IN
K = MISO0 -> ZDIR 10
L = SCK0 -> X- 11
M = P3.26 -> Y- 12
N = SSEL0 -> E1DET 13
O = P3.25 -> TH1 A0
P = MOSI0 -> TH0 A1
Q = P1.31 -> THB A2
R = RESET -> SDA1 A4
S = GND N/C
T = E0DET -> SCL1 A5
17
*/
//---------- DEFINIÇÃO DE PORTAS ----------//
//portas de leitura para termistores
#define TH0 A0 // Termistor A
#define TH1 A1 // Termistor B
#define TH2 A2 // Termistor C
// portas de controle para resistencias
#define OUT1 2 // Resistencia A
#define OUT2 3 // Resistencia B
#define OUT3 4 // Resistencia C
// define o numero de pasos para cada motor
#define Step1 5 // Motor A
#define Step2 6 // Motor B
#define Step3 7 // Motor C
#define Dir1 8
#define Dir2 9
#define Dir3 10
#define NUM_MOTORES 3
// define a direção de rotação para cada motor
// define os Botões de controle
#define Bot1 13 // botão +
#define Bot2 12 // botão Menu
#define Bot3 11 // botão -
//--------- DEFINIÇÃO DE VARIAVEIS --------//
//double LastRead[] = {0, 0, 0}; //ultima leitura para cada resistencia
//double LastSet[] = {0, 0, 0}; //Ultimo setpoint
double Output[] = {00.0, 00.0, 00.0}; // Define os valores de controle da saída
double Input[] = {00.0, 00.0, 00.0}; // Define os valores recebidos de Leitura
double f1 = 0, f2 = 0, f3 = 0;
double Setpoint[] = {250.0, 250.0, 250.0}; // Define a temperatura desejada
// p i d
double PID_A[] = {10.0, 1.5, 80.0}; // Parametros do PID para cada resistencia
double PID_B[] = {10.0, 1.5, 80.0}; //
double PID_C[] = {10.0, 1.5, 80.0}; //
byte MenuPosition[3][3] = {
{0, 0, 0},
{1, 0, 0},
{3, 2, 1}
};
byte count[] = {0, 0, 0};
byte One[] = {0, 0, 0, 0};
byte One_Display = 1; //usado para evitar repetições de reescrita para os menus do display
byte maxMenuLimits[] = {2, 3, 3, 3}; //valores maximos no qual o cursor poderá alcançar
byte menuSelect = 0; //usado para selecionar dentre as configurações de menus
byte C_Position = 0; //define a posição atual do cursor
byte A_Position = 1; //define a posição anterior do cursor
byte Speed[] = {100, 0, 0}; //utilizado para controle de velocidade dos motores de passo
byte Function[] = {0, 0, 0}; //usado para ativar ou desativar um dos 3 modulos de reciclagem por completo
byte PwrR[] = {0, 0, 0}; //Potencia de controle ds resistencias
byte Sinal_S[] = {0, 0, 0}; //Usado no controle de Pid para Resistencias
byte DP[] = {OUT1, OUT2, OUT3, Step1, Step2, Step3}; //define todas as portas digitais
byte AP[] = {TH0, TH1, TH2, Bot1, Bot2, Bot3}; //define todas as portas Analogicas
byte Paw[] = {
B00000,
B00100,
B10101,
B10001,
B01110,
B11111,
B11011,
B00000
};
struct {
short adc;
short temp;
} tabela[] = {
{1000, 25},
{900, 50},
{800, 75},
{700, 100},
{600, 125},
{500, 150},
{400, 175},
{300, 200},
{200, 230},
{150, 250},
{100, 270},
{80, 290}
};
//testes
unsigned long Temp_A = 0; //usado como delay de leiura e procesamento de dados do sistema PID
unsigned long Temp_B = 0; //usado na contagem de tempo dos botões
unsigned long Temp_C = 0; //Usado No display
unsigned long Temp_C2 = 0; //usado no display
unsigned long Temp_D = 0; //Usado No Controle de botões
unsigned long Temp_E = 0; //controle da resistencia A
unsigned long Temp_F = 0; //controle da resistencia B
unsigned long Temp_G = 0; //controle da resistencia C
// Limite de velocidade (ajuste conforme seu motor)
float velocidadeMax = 2000.0; // passos por segundo
short LastVar[6][3] = { //usado para detectar se houve mudança de valor nas configurações, limpando o display caso a condição seja verdadeira
{0, 0, 0}, //usado nas configurações do setpoint
{1, 1, 1}, //usado frequentemente menu inicial com informações da leitura
{0, 0, 0}, //usado nas configurações de velocidade]
{0, 0, 0}, //PID A
{0, 0, 0}, //PID B
{0, 0, 0}, //PID C
};
short setValor = 0;
short Tempo[] = {300, 300, 300}; // define o tempo de atuação do controle da resistencia
short intervalo[] = {0, 0, 0};
short maxValLimits[4][2] = { //define os valores Maximo para as configurações como Setpoint, velocidade e PID
// M1 M2
{290, 0}, //menuSelect = 0
{100, 200}, //menuSelect = 1
{0, 200}, //menuSelect = 2
{0, 200}, //menuSelect = 3
};
bool R_Ativo[] = {HIGH, HIGH, HIGH}; // define em qual estado logico cada resistencia será ligada
bool On = LOW; //define em que estádo os botões ficarão ao serem apertados
//-------- DEFINIÇÃO DE BIBLIOTECAS -------//
#include <PID_v1_bc.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
PID RstA(&Input[0], &Output[0], &Setpoint[0], PID_A[0], PID_A[1], PID_A[2], DIRECT);
PID RstB(&Input[1], &Output[1], &Setpoint[1], PID_B[0], PID_B[1], PID_B[2], DIRECT);
PID RstC(&Input[2], &Output[2], &Setpoint[2], PID_C[0], PID_C[1], PID_C[2], DIRECT);
AccelStepper motores[NUM_MOTORES] = {
AccelStepper(AccelStepper::DRIVER, Step1, Dir1),
AccelStepper(AccelStepper::DRIVER, Step2, Dir2),
AccelStepper(AccelStepper::DRIVER, Step3, Dir2)
};
LiquidCrystal_I2C lcd(0x27, 20, 4);
void setup() {
Serial.begin(115200);
Serial.print("Iniciando...");
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
lcd.createChar(0, Paw);
lcd.setCursor(3, 1);
lcd.print("T e n n i k o"); // Escreve um Nome Logo
delay(3000);
//digitalWrite(Portas[0], On); // liga o buzzer
lcd.setCursor(15, 1); // Move o cursor no display
lcd.write(byte(0)); // desenha iconeAs ao lado do nome
RstA.SetOutputLimits(0, 255); // PWM 8 bits - Configura a saída máxima do PWM
RstA.SetMode(AUTOMATIC); // Inicializa o PID em modo automático
RstB.SetOutputLimits(0, 255); //
RstB.SetMode(AUTOMATIC); //
RstC.SetOutputLimits(0, 255); //
RstC.SetMode(AUTOMATIC); //
for (byte i = 0; i < NUM_MOTORES; i++) {
motores[i].setMaxSpeed(velocidadeMax);
motores[i].setAcceleration(500); // pode ajustar depois
motores[i].setSpeed(0);
}
for (byte Np = 0; Np <= 5; Np++) {
pinMode(DP[Np], OUTPUT); // Define todas as portas como saída
digitalWrite(DP[Np], LOW); // Desliga todas as portas
if (Np <= 5) {
pinMode(AP[Np], INPUT); // Define todas as portas como Entrada
}
}
delay(3000);
lcd.clear();
}
void loop() {
/* Objetivo:
Criar um código capaz de controlar 3 recicladores de forma independente.
cada reciclador utilizará uma resistencia e um motor de passo Nema 17-23
Criar um menu que mostra a temperatura escolhida para cada resistencia e a temperatura lida para
cada resistencia.
funcionamento:
Cada resistencia e motor deverá ser contorlada de forma independente;
Em casos emque algum resistenia apresente falha, o circuito deverá parar apenas
a unidade em que se encontrar a falha, enquanto as demais trabalham normalmente;
Motores podem ser iniciados normamente independende de uma falha na resistencia
*/
/*teste de funcionamento do motor de passo
delay(500);
digitalWrite(Step1, On);
delay(1);
digitalWrite(Step1, LOW);
*/
atualizarMotores();
Sistema();
Botoes();
if (Delay(Temp_C2, 100)) {
Display();
}
}
void Sistema () {
/* Controle do sistema
*/
short T1 = analogRead(TH0);
short T2 = analogRead(TH1);
short T3 = analogRead(TH2);
short L1 = L_NTC(T1); //faz leitura do termistor convertendo-a em graus C
short L2 = L_NTC(T2); //
short L3 = L_NTC(T3); //
if (Delay(Temp_A, 1)) { //delay de procesamento do PID
if (Function[0] == 1) {
Input[0] = F_NTC(L1, f1); // filtra as possíveis oscilações dos termistores
RstA.Compute(); //faz o controle do PID
} else {
Output[0] = 00.0;
}
if (Function[1] == 1) {
Input[1] = F_NTC(L2, f2); // filtra as possíveis oscilações dos termistores
RstB.Compute(); //faz o controle do PID
} else {
Output[1] = 00.0;
}
if (Function[2] == 1) {
Input[2] = F_NTC(L3, f3); // filtra as possíveis oscilações dos termistores
RstC.Compute(); //faz o controle do PID
} else {
Output[2] = 00.0;
}
}
//--------------------------------------------------------------------------------------------------------------------------
if (Function[0] == 1) {
byte Map = map(Output[0], 0, 255, 0, 100);
if (Delay(Temp_E, intervalo[0])) { //faz controle de potencia da resistencia
double porcentagem = (double)Map / 100; //divide o valor da potencia(0 a 100) para obter uma porcentagem
double TempoOn = Tempo[0] * porcentagem; //multiplica o valor da porcentagem para obter uma porcentagem de 1 segundo
double TempoOff = Tempo[0] - TempoOn; //obtem a porcentagem restante de milisegundos que sobrarem para usar como tempo desligado
if (Sinal_S[0] == 1 && Map >= 1) {
digitalWrite(OUT1, R_Ativo[0]); //liga a resistencia
Sinal_S[0] = 0;
intervalo[0] = (short)TempoOn; //define o tempo em que a resistencia ficará desligada
} else {
digitalWrite(OUT1, !R_Ativo[0]); //desliga a resistencia
Sinal_S[0] = 1;
intervalo[0] = (short)TempoOff; //Define o tempo em que a resistencia ficará ligada;
}
}
} else {
digitalWrite(OUT1, !R_Ativo[0]); //desliga a resistencia
}
//--------------------------------------------------------------------------------------------------------------------------
if (Function[1] == 1) {
byte Map = map(Output[1], 0, 255, 0, 100);
if (Delay(Temp_D, intervalo[1])) { //faz controle de potencia da resistencia
double porcentagem = (double)Map / 100; //divide o valor da potencia(0 a 100) para obter uma porcentagem
double TempoOn = Tempo[1] * porcentagem; //multiplica o valor da porcentagem para obter uma porcentagem de 1 segundo
double TempoOff = Tempo[1] - TempoOn; //obtem a porcentagem restante de milisegundos que sobrarem para usar como tempo desligado
if (Sinal_S[1] == 1 && Map >= 1) {
digitalWrite(OUT2, R_Ativo[1]); //liga a resistencia
Sinal_S[1] = 0;
intervalo[1] = (short)TempoOn; //define o tempo em que a resistencia ficará desligada
} else {
digitalWrite(OUT2, !R_Ativo[1]); //desliga a resistencia
Sinal_S[1] = 1;
intervalo[1] = (short)TempoOff; //Define o tempo em que a resistencia ficará ligada;
}
}
} else {
digitalWrite(OUT2, !R_Ativo[1]); //desliga a resistencia
}
//--------------------------------------------------------------------------------------------------------------------------
if (Function[2] == 1) {
byte Map = map(Output[2], 0, 255, 0, 100);
if (Delay(Temp_F, intervalo[2])) { //faz controle de potencia da resistencia
double porcentagem = (double)Map / 100; //divide o valor da potencia(0 a 100) para obter uma porcentagem
double TempoOn = Tempo[2] * porcentagem; //multiplica o valor da porcentagem para obter uma porcentagem de 1 segundo
double TempoOff = Tempo[2] - TempoOn; //obtem a porcentagem restante de milisegundos que sobrarem para usar como tempo desligado
if (Sinal_S[2] == 1 && Map >= 1) {
digitalWrite(OUT3, R_Ativo[2]); //liga a resistencia
Sinal_S[2] = 0;
intervalo[2] = (short)TempoOn; //define o tempo em que a resistencia ficará desligada
} else {
digitalWrite(OUT3, !R_Ativo[2]); //desliga a resistencia
Sinal_S[2] = 1;
intervalo[2] = (short)TempoOff; //Define o tempo em que a resistencia ficará ligada;
}
}
} else {
digitalWrite(OUT3, !R_Ativo[2]); //desliga a resistencia
}
//--------------------------------------------------------------------------------------------------------------------------
}
short T_Bot[3] = {0, 0, 0}; //variável responsável por guardar o tempo em que cada botão esteve pressionado
byte Mode = 0;
byte Ok = 0;
bool editMode = false;
bool Pc = false;
void Display() {
/* Funcionamento do display: 4x20
Deverá iniciar a logo Linhas centrais
Definição de funcionamnto do programa (Tipo de projeto)
o Menu pincipal aparecerá após 3 segundos de exibição das informações iniciais;
O menu será dividido em 3 áreas de 6x4 com espaço de 1x4 demtre elas
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
[S][v][:][1][0][0][C][ ][ ][ ][ ][ ][ ][C][ ][ ][ ][ ][ ][ ]
[P][v][:][1][0][0][x][ ][ ][ ][ ][ ][ ][x][ ][ ][ ][ ][ ][ ]
[W][K][:][O][f][f][C][ ][ ][ ][ ][ ][ ][C][ ][ ][ ][ ][ ][ ]
[S][p][:][1][0][0][C][ ][ ][ ][ ][ ][ ][C][ ][ ][ ][ ][ ][ ]
Local com "X" ficará apagado
Local com "C" Posiveis areas do cursor
Local em aberto deverá conter as seguintes informações:
1. setpoint
2. temperatura
3. Velocidade do motor
4. estado (Ativado/desativado)
Menu de confiurações:
Na tela inicial haverá disponível as opções ajustes:
Setpoint;
Velocidade;
Estádo;
Ao clicar em quaisquer uma, será necesário definir em qual das 3 areas do menu essa alteração será feita.
Ex: Seleção > Setpoint(1) = Area de atuação da primeira resistencia
Funcionamento:
O cursor se manterá na função escolhida e um dos valores amostrados ficará Piscando representando o cursor
PID;
Tempo de leitura;
Tempo de analise;
*/
if ( Mode == 0 ) { //menu principal
String EstadoVariavel[] = {"", "", ""}; //define 3 possiveis opções de estado de funcionamento
for (byte nf = 0; nf <= 2; nf++) {
if (Function[nf] == 1) {
EstadoVariavel[nf] = "On"; //define estado de funcionamento como ligado
} else {
EstadoVariavel[nf] = "Off"; //define estado de funcionamento como desligado
}
}
if (One_Display == 1) { //escrever o menu uma unica vez
for (byte np = 0; np <= 2; np++) {
short pl[] = {0, 6, 12}; //define a posição onde será escrito cada "Sv:"
lcd.setCursor(pl[np], 0);
lcd.print("S:"); //setpoint
}
for (byte np = 0; np <= 2; np++) {
short pl[] = {0, 6, 12};
lcd.setCursor(pl[np], 1);
lcd.print("I:"); //leitura
}
for (byte np = 0; np <= 2; np++) {
short pl[] = {0, 6, 12};
lcd.setCursor(pl[np], 3);
lcd.print("F:"); //funcionamento
}
for (byte np = 0; np <= 2; np++) {
short pl[] = {0, 6, 12};
lcd.setCursor(pl[np], 2);
lcd.print("V:"); //velocidade
}
for (byte nv = 0; nv <= 2; nv++) {
short Vm = (short)Setpoint[nv];
short pl[] = {2, 8, 14};
lcd.setCursor(pl[nv], 0);
lcd.print(Vm); //escrve os valores de cada setpoint
lcd.setCursor(pl[nv], 3);
lcd.print(EstadoVariavel[nv]); //escreve cada estado de funcionamento do mdulo
lcd.setCursor(pl[nv], 2);
lcd.print(Speed[nv]); //escreve os valores de cada velocidade
}
One_Display = 0;
}
for (byte nv = 0; nv <= 2; nv++) {
short Vm = (short)Input[nv];
byte pl[] = {2, 8, 14};
if (Vm != LastVar[1][nv]) {
lcd.setCursor(pl[nv], 1);
lcd.print(" "); //limpa apenas o ponto em que é escrito o Sinal_S de leitura
LastVar[1][nv] = Vm;
lcd.setCursor(pl[nv], 1);
lcd.print(Vm); //escreve os valores de cada termistor
}
}
if (C_Position != A_Position) { //verifica se o cursor mudou de posição
byte Pm[] = {0, 2, 3};
if (C_Position > A_Position) { //verifica se o cursor se moveu para Baixo no display
lcd.setCursor(18, Pm[C_Position - 1]);
lcd.print(" ");
lcd.setCursor(18, Pm[C_Position]); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
} else {
lcd.setCursor(18, Pm[C_Position + 1]);
lcd.print(" ");
lcd.setCursor(18, Pm[C_Position]); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
}
}
if (Ok == 1) { //OBJ: UTILIZAR APENAS UM Sinal_S DO BOTÃO MENU PARA ALTERNAR DENTRE OS MENUS
menuSelect = C_Position; //define qual parametro será configurado.
Mode = 1; //inicia a seleção do menu para configurar um dos paramentos em que o cursor estava sobrepondo
lcd.clear(); //limpa o display
One_Display = 1; //Permite que outro menu seja escrito no display
Ok = 0; //reseta o Sinal_S Ok do botão menu
C_Position = 0; //reseta a posição do Cursor
A_Position = 1; //reseta a Posição anterior ( 1 = permite o cursor aparecer quando o menu mudar )
} else if ( Ok == 2 ) {
Mode = 2; //inicia o menu de configurações avançadas
lcd.clear();
One_Display = 1; //Permite que outro menu seja escrito no display
C_Position = 0; //reseta a posição do Cursor
A_Position = 1; //reseta a Posição anterior ( 1 = permite o cursor aparecer quando o menu mudar )
Ok = 0;
}
} else if (Mode == 1) {
if (Ok >= 2) { //impede que o usuário mude de um menu para outro sem antes sair do mesmo
Ok = 1; //
}
//-----------------------------------------------------------------------------------------
if (menuSelect == 0) { //Se cursor estava sobre a função: Setpoint
String options[] = {"Back", "Setpoint A:", "Setpoint B:", "Setpoint C:"}; //opções disponíveis no menu
if (editMode == true) { //se o modo de edição estiver ativo
if (One[3] == 0) { //Obtêm o valor do setpoint atual
setValor = (short)Setpoint[C_Position - 1];
One[3] = 1;
}
if (Delay(Temp_C, 500)) { //função que faz o cursor piscar
Pc = !Pc; //inverte o estado de Pc(Piscar_Cursor) para criar um efeito piscante no cursor
if (Pc == true) {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.write(byte(0)); //desenha o cursor
} else {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.print(" "); //apaga o icone do cursor
}
}
if (One_Display == 0) {
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0 && np != C_Position) { //utiliza a posição especifica do cursor para alterar apenas o setpoint definido
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print((short)Setpoint[np - 1]); //escreve os valores de setpoint que nãos estão marcados pelo cursor
}
}
One_Display = 1;
}
if (setValor != (short)LastVar[0][C_Position - 1]) {
LastVar[0][C_Position - 1] = (double)setValor;
lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
lcd.print(" "); //apaga o ultimo valor que antes estava escrito
lcd.setCursor(12, C_Position);
lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
}
One[3] = 1;
} else {
if (One[3] == 1) {
Setpoint[C_Position - 1] = (double)setValor; //salva o novo valor para o setpoint atual
lcd.setCursor(12, C_Position);
lcd.print(" "); //apaga apenas a area em que o cursor esteve para atualização do setpoint
setValor = 0; //reseta a variável
One[3] = 0; //reseta a função
}
if (One_Display == 1) { //permite escrever as informações do display apenas uma vez por ação
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0) {
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print((short)Setpoint[np - 1]); //escreve os valores de setpoint
}
}
One_Display = 0;
}
if (C_Position != A_Position) { //verifica se o cursor mudou de posição
byte Pm[] = {5, 16, 16, 16};
if (C_Position > A_Position) { //verifica se o cursor se moveu para Baixo no display
lcd.setCursor(Pm[C_Position - 1], C_Position - 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
} else {
lcd.setCursor(Pm[C_Position + 1], C_Position + 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
}
}
}
}
//-----------------------------------------------------------------------------------------
if (menuSelect == 2) { //Se cursor estava sobre a função: Definição de trabalho
String options[] = {"Back", "Module A:", "Module B:", "Module C:"}; //opções disponíveis no menu
String EstadoVariavel[] = {"", "", ""}; //define 3 possiveis opções de estado de funcionamento
for (byte nf = 0; nf <= 2; nf++) {
if (Function[nf] == 1) {
EstadoVariavel[nf] = "On"; //define estado de funcionamento como ligado
} else {
EstadoVariavel[nf] = "Off"; //define estado de funcionamento como desligado
}
}
if (editMode == 1) { //se o modo de edição estiver ativo
if (One_Display == 0) { //permite as configurações do editmode serem escritos apenas uma vez
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0 && np != C_Position) { //utiliza a posição especifica do cursor para alterar apenas a fnção definida
lcd.setCursor(12, np); //define a posição do estado de funcionamento da configurção ("On" "Off")
lcd.print(EstadoVariavel[np - 1]); //escreve o estado de funcionamento da configurção ("On" "Off")
}
}
One_Display = 1;
}
Function[C_Position - 1] = !Function[C_Position - 1]; //inverte o estado da função para ativar/desativar um modulo completo de reciclagem (resistencia motor)
editMode = 0;
lcd.setCursor(12, C_Position);
lcd.print(" ");
} else {
if (One_Display == 1) {
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0) {
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print(EstadoVariavel[np - 1]); //escreve os valores de setpoint
}
}
One_Display = 0;
}
if (C_Position != A_Position) { //verifica se o cursor mudou de posição
byte Pm[] = {5, 16, 16, 16};
if (C_Position > A_Position) { //verifica se o cursor se moveu para Baixo no display
lcd.setCursor(Pm[C_Position - 1], C_Position - 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
} else {
lcd.setCursor(Pm[C_Position + 1], C_Position + 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
}
}
}
}
//-----------------------------------------------------------------------------------------
if (menuSelect == 1) { //Se cursor estava sobre a função: velocidade
String options[] = {"Back", "Speed A:", "Speed B:", "Speed C:"}; //opções disponíveis no menu
if (editMode == 1) { //se o modo de edição estiver ativo
if (One[3] == 0) { //Obtêm o valor do setpoint atual
setValor = Speed[C_Position - 1];
One[3] = 1;
}
if (Delay(Temp_C, 500)) { //função que faz o cursor piscar
Pc = !Pc; //inverte o estado de Pc(Piscar_Cursor) para criar um efeito piscante no cursor
if (Pc == true) {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.write(byte(0)); //desenha o cursor
} else {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.print(" "); //apaga o icone do cursor
}
}
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0 && np != C_Position) { //utiliza a posição especifica do cursor para alterar apenas o setpoint definido
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print(Speed[np - 1]); //escreve os valores de setpoint que nãos estão marcados pelo cursor
}
}
if (setValor != (short)LastVar[2][C_Position - 1]) {
LastVar[2][C_Position - 1] = (double)setValor;
lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
lcd.print(" "); //apaga o ultimo valor que antes estava escrito
lcd.setCursor(12, C_Position);
lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
}
//lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
//lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
One[3] = 1; //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
Speed[C_Position - 1] = setValor; //salva o novo valor para a velocidade atual
} else {
if (One[3] == 1) {
//Speed[C_Position - 1] = setValor; //salva o novo valor para o setpoint atual
lcd.setCursor(12, C_Position);
lcd.print(" ");
setValor = 0; //reseta a variável
One[3] = 0; //reseta a função
}
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0) {
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print(Speed[np - 1]); //escreve os valores de setpoint
}
}
if (C_Position != A_Position) { //verifica se o cursor mudou de posição
byte Pm[] = {5, 16, 16, 16};
if (C_Position > A_Position) { //verifica se o cursor se moveu para Baixo no display
lcd.setCursor(Pm[C_Position - 1], C_Position - 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
} else {
lcd.setCursor(Pm[C_Position + 1], C_Position + 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
}
}
}
}
if (Ok == 1 && C_Position != 0) { //verifica se alguma das opções foram selecionadas
editMode = !editMode; //inverte o estado da Variável para entrar em modo de edição
Ok = 0; //reseta o botão menu
} else if (Ok == 1 && C_Position == 0) {
Ok = 0; //reseta o botão menu
C_Position = 0; //reseta o cursor
A_Position = 1; //reseta a Posição anterior ( 1 = permite o cursor aparecer quando o menu mudar )
Mode = 0; //retorna para o menu inicial
lcd.clear(); //limpa o display
One_Display = 1; //Permite que outro menu seja escrito no display
}
//-----------------------------------------------------------------------------------------
} else if (Mode == 2) { //Configurações avançadas
String Options[] = {"Back", "PID A", "PID B", "PID C"};
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np);
lcd.print(Options[np]); //escreve todas as opções disponíveis no menu
}
if (C_Position != A_Position) { //verifica se o cursor mudou de posição
byte Pm[] = {5, 16, 16, 16};
if (C_Position > A_Position) { //verifica se o cursor se moveu para Baixo no display
lcd.setCursor(Pm[C_Position - 1], C_Position - 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
} else {
lcd.setCursor(Pm[C_Position + 1], C_Position + 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
}
}
if (Ok == 1 && C_Position != 0) { //verifica se alguma das opções foram selecionadas
menuSelect = C_Position; //define qual parametro será configurado.
Mode = 3; //inicia a seleção do menu para configurar um dos paramentos em que o cursor estava sobrepondo
lcd.clear();
Ok = 0; //reseta o Sinal_S Ok do botão menu
C_Position = 0; //reseta a poição do Cursor
} else if (Ok == 1 && C_Position == 0) {
Ok = 0; //reseta o botão menu
C_Position = 0; //reseta o cursor
Mode = 0; //retorna para o menu inicial
lcd.clear();
}
} else if (Mode == 3) {
if (menuSelect == 1) { //Se cursor estava sobre a função: Setpoint
String options[] = {"Back", "Kp:", "Ki:", "Kd:"}; //opções disponíveis no menu
if (editMode == true) { //se o modo de edição estiver ativo
if (One[3] == 0) { //Obtêm o valor do setpoint atual
setValor = (short)PID_A[C_Position - 1];
One[3] = 1;
}
if (Delay(Temp_C, 500)) { //função que faz o cursor piscar
Pc = !Pc; //inverte o estado de Pc(Piscar_Cursor) para criar um efeito piscante no cursor
if (Pc == true) {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.write(byte(0)); //desenha o cursor
} else {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.print(" "); //apaga o icone do cursor
}
}
lcd.setCursor(10, 0);
lcd.print("Module: A"); //Escreve qual modulo está sendo configurado
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0 && np != C_Position) { //utiliza a posição especifica do cursor para alterar apenas o setpoint definido
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print((short)PID_A[np - 1]); //escreve os valores de setpoint que nãos estão marcados pelo cursor
}
}
if (setValor != (short)LastVar[3][C_Position - 1]) {
LastVar[3][C_Position - 1] = (double)setValor;
lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
lcd.print(" "); //apaga o ultimo valor que antes estava escrito
lcd.setCursor(12, C_Position);
lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
}
//lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
// lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
One[3] = 1;
} else {
if (One[3] == 1) {
PID_A[C_Position - 1] = (double)setValor; //salva o novo valor para o setpoint atual
lcd.setCursor(12, C_Position);
lcd.print(" ");
// Setpoint_S[C_Position - 1] = Setpoint[C_Position - 1];
setValor = 0; //reseta a variável
One[3] = 0; //reseta a função
}
lcd.setCursor(10, 0);
lcd.print("Module: A"); //Escreve qual modulo está sendo configurado
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0) {
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print((short)PID_A[np - 1]); //escreve os valores de setpoint
}
}
if (C_Position != A_Position) { //verifica se o cursor mudou de posição
byte Pm[] = {5, 16, 16, 16};
if (C_Position > A_Position) { //verifica se o cursor se moveu para Baixo no display
lcd.setCursor(Pm[C_Position - 1], C_Position - 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
} else {
lcd.setCursor(Pm[C_Position + 1], C_Position + 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
}
}
}
}
//-----------------------------------------------------------------------------------------
if (menuSelect == 2) { //Se cursor estava sobre a função: Definição de trabalho
String options[] = {"Back", "Kp:", "Ki:", "Kd:"}; //opções disponíveis no menu
if (editMode == true) { //se o modo de edição estiver ativo
if (One[3] == 0) { //Obtêm o valor do setpoint atual
setValor = (short)PID_B[C_Position - 1];
One[3] = 1;
}
if (Delay(Temp_C, 500)) { //função que faz o cursor piscar
Pc = !Pc; //inverte o estado de Pc(Piscar_Cursor) para criar um efeito piscante no cursor
if (Pc == true) {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.write(byte(0)); //desenha o cursor
} else {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.print(" "); //apaga o icone do cursor
}
}
lcd.setCursor(10, 0);
lcd.print("Module: B"); //Escreve qual modulo está sendo configurado
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0 && np != C_Position) { //utiliza a posição especifica do cursor para alterar apenas o setpoint definido
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print((short)PID_B[np - 1]); //escreve os valores de setpoint que nãos estão marcados pelo cursor
}
}
if (setValor != (short)LastVar[4][C_Position - 1]) {
LastVar[4][C_Position - 1] = (double)setValor;
lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
lcd.print(" "); //apaga o ultimo valor que antes estava escrito
lcd.setCursor(12, C_Position);
lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
}
//lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
// lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
One[3] = 1;
} else {
if (One[3] == 1) {
PID_B[C_Position - 1] = (double)setValor; //salva o novo valor para o setpoint atual
lcd.setCursor(12, C_Position);
lcd.print(" ");
// Setpoint_S[C_Position - 1] = Setpoint[C_Position - 1];
setValor = 0; //reseta a variável
One[3] = 0; //reseta a função
}
lcd.setCursor(10, 0);
lcd.print("Module: B"); //Escreve qual modulo está sendo configurado
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0) {
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print((short)PID_B[np - 1]); //escreve os valores de setpoint
}
}
if (C_Position != A_Position) { //verifica se o cursor mudou de posição
byte Pm[] = {5, 16, 16, 16};
if (C_Position > A_Position) { //verifica se o cursor se moveu para Baixo no display
lcd.setCursor(Pm[C_Position - 1], C_Position - 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
} else {
lcd.setCursor(Pm[C_Position + 1], C_Position + 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
}
}
}
}
//-----------------------------------------------------------------------------------------
if (menuSelect == 3) { //Se cursor estava sobre a função: velocidade
String options[] = {"Back", "Kp:", "Ki:", "Kd:"}; //opções disponíveis no menu
if (editMode == true) { //se o modo de edição estiver ativo
if (One[3] == 0) { //Obtêm o valor do setpoint atual
setValor = (short)PID_C[C_Position - 1];
One[3] = 1;
}
if (Delay(Temp_C, 500)) { //função que faz o cursor piscar
Pc = !Pc; //inverte o estado de Pc(Piscar_Cursor) para criar um efeito piscante no cursor
if (Pc == true) {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.write(byte(0)); //desenha o cursor
} else {
lcd.setCursor(16, C_Position); //define a posição do cursor
lcd.print(" "); //apaga o icone do cursor
}
}
lcd.setCursor(10, 0);
lcd.print("Module: C"); //Escreve qual modulo está sendo configurado
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0 && np != C_Position) { //utiliza a posição especifica do cursor para alterar apenas o setpoint definido
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print((short)PID_C[np - 1]); //escreve os valores de setpoint que nãos estão marcados pelo cursor
}
}
if (setValor != (short)LastVar[5][C_Position - 1]) {
LastVar[5][C_Position - 1] = (double)setValor;
lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
lcd.print(" "); //apaga o ultimo valor que antes estava escrito
lcd.setCursor(12, C_Position);
lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
}
//lcd.setCursor(12, C_Position); //obtem a posição atual do cursor
// lcd.print(setValor); //Mostra ao usuario o valor que será definido no setpoint após sua confirmação
One[3] = 1;
} else {
if (One[3] == 1) {
PID_C[C_Position - 1] = (double)setValor; //salva o novo valor para o setpoint atual
lcd.setCursor(12, C_Position);
lcd.print(" ");
// Setpoint_S[C_Position - 1] = Setpoint[C_Position - 1];
setValor = 0; //reseta a variável
One[3] = 0; //reseta a função
}
lcd.setCursor(10, 0);
lcd.print("Module: C"); //Escreve qual modulo está sendo configurado
for (byte np = 0; np <= 3; np++) {
lcd.setCursor(0, np); //define automaticamente a linha em que será escrito cada opção
lcd.print(options[np]); //imprime as opções defnidas no display
if (np > 0) {
lcd.setCursor(12, np); //define a posição dos valores setpoint
lcd.print((short)PID_C[np - 1]); //escreve os valores de setpoint
}
}
if (C_Position != A_Position) { //verifica se o cursor mudou de posição
byte Pm[] = {5, 16, 16, 16};
if (C_Position > A_Position) { //verifica se o cursor se moveu para Baixo no display
lcd.setCursor(Pm[C_Position - 1], C_Position - 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
} else {
lcd.setCursor(Pm[C_Position + 1], C_Position + 1);
lcd.print(" ");
lcd.setCursor(Pm[C_Position], C_Position); //define a posição do cursor do usuário
lcd.write(byte(0)); //imprime patinhas no local do cursor
A_Position = C_Position; //guarda a posição atual do cursor
}
}
}
}
if (Ok == 1 && C_Position != 0) { //verifica se alguma das opções foram selecionadas
editMode = !editMode; //inverte o estado da Variável para entrar em modo de edição
Ok = 0; //reseta o botão menu
} else if (Ok == 1 && C_Position == 0) {
Ok = 0; //reseta o botão menu
C_Position = 0; //reseta o cursor
Mode = 2; //retorna para o menu inicial
lcd.clear();
}
}
//-----------------------------------------------------------------------------------------
}
void Botoes() {
if (digitalRead(Bot1) == On && T_Bot[0] < 1000) { //funcionamento do botão +
if (Delay(Temp_B, 100) && count[0] < 22) {
count[0]++;
T_Bot[0] = T_Bot[0] + 50;
}
} else if (digitalRead(Bot1) == On && T_Bot[0] >= 1000) {
if (Delay(Temp_D, 100) && editMode == true) {
if (Mode == 1 && setValor < maxValLimits[menuSelect][0] - 10) {
setValor = setValor + 10; //aumenta o valor de 10 em 10 para ajustes de velocidade
} else if (Mode == 3 && setValor < maxValLimits[menuSelect][1] - 10) {
setValor = setValor + 10; //aumenta o valor de 10 em 10 para ajustes de velocidade
}
} else {
if (C_Position > 0 && editMode == false) {
C_Position--;
}
}
One[0] = 1;
} else if (T_Bot[0] > 50 && T_Bot[0] < 1000) {
//codigo de funcionamento após um cique do botão
Serial.println("Botão: + apertado");
if (editMode == true && menuSelect == 1 && Mode == 1) {
if (setValor < 100) {
setValor = setValor + 10; //aumenta o valor de 10 em 10 para ajustes de velocidade
}
} else if (editMode == true) {
if (Mode == 1 && setValor < maxValLimits[menuSelect][0]) {
setValor++; //aumenta o valor de 10 em 10 para ajustes de velocidade
} else if (Mode == 3 && setValor < maxValLimits[menuSelect][1]) {
setValor++; //aumenta o valor de 10 em 10 para ajustes de velocidade
}
} else {
if (C_Position > 0) {
C_Position--;
}
}
T_Bot[0] = 0;
One[0] = 1;
} else {
if (One[0] == 1) {
T_Bot[0] = 0;
count[0] = 0;
One[0] = 0;
}
}
//-----------------------------------------------------------------------------------------
// if (Delay(Temp_B, 1)) {
if (digitalRead(Bot2) == On && T_Bot[1] < 1000) { //funcionamento do botão Menu
if (Delay(Temp_B, 100) && count[1] < 22) {
T_Bot[1] = T_Bot[1] + 50;
count[1]++;
}
} else if (digitalRead(Bot2) == On && T_Bot[1] >= 1000) {
//inserir código para aumento de Setpoint/velocidade/PID
Ok = 2; //envia o comando de "Botão segurado" para interagir com opções especificas
One[1] = 1;
Serial.println("Botão: M segurado");
} else if (T_Bot[1] > 50 && T_Bot[1] < 1000) {
//codigo de funcionamento após um cique do botão
Ok = 1; //envia o comando de "Botão presionado" para interagir com quaiquer opções do menu
Serial.println("Botão: M apertado");
T_Bot[1] = 0;
One[1] = 1;
} else {
if (One[1] == 1) {
count[1] = 0;
T_Bot[1] = 0;
One[1] = 0;
}
}
// }
//-----------------------------------------------------------------------------------------
if (digitalRead(Bot3) == On && T_Bot[2] < 1000) { //funcionamento do botão -
if (Delay(Temp_B, 100) && count[2] < 22) {
T_Bot[2] = T_Bot[2] + 50;
}
} else if (digitalRead(Bot3) == On && T_Bot[2] >= 1000) {
//inserir código para aumento de Setpoint/velocidade/PID
if (Delay(Temp_D, 100) && editMode == true) {
if (setValor > 10) {
setValor = setValor - 10; //aumenta o valor de 10 em 10 para ajustes de velocidade
}
} else {
if (C_Position < maxMenuLimits[Mode] && editMode == false) {
C_Position++;
}
}
One[2] = 1;
} else if (T_Bot[2] > 50 && T_Bot[2] < 1000) {
//codigo de funcionamento após um cique do botão
if (editMode == true && menuSelect == 1 && Mode == 1) {
if (setValor > 0) {
setValor = setValor - 10; //aumenta o valor de 10 em 10 para ajustes de velocidade
}
} else if (editMode == true) {
if (setValor > 0) {
setValor--; //aumenta o valor de 10 em 10 para ajustes de velocidade
}
} else {
if (C_Position < maxMenuLimits[Mode]) {
C_Position++;
}
}
Serial.println("Botão: - apertado");
T_Bot[2] = 0;
One[2] = 1;
} else {
if (One[2] == 1) {
T_Bot[2] = 0;
count[2] = 0;
One[2] = 0;
}
}
}
void atualizarMotores() {
for (byte i = 0; i < NUM_MOTORES; i++) {
short vel = (short)Speed[i];
short Map = map(vel, 0, 100, 0, velocidadeMax);
//float velocidade = calculaVelocidade(vel);
motores[i].setSpeed(Map);
// Faz o motor girar continuamente
motores[i].runSpeed();
}
}
// ----- CONVERSÃO % → VELOCIDADE -----
float calculaVelocidade(short porcentagem) {
if (porcentagem == 0) return 0;
float x = porcentagem / 100.0;
// curva opcional (deixa mais suave)
//float curva = pow(x, 2);
float curva = x;
return curva * velocidadeMax;
}
double F_NTC(double leitura, double &estado) {
const double alpha = 0.1;
estado = alpha * leitura + (1.0 - alpha) * estado;
return estado;
}
float L_NTC(short leitura) {
for (byte i = 0; i < 11; i++) {
if (leitura <= tabela[i].adc && leitura >= tabela[i + 1].adc) {
float t = (float)(leitura - tabela[i + 1].adc) /
(tabela[i].adc - tabela[i + 1].adc);
return tabela[i + 1].temp + t * (tabela[i].temp - tabela[i + 1].temp);
}
}
return -1;
}
bool Delay(unsigned long & Tempo, short intervalo) { // função Neotimer
if (millis() - Tempo >= intervalo) { // verifica se o tempo de inervalo foi alcançado
Tempo = millis(); // guarda o valor de millis() par criar um novo intervalo
return true;
} else {
return false;
}
}