CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Strange problem with printf()

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JPH



Joined: 02 Feb 2005
Posts: 9
Location: Finland

View user's profile Send private message

Strange problem with printf()
PostPosted: Tue Feb 28, 2006 2:40 pm     Reply with quote

Hey

I have PCH 3.242 compiler and PIC18F6722@32MHz.I have strange problem with printf() when I read data from the Sensirion SHT15 sensor. It works's right when I have uncommented one of the printf() lines in the end of the CASE 3. But when all printf() lines are commented and I try to read temp and humi inside the program, values are off the scale. When I put the program to print out temp or humi, then the function works like it should be I can read right values to other function.

So question is where should I start to look the problem?

Code:

////////////////////////////////////////////////////////////////////////////////
execute(int8 number)
{
   switch(number)
   {
      case 0:
      {
         sht1x_connection_reset();
         sht1x_command_mode(MEASURE_TEMP);
         set_timer0(58660);                 //220ms
         state++;
      }
      break;

      case 1:
      {
         lValue_temp = sht1x_read_data();
         fTemp_true = (D1+(D2*lValue_temp));
         set_timer0(65224);               //10ms
         state++;
      }
      break;
 
      case 2:
      {
         sht1x_connection_reset();
         sht1x_command_mode(MEASURE_HUMI);
         set_timer0(63503);                 //65ms
         state++;
      }
      break;

      case 3:
      {
         clear_interrupt(int_timer0);
         disable_interrupts(int_timer0);
         lValue_rh = sht1x_read_data();
         fRh_lin = (C1+(C2*lValue_rh)+(C3*lValue_rh*lValue_rh));
         fRh_true = (((fTemp_true-25)*(T1+(T2*lValue_rh)))+fRh_lin);
         fDew_point = sht1x_calc_dewpoint(fRh_true,fTemp_true);
         
         //printf("\nRelative Humidity: %3.4f%%",fRh_true);
         //printf("\nDew Point: %3.4fC",fDew_point);
         printf("\nTemperature: %3.4fC",fTemp_true);
       
      }
      break;

      default:
      {

      }
      break;
   }
}
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
void read_temp_humi(void)
{
   set_timer0(65000);
   state=0;
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
}
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
#INT_TIMER0
int_timer0_isr()
{
   execute(state);
}
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
main()
{
SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_256);
while(1)
{

   if(!input(PIN_F1))
   {
      read_temp_humi();
   }
}
}
////////////////////////////////////////////////////////////////////////////////


Cheers
Jussi
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 28, 2006 3:21 pm     Reply with quote

It takes time to send characters with the UART. It also takes time
for the floating point printf routines to execute. At 9600 baud, it takes
about 1 ms to transmit a character.

So I would guess that just one of your printf statements is at least
the equivalent of this statement:
Code:
delay_ms(25);


That may give you a clue regarding the source of the problem.
JPH



Joined: 02 Feb 2005
Posts: 9
Location: Finland

View user's profile Send private message

PostPosted: Wed Mar 01, 2006 2:02 pm     Reply with quote

Thanks for the fast reply. I debugged and tested function with different interrupt times and I still didn't get it work without using at least one printf(). How should I fix the problem?

Code:

execute(int8 number)
{
   switch(number)
   {
      case 0:
      {
         sht1x_connection_reset();
         sht1x_command_mode(MEASURE_TEMP);
         set_timer0(58660);                 //220ms
         state++;
      }
      break;

      case 1:
      {
         lValue_temp = sht1x_read_data();
         fTemp_true = (D1+(D2*lValue_temp));
         set_timer0(65224);               //10ms
         state++;
      }
      break;

      case 2:
      {
         sht1x_connection_reset();
         sht1x_command_mode(MEASURE_HUMI);
         set_timer0(20000);                 //1.4s
         state++;
      }
      break;

      case 3:
      {
         lValue_rh = sht1x_read_data();       
         fRh_lin = (C1+(C2*lValue_rh)+(C3*lValue_rh*lValue_rh));
         fRh_true = (((fTemp_true-25)*(T1+(T2*lValue_rh)))+fRh_lin);
         fDew_point = sht1x_calc_dewpoint(fRh_true,fTemp_true);
         set_timer0(20000);                 //1.4s
         state++;
         //printf("\nRelative Humidity: %3.4f%%",fRh_true);
         //printf("\nDew Point: %3.4fC",fDew_point);
         //printf("\nTemperature: %3.4fC",fTemp_true);
      }
      break;
     
      case 4:
      {
         clear_interrupt(int_timer0);
         disable_interrupts(int_timer0);
      }
      break;

      default:
      {

      }
      break;
   }
}
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed Mar 01, 2006 3:31 pm     Reply with quote

Your problem might not be with the printf() command. I've worked with this sensor quite a bit and you need to allow the sensor to do it's thing once you give it a read() command. The sensor is not quite I2C compatible so you need to bit_bang communications to it.

Once you have sent a read() command to the sensor it will hold the SDA line High until it's finished it's measurement. Monitoring this line will allow you to know when to clock the result out of it. You can put a specified delay time if you want but, to reduce down time, simply monitor when the SDA line goes low to clock the data out.

Here's a small section of code that I have used that works quite well. The SDA line is assigned to the variable XSDA. Send_sense() and read_sense() are simply bit_bang routines. Calc_rh() and calc_temp() are routines to convert the values that are read to displayable values.

Code:

if(sensor)// time to read the sensor
{
  switch(status)
  {
    CASE 1:
      if(send_sense(0x03))// send command to read the Temperature and test if it ACK'd
      {
        status = 0;// if this is entered, the sensor did NOT ACK and we stop trying to
        sensor = 0;// talk to the sensor until the next time we want to read it
      }
      else
      {
        status = 2;// if the sensor ACK'd, increment the status var
      }
      break;
    CASE 2:
      if(!input(XSDA))// we need to wait until the sensor is finished
      {                // making it's measurement before we try to get
        stemp = read_sense(); // the data from it
        status = 3;
      }
      break;
    CASE 3:
      if(!send_sense(0x05))// this is the read command for the RH
      {
        status = 4;
      }
      break;
    CASE 4:
      if(!input(XSDA))// we need to wait for the same thing as the temp
      {
        shumid = read_sense();
        status = 5;
      }
      break;
    CASE 5:
      if((!stemp && !shumid) || (stemp > 0x3FFF || shumid > 0xFFF))
      {                       // if the sensor has
        if(pwr++ > 10) // wigged out, cycle the power to it
        {
          puked = 1;
        }
        cycle_power();
      }
      else
      {
        TEMP = calc_temp(stemp);
        HUMI = calc_rh(shumid);
        pwr = 0;
      }
      status = 6;
      break;
    CASE 6:
      if(!send_sense(0x07));// this sends the command to address the Sesor's
      {                            // Status Register
        status = 7;
      }
      break;
    CASE 7:
      if(!input(XSDA))// we need to wait until the sensor is ready to
      {                 // send the data
        r_stat = read_status();
        if((r_stat & 0x40) == 0x40)// mask out unwanted bits
        {
          if(eol_status++ > 9)// test the End of Life bit from the sensor and
          {                    // if it is set for 9 straight tests...
            eol_done = 1; // set the End of Life status bit
          }
        }
        else
        {
          eol_status = 0;
          eol_done = 0;
        }

        status = 0;// reset these flags for the next use
        sensor = 0;
      }
      break;
    default:
      break;
  }// end of switch()
}// end of if(sensor)


This code is placed inside of main() and a timer sets a flag 'sensor' whenever a measurement needs to be made. Since it's inside of main() each Case is tested every scan and there is very little down time waiting for any delay.

Clear as mud? Twisted Evil

Ronald
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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