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

Read RS232, Read ADC, PWM output

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



Joined: 12 Oct 2015
Posts: 8

View user's profile Send private message

Read RS232, Read ADC, PWM output
PostPosted: Mon Oct 12, 2015 3:07 am     Reply with quote

Guys please help me!

I'm stuck in a loop, Embarrassed plz help me!

First I'll tell my program briefly. Smile
* I want to control the brightness of LED. (Day and Night mode) through POT
* I'll receive HEX value through RS232.
- if I receive 0x30, it is night mode. so LED brightness should be 0-50%. POT minimum is 0 and max is 50%.
- if I receive 0x39, it is Day mode. so LED brightness should be 50%-100%. POT minimum is 50% and max is 100%.
* I have done these things through PWM.
My problem is, if I'm receiving the date and it is true, I'm stuck into the loop and I'm not able to come back and check the rs232 data again so I'm not able to change the mode.
NOTE: DATA RECEIVED THROUGH RS232 is not continuous. USER DEPENDENT. Rolling Eyes
Code:

#include <16f877A.h>
#device adc=8
 #fuses HS,NOLVP,NOWDT
 #use delay (clock=20000000)
 #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

 unsigned int value;

 void main()
 {

 unsigned int pwm1;

 setup_adc(ADC_CLOCK_DIV_32); // Enable the A/D and use the internal clock

 setup_port_a(AN0);
 setup_ccp1(CCP_PWM);
 setup_timer_2(T2_DIV_BY_4, 254, 1);
 set_adc_channel(0);

while(1)
  {
   value=getc();
   if(value==0x30)
     {
      while(1)
        {
         pwm1 = read_adc();
         delay_ms(20);
         set_pwm1_duty((pwm1/2)); // night 0 to 2.5 v
        }
      }

   if(value==0x39)
     {
      while(1)
        {
         pwm1 = read_adc();
         delay_ms(20);
         if(pwm1>=128)
            set_pwm1_duty(pwm1);
         else
            set_pwm1_duty(128);
        }
     }
  }
}

Plz help me. Urgent requirement. My friend told me to put in a interrupt but I don't know how to make it. I'm new to this.

_________________
+1923+ Idea Idea
_________________
+1923+


Last edited by shan1923 on Mon Oct 12, 2015 4:28 am; edited 2 times in total
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

Re: READ RS232, READ ADC, PWM OUTPUT.
PostPosted: Mon Oct 12, 2015 3:31 am     Reply with quote

Use the code button - it is there so we can read your code easily.

You need to sit back and think this through. There are multiple problems.

Problem 1:
You perform a getc() at the start of your main loop. This may be intended but of course if there is no character in the uart receive buffer then the code is stuck inside this loop until a character is received. Perhaps this was your intention.

Problem 2:
You have several instance in your code of:

Code:
while (1) {
...
...
}


You would typically expect to see this construct used only once. In the mainline code, once you have initialised the application and want to repeat continuously the main execution loop.

There are exceptions, you could for example use break (you haven't) in order to break out of a while loop.

Lets say for example the value you read was 0x30. You pass into another while (1) loop with no way to break out of this. So the PIC stays in this endless loop.

Problem 3:
(Same as problem 2) if the value read was 0x39 you will enter an endless loop.

Perhaps you should draw out a flow chart - then you would get a better understanding of what you have coded versus what you thought you were coding.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!


Last edited by asmallri on Mon Oct 12, 2015 4:16 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Mon Oct 12, 2015 4:08 am     Reply with quote

Lets make another couple of comments.

The internal serial buffer, is just two characters. At 9600bps, you can receive 19 characters in 20mSec. Though you say the input is 'USER DEPENDENT', if multiple characters did come in the delays, this would hang the UART.

Either ensure the UART will not be hung (Look at what the keyword 'ERRORS' does in #use RS232), or use software serial buffering (either using the version built in to #use rs232 now, or ex_sisr.c).

Asmallri has pointed out the other big killer.
shan1923



Joined: 12 Oct 2015
Posts: 8

View user's profile Send private message

PostPosted: Mon Oct 12, 2015 4:18 am     Reply with quote

thank u asmallri for your reply.

" PROBLEM 1: " - My intention is to wait until the data receive through RS232.
NOTE: I ll receive data from subsystem for every 30ms. so no problem for me.

" PROBLEM 2:" - I ll get 0x30 or 0x39 only once when the user press button.
also if i wont put while loop, i cant read ADC value continuously and i fail to update the PWM value when user rotate the POT.
NOTE: if i put break; I'll come out form the loop and i have to wait for 0x30 or 0x39 to update the PWM value
Exclamation Shocked
_________________
+1923+
shan1923



Joined: 12 Oct 2015
Posts: 8

View user's profile Send private message

PostPosted: Mon Oct 12, 2015 4:24 am     Reply with quote

thanks for your valuable comment Ttelmah. I ll consider it. Smile
_________________
+1923+
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Mon Oct 12, 2015 5:06 am     Reply with quote

You are missing the point slightly. Waiting for the data is one thing, never exiting a loop is another. Once one character is seen, it's never going to leave it's loop....
Remember the PWM _keeps_ generating it's output. It doesn't matter if you leave the loop.
shan1923



Joined: 12 Oct 2015
Posts: 8

View user's profile Send private message

PostPosted: Mon Oct 12, 2015 5:45 am     Reply with quote

@ Ttelmah. what I have to do now?
continuously I have to read ADC value and check the RS-232. this is my condition. should I change the conditions?
I have no clue to make it out. if you have any sample program plz give me or else plz correct my program and revert it back. I ll be thank full Rolling Eyes
_________________
+1923+
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Oct 12, 2015 8:03 am     Reply with quote

Hi shan1923,

This is a "help you" forum, NOT a "do it for you" forum. With that in mind, you should make the following changes to YOUR program, and see what happens:

1. Add the 'Errors' keyword to the #use rs232 directive. See the CCS manual entry for the #use rs232 directive if you don't know what this means.

2. Get rid of the two inner 'while(1)' loops. Inside the remaining while(1) loop, check for a character, read the A/D, and then do your evaluation of 'Value' with an 'If' statement. As was already pointed out, you don't need to do this continuously - once the PWM is set, it will run continuously.

3. In Main(), above the 'while(1)', set the PWM to some default value. This will set the PWM to *something* before the first command is received.

BTW, is this a *real* hardware project, or a Proteus simulation?
_________________
John

If it's worth doing, it's worth doing in real hardware!
shan1923



Joined: 12 Oct 2015
Posts: 8

View user's profile Send private message

PostPosted: Tue Oct 13, 2015 12:09 am     Reply with quote

@ezflyr. it is a real hardware project but right now im checking it in Proteus simulation.
I have checked what you said. still the same issue.
Code:

while(1)
{
pwm1 = read_adc();
delay_ms(20);
}
set_pwm1_duty(pwm1);
Rolling Eyes
my pwm is not updating when the adc value change.
_________________
+1923+
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Tue Oct 13, 2015 12:27 am     Reply with quote

Of course it wouldn't.

You are sitting reading the ADC forever. Nothing else.

I really think you need to get a basic 'C' primer, and spend some time learning the language.
shan1923



Joined: 12 Oct 2015
Posts: 8

View user's profile Send private message

PostPosted: Wed Oct 14, 2015 1:26 am     Reply with quote

Very Happy Laughing thanks guys! finally I got it with all your help.
in simulation it is working fine but in simulation log it is showing " simulation is not running in real time due to excessive cpu load" Shocked
so have to check in real hardware. Question


Code:

#include <16f877A.h>
#device adc=8
#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,errors)

void main()
 {
unsigned int day, night;
unsigned int  value;
unsigned char pwm1;

setup_adc(ADC_CLOCK_DIV_32);   
setup_port_a(AN0); 
setup_timer_2(T2_DIV_BY_4, 254, 1);
set_adc_channel(0);
setup_ccp1(CCP_PWM);   
pwm1=200;

while(1)
{
if(kbhit())
{
    value=getc(); 
    if(value==0x30) 
        {night=1;day=0;}
    if(value==0x39)
        {day=1;night=0;}
}
   
    if(night==1)         // rs232-night
    {
       
    pwm1 = read_adc();
    delay_ms(10);
    set_pwm1_duty((pwm1/2)); // night 0 to 2.5 v 
   
    }
   
    if(day==1)          // rs232 -day
    {
   
    pwm1 = read_adc();
    delay_ms(10);
    if(pwm1>=128)             // day 2.5 to 5v
    set_pwm1_duty(pwm1);
    else
      set_pwm1_duty(0x80);   
   
   
    }
}
 }

_________________
+1923+
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Oct 14, 2015 2:10 am     Reply with quote

That is the CPU load in the PC.

It can't keep up with what the PIC is doing. Smile

Why have two variables for night and day?.

Think about it the code is _either_ in 'night' mode, _or_ in 'day' mode.

Code:

#define NIGHT 1
#define DAY 0

int1 time_of_day = DAY;

while(1)
{
    delay_ms(10); //only one delay needed to slow the loop a little
    if(kbhit())
    {
        value=getc();
        if(value==0x30)
            time_of_day=NIGHT;
        if(value==0x39)
            time_of_day=DAY;
    }   

    if(time_of_day==NIGHT)         // rs232-night
    {
       
        pwm1 = read_adc();
        set_pwm1_duty((pwm1/2)); // night 0 to 2.5 v
    }
    else 
    {
        pwm1 = read_adc();
        if (pwm1>=128)             // day 2.5 to 5v
            set_pwm1_duty(pwm1);
        else
            set_pwm1_duty(0x80); 
    } 
}

There is also something 'odd' about your PWM values.

You are sending 128 maximum to the PWM. This will give you just fractionally over 50% duty cycle. This is not '5v'.
shan1923



Joined: 12 Oct 2015
Posts: 8

View user's profile Send private message

PostPosted: Wed Oct 14, 2015 4:09 am     Reply with quote

Thank you for your code Ttelmah Very Happy

I'm planning to control FET base with the help of PWM Pulse. I think I'll do it.
I have a doubt in one statement. plz clear me

Code:
set_pwm1_duty(0x80);


Why I should not put 128?
_________________
+1923+
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Oct 14, 2015 7:54 am     Reply with quote

No reason at all.

The point is that you lose the whole bottom half of your pot travel.
Currently you will turn the pot through the bottom half of it's travel, and the PWM will stay at 128. Then only on the top half of it's travel will the output PWM start to change.

So instead of getting 2.5 to 5v for the entire pot travel, you get 2.5......2.5......5. as the pot turns.

You really want something like:
Code:

    else //for the day output
    {
        pwm1 = read_adc();
        set_pwm1_duty(pwm1/2+128);
    }

This will then give:
2.5................5

as the pot turns.

You had 0x80 in your original code. Entirely 'up to you' what format you use. Generally hex is useful when dealing with numbers that have a binary significance.
shan1923



Joined: 12 Oct 2015
Posts: 8

View user's profile Send private message

PostPosted: Sat Oct 17, 2015 2:55 am     Reply with quote

@Ttelmah. Thanks a lot. Smile
_________________
+1923+
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