|
|
View previous topic :: View next topic |
Author |
Message |
rd7l
Joined: 05 Jul 2012 Posts: 3
|
Waste printed on the LCD |
Posted: Mon Jul 09, 2012 5:24 pm |
|
|
------------------------------------
Automatically translated
------------------------------------
Good night!
I am converting voltage to another drive using a 18f.
I read the AN0 pin and do some math before I print on the LCD. However, the first time I turn on the board, is displayed a kind of garbage (but constant) and then the LCD is normal.
What can be? It is necessary to "cleanse" the port AN0 to connect the circuit (before the first reading of this port)? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Mon Jul 09, 2012 5:33 pm |
|
|
Without seeing your program we can't tell where the bad data is coming from, however it is a good practice to always 'cleanse' or zero all variables before you use them
One possible error for the bad data is incorrect timing when you read the ADC port. However that usually results in random data not the same value every time. |
|
|
rd7l
Joined: 05 Jul 2012 Posts: 3
|
|
Posted: Mon Jul 09, 2012 5:51 pm |
|
|
Sorry for the simplicity of the program ... this is my first!
Code: | #include <18F4550.h> //PIC utilizado
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Clock <=4Mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000)
#define USB_CON_SENSE_PIN PIN_B2
#include <usb_cdc.h>
#include <LCD.c>
int16 ad, i, b_nulo = 504;
float dif, tensao;
signed int16 media, acumula, b;
void main()
{
lcd_init();
setup_adc_ports(AN0); //Configura canal 0 analógico.
setup_adc(ADC_CLOCK_DIV_8); //De acordo com relógio interno.
set_adc_channel(0); //Habilita canal 0.
delay_us(20); //Espera um pouco, obrigatório!
while(TRUE)
{
for (i=0;i<10;i++)
{
ad = read_adc();
dif = ad - b_nulo;
acumula = acumula + dif;
}
{
media = acumula/i;
tensao = (media * 5.f ) / 1024.f; // Converte para tensão
b = tensao / 0.0025; // Converte para Gauss
acumula = 0; // Reinicia a variável acumula para mostrar no LCD e começar nova media.
}
if (b > 0)
{
printf (lcd_putc,"\nPolo Sul");
}
if (b < 0)
{
printf (lcd_putc,"\nPolo Norte");
}
if (b == 0)
{
printf (lcd_putc,"\nNulo");
}
delay_ms (500);
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Jul 10, 2012 1:21 am |
|
|
signed int16 media, acumula, b;
change to:
signed int16 media, acumula=0, b;
or:
static signed int16 media, acumula, b;
Either will ensure 'acumula' is set to zero before the first sum.
Best Wishes |
|
|
rd7l
Joined: 05 Jul 2012 Posts: 3
|
|
Posted: Tue Jul 10, 2012 2:54 am |
|
|
It worked perfectly. Thank you!
I would like to take one last question: How many times per second the PIC reads the port AN0? That is, I can adjust my counter i for which the maximum value for (i = 0, i <10; i + +)?
Thank you! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Jul 10, 2012 4:24 am |
|
|
OK.
You loop ten times, reading the ADC, and generating a sum. Now the speed of this, is dependant on the arithmetic, and the clock speed, with the loop containing:
one 16bit integer addition for the loop
one 16bit integer subtraction for 'dif'
one 16bit integer addition for 'sum'.
Together these take about 12uSec.
The reading itself, takes 11 cycles of the ADC clock, which in your case, is set to 1/8th the master peripheral clock. So, 125KHz. 88uSec for the reading.
So the loop taking the readings, takes about 100uSec.
Then the floating point arithmetic, takes probably about 3mSec, and the LCD displays, perhaps 200uSec. You then delay for 100mSec, which is the biggest pause in the code, so you will probably get about 9 updates per second.
Now, some comments:
The ADC needs time to acquire between readings. This is specified (data sheet) as 6.4uSec minimum. With your slow clock rate, and the maths in the loop, you are 'OK' for this, taking 12uSec to loop back round between readings. However if your clock rate increases, you need to consider this, and include a delay here.
I suspect you will need to increase the processor clock rate, because normally USB will not function correctly, with the CPU running this slow.
You don't specify the USB clock divider, voltage regulator setup, or USB clock settings. I doubt again if USB will be working, yet you include the code for this....
You can clock the ADC significantly faster to speed the conversions. The data sheet gives examples, and how to calculate these.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|