Olá, gostaria da ajuda da comunidade.
Tenho um dispositivo criado para execução de um teste de resistência.
O teste é executado ate a quebra do produto, então são normalmente, +/- 150.000 execuções.
O meu problema é, quando o dispositivo é desligado, ate o momento não consegui uma forma de recuperar a quantidade de execuções ate o desligamento.
Pensei na eeprom, mas ai tem o problema da limitação da quantidade de gravações, também pensei no SD, mas não consegui uma forma de criar um arquivo txt e só alterar o valor do contador, sem a necessidade de ficar criando varias linhas.
Também procurei como excluir o arquivo txt do SD, para sempre criar um novo com o valor da contagem a cada execução, mas também não encontrei nada sobre.
Se alguém da comunidade tiver alguma forma para eu implementar isso agradeço desde já.
Estou usando Arduino mega, com um display nextion.
Ola,
não entendi bem a questão do desligamento.
Este desligamento que você quer ter os dados salvos, é um desligamento feito por você ou é quando falta energia?
Informe que micro controlador você está usando.
Usando as tags </>, publique o código que você fez até agora, mesmo que não funcione.
![]()
Posta também um esquemático do seu projeto.
Assim podemos entender seu projeto e ter melhores condições de ajuda-lo.
O desligamento seria pelo usuário, ou por uma queda de energia mesmo.
Não posso perder o valor da contagem , já que o principal parâmetro do teste é a quantidade de impactos que a peça suportou.
Cada execução entre aberto e fechado, tem a duração de +/- 3 segundos.
//DEFINE BIBLIOTECAS USADAS
#include <Arduino.h>
#include "Nextion.h"
//NEXTION++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
NexDSButton bot0 = NexDSButton(0,6, "bt0"); //CRIA BOTÃO NEXTION
NexNumber num = NexNumber(0, 10, "n3"); //CRIA ETIQUETA PARA RECEBER VALOR NEXTION
NexNumber num0 = NexNumber(0, 7, "n0"); //CRIA ETIQUETA PARA PASSAR VALOR NUMERICO NEXTION
NexNumber num1 = NexNumber(0, 8, "n1"); //CRIA ETIQUETA PARA PASSAR VALOR NUMERICO NEXTION
NexNumber num2 = NexNumber(0, 9, "n2"); //CRIA ETIQUETA PARA PASSAR VALOR NUMERICO NEXTION
NexText text = NexText(0, 5, "t8"); //CRIA ETIQUETA PARA TEXTO VALOR NEXTION
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Definições das variaveis//////////////////////////////////////////////////////////////////////////////////////////
uint32_t estado_botao; // VARIAVEL QUE ARMAZENA A CONDIÇÃO DO BOTÃO NEXTION
uint32_t TempoAtivo = 0; // VARIAVEL TEMPO ATIVO NEXTION
uint32_t TempoInativo = 0; // VARIAVEL TEMPO INATIVO NEXTION
int QuantidadeCiclos; // VARIAVEL QUE ARMAZENA A QUANTIDADE DE EXECUÇÕES (INTERNAS)
int Qtd; // VARIAVEL QUE ARMAZENA A QUANTIDADE DE EXECUÇÕES (INTERNAS)
int QuantidadeCiclosAtual; // VARIAVEL QUE ARMAZENA A QUANTIDADE DE EXECUÇÕES (CONTADOR)
unsigned long Quantidade; // VARIAVEL QUE ARMAZENA A QUANTIDADE DE EXECUÇÕES (EXTRNAS) NEXTION
const int pinoRele = 10; //DEFINE SAIDA DIGITA RELE
int estadoCilindro = HIGH; //DEFINE ESTADO DA SAIDA
unsigned long tempoAnterior = 0; // VARIAVEL Q Armazena o último momento em que o Rele foi acionado
//Fim das Variaveis//////////////////////////////////////////////////////////////////////////////////////////////////
//****setap inicial**********************************************************************************************
void setup() {
Serial.begin(9600); //INICIA SERIAL DO CONTOLADOR
nexInit(); //INICIA SERIAL IHM
delay(4000);// espera o nextion iniciar
pinMode(pinoRele, OUTPUT); //EXECUTA O PINO COMO SAÍDA RELE
digitalWrite(pinoRele, HIGH); //EXECUTA RELE INICIA ABERTO
text.setText("Parado"); //ESCREVE NA TELA DO NEXTION
}//FIM DO SETUP****************************************************************************************************
//****loop principal***************************************************************************************
void loop() {
bot0.getValue(&estado_botao); //LEZ A CONDIÇÃO DO BOTÃO NO IHM
unsigned long tempoAtual = millis(); //VARIAVEL RESPONSAVEL PELO CONTADOR DE TEMPO ATUAL
if ((estado_botao == 1) && (QuantidadeCiclos > 0)) // VERIFICA SE O BOTÃO ESTA ATIVO E SE CICLOS É MAIOR Q 0, CASO POSITIVO INICIA
{
if ((estadoCilindro == HIGH) && (TempoInativo > 0) && (tempoAtual - tempoAnterior >= TempoAtivo)) //VERIFICA SE RELE ESTA ABERTO, SE TEMPO INATIVO É MAIOR Q 0, CASO POSITIVO INICIA CONTAGEM E EXECUTA OS COMANDOS
{
text.setText("Executando"); //ESCREVE NA IHM
tempoAnterior = tempoAtual; //COLOCA TEMPO AGORA NA VARIAVEL TEMPO ANTERIOR
estadoCilindro = LOW; //DEFINE RELE COMO FECHADO
digitalWrite(pinoRele, estadoCilindro);//EXECUTA RELE
}
else if ((estadoCilindro == LOW) && (TempoAtivo > 0) && (tempoAtual - tempoAnterior >=TempoInativo)) //VERIFICA SE RELE ESTA ABERTO, SE TEMPO ATIVO É MAIOR Q 0, CASO POSITIVO INICIA CONTAGEM E EXECUTA OS COMANDOS
{
estadoCilindro = HIGH; //DEFINE RELE COMO ABERTO
tempoAnterior = tempoAtual; //COLOCA TEMPO AGORA NA VARIAVEL TEMPO ANTERIOR
digitalWrite(pinoRele, estadoCilindro);//EXECUTA RELE
QuantidadeCiclosAtual ++; //SOMA MAIS 1 A VARIAVEL
QuantidadeCiclos --; //DIMINUE 1 DA VARIAVEL
}
num.setValue(QuantidadeCiclosAtual);//ESCREVE QUANTIDADE EXECUTADA NA IHM
if (QuantidadeCiclos <= 0) //VERIFICA SE JA EXECUTOU OS CICLOS SOLICITADOS
{
text.setText("Finalizado");//ESCREVE NA IHM
}
}
else if (estado_botao == 0) //TESTA SE BOTÀO DA IHM FOI DESLIGADO
{
estadoCilindro = HIGH; //DEFINE RELE COMO ABERTO
digitalWrite(pinoRele, estadoCilindro);//EXECUTA RELE FECHADO
}
num0.getValue(&TempoAtivo); //VERIFICA O VALOR NO CAMPO DA IHM E COLOCA NA VARIAVEL
num1.getValue(&TempoInativo);//VERIFICA O VALOR NO CAMPO DA IHM E COLOCA NA VARIAVEL
num2.getValue(&Quantidade); //VERIFICA O VALOR NO CAMPO DA IHM E COLOCA NA VARIAVEL
// Serial.println(TempoAtivo);
if (Qtd != Quantidade)//VERIFICA SE QUANTIDADE DAS VARIAVEIS SÃO DIFERENTES
{
Qtd = Quantidade; //COPIA VALOR DA VARIAVEL 1 PARA 2
QuantidadeCiclos = Quantidade; //COPIA VALOR DA VARIAVEL 1 PARA 2
QuantidadeCiclosAtual = 0;//ZERA CONTAGEM ATUAL
}
delay(5); //PARA CONTROLADOR POR 5 MILESEGUNDO, PARA COMUNICAÇÃO DA IHM FUNCIONAR
}
Qualquer que seja a mídia de gravação que você escolher, sempre existe a possibilidade de que a falta de energia capture a gravação do arduino. Se isso acontecer, os dados gravados serão corrompidos e inutilizáveis.
A primeira coisa que eu acrescentaria ao seu projeto é uma pequena bateria lipo (que duraria apenas alguns segundos para terminar a gravação), com seu carregador. Obviamente eu usaria um pino conectado, (provavelmente com um divisor de tensão de 5v), a um pino de entrada livre para detectar a falta de corrente.
Se fizer isso, não é mais necessário registrar a cada mudança de ciclo, registre apenas quando você mandar parar ou quando houver uma falha de energia. Se você fizer isso, por que não usar a eeprom? Vamos fazer alguns números:
- Paradas de usuários/dia = 10
- Falhas de energia = 5 (eu processaria a companhia de energia).
- vida da eeprom = 100.000 / 15 /365 = 18,2 anos
Nada mal, você acha pouco?. Bem, por segurança, em 15 anos você muda o endereço de escrita para 100 e assim, a cada 15 anos você muda o endereço de escrita, com o qual você, tem uma eeprom por 150 anos.
Hmm... esqueci que você usa um Mega, multiplica por 4.
Boa noite, obrigado pela ajuda.
Segue como resolvi, vou adiciona a bateria e a rotina de verificação de falta de energia.
Assim, fica completo!
else if ((estadoCilindro == LOW) && (TempoAtivo > 0) && (tempoAtual - tempoAnterior >=TempoInativo)) //VERIFICA SE RELE ESTA ABERTO, SE TEMPO ATIVO É MAIOR Q 0, CASO POSITIVO INICIA CONTAGEM E EXECUTA OS COMANDOS
{
estadoCilindro = HIGH; //DEFINE RELE COMO ABERTO
tempoAnterior = tempoAtual; //COLOCA TEMPO AGORA NA VARIAVEL TEMPO ANTERIOR
digitalWrite(pinoRele, estadoCilindro);//EXECUTA RELE
SD.remove("log.txt"); //APAGA ARQUIVO COM A QUANTIDADE ATUAL
QuantidadeCiclosAtual ++; //SOMA MAIS 1 A VARIAVEL
QuantidadeCiclos --; //DIMINUE 1 DA VARIAVEL
//INICIA GRAVAÇÃO COM O NOVO VALOR =======================================================
dataFile = SD.open("log.txt", FILE_WRITE); // Abre o arquivo Log.txt do cartao SD
// Grava os dados no arquivo
if (dataFile)
{
dataFile.println(QuantidadeCiclosAtual);
dataFile.close();
}
else
{
// Mensagem de erro caso ocorra algum problema na abertura do arquivo
Serial.println("Erro ao abrir log.txt !");
}
//TERMINA GRAVAÇÃO DO NOVO VALOR ======================================================
}