View previous topic :: View next topic |
Author |
Message |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed May 27, 2015 3:02 pm |
|
|
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
|
|
Posted: Wed May 27, 2015 10:27 pm |
|
|
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
|
|
Posted: Thu May 28, 2015 1:58 am |
|
|
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
|
|
Posted: Thu May 28, 2015 8:45 am |
|
|
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: 1934 Location: Norman, OK
|
|
Posted: Thu May 28, 2015 9:46 am |
|
|
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
|
|
Posted: Thu May 28, 2015 12:25 pm |
|
|
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
|
|
Posted: Sat May 30, 2015 9:41 am |
|
|
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
|
|
|
|