|
|
View previous topic :: View next topic |
Author |
Message |
Harry Mueller
Joined: 17 Oct 2005 Posts: 116
|
problem with printf formats or variable types |
Posted: Wed Dec 14, 2005 11:41 am |
|
|
I'm trying to debug a program with printf statements and I'm having some problems. Here is some of the output from a terminal program.
Code: | Gyro_fe = 18195
Gyro_re = 10632
Gyro value_lu = 7563
Gyro value_ld = 7563
Gyro value = 7503
Acceleration due to gravity = 37.65%
Gyro rate of change = 0
===============================================
Gyro_fe = 61684
Gyro_re = 54184
Gyro value_lu = 7500
Gyro value_ld = 7503
Gyro value = 0
Acceleration due to gravity = 3.33%
Gyro rate of change = 0
===============================================
Gyro_fe = 39383
Gyro_re = 56627
Gyro value_lu = 7505
Gyro value_ld = 7505
Gyro value = 1
Acceleration due to gravity = 2.16%
Gyro rate of change = 1
|
Seven lines forms a complete data set. I show 3 data sets.
This data relates to the program as follows:
Line 1 is the Timer_1 count for CCP_2 on a falling edge.
Line 2 is the Timer_1 count for CCP_2 on a rising edge.
Lines 3 & 4 should be line 1 - line 2.
LIne 5 should be ((line 1 - line 2)/5) - 1500.
In the first set, the first 4 lines show exactly what is expected. Then line 5 should be 12 or 13 instead of 7503.
In the second set I would expect lines 3 and 4 to be identical.
In the third set the first 2 values are incomprehesible to me, while the rest of the numbers, some of which are calculated using the first 2, look OK.
I've tried many different printf formats and variable types but always seem to have these kind of issues.
Oddly enough the program appears to be working properly...only the intermediate values are odd.
Here is the code with the debugging printf statements:
Code: | #include <16F877.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)
#use RS232(BAUD=38400,XMIT=PIN_C6,RCV=PIN_C7) //communication link with BotLoader
//raise this value as high as you can without overflowing the math
#define ADXL202_SCALING_FACTOR 100000
//global vars used to calculate G
long adxl_t1, adxl_t2;
unsigned int16 gyro_re, gyro_fe, gyro_value;
short adxl_waiting_for_fall, gyro_waiting_for_fall;
//global vars used calibrate
signed int32 adxl_zerog;
long adxl_ppg;
int8 count = 0;
#int_RTCC
Gyro_input_isr()
{
set_timer0(22);
if (++count==12)
count = 0;
else
{
if(count<2)
output_high(PIN_E2);
else
output_low(PIN_E2);
}
}
#int_ccp1 // Calculate duty cycle and period of Accelerometer output on X-axis
void accelerometer_isr(void)
{
static long adxl_last_rise;
if(adxl_waiting_for_fall)
{
adxl_t1=CCP_1-adxl_last_rise;
setup_ccp1(CCP_CAPTURE_RE);
adxl_waiting_for_fall=FALSE;
}
else
{
adxl_t2=CCP_1-adxl_last_rise;
adxl_last_rise=CCP_1;
setup_ccp1(CCP_CAPTURE_FE);
adxl_waiting_for_fall=TRUE;
}
}
#int_ccp2 // Calculate duty cycle and period of Gyro output
void gyro_isr(void)
{
if(gyro_waiting_for_fall)
{
gyro_fe=CCP_2;
gyro_value = gyro_fe - gyro_re;
setup_ccp2(CCP_CAPTURE_RE);
gyro_waiting_for_fall=FALSE;
}
else
{
gyro_re=CCP_2;
setup_ccp2(CCP_CAPTURE_FE);
gyro_waiting_for_fall=TRUE;
}
}
void initialization(signed int32 zerog, long ppg) {
adxl_zerog=zerog;
adxl_ppg=ppg;
setup_ccp1(CCP_CAPTURE_RE);
setup_ccp2(CCP_CAPTURE_RE);
adxl_waiting_for_fall=FALSE;
gyro_waiting_for_fall=FALSE;
setup_timer_0 (RTCC_INTERNAL | RTCC_DIV_32);
setup_timer_1 (T1_INTERNAL);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_CCP1);
enable_interrupts(INT_CCP2);
enable_interrupts(GLOBAL);
}
// A(g) = (T1/T2 - 0.456) / 0.118
// 0g = 50% duty cycle
signed int16 accelerometer_read(void)
{
float value;
value = adxl_t1 * ADXL202_SCALING_FACTOR;
value = value / adxl_t2;
value = value - adxl_zerog;
value = (value / adxl_ppg) * 10000;
return(value);
}
int16 gyro_read(void)
{
printf("\r\nGyro_fe = %lu",gyro_fe);
printf("\r\nGyro_re = %lu",gyro_re);
printf("\r\nGyro value_lu = %lu",gyro_value);
printf("\r\nGyro value_ld = %ld",gyro_value);
//(gyro_value>1000) ? (gyro_value = previous_gyro_value) : (gyro_value = gyro_value);
gyro_value = ((gyro_value) / 5) - 1500; //
printf("\r\nGyro value = %ld",gyro_value);
return(gyro_value);
}
main()
{
initialization(45600,11750); //calibrated values
output_low(PIN_E2);
{
while (1)
{
signed int16 accel_value, gyro_value;
accel_value = accelerometer_read(); // "Value" varies from -10,000 to +10,000
gyro_value = gyro_read();
if (gyro_value>1000)
Gyro_value = 0 ;
printf("\r\nAcceleration due to gravity = %4ld.%02ld%%",accel_value/100, accel_value%100);
printf("\r\nGyro rate of change = %ld",gyro_value);
delay_ms(1000);
}
}
} |
|
|
|
Ttemah Guest
|
|
Posted: Wed Dec 14, 2005 2:23 pm |
|
|
Try synchronising the print to the interrupt. Wait after the delay, till you see adxl_waiting_for_fall go false. So you need to wait if it is false, till it goes true, and then wait till it goes false. Then copy the values into local storage, and print from this. There are a lot of problems is values change inside an interrupt, while a print is taking place.
Best Wishes |
|
|
Harry Mueller
Joined: 17 Oct 2005 Posts: 116
|
|
Posted: Wed Dec 14, 2005 2:58 pm |
|
|
Thanks Ttemah, I've just done a lot of calculations and the results are always correct, even though intermediate numbers look incorrect, so the problem lies either with the print timing (as you have stated) or with print formating.
Regards....Harry |
|
|
|
|
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
|