Fala garagistas,

estou fazendo um projeto com o Arduino Mega 2560 no qual preciso captar alguns dados sensoriais de um veículo e salvá-los em um cartão de memória. Estou utilizando o SD Ethernert shield do Arduino. Contudo, estou tendo alguns problemas com o tempo. Alguém poderia me ajudar? O código que fiz está abaixo:

// biblioteca para interrupcao
#include <avr/io.h>
#include <avr/interrupt.h> //estava esquecendo essas 2 bibliotecas para fazer as interrupcoes

//biblioteca SD
#include <SD.h>

//arquivo para salvar no cartão
volatile File carro;

//chip select do SD
volatile const int CS_SD = 4;

//declaração de variaveis para sensor de efeito Hall
//volatile const int hall = 44;
//volatile int rotacao = 0;


//declara variaveis sensor de temperatura
volatile int pinoSensor = 2; //porta analogica
volatile int valorLido = 0;
volatile float temperatura = 0;
volatile int volta = 0;
volatile int dente = 0;
volatile int led = 6;
volatile float contvalor;
//volatile int valor;
volatile float conthigh;
volatile float per;
volatile int porta=5;

//declaração de variaveis para calculo da velocidade
//volatile const int S_VEL = 38; // porta para pulso do sensor
//volatile int velocidade =0;

void setup()
{
// cli(); //disable interrupts
//aqui sao as interrupcoes dos sensores digitais rapidos
attachInterrupt(0, RPM, RISING); // 0 pino2, chama a funcao RPM, no RISING edge
attachInterrupt(1, VEL, RISING); // 0 pino3, chama a funcao VEL, no RISING edge

cli();
Serial.begin(9600);

pinMode (pinoSensor, INPUT);
pinMode (led, OUTPUT);
pinMode (porta,INPUT);
//pinMode(S_VEL, OUTPUT);
//pinMode(hall, OUTPUT);
Serial.println("a");

//conf do sd com saida
pinMode(10, OUTPUT);
pinMode(CS_SD, OUTPUT);

if (!SD.begin(CS_SD))
{
Serial.println("falha na inicializacao do cartao");
return;
}
else
{
Serial.println("OK");
//carro.println("OK");
}

TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= (1 CS10); // \___1024 prescaler -- cada valor da 0,000064s ou 0,064ms - acho q é suficientemente preciso
TCCR1B |= (1 CS12); // / -so o bit CS12-preescaler 256 (vide tabela AVR)


TIMSK1 |= (1 OCIE1A); // enable timer 1 compare interrupt A
TIMSK1 |= (1 OCIE1B); // enable timer 1 compare interrupt B
TIMSK1 |= (1 TOIE1); // enable timer overflow interrupt

/* TCCR2A = 0;
TCCR2B = 0;
TCCR2B |= (1 CS20);
TCCR2B |= (1 CS21);
TCCR2B |= (1 CS22);
// TCCR2B |= (1 WGM21);
// TCCR2B |= (1 WGM20);

TIMSK2 |= (1 OCIE2A);
TIMSK2 |= (1 OCIE2B);
TIMSK2 |= (1 TOIE2);
*/
TCNT1 = 0;
// TCNT2 = 0;

OCR1A = 15625; //esse valor com o preescaler 1024, da exato 1 seg
//Serial.println(OCR1A);
//comeca com volta ZERO
//volta = 0;

sei(); //enable interrupts
//Serial.println("b");
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
void RPM()//interrupcao de volta do motor
{
volta++;
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void VEL() //interrupcao por dentes da caixa de redução(velocidade)
{
dente++;
}


ISR(TIMER1_COMPA_vect)// timer compare interrupt service routine
{
Principal();
}
void Principal()// interrupção principal no setup ja foi colocado o comparador para disparar essa função a cada 1 seg (pode ser alterado)
{
TCNT1 = 0;

//calculo da temperatura
valorLido = analogRead(pinoSensor);
//temperatura = (valorLido * 0.00488);
//temperatura = temperatura * 100; //OU entao:
temperatura = valorLido * 0.488;

//calculo combustivel
per = (conthigh)/(contvalor);


//acende led com interrupcao
if(dente>0)
{
digitalWrite(led, HIGH);
}
else
{
digitalWrite(led, LOW);
}

//calculando a RPM e velocidade 
// rotacao = volta / 60;
// volta = 0;

//velocidade = dente / 30;
Serial.println("volta: ");
Serial.println(volta);
Serial.println("combustivel");
Serial.println(per);
Serial.println("temperatura");
Serial.println(temperatura);


//salvando cartão de menoria
File carro = SD.open("dados.csv", FILE_WRITE);
if (carro)
{
carro.print(volta);
carro.print(";");
carro.print(dente);
carro.print(";");
carro.print(per);
carro.print(";");
carro.print(temperatura);
carro.println();
// fecha arquivo:
carro.close();
}
else
{
//se arquivo não abrir, mostra erro
Serial.println("erro ao ler o cartao");
}

contvalor = 0;
dente = 0;
conthigh=0;
volta=0;
}

void loop()
{
// valor = digitalRead(5);
if(digitalRead(porta)==HIGH)
{
conthigh++;
}
contvalor++;
}

Exibições: 1760

Responder esta

Respostas a este tópico

 estou tendo alguns problemas com o tempo

Que tipos de problemas? seja mais especifico, seu código é extenso pra ficar procurando erros...  

Me desculpa, acabei esquecendo de colocar. Preciso salvar os dados a cada 0,5s. Mas acho que está dando estouro ou algo do tipo, porque não está dando certo este tempo. Ele esta variando.

você diz a cada 0,5s mas cofigura o timer pra 1 segundo?!?!

  • verifique a velocidade de escrita no SD, a library original do arduino 0023 é muito lenta. escrita lenta no SD. olha no teste quanto demora usando errado a biblioteca(mais de 7s...)
  • o problema do stack é que ele tem se não me engano 5 ou 6 posiçoes e cada chamada de função/int sobre a outra usa, costuma dar problemas e não se descobre fácil...
  • você abre o arquivo dentro da interrupção, abra-o dentro do setup()...
  • quando faço log, sempre coloco o millis como um dos campos, tipo: 

millis,temperatura,velocidade...

 

o que te impede de usar o millis? por cima já vi alguns erros:

  • dentro da interrupção você chama outra função, gasta o stack à toa
  • dentro da interrupção você chama o analogRead
  • usa o Serial e escreve no SD dentro da interrupção...

praticamente o que era pra ficar fora da interrupção você colocou dentro, e o que era pra ficar dentro você colocou fora(no loop)... dentro da interrupção de 1 segundo, coloque apenas um flag para processar o dados/serial/SD

e no loop monitore esse flag , se TRUE faça o log.

o que mede no pino 5?

Olá Matheus, sou formando em um curso técnico na área de eletroeletrônica estou com um projeto de TCC que é muito parecido com o seu. No projeto irei realizar um monitoramento da corrente de um motor DC com alimentação de 110 V corrente nominal de aproximadamente 6 A e de pico com mais ou menos 14 A. Irei utilizar um transdutor de efeito hall para fazer a medição desta corrente e essas informações serão armazenadas em um cartão de memória plugado em módulo SD Card e visualizadas em tempo real em um display LCD com data e hora ( vou utilizar o CI RTC DS 1307). A dúvida é a seguinte analisei o seu código e não encontrei a biblioteca para o sensor hall, não existe ou não é necessário usar a biblioteca ? Você pode me ajudar com alguma dica ? Se puder me add no fórum para eu lhe enviar outras dúvidas, eu agradeço? E o projeto deu certo ?

flw, aguardo a sua resposta.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço