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 CCS Technical Support

asking for clarification

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



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

asking for clarification
PostPosted: Fri May 07, 2010 10:37 am     Reply with quote

Here I would to ask for your opinion regarding my code and diagram.
The code is basically PWM controlling speed of dc motor.
compile = no error
Code:

#include <16F877A.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use Delay(clock=20000000)

#include "C:\Users\deli\Desktop\pwx2\brum\Flexlcd2.c"

#define cel20     30
#define cel50     125
#define medium    120
#define slow      25
#define fast      175

main()
{
int16 pwm_duty;
int16 temp_adc;
float temp;

setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(PIN_A1);
set_adc_channel(1); //read analog input from channel 1

output_low(PIN_C2);    // Set CCP1 output low
setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_4, 249, 1);         // 5khz
set_pwm1_duty(medium);  // Set for 50% duty cycle

lcd_init();
lcd_putc("\ftemperature is:\n");

while(1);
{
            temp_adc = read_adc();

            temp = 5.00*temp_adc*100.00/1023.00;

            if ( temp_adc < cel20)
            {
               temp_adc=slow;
           }
           if ( ( temp_adc > cel20) & ( temp_adc < cel50) )
           {
               temp_adc=medium;
           }
           if ( temp_adc > cel50)
           {
               temp_adc=fast;
           }
           set_pwm1_duty(temp_adc); //Change duty cycle and adjust
           //delay_ms(100); //Wait for adjusting (Optional and may be left out)
         lcd_gotoxy(1,2);
            printf(lcd_putc,"%f",temp);
            delay_ms(3000);
}
}

Isn't true?
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Fri May 07, 2010 12:08 pm     Reply with quote

Your duty cycles are wrong.
You have Timer2, counting to 250 (249+1). The PWM, updates _four times_ for each count. So the pwm values run from 0 to 1000. 50% duty cycle will be 500, not 120 - _when the value is stored in an int16_. The compiler looks at the value handed to set_pwm_duty, and if it is an int8, automatically multiplies it by 4 for the set_pwm_duty function. So:

set_pwm_duty(medium);

will basically give just under 50% duty, but:

temp_adc=medium;
set_pwm_duty(temp_adc);

Will give just under 12% duty.

Do the following:

Update your constants, as:

#define medium (500L)
#define slow (100L)
#define fast (700L)

This will force the compiler to treat the numbers as 16bity, no matter what the value.

Best Wishes
delifadzli



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

PostPosted: Sat May 08, 2010 12:35 am     Reply with quote

Thanks for explanation. Can you explain a little bit on how to get 50% duty cycle? I assume 125/249= 0.5 isn't true. Sorry for my weakness.

Then how about cel 20 and cel 50 ...?

Isn't need to replace it? like cel 20 = 250L and cel 50= 600L ??
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Sat May 08, 2010 4:41 am     Reply with quote

The PWM, counts to the value you set for timer2 _plus one_, in '1/4' counts. So with Timer2=249, the PWM accepts values from 0 to 1000. With '1000' being 'fully on' (no pulse, signal fully high), and '0' being 'fully off' (signal fully low). The half way point, is 1000/2 = 500. Pulse on 1/4 time, is 250, etc..

Best Wishes
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Sat May 08, 2010 7:26 am     Reply with quote

Your 'cel' values, are the value you are reading from the ADC, nothing to do with the PWM values.
The values you need here, will; depend on what you are doing with the ADC.
You don't need to use the 'L' designation for these, since nothing you are doing makes any 'distinction' between 8bit integers, and long (16bit) integers.
The point is that the PWM code _does_ make a distinction. If it receives a 'long' integer (a value >255, a value stored in an int16, _or_ a value with 'L' appended), then it uses this value directly. If it receives an 8bit value, then it automatically multiplies it by 4, assuming that you only want to set the top 8 bits of the 10bit PWM value. This is documented in the manual.

Best Wishes
delifadzli



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

PostPosted: Sun May 09, 2010 3:20 pm     Reply with quote

Here is a little improvement that I had managed to compile it without any error...
Code:

#include <16F877A.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use Delay(clock=20000000)

#include "C:\Users\deli\Desktop\pwx2\brum\Flexlcd2.c"

#define medium    500L
#define slow      100L
#define fast      700L

void main(void)
{
       int16 temp_adc;
       float temp;
      int16 pwm_duty;

        setup_adc(ADC_CLOCK_DIV_8);
        setup_adc_ports(PIN_A1);
        set_adc_channel(1); //read analog input from channel 1

         output_low(PIN_C2);    // Set CCP1 output low
         setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
         setup_timer_2(T2_DIV_BY_4, 249, 1);         // 5khz
         set_pwm1_duty(medium);  // Set for 50% duty cycle

        lcd_init();

         lcd_putc("\ftemperature is:\n");

          while(1)
            {
            temp_adc = read_adc();

            temp = 5.00*temp_adc*100.00/1023.00;
         lcd_gotoxy(1,2);
            printf(lcd_putc,"%f",temp);
            delay_ms(3000);
            }
            {

                               if ( temp_adc < 58)
                         {
                               temp_adc=slow;
                         }


                              if ( ( temp_adc > 58) & ( temp_adc < 70) )
                         {
                              temp_adc=medium;
                         }


                              if ( temp_adc > 70)
           {
                              temp_adc=fast;
           }


                            set_pwm1_duty(temp_adc); //Change duty cycle and adjust


        }

}

The problem is, when I run it, the LCD does produce the result- actual temperature in Celsius...but the fan doesn't work at all.

Hope for your response.

Here is simple diagram...on how I interface dc motor with the pic.

The motor I used:
http://img.directindustry.com/images_di/photo-g/ac-or-dc-fan-359065.jpg

http://images.elektroda.net/22_1273439913.png
delifadzli



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

PostPosted: Sun May 09, 2010 3:21 pm     Reply with quote

the component 2sj48 i replace it with IRF9540...sorry for that one...
delifadzli



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

PostPosted: Mon May 10, 2010 2:37 am     Reply with quote

anyone?...please help..me...i quite new is this area...actually.....sorry for my weakness
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 10, 2010 3:20 am     Reply with quote

Hint: fix the layout of your code. Now the indentation goes left and right at random.

When you have fixed this, look at where the while-loop ends. Do you think this is correct?
delifadzli



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

PostPosted: Mon May 10, 2010 3:33 am     Reply with quote

#include <16F877A.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use Delay(clock=20000000)

#include "C:\Users\deli\Desktop\pwx2\brum\Flexlcd2.c"


#define medium 125L
#define slow 63L
#define fast 240L

void main()
{
int16 temp_adc;
float temp;
int16 pwm_duty;




setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(PIN_A1);
set_adc_channel(1); //read analog input from channel 1
output_low(PIN_C2); // Set CCP1 output low
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_4, 249, 1); // 5khz
set_pwm1_duty(medium); // Set for 50% duty cycle

lcd_init();

lcd_putc("\ftemperature is:\n");

while(1)

{
temp_adc = read_adc();

temp = 5.00*temp_adc*100.00/1023.00;
lcd_gotoxy(1,2);
printf(lcd_putc,"%f",temp);
delay_ms(3000);



if ( temp_adc < 58)
{
temp_adc=slow;
}


if ( ( temp_adc > 58) & ( temp_adc < 70) )
{
temp_adc=medium;
}


if ( temp_adc > 70)
{
temp_adc=fast;
}

set_pwm1_duty(temp_adc); //Change duty cycle and adjust


}

like this?


i truly sorry if i'm wrong...i'm still newbie....
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 10, 2010 3:59 am     Reply with quote

Use the 'code' buttons when posting code. Now it is very difficult to read.

Quote:
like this?
More or less. Does it work?
I Think you created a compile error, or the last line of your program got lost during copy/paste.
delifadzli



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

PostPosted: Mon May 10, 2010 5:14 am     Reply with quote

Code:
#include <16F877A.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use Delay(clock=20000000)

#include "C:\Users\deli\Desktop\pwx2\brum\Flexlcd2.c"


#define medium 125L
#define slow 63L
#define fast 240L

void main()
{
int16 temp_adc;
float temp;
int16 pwm_duty;




setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(PIN_A1);
set_adc_channel(1); //read analog input from channel 1
output_low(PIN_C2); // Set CCP1 output low
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_4, 249, 1); // 5khz
set_pwm1_duty(medium); // Set for 50% duty cycle

lcd_init();

lcd_putc("\ftemperature is:\n");

while(1)

{
temp_adc = read_adc();

temp = 5.00*temp_adc*100.00/1023.00;
lcd_gotoxy(1,2);
printf(lcd_putc,"%f",temp);
delay_ms(3000);



if ( temp_adc < 58)
{
temp_adc=slow;
}


if ( ( temp_adc > 58) & ( temp_adc < 70) )
{
temp_adc=medium;
}


if ( temp_adc > 70)
{
temp_adc=fast;
}

set_pwm1_duty(temp_adc); //Change duty cycle and adjust


}


here is the code...compile without error...but still the fan doesn't work...
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 10, 2010 5:56 am     Reply with quote

Code:
if ( ( temp_adc > 58) & ( temp_adc < 70) )
Change '&' to '&&'.
A single '&' means 'binary AND'
A double '&&' means 'logical AND'

You also have to change the '> 58' to '>= 58' because the other test is testing '< 58' and your code is doing nothing when temp_adc == 58.

Same for testing '70'.

Your code will be easier to read and faster to execute if you code it like:
Code:
if (temp_adc < 58)
{
  temp_adc = slow;
}
else if ( (temp_adc >= 58) && (temp_adc < 70) )
{
  temp_adc = medium;
}
else
  temp_adc = fast;
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