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

PIC12F675 Delay Question

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



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PIC12F675 Delay Question
PostPosted: Wed May 27, 2015 8:12 am     Reply with quote

Dear colleagues,

First of all, thank you for having me.

I've recently started a new project that has the purpose of turning on a "light bulb" for 1 min at the press of a button (one press of the button the circuit is closed, second press the circuit opens again - we call it "non-release" button).

I've successfully did that:). Every time the button is pressed and stays pressed the light stays on for 1 min. When the button is released the circuit opens and of course, the light goes off. My problem is that the delay doesn't stop when the circuit opens, so if someone wants to turn on the light for 30 sec, closes it for 10 sec, and starts it again the delay is still running and the light will be on only for 20 more seconds, not for 1 min.

I'm using a PIC12F675, PCWHD and Proteus 8.

My code is :

Code:
void main()
{
   port_a_pullups (0x01);
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
 
 
   in:   while(!input(PIN_A0))
         goto in; 
         output_HIGH(PIN_A5);
         delay_ms(4000);
         output_low(PIN_A5);
         delay_ms(100);
         goto in2;

   in2:  while (input(PIN_A0))
         output_LOW(PIN_A5);
         delay_ms(100);
         goto in;
   
}


Thanks you,

Warm regards,

Eugeniu
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Wed May 27, 2015 8:15 am     Reply with quote

Ttelmah



Joined: 11 Mar 2010
Posts: 19360

View user's profile Send private message

PostPosted: Wed May 27, 2015 8:28 am     Reply with quote

goto..... Aargh!....

Seriously ignoring everything else, get rid of these....

There _are_ places in some programming, where goto can be sensible/worthwhile. What you are doing is _not_ one of these.

Then you have to re-think your approach.

Have a 'master' loop. Have an interrupt driven timer. Use state machine in the master loop to detect the button operation. Have the button operation change a counter, which is updated for you by the timer. Test this counter to know when the time has finished.

This way pushing the button, resets the counter.
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Wed May 27, 2015 9:18 am     Reply with quote

Dear Ttelmah,

Sorry, but my knowledge regarding programming is very limited.

If you have the time, and the desire, please write a code that I can modify in order to achieve the desired "delay" by modifying the value of the counter.

Warm regards,

Eugeniu
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed May 27, 2015 11:33 am     Reply with quote

corgenius wrote:
Dear Ttelmah,

Sorry, but my knowledge regarding programming is very limited.

If you have the time, and the desire, please write a code that I can modify in order to achieve the desired "delay" by modifying the value of the counter.

Warm regards,

Eugeniu

Sorry, this is a help forum not a do it for you one.

A search on this forum, google, CCS manual and PIC manuals will find examples of all you need.

As a useful tip, get rid of Proteus/ISIS. It will waste you more time than it saves.

Mike
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Wed May 27, 2015 11:51 am     Reply with quote

Dear Mike,

I've tried searching for a "counter delay" for the 12F675 but I didn't found anything.

Do you know where I can find it?

Regards,

Eugeniu
Ttelmah



Joined: 11 Mar 2010
Posts: 19360

View user's profile Send private message

PostPosted: Wed May 27, 2015 2:35 pm     Reply with quote

Quite a few things are covered in the supplied examples. If you look at ex_ticks.c, and then realise that this uses TICKS_PER_SECOND/4 (and 6) to give an LED flashing at 4Hz, and 6Hz. What do you think would happen if you used TICKS_PER_SECOND*60 instead?.
It also toggles the LED, rather than simply putting it on/off.

It'd need some tweaking, but shows some of the things needed.
ckielstra



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

View user's profile Send private message

PostPosted: Wed May 27, 2015 3:02 pm     Reply with quote

I'm not exactly sure I understand what you are trying to do but these look like early programming exercises. Perhaps for school or self study, but the only way you will learn is by trying yourself and making mistakes.

From the code you posted I can see you have just started to learn programming.

As Ttelmah said, the goto-statement is considered a bad programming practice and is best to never be used any more. There are some special cases where the goto-statement is useful but those are for advanced use only and, for now, forget about this instruction.

When you want to make a loop that never exits, then you code something like this:
Code:
while (TRUE) {
   // your code here
}
The advantage over using the goto-statement here is that your code is easier to read. The code is now 'self documenting' because it 'says' you want to do a loop.

I suggest you do some more reading in your C-language book over the while-loop because you repeat a particular error in your code. For example:
Code:
   in2:  while (input(PIN_A0))
         output_LOW(PIN_A5);
The while command will repeat the statement directly following this command. When I rewrite your code I can make this clear:
Code:
   in2:  while (input(PIN_A0))
         {
            output_LOW(PIN_A5);
         }
You are repeatedly setting PIN_A5 low for as long as PIN_A0 is high.
To avoid making mistakes like this it is good practice to always use the '{}' combination in while-loops and for-loops.

Ttelmah's suggestion for using a state machine and timer interrupts is very good but a bit too difficult for your programming knowledge.

Try to think about your problem in a different way by decoupling the switch logic and the timer into two separate steps. For example the next program will light a lamp for 30 seconds after the user releases the button.
Code:
#include <12F675.h>
#FUSES XT, NOWDT

#use delay(clock=4MHz)

#define SECONDS_1     (100 * 10)        // 100 x 10 ms == 1 second
#define SECONDS_30    (30 * SECONDS_1)

#define LAMP_BUTTON    PIN_A0
#define LAMP           PIN_A5

void main()
{
   int16 lamp_button_counter = 0;

   while(TRUE)
   {
      delay_ms(10);

      // If user pressed lamp button
      if (input(LAMP_BUTTON))
      {
         output_high(LAMP);
         lamp_button_counter = SECONDS_30;
      }

      // if lamp timer active
      if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);
         }
      }
   }
}
You can use this code as a base to expand.
Note how the use of #define makes the program easier to read.
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Wed May 27, 2015 10:27 pm     Reply with quote

Dear ckielstra,

First of all I want to thank you for your time. This is exactly the type of code that I've been searching for:).
I've compiled it before work but I didn't manage to make the led blink. I will post some result as soon as I get home.


Ttelmah, also thank you for your time.


Warm regards,

Eugeniu
ckielstra



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

View user's profile Send private message

PostPosted: Thu May 28, 2015 1:58 am     Reply with quote

One thing to check is the switch logic. In my example program the switch input is high when the switch is pressed. I see your program has this reversed.
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Thu May 28, 2015 8:45 am     Reply with quote

Dear ckielstra,

I've tried modifying the code in order to make the led blink. I even tried making a simple LED that is connected to PIN_A5 to blink, but with no success. I've tried to turn the LED ON with

Code:
#include <12F675.h>
#FUSES XT, NOWDT

#use delay(clock=4MHz)

#define SECONDS_1     (100 * 10)        // 100 x 10 ms == 1 second
#define SECONDS_30    (30 * SECONDS_1)

#define LAMP_BUTTON    PIN_A0
#define LAMP           PIN_A5


void main()
{
   port_a_pullups (0x01);

      // If user pressed lamp button
      if (!input(PIN_A0))
      {
         output_HIGH(PIN_A5);
      }
}


, but also 0 success:(.

Do you have any idea why the code doesn't work?




Regards,

Eugeniu
dyeatman



Joined: 06 Sep 2003
Posts: 1924
Location: Norman, OK

View user's profile Send private message

PostPosted: Thu May 28, 2015 9:46 am     Reply with quote

The chip won't run without a clock. You are using the XT fuse.
A5 is normally an Xtal input and you don't have an Xtal.
In your fuses change XT to INTRC_IO to enable the
internal osc and make A5 (GP5) an output. You need to read the datasheet.
_________________
Google and Forum Search are some of your best tools!!!!
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Thu May 28, 2015 12:25 pm     Reply with quote

Dear colleagues,

I've modified the code so the LED will "blink", but, for a continuous input (like I have in my project, the LED will not go off :(.

I've tryied changin the
Code:
  if (!input(LAMP_BUTTON))
         {
          output_high(LAMP);
          lamp_button_counter = SECONDS_5;
         }
      // if lamp timer active
         if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);
into

Code:
  while (!input(LAMP_BUTTON))
         {
          output_high(LAMP);
          lamp_button_counter = SECONDS_5;
         }
      // if lamp timer active
         if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);


and many more combinations, but with no result :(. I even added a GOTO expression, but still no result.

My complete code is
Code:

#include <12F675.h>
#FUSES INTRC_IO
#define portOut1 pin_a5

#use delay(clock=4MHz)

#define SECONDS_1     (100 * 10)        // 100 x 10 ms == 1 second
#define SECONDS_5     (5 * SECONDS_1)

#define LAMP_BUTTON    PIN_A0
#define LAMP           PIN_A5

void main()
{
   port_a_pullups (0x01);
   int8 lamp_button_counter = 0;

   while(TRUE)
   {
      delay_ms(10);

      // If user pressed lamp button
      if (!input(LAMP_BUTTON))
         {
          output_high(LAMP);
          lamp_button_counter = SECONDS_5;
         }
      // if lamp timer active
         if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);
         }
      }
   }
}


Thank you again for your time and knowledge.

Regards,

Eugeniu
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Sat May 30, 2015 9:41 am     Reply with quote

Dear colleagues,

I've tried adding a counter, in order to make the loop run just once when the input is continuously 1, but I didn't had any luck. The loop runs once, even though the input stays 1, but after realizing the button and pressing it again the loop doesn't start again.

My code is:

Code:
#include <12F675.h>
#FUSES INTRC_IO
#define portOut1 pin_a5

#use delay(clock=4MHz)

#define SECONDS_1     (100 * 10)        // 100 x 10 ms == 1 second
#define SECONDS_5     (5 * SECONDS_1)

#define LAMP_BUTTON    PIN_A0
#define LAMP           PIN_A5

void main()
{
port_a_pullups (0x01);
int8 lamp_button_counter = 0;
int counter = 0;



while(counter < 1)
   {
      delay_ms(10);

      // If user pressed lamp button
      if (input(LAMP_BUTTON))
      {
         output_high(LAMP);
         lamp_button_counter = SECONDS_5;
      }

      // if lamp timer active
      if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);
            counter = counter + 1;
         }
      }
   }
 while (input(LAMP_BUTTON))
      {
         counter = 0;
      }   
}



I even tried using the !input in order to make the counter 0 again with
Code:
 while (!input(LAMP_BUTTON))
      {
         output_low(LAMP);
         counter = 0;
      }


No luck.

Any ideas as how I can fix this?

Regards,

Eugeniu
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 30, 2015 10:52 am     Reply with quote

You need to look for an edge instead of a level. Read the switch input,
and when it changes from the inactive level to the active (pressed) level,
then you can turn on your LED. Example:
http://www.ccsinfo.com/forum/viewtopic.php?t=53600&start=11
and more:

Here is the "Button Command" code that I wrote for the Code Library:
http://www.ccsinfo.com/forum/viewtopic.php?t=23837

Here's a version of it that polls the buttons during a timer interrupt:
http://www.ccsinfo.com/forum/viewtopic.php?t=31849

This version stores the button presses in a buffer, which can be read:
http://www.ccsinfo.com/forum/viewtopic.php?t=39585&start=1
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