|
|
View previous topic :: View next topic |
Author |
Message |
martin_ac
Joined: 03 Sep 2012 Posts: 1 Location: island
|
Equation error |
Posted: Mon Sep 03, 2012 9:11 pm |
|
|
hi folks, I need to perform a mathematical formula in the pic, but do not know where the error values and I can not get, can someone please look at the code and tell me where I am wrong?
Thanks and regards.
This is the equation:
This is my code:
Code: |
#include <16f1936.h>
#FUSES NOWDT, XT, INTRC_IO, MCLR, NOPROTECT, NOBROWNOUT, NOCPD, PLL_SW
#FUSES NOPUT, NOFCMEN, NOLVP, NODEBUG, NOWRT, NOVCAP
#use delay (clock=4000000)
#include <math.h>
#define pul1 pin_b0
#define pul2 pin_b1
#define ledv pin_c3
#define ledr pin_c4
int px,py;
signed int8 vectorx[]={0,0,0,0,0};
signed int8 vectory[]={0,0,0,0,0};
signed int8 angulof[]={0,0,0,0,0};
////////////////////////////PROTOTIPOS DE FUNCIONES/////////////////////////////
void vector (void);
void angulo (void);
void atotal (void);
////////////////////////////////////////////////////////////////////////////////
void main(){
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
SETUP_DAC(DAC_OFF);
setup_lcd(LCD_DISABLED);
while(true){
if (input (pul1)==0){
px = 3;
py = 1;
vector();
angulo();
atotal();
}
else if(input(pul2)==0){
px = 7;
py = 5;
vector();
angulo();
atotal();
}
}
}
////////////////////////////////FUNCIONES///////////////////////////////////////
////////////////////////////////////VECTOR//////////////////////////////////////
void vector (void){
int pxp []={6,1,1,6,5};
int pyp []={3,4,1,1,2};
//signed int8 pendpol[]={0,0,0,0};
int i;
for (i=0;i<5;i++){
vectorx[i]=(pxp[i]-px);
vectory[i]=(pyp[i]-py);
}
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////ANGULO/////////////////////////////////////////
void angulo(void){
int i;
signed int8 n1,n2,n3,n4,n5;
signed int8 vecx1,vecx2,vecx3,vecx4,vecx5;
signed int8 vecy1,vecy2,vecy3,vecy4,vecy5;
signed int8 angf1,angf2,angf3,angf4,angf5;
float r1,r2,r3,r4,r5;
float d1,d2,d3,d4,d5;
float an1,an2,an3,an4,an5;
float at;
for (i=0;i<5;i++){
if (i==0){vecx1=vectorx[i];
vecy1=vectory[i];}
if (i==1){vecx2=vectorx[i];
vecy2=vectory[i];}
if (i==2){vecx3=vectorx[i];
vecy3=vectory[i];}
if (i==3){vecx4=vectorx[i];
vecy4=vectory[i];}
if (i==4){vecx5=vectorx[i];
vecy5=vectory[i];}
}
n1 = ((vecx1*vecy2)-(vecx2*vecy1));
n2 = ((vecx2*vecy3)-(vecx3*vecy2));
n3 = ((vecx3*vecy4)-(vecx4*vecy3));
n4 = ((vecx4*vecy5)-(vecx5*vecy4));
n5 = ((vecx5*vecy1)-(vecx1*vecy5));
r1= ((vecx1*vecx1)+(vecy1*vecy1));
r1= sqrt(r1);
r2= ((vecx2*vecx2)+(vecy2*vecy2));
r2= sqrt(r2);
r3= ((vecx3*vecx3)+(vecy3*vecy3));
r3= sqrt(r3);
r4= ((vecx4*vecx4)+(vecy4*vecy4));
r4= sqrt(r4);
r5= ((vecx5*vecx5)+(vecy5*vecy5));
r5= sqrt(r5);
d1= r1*r2;
d2= r2*r3;
d3= r3*r4;
d4= r4*r5;
d5= r5*r1;
an1= n1/d1;
an1= asin(an1);
an2= n2/d2;
an2= asin(an2);
an3= n3/d3;
an3= asin(an3);
an4= n4/d4;
an4= asin(an4);
an5= n5/d5;
an5= asin(an5);
at= an1+an2+an3+an4+an5;
if (at>150){
output_high(ledv);
delay_ms(1000);
output_low(ledv);}
else{
output_high(ledr);
delay_ms(1000);
output_low(ledr);}
/*for (i=0;i<5;i++){
if (i<4) a = (vectorx[i]*vectory[i+1])-(vectory[i]*vectorx[i+1]);
if (i==4) a = (vectorx[i]*vectory[0])-(vectory[i]*vectorx[0]);
p1=vectorx[i];
p2=vectory[i];
// b = (vectorx[i]*vectorx[i])+(vectory[i]*vectory[i]);
b = (p1*p1)+(p2*p2);
raiz1 = sqrt(b);
if (i<4){
c = (vectorx[i+1]*vectorx[i+1])+(vectory[i+1]*vectory[i+1]);
raiz2 = sqrt(c);}
if (i==4){
c = (vectorx[0]*vectorx[0])+(vectory[0]*vectory[0]);
raiz2 = sqrt(c);}
d = raiz1*raiz2;
e = a/d;
va = asin(e);
angulof[i]=va;
} */
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////Angulo total///////////////////////////////////////
void atotal (void){
int i;
float at=0;
for (i=0;i<5;i++){
at = at+angulof[i];
}
if (at>300){
output_high(ledv);
delay_ms(2000);
output_low(ledv);}
else{
output_high(ledr);
delay_ms(2000);
output_low(ledr);}
}
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Sep 03, 2012 9:29 pm |
|
|
compiled for what chip and version of CCS?? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue Sep 04, 2012 2:14 am |
|
|
1) Remember an 'int' in CCS, is just an int8. 0 to 255. A signed int, is +127 to -255. In your 'vector' program, you have unsigned int quantities, and then subtract a value from them. 1-7 for example..... Overflow. I'd change _all_ your int declarations to signed int16.
2) The same comment then applies with the arithmetic in the early stages. You are multiplying numbers that have overflowed, and the results are going to be screwed....
Best Wishes |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Tue Sep 04, 2012 8:59 am |
|
|
Brute force coding of a mathematical expression to c code then via the compiler to machine instructions has drawbacks.
Mathematical equations involving Trig functions and sqrt (x^2 +y^2) are based on rotations in the unit circle. The PIC is a binary processor with a finite register size. Now the PIC can mimic trig functions with look up tables and interpolation but it is a challenge to maintain precision. For large giga-hertz processors with large register sizes this mimicking of trig with look up tables works well out to many decimal places of precision. Trig assumes there are always an infinite number of numbers between any two numbers in the unit circle. A finite binary register doesn't fit this well so imprecision is the result. With a large processor this imprecision can be acceptable.
In the past ( when processors were limited to 8 bits and sub megahertz) software engineers would use the CORDIC. Some liken it to binary angles where tan (45 deg) is binary 1. Since it is inherently binary the CORDIC can calculate sqrt(x^2 Y^2) sin cos arctan etc often simultaneously by simple shifting and adding. The precision can be of arbitrary length but often it is 32 bit 64 bit etc to be compatible with the word lengths used by the compiler. The burden is the engineer must be aware of the boundary conditions. Tan will misbehave becoming infinite near 90 deg. However since the unit circle is perfectly symmetrical to any angular transform; this can be avoided.
The software engineer must also be aware of the inherent imprecision incurred when changing notation from binary to decimal. The CORDIC provides accurate binary values which is fine if you are controlling a thruster. If you wish to view the angles in human terms you need decimal notation and you will for most angles( not being a power series of 2) get a precision error due to number base conversions ( often incorrectly described as rounding errors) . |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Sep 04, 2012 2:16 pm |
|
|
i further urge you to do what most of US would do IN YOUR SHOES:
TEST the library functions
square and SQRT are not bad ..
but TRIG functs??
( at least its ONLY the ASIN() you want ... phew....)
do a printf of the FP results of a decreasing range of arguments
asin(.700) asin(.710) asin(.701) asin(.7001)
then
asin(.70002)=44.428608 , asin(.70001)=44.427806 etc, etc
and you will see how the library function breaks down precision wise
compared to the same result on an good HP calculator
you can also TIME the process - which may be of concern as well
if there is a HOST PC in the mix - i prefer to send the raw data to the PC
and do the heavy number grinding on that platform. i do that now with a customer design that is a synchronous demod/ lockin type of unit where i have quad demod raw data that needs to be resolved to Theta, R,C and Z
my squaring, rooting and SIN() calc work is ALL done in the PC on raw X,Y filtered 16 bit demod data - i would NEVER do sqr-SQRT or SIN() in the pic , ever . ( short of my life depending on it, that is ) |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Sep 05, 2012 7:15 am |
|
|
This goes back to the principle that any measurement without a tolerance is meaningless. Decide what you want to measure and HOW ACCURATELY YOU WANT TO MEASURE IT. Once you have answered BOTH those questions you can start to design the measurement process.
In some cases, like which way should a token move on a square grid game board, you can make do with 3 or 4 bits of resolution and 8 bit math is fine. If you are targeting a long range gun you will need to do much better. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
|
|
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
|