View previous topic :: View next topic |
Author |
Message |
Jan Noman
Joined: 28 May 2005 Posts: 14
|
Why ? |
Posted: Sat Jun 23, 2007 7:41 am |
|
|
Hi everybody!
signed int32 value_111;
signed int32 ADC_value
.............................................
ADC_value = value_111/32; result is OK
ADC_value = value_111/64; or high result is WRONG !
compiler is 3.249 , MCU is PIC18F4580
WHY ?!
Regards
Jan |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 23, 2007 9:20 am |
|
|
Edit your post title and put in something better than "Why ?".
Also, post a small test program that shows the line of code that
loads 'value_111' with a value.
Show the printf statements that display the results.
Then tell us your expected results and tell us what you're actually
getting. In other words, don't just say the answer is "wrong". |
|
|
Jan Noman
Joined: 28 May 2005 Posts: 14
|
|
Posted: Sat Jun 23, 2007 10:00 am |
|
|
more of code:
MCP_read();
ADC_value = value_111/64;
ADC_unsig = abs(ADC_value);
ADC_unsig = mean_filter(ADC_unsig);
value_11 = ADC_unsig - zero;
value_0 = abs(value_11);
............................................................................................................
value_111 is value as result convertnig of ADC MCP3550
void MCP_read()
{
unsigned int i=0;
output_low(MCP_SCK);
output_low(MCP_CS);
delay_ms(1);
ADCbuffer[0]=0;
ADCbuffer[1]=0;
ADCbuffer[2]=0;
while ( input(MCP_SDA) );
for (i = 1; i <= 24; i++) shift_left(ADCbuffer,3,mcp_clock());
output_high(MCP_CS);
value_111 = make32(ADCBuffer[2],ADCBuffer[1],ADCBuffer[0]);
}
...........................................................................................................
for test where is error I wrote
lcd_gotoxy(1,1);
printf(lcd_putc,"\f\ %05ld",ADC_value);
and when ADC_value = value_111/64; ,and value_111 was negative near zero
overflow was occur
for positive values of Value_111 all was OK
when ADC_value = value_111/32 all OK for positive and negative values of value_111 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 23, 2007 2:16 pm |
|
|
Post a complete test program instead of code fragments.
Posting code fragments doesn't help.
The program shown below is an example of a test program.
It has all the necessary #include, #fuses, and #use statements.
It shows all variable declarations.
(It doesn't have the code for the mean_filter() function, because I don't
know what you have in there).
At the end of the program, there is a printf statement that displays
the result of the calculations.
Your complaint is that certain numbers, when read from the MPC_read()
routine, cause an incorrect result. So, comment out the call to the
MPC_read() routine, and substitute a numeric constant instead. Choose
a number that will cause the bad result. Do it like I've done in the code
below, except modify the program as required, so it's similar to your own
code.
If you can post a full test program and tell me what are the "bad"
results, and also post what would you like to see (or expect to see) as
the "good" results, then I can look at the problem.
Code: |
#include <18F4580.h>
#fuses XT, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <lcd.c>
signed int32 mean_filter(signed int32 data)
{
signed int32 retval;
// Put filter code here.
return(retval);
}
//============================
void main()
{
signed int32 ADC_value;
signed int32 ADC_unsig;
signed int32 value_111;
signed int32 value_11;
signed int32 value_0;
signed int32 zero;
lcd_init();
// MCP_read();
value_111 = -278;
zero = 0;
ADC_value = value_111/64;
ADC_unsig = abs(ADC_value);
ADC_unsig = mean_filter(ADC_unsig);
value_11 = ADC_unsig - zero;
value_0 = abs(value_11);
printf(lcd_putc,"\f\ %05ld",ADC_value);
while(1);
} |
|
|
|
Jan Noman
Joined: 28 May 2005 Posts: 14
|
|
Posted: Sat Jun 23, 2007 3:36 pm |
|
|
Dear PCM Programmer
thanks for help
it very strange
It is my full test code
it work very good
on LCD is -1234
Code: | #include <18F4580.h>
#fuses HS,NOLVP,NOWDT,NOPROTECT
#use delay(clock=10000000)
#include <lcd_D.c> // it is my own driver for DOG type LCD Display
#include <math.h>
signed int16 ADC_value;
signed int32 value_111;
int x;
void main()
{
lcd_init();
lcd_gotoxy(3,1);
printf(lcd_putc,"INIT");
delay_ms(4000);
printf(lcd_putc,"\f");
while(TRUE)
{
if(x==15)
X=1;
else
x=x+1;
value_111 = -790080;
ADC_value = value_111/64;
if(x==14)
printf(lcd_putc,"\f\ %ld",ADC_value);
}
}
|
Now I use ADC
Code: |
#include <18F4580.h>
#fuses HS,NOLVP,NOWDT,NOPROTECT
#use delay(clock=10000000)
#include <lcd_D.c> // it is my own driver for DOG type LCD Display
#include <math.h>
#include <MCP3550.c>
signed int16 ADC_value;
int x;
void main()
{
lcd_init();
lcd_gotoxy(3,1);
printf(lcd_putc,"INIT");
delay_ms(4000);
printf(lcd_putc,"\f");
while(TRUE)
{
if(x==15)
X=1;
else
x=x+1;
MCP_read();
ADC_value = value_111/64;
if(x==14)
printf(lcd_putc,"\f\ %ld",ADC_value);
}
}
|
//driver for MCP3550
Code: | #define MCP_CS PIN_C0
#define MCP_SCK PIN_C1
#define MCP_SDA PIN_C2
signed int32 value_111;
int ADCBuffer[3];
int1 mcp_clock()
{
int1 in=0;
output_high(MCP_SCK);
in=input(MCP_SDA);
delay_us(1);
output_low(MCP_SCK);
delay_us(1);
return(in);
}
void MCP_read()
{
unsigned int i=0;
output_low(MCP_SCK);
output_low(MCP_CS);
delay_ms(1);
ADCbuffer[0]=0;
ADCbuffer[1]=0;
ADCbuffer[2]=0;
while ( input(MCP_SDA) );
for(i = 1; i <= 24; i++)
shift_left(ADCbuffer,3,mcp_clock());
output_high(MCP_CS);
value_111 = make32(ADCBuffer[2], ADCBuffer[1], ADCBuffer[0]);
}
|
The same horror !
if signal is positive
in LCD is eg.11021 when negatiwe not -11021 but 21746
Now divide value_111 not by 64 but by 32
IT IS OK !!! +22044 and -22044
WHY !!!! |
|
|
Jan Noman
Joined: 28 May 2005 Posts: 14
|
|
Posted: Sat Jun 23, 2007 4:10 pm |
|
|
FINALLY I FIND SOLUTION !!!!
ADC_value = (signed int16)value_111/64
on LCD is 242 and -242
AND IT WORK very good but EXACTLY I don't know WHY.
Best Regards
Jan |
|
|
Jan Noman
Joined: 28 May 2005 Posts: 14
|
|
Posted: Sat Jun 23, 2007 4:29 pm |
|
|
Sorry
I'm very TIRED this solution in former message is NO GOOD
GOOD NIGHT |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 25, 2007 12:03 am |
|
|
If it's not fixed, then run a test and use printf to display the 3 bytes
that are received from the A/D.
When you see a failure, write down the failed result as displayed on
the LCD, and also write down the 3 bytes that caused it.
Create an RS232 connection to your PC, to display these numbers.
Then post those numbers. |
|
|
Guest
|
|
Posted: Mon Oct 27, 2008 3:40 am |
|
|
Code: |
signed int32 mean_filter(signed int32 data)
{
signed int32 retval;
// Put filter code here.
return(retval);
}
|
How can I use filter code? What does filter code mean?
Would you help me please? I use MCP3550-50 ADC.
Our circuits have some dc and ac motor (engine)
If we use mcp3201 we can not see any problem but if we use mcp3550
Our program has stoped or locked. I do not understand MCP3550 properties for that.
Thanks for your help.. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Oct 27, 2008 5:07 pm |
|
|
Anonymous wrote: | How can I use filter code? What does filter code mean?
| If you don't know what a filter is, why do you want to use one?
In electronics a filter is used to get rid of unwanted signals. In software you can do something similar to get rid of wrong data samples.
How the original poster in this thread implemented the filter we don't know. The thread is more then 1 year old, small chance you will get an answer.
Filter code examples can be found a lot on the internet or use the search function of this forum. Here is a good thread: http://www.ccsinfo.com/forum/viewtopic.php?t=3462
Quote: | I use MCP3550-50 ADC.
Our circuits have some dc and ac motor (engine)
If we use mcp3201 we can not see any problem but if we use mcp3550
Our program has stoped or locked. I do not understand MCP3550 proporties for that. | You will have to provide more details. This information is not enough to help solve your problem.
For example, the MCP3550 and MCP3201 have different connections. You changed the circuit for this?
Post a small program demonstrating your problem.
What is your compiler version number? |
|
|
Guest
|
|
Posted: Wed Oct 29, 2008 11:39 am |
|
|
Code: |
#define MCP_CS PIN_C4
#define MCP_SCK PIN_D3
#define MCP_SDA PIN_C5
int32 value_111;
int ADCBuffer[3];
int1 mcp_clock()
{
int1 in=0;
output_high(MCP_SCK);
in=input(MCP_SDA);
delay_us(1);
output_low(MCP_SCK);
delay_us(1);
return(in);
}
void MCP_read()
{ int8 i=0;
output_low(MCP_SCK);
output_low(MCP_CS);
delay_ms(1);
ADCbuffer[0]=0;
ADCbuffer[1]=0;
ADCbuffer[2]=0;
while ( input(MCP_SDA) ) {}
for(i = 1; i <= 24; i++)
shift_left(ADCbuffer,3,mcp_clock());
output_high(MCP_CS);
value_111 = make32 (ADCBuffer[2], ADCBuffer[1], ADCBuffer[0]);
output_low(PIN_D1);
}
|
Code: |
while ( input(MCP_SDA) ); /////////// this part
|
In this part sometimes my program is waiting or locking. I catch this problem with this syntax..
Code: |
while ( input(MCP_SDA) ){output_high(PIN_A0);Delay_us(1);
output_low(PIN_A0); Delay_us(1);}
|
After that I get square wave signal from PIN_A0. If My controller is not stop I have to get this signal. Ok. I get this signal but my program is stoping this line. Because MCP 3550 is not give answer for dc motor interference. How can I do that? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Oct 29, 2008 5:33 pm |
|
|
You are using code that didn't work for the original poster as well.
One problem is that the code uses SPI mode 1-1 which requires 25 clock pulses, not 24 as would be used for SPI mode 0-0. Easiest fix is to increase the loop from 24 to 25.
You are using the MCP3550 in continuous mode (CS is not toggled during conversion). Is this what you want to do? It might have some side effects, but I haven't read the entire data sheet.
Again, what is your compiler version number? |
|
|
|