|
|
View previous topic :: View next topic |
Author |
Message |
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
My PIC often won't run all the code I have written... |
Posted: Sat Feb 04, 2006 5:56 am |
|
|
Please check my code...anything wrong or not??
sometimes, if I power off and on...it is normal again...
Code: | /////////////////////////////////////////////////////////////////////////
//// 040206.C ////
//// Parallel Pump Control Project ////
//// This program displays the min and max of 30 A/D samples over ////
//// the RS-232 interface. The process is repeated forever. ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 2006, Sayar Maung Kyaw Tun ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
//System Initialisation
#include <18F2525.h> //PIC18F2525 header file
#device ADC=10 //10 Bits
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=16000000) // 16Mhz Crystal is Used
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8) // RS232 Configuration
#include <stdlib.h>
#include <math.h>
//Functions Initailisation
void freq_curve(float freq,float &a1,float &b1,float &c1);
void fricfact_curve(float fricfact,float &a2,float &b2,float &c2);
float newton_root(float a,float b,float c,float maxerr);
float Read_fricfact_percent_from_ADC();
float find_new_freq(float x,float &y,float maxerr);
//Start main program
void main()
{
float freq=55;
float fricfact=0.5;
float maxerr=0.01;
float a1,b1,c1,a2,b2,c2;
float x,y,yhead;
char st1[5];
printf(" \n\r Parallel Pump Control Projet\n\n",yhead);
//Calculating Frequency curve
freq_curve(freq,a1,b1,c1);
printf("\n %8.4f %8.4f %8.4f\n",a1,b1,c1);
//Calculating Friction Factor curve
fricfact_curve(fricfact,a2,b2,c2);
//Finding the intersection point
x=newton_root(a1-a2,b1-b2,c1-c2,maxerr);
//calculate the y-mark from known x-mark using freq_curve.
y= a1*x*x + b1*x + c1;
printf("\n\rThe intersection point is x =%8.4f, y =%8.4f\n",x,y);
//Inquiry the desired fixed head from user
output_high(PIN_A1); // Power On
delay_ms(500);
printf("\n\r Enter desired fixed HEAD : "); // Ask for user input
gets(st1);
yhead=atof(st1);
//printf(" \n\r You have entered = %8.2f",yhead);
//Reading the friction factor from ADC
fricfact=Read_fricfact_percent_from_ADC();
printf("\n\rThe percent read from ADC = %8.4f",fricfact);
//***My program HANG here most of the time***///
//Calculating new Fricfact_curve
fricfact_curve(fricfact,a2,b2,c2);//here is problem??
//Evaluating new intersection point
x=newton_root(a1-a2,b1-b2,c1-c2,maxerr);
//Calculate the y-mark from new x-mark
y=a1*x*x + b1*x + c1;
printf("\n\rThe NEW intersection point is x =%8.4f, y =%8.4f\n",x,y);
delay_ms(500);
//evaluating intersection pt which intersect fricfact_curve & yhead pt.3
x=newton_root(a2,b2,c2-yhead,maxerr);
y=a2*x*x + b2*x + c2;
delay_ms(500);
printf("\n\rThe intersection point 3 is x =%8.4f, y =%8.4f\n",x,y);
//finding the new frequency curve which goes through the pt.3 (x,y)
freq=find_new_freq(x,y,maxerr);
delay_ms(500);
printf("\n\rThe new frequency and New Head= %8.4f %8.4f",freq,y);
printf("\n\rNew head(y) = %8.4f",y);
output_low(PIN_A1);
delay_ms(500);
}
//the called sub functions
void freq_curve(float freq,float &a1,float &b1,float &c1)
{
a1=-0.0019;
b1=-0.00004559-0.00092457*freq;
c1=0.00307143-0.0001214286*freq+0.018353*freq*freq;
}
void fricfact_curve(float fricfact,float &a2,float &b2,float &c2)
{
a2=0.0491555 - 0.94984*fricfact + 4.8265*fricfact*fricfact;
b2=-0.32667 + 4.355*fricfact - 20.14228*fricfact*fricfact;
c2=1.11171 - 11.9291*fricfact + 56.499*fricfact*fricfact;
}
float newton_root(float a,float b,float c,float maxerr)
{ float x=4,old,t,r;
do{
old=x;
x=x-((a*x*x) + b*x + c)/( 2*a*x + b);
}while(abs((x-old)/x*100)>maxerr);
if (x<0)
{ t=x;
r=b+a*t;
x=-r/a;
}
return(x);
}
float Read_fricfact_percent_from_ADC()
{ float fricfact;
float temp1,temp2;
setup_port_a( AN0 );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 );
temp1 = Read_ADC();
temp2 = (temp1/204); // if 8 bits divide by 51, if 10bits dvides by 204, %=divide by 10.2
printf("\n\r Voltage is x =%8.4f ",temp2);
fricfact = (temp1/10.2/100); // if 8 bits divide by 51, if 10bits dvides by 204, %=divide by 10.2
if (fricfact<0.1)
fricfact=0.1;
else if (fricfact>1)
fricfact=1;
return (fricfact);
}
float find_new_freq(float x,float &y,float maxerr)
{ float temp,freq,a1,b1,c1;
float stepsize=0;
do{
freq=freq+stepsize;
freq_curve(freq,a1,b1,c1);
temp=a1*x*x + b1*x + c1;
stepsize=(y-temp)*0.5;
}while(abs((y-temp)/y*100)>maxerr);
return (freq);
}
|
|
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sat Feb 04, 2006 6:41 am |
|
|
I've noticed that it has something to do with my ADC.... PIN A0
my ADC is connected to Variable Resistor with 5V supply...
If my variable resistor is more than 1V(1-5V),,,,it will hang,,,,
If it is less than 1V,,it is working fine and all the remianinng code will be proceed...
any idea? |
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sat Feb 04, 2006 7:06 am |
|
|
As you can see from my "Hyper Terminal",,, when voltage (x) output of ADC(PIN A0) is less than 1 V (refer to 1)...
and the program process the rest of code...(refer to 2)...
after reset....
when voltage (x) output of ADC(PIN A0) is more than 1 V (refer to 3)...
it won't process the remaining code anymore ...
any idea??
sonic
Last edited by sonicdeejay on Sat Feb 04, 2006 10:31 am; edited 1 time in total |
|
|
futureathome Guest
|
|
Posted: Sat Feb 04, 2006 7:29 am |
|
|
I had a similar problem once and it was related to TRISE bits, they were not set correctly.
Try adding TRISEBits = 0b00000111; at the start of main() |
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sat Feb 04, 2006 7:53 am |
|
|
futureathome wrote: | I had a similar problem once and it was related to TRISE bits, they were not set correctly.
Try adding TRISEBits = 0b00000111; at the start of main() |
thx for your help buddy,,,,,
I change the code
Code: |
setup_port_a( AN0 );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 );
SET_TRIS_A( 0x01); // I add this line to define PIN A0 as input
|
but the problem still persist,,,,
|
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sat Feb 04, 2006 9:34 am |
|
|
Guys...this function is causing the problem...I'can't seem to find error..in the function,,,,
function declaraction
Code: | float newton_root(float a,float b,float c,float maxerr); |
Code: | x=newton_root(a2,b2,c2-yhead,maxerr); |
Code: | float newton_root(float a,float b,float c,float maxerr)
{
float x=4,old,t,r;
do{
old=x;
x=x-((a*x*x) + b*x + c)/( 2*a*x + b);
}while(abs((x-old)/x*100)>maxerr);
if (x<0)
{ t=x;
r=b+a*t;
x=-r/a;
}
return(x);
} |
I don't know how and why this function gota related with my ADC (Pin A0)...
I can get it to process.. only when ADC(PIN A0) is less then 1V.... or I grey out the above function...
|
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sat Feb 04, 2006 10:07 am |
|
|
In fact...I start having this issue...since today I change PIC from PIC18F2331 to PIC18F2525....(I can't switch back to 2331 as my code is larger than its ROM avail)
as you can see, there is no much difference except PIN7 VDD....
Last edited by sonicdeejay on Sat Feb 04, 2006 10:52 am; edited 1 time in total |
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sat Feb 04, 2006 10:28 am |
|
|
Code: |
x=newton_root(a1-a2,b1-b2,c1-c2,maxerr);
//calculate the y-mark from known x-mark using freq_curve.
.
.
.
fricfact=Read_fricfact_percent_from_ADC();
printf("\n\rThe percent read from ADC = %8.4f",fricfact);
.
.
.
.
//Evaluating new intersection point
x=newton_root(a1-a2,b1-b2,c1-c2,maxerr);
//Calculate the y-mark from new x-mark
y=a1*x*x + b1*x + c1; |
as you can see, I called
Code: | x=newton_root(a1-a2,b1-b2,c1-c2,maxerr); |
this function twice... before and after ADC.....
The function call before ADC has no problem....
but as for the function after the ADC (if ADC PINA0 is more than 1 V)....
the program will hang there....
any info?
sonic |
|
|
futureathome Guest
|
|
Posted: Sat Feb 04, 2006 10:50 am |
|
|
I think you misunderstood my post, I said TRISE... yes.. E.
I dont know why that happen, but if I set bits 7 to 4 the problem you are having occurs. |
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sat Feb 04, 2006 11:18 am |
|
|
futureathome wrote: | I think you misunderstood my post, I said TRISE... yes.. E.
I dont know why that happen, but if I set bits 7 to 4 the problem you are having occurs. |
pls state the exact command I need to type...
I have tried the following codes One by one after main but all give me "compile error"
Code: |
//Start main program
void main()
{
//TRISDBits = 0b00000111;
//TRISEBits = 0b00000111;
//SET_TRIS_D( 0b00000111); |
thx
sonic |
|
|
specialk
Joined: 12 Nov 2005 Posts: 27
|
|
Posted: Sat Feb 04, 2006 11:54 am |
|
|
Have you checked your while loop in the function?
Code: | do{
old=x;
x=x-((a*x*x) + b*x + c)/( 2*a*x + b);
}while(abs((x-old)/x*100)>maxerr); |
I'll bet you that you are feeding values that won't allow it to exit the loop.
-special [k] |
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sat Feb 04, 2006 12:22 pm |
|
|
specialk wrote: | Have you checked your while loop in the function?
Code: | do{
old=x;
x=x-((a*x*x) + b*x + c)/( 2*a*x + b);
}while(abs((x-old)/x*100)>maxerr); |
I'll bet you that you are feeding values that won't allow it to exit the loop.
-special [k] |
yes...you are right I have caught it is due to the loop...
BUT if I can't back to my previous chip(PIC18F2331).... the loop is working welll.... but not for the new PIC18F2525...
so any .h different or configuration different??
|
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Sun Feb 05, 2006 6:52 am |
|
|
Firstly, with ADC operations you need to give the ADC mux to settle after a set_adc_channel() call. A delay of 10us to 50us is typical but the minimum can be found by reading the datasheet in detail. If you don't, then the read_adc will return some unexpected values.
As you only seem to use a single adc channel, put the initialization/setup code at the top of main(), so you don't init the adc and switch channels unnecessarily each time you do a call to Read_fricfact_percent_from_ADC().
Secondly, what version of PCH are you using ? I've had BIG problems over the last few weeks and very odd program behaviour as a bug has crept into V3.242 which assigns variables into overlapping memory bytes.
So I have reverted back to V3.236 which fixed the crashes ! _________________ Regards,
Simon. |
|
|
sonicdeejay
Joined: 20 Dec 2005 Posts: 112
|
|
Posted: Sun Feb 05, 2006 8:07 pm |
|
|
I am using
IDE V3.212
PCB V3.214
PCM V3.214
PCB V3.214
I think it is a bug with my compiler??? |
|
|
|
|
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
|