Boa tarde pessoal, estou montando um circuito que efetua leituras de 4 entradas analógicas do arduino ao mesmo tempo e imprime o resultado na tela (lcd 16x2 com keypad), porém, não há precisão nem estabilidade nestas leituras, já verifiquei as conexões e sinal da fonte e não há problemas, desconfio que seja algum erro nas minhas instruções, pois ainda sou verde no domínio do arduino, testei as mesmas condições e operadores individualmente e funcionam perfeitamente, mas lendo e imprimindo todas as leituras os valores ficaram confusos.

Abaixo estão as instruções que utilizei para estas leituras, se alguém puder apontar meus erros ficarei muito grato.

#include<LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);
#define lm35 A1
#define ntc A2
#define voltimetro A3
#define tps A4
#define lambda A5
long a=0;
int b=0;
int m=0;
int t=0;
int l=0;

byte graus[8] =
{
0b00011,
0b00011,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
};
byte termometro[8] =
{
0b00100,
0b00100,
0b00100,
0b00100,
0b00100,
0b01110,
0b01110,
0b01110
};
byte pistao[8] =
{
0b11111,
0b11111,
0b11111,
0b00100,
0b00100,
0b00100,
0b01110,
0b01110
};
byte bateria[8] =
{
0b01110,
0b11111,
0b10001,
0b11111,
0b10001,
0b11111,
0b10001,
0b11111
};
byte porcento[8] =
{
0b00000,
0b01100,
0b00001,
0b00010,
0b00100,
0b01000,
0b10000,
0b00011
};
void setup()
{
lcd.begin(16,2);
lcd.createChar(1, graus);
lcd.createChar(2, termometro);
lcd.createChar(3, pistao);
lcd.createChar(4, bateria);
lcd.createChar(5, porcento);
lcd.setCursor(0,0);
lcd.print("Ar");
lcd.setCursor(6,0);
lcd.write(1);
lcd.setCursor(7,0);
lcd.print("C");
lcd.setCursor(9,0);
lcd.write(3);
lcd.setCursor(14,0);
lcd.write(1);
lcd.setCursor(15,0);
lcd.print("C");
lcd.setCursor(15,1);
lcd.print("V");
lcd.setCursor(9,1);
lcd.write(4);
lcd.setCursor(0,1);
lcd.print("TPS");
lcd.setCursor(7,1);
lcd.write(5);

}
void loop()
{

/*---------Temperatura ar-------*/

int Ar=analogRead(lm35);
long a=(Ar*500/1023);
lcd.setCursor(3,0);
lcd.print(a);
delay(500);

/*---------Temperatura motor-------*/

unsigned int Motor=analogRead(ntc);
unsigned int m=(Motor*500/1023);
lcd.setCursor(11,0);
lcd.print(m);
delay(500);

/*---------TPS-------*/

int TPS=analogRead(tps);
int t=(TPS/1023*100);
lcd.setCursor(4,1);
lcd.print(t);
delay(500);

/*---------Bateria-------*/

float Bateria=analogRead(voltimetro);
float b=(Bateria*10.0/1023);
lcd.setCursor(11,1);
lcd.print(b);
delay(500);

}

Exibições: 524

Responder esta

Respostas a este tópico

Esta usando esse Arduino em um carro? Como esta alimentando-o ?

O que esta conectados nas portas analógicas ?

Olá José, por enquanto estou efetuando os testes em bancada, a alimentação do arduino é uma porta usb do PC.

Na Porta A1 e A2 utilizo 2 LM35, na A3 e A4 tenho 2 potênciometros de 10k e o A0 é a entrada do teclado de 6 botões, como comentei testando todas as entradas nas mesmas condições porém lendo uma por vez o programa funciona perfeitamente, a loucura e instabilidade de valores começa quando leio todas entradas ao mesmo tempo, verifiquei com um multímetro true RMS todos componentes e tensão de alimentação e está tudo certo, na leitura do LM35 por exemplo chega á variar mais de 10 C de leitura e quando leio apenas ele isso não ocorre.

Recomendações :

- É necessário um tempo entre as medições ! nâo pode medir todas as portas ao mesmo tempo. 

  O tempo de cada leitura é de 100 microsegundos. 

- Use uma fonte externa para alimentar o seu Arduino ( a tensão USB é sempre abaixo de 5V ! ) 

- instale um capacitor de 10uF 16V no pino Vref ( positivo) - negativo do capacitor no terra (GND) . 

  Esse pino Vref é a tensão de referência do ADC do Arduino. 

- se não estiver usando alguma porta analógica, conecte-a no terra. 

https://www.arduino.cc/en/Reference/AnalogRead

Se não é possível ler todos pinos complica para a finalidade que eu pretendia utilizar, como módulo de injeção eletrônica, mas para um bom funcionamento é necessário estabilizar as leituras, o tempo mínimo necessário para o processamento é de 3ms é o tempo de injeção em 10.000RPM.

A injeção eletrônica controla o tempo de abertura dos bicos injetores e essa condição é dada através destas leituras, na entrada digital leio a posição do virabrequim (rpm), nas entradas analógicas leio a posição de TPS (borboleta que controla a passagem de ar), temperaturas do ar e do motor, sonda lambda (emissão de CO2), com estes valores lidos jogo em uma fórmula matemática chamada de estequiometria ideal, e através dela é executado o cálculo do tempo de abertura dos injetores em ms, gostaria de ler e escrever esses valores em um display.

Será que com o atmega 2560 consigo estabilidade para esta aplicação?  

Você não entendeu = nâo é possível medir todas as portas ao mesmo tempo. 

Mas pode medir uma porta  de cada vez. 

E insira um atraso de 150 microsegundos ( não sei o valor exato) entre cada medição.

A0 - atraso - A1 - atraso, etc 

Com uma programação adequada , poderá fazer todas leituras que deseja. 

Bom dia Jonas

Você pensou em fazer mais capturas por canal e calcular a media desta leituras?

Sempre que você troca de canal analógico existem uma tendência do valor que estava no canal anterior influenciar um pouco na primeira amostra do canal atual... calculando uma media isso dissolve.. pois você captura o mesmo canal varias vezes para depois trocar de canal...

tipo assim...

#include<LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);
#define lm35 A1
#define ntc A2
#define voltimetro A3
#define tps A4
#define lambda A5
long a=0;
int b=0;
int m=0;
int t=0;
int l=0;

byte graus[8] =
{
0b00011,
0b00011,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
};
byte termometro[8] =
{
0b00100,
0b00100,
0b00100,
0b00100,
0b00100,
0b01110,
0b01110,
0b01110
};
byte pistao[8] =
{
0b11111,
0b11111,
0b11111,
0b00100,
0b00100,
0b00100,
0b01110,
0b01110
};
byte bateria[8] =
{
0b01110,
0b11111,
0b10001,
0b11111,
0b10001,
0b11111,
0b10001,
0b11111
};
byte porcento[8] =
{
0b00000,
0b01100,
0b00001,
0b00010,
0b00100,
0b01000,
0b10000,
0b00011
};

//**************************************
//Media (canal, numero de amostras) leko
//**************************************
long media(int canal, int vezes)
{
long int soma = 0;
for (byte i = 0; i < vezes; i++)
{
soma += analogRead(canal);
}
return soma/vezes;
}
//**************************************
//**************************************


void setup()
{
lcd.begin(16,2);
lcd.createChar(1, graus);
lcd.createChar(2, termometro);
lcd.createChar(3, pistao);
lcd.createChar(4, bateria);
lcd.createChar(5, porcento);
lcd.setCursor(0,0);
lcd.print("Ar");
lcd.setCursor(6,0);
lcd.write(1);
lcd.setCursor(7,0);
lcd.print("C");
lcd.setCursor(9,0);
lcd.write(3);
lcd.setCursor(14,0);
lcd.write(1);
lcd.setCursor(15,0);
lcd.print("C");
lcd.setCursor(15,1);
lcd.print("V");
lcd.setCursor(9,1);
lcd.write(4);
lcd.setCursor(0,1);
lcd.print("TPS");
lcd.setCursor(7,1);
lcd.write(5);

}
void loop()
{

/*---------Temperatura ar-------*/

int Ar=media(lm35, 30);
long a=(Ar*500/1023);
lcd.setCursor(3,0);
lcd.print(a);
delay(500);

/*---------Temperatura motor-------*/

unsigned int Motor=media(ntc, 30);
unsigned int m=(Motor*500/1023);
lcd.setCursor(11,0);
lcd.print(m);
delay(500);

/*---------TPS-------*/

int TPS=media(tps, 30);
int t=(TPS/1023*100);
lcd.setCursor(4,1);
lcd.print(t);
delay(500);

/*---------Bateria-------*/

float Bateria=media(voltimetro, 30);
float b=(Bateria*10.0/1023);
lcd.setCursor(11,1);
lcd.print(b);
delay(500);

}

 

Oi JGP, boa tarde.

Veja o que diz o datasheet do Atmega328:

" A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched on (ADEN in

ADCSRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry.
When the bandgap reference voltage is used as input to the ADC, it will take a certain time for the voltage to
stabilize. If not stabilized, the first value read after the first conversion may be wrong.

 "

The actual sample-and-hold takes place 1.5 ADC clock cycles after the start of a normal conversion and 13.5
ADC clock cycles after the start of an first conversion. When a conversion is complete, the result is written to the ADC Data Registers, and ADIF is set. In Single Conversion mode, ADSC is cleared simultaneously. The
software may then set ADSC again, and a new conversion will be initiated on the first rising ADC clock edge.
When Auto Triggering is used, the prescaler is reset when the trigger event occurs. This assures a fixed delay
from the trigger event to the start of conversion. In this mode, the sample-and-hold takes place two ADC clock
cycles after the rising edge on the trigger source signal. Three additional CPU clock cycles are used for
synchronization logic

Rui

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço