|
|
View previous topic :: View next topic |
Author |
Message |
corgenius
Joined: 27 May 2015 Posts: 18
|
|
Posted: Sun Jul 26, 2015 10:19 am |
|
|
Hurrah, I understand the code completely!
Also I've tried to define all the missing parts and compile the code, and I got 3 errors : Expecting LVALUE such as a variable name or * expression (Lines 25, 29,59) and one error : A numeric expression must appear here (Line 43)
I've read about them in the PCW help menu but it doesn't make any sense because input(LAMP_BUTTON2) is a variable.
I will bold the 3 lines with LVALUE error and make italic the line with "numeric expression must appear here".
Code: | #include <12F675.h>
#FUSES INTRC_IO
#use delay(clock=4MHz)
#define LAMP_BUTTON2 PIN_A2
#define LAMP PIN_A5
#define LAMP3 PIN_A1
#define button_pressed() (input(LAMP_BUTTON2)=SWITCH_NOT_PRESSED)
#define lamp_on() (output_high(LAMP))
#define lamp_off() (output_low(LAMP))
#define SWITCH_PRESSED 0 // 5V
#define SWITCH_NOT_PRESSED 1 // 0
//============================================================================================
void main()
{
output_high(LAMP3); // STATUS - LED ON = MICROCONTROLER ON
enum {LOOK_FOR_BUTTON, WAIT_200, LAMP_500, IGNORE_STILL_ON} task;
int16 ticks;
switch (task)
{
case LOOK_FOR_BUTTON:
[b]if (button_pressed())[/b]
{
task=WAIT_200;
ticks=200;
}
break;
case WAIT_200:
[b] if (button_pressed()) [/b]
{
if (ticks)
--ticks;
else
{
//button has been pressed for 200 ticks
ticks=500;
task=LAMP_500;
}
}
[i] else [/i]
task=LOOK_FOR_BUTTON;
break;
case LAMP_500:
if (ticks)
{
lamp_on(); //again I'd define this - haven't done so
--ticks;
}
else
{
lamp_off(); //same comment
task=IGNORE_STILL_ON;
}
break;
case IGNORE_STILL_ON:
[b] if (! button_pressed()) [/b]
task=LOOK_FOR_BUTTON;
break; //wait for the button to go off
}//end of switch
} |
Edit : I've found out were the mistake was.... the line #define button_pressed() (input(LAMP_BUTTON2)=SWITCH_NOT_PRESSED) was incorrect. The correct code is #define button_pressed() (input(LAMP_BUTTON2)==SWITCH_NOT_PRESSED)
Edit2: The code compiles, but, it doesn't do anything...the compiled code is:
Code: | #include <12F675.h>
#FUSES INTRC_IO
#use delay(clock=4MHz)
#define LAMP_BUTTON2 PIN_A2
#define LAMP PIN_A5
#define LAMP3 PIN_A1
#define SWITCH_PRESSED 0 // 5V
#define SWITCH_NOT_PRESSED 1 // 0
#define button_pressed() (input(LAMP_BUTTON2)==SWITCH_NOT_PRESSED)
#define lamp_on() output_high(LAMP)
#define lamp_off() output_low(LAMP)
//==============================================
void main()
{
output_high(LAMP3); // STATUS - LED ON = MICROCONTROLER ON
enum {LOOK_FOR_BUTTON, WAIT_200, LAMP_500, IGNORE_STILL_ON} task;
int16 ticks;
switch (task)
{
case LOOK_FOR_BUTTON:
if (button_pressed())
{
ticks=20;
task=WAIT_200;
}
break;
case WAIT_200:
if (button_pressed())
{
if (ticks>0)
--ticks;
else
{
//button has been pressed for 200 ticks
ticks=100;
task=LAMP_500;
}
}
else
task=LOOK_FOR_BUTTON;
break;
case LAMP_500:
if (ticks>0)
{
lamp_on(); //again I'd define this - haven't done so
--ticks;
}
else
{
lamp_off(); //same comment
task=IGNORE_STILL_ON;
}
break;
case IGNORE_STILL_ON:
if (!button_pressed())
task=LOOK_FOR_BUTTON;
break; //wait for the button to go off
}//end of switch
} |
Any ideas as why it doesn't do anything?
Regards,
Eugeniu |
|
|
corgenius
Joined: 27 May 2015 Posts: 18
|
|
Posted: Sun Jul 26, 2015 1:58 pm |
|
|
Hurrahhhhh
I've managed to make it do exactly what I want
Thank you for the support Ttelmah ! Please have a look at my code to see if everything looks alright:)
Regards,
Eugeniu
Code: | #include <12F675.h>
#FUSES INTRC_IO
#use delay(clock=4MHz)
#define LAMP3 PIN_A1
#define SWITCH_PRESSED 0 // 5V
#define SWITCH_NOT_PRESSED 1 // 0
#define button_pressed() input(PIN_A2)==SWITCH_NOT_PRESSED
#define button_not_pressed() input(PIN_A2)==SWITCH_PRESSED
#define lamp_on() output_high(PIN_A5)
#define lamp_on2() output_high(PIN_A4)
#define lamp_off() output_low(PIN_A5)
//============================================================================================
void main()
{
output_high(LAMP3); // STATUS - LED ON = MICROCONTROLER ON
enum {LOOK_FOR_BUTTON, WAIT_200, LAMP_500, IGNORE_STILL_ON} task;
int16 ticks;
While(true)
{
switch (task)
{
case LOOK_FOR_BUTTON:
if (button_pressed())
{
ticks=2000;
task=WAIT_200;
}
break;
case WAIT_200:
if (button_pressed())
{
if (ticks>0)
--ticks;
else
{
//button has been pressed for 100 ticks
ticks=1000;
task=LAMP_500;
}
}
else
task=LOOK_FOR_BUTTON;
break;
case LAMP_500:
if (ticks>0)
{
lamp_on();
delay_ms(5);
--ticks;
}
else
{
lamp_off();
ticks=300;
task=IGNORE_STILL_ON;
}
break;
case IGNORE_STILL_ON:
if (!button_pressed())
{
if (ticks>0)
--ticks;
else
{
task=LOOK_FOR_BUTTON;
}
//wait for the button to go off
}//end of switch
break;
}
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19540
|
|
Posted: Sun Jul 26, 2015 2:05 pm |
|
|
It's looking a good start.
Now if you want to get more complex (not necessary for your application), the 'tick' that makes the loop time can be done with a timer.
The advantage then is that the loop then takes 1mSec every time (assuming this is the time used). If a particular route through the code takes a fraction longer it doesn't change the timings.
Once you do that, and add more states to do anything else, you basically have the core of how people make the PIC do multiple jobs. Since the loop keeps looping you can handle multiple buttons, multiple lamps, whatever you want!.
The enum, with the switch, is called a 'state machine'. The code just moves through the states to do the various operations.
Have fun. |
|
|
Petar_2010
Joined: 18 Nov 2018 Posts: 5
|
|
Posted: Mon Aug 19, 2019 9:36 am |
|
|
Hello,
I have a similar problem. I need to program a push-button with three states:
1 state: if the time of press is less than 1000ms the led must be permanent.
2 state: if the time of press is more than 1000ms the led must be flashing with 500ms on 500ms off.
3 state: another press - led off.
I've done states 1, 3 and 2, 3 separately and I tried to combine both but at the moment I don't have any success.
This is my code (states 1 and 3 without the time counter of 1000ms):
Code: |
#include <16F1828.h>
#fuses NOMCLR //Master Clear pin used for I/O
#fuses BORV25 //Brownout reset at 2.5V
#use FIXED_IO( A_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3,PIN_A4,PIN_A5 )
#use FIXED_IO( B_outputs=PIN_B4,PIN_B5,PIN_B6,PIN_B7 )
#use STANDARD_IO(C)
#use delay(internal=8MHz)
// DEFINE INPUT BUTTONS
#define BUTTON_1 PIN_C0
// DEFINE OUTPUT LEDS
#define LED_GREEN PIN_A0
int16 cont_green=0;
#int_timer2
void interm_green()
{
cont_green++;
if(cont_green==1600)
{
output_toggle(LED_GREEN);
cont_green=0;
}
}
//======================================================================
void main()
{
port_c_pullups(0xff);
output_a(0x00);
WHILE(true){
enable_interrupts(GLOBAL); //Habilita int. general
setup_timer_2(T2_DIV_BY_4,124,1);
if((input(BUTTON_1) == 0)){
char count; count = 0;
while(true){ //push-button pressed
if((input(BUTTON_1) == 0)) delay_ms(10); //debounce
if((input(BUTTON_1) == 0))
count++;
else
count = 0;
if(count == 1)
break;
delay_ms(10);
}
while(true){ //push-button loosed
if (input(BUTTON_1)) delay_ms(10); //debounce
if(input(BUTTON_1))
count++;
else
count = 0;
if(count == 1)
break;
delay_ms(30);
}
output_toggle(LED_GREEN);
} //if green
} //while principal
} //void main
|
This is my code (states 2 and 3 without the time counter of 1000ms):
Code: |
#include <16F1828.h>
#fuses NOMCLR //Master Clear pin used for I/O
#fuses BORV25 //Brownout reset at 2.5V
#use FIXED_IO( A_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3,PIN_A4,PIN_A5 )
#use FIXED_IO( B_outputs=PIN_B4,PIN_B5,PIN_B6,PIN_B7 )
#use STANDARD_IO(C)
#use delay(internal=8MHz)
// DEFINE INPUT BUTTONS
#define BUTTON_1 PIN_C0
// DEFINE OUTPUT LEDS
#define LED_GREEN PIN_A0
int16 cont_green=0;
#int_timer2
void interm_green()
{
cont_green++;
if(cont_green==1600)
{
output_toggle(LED_GREEN);
cont_green=0;
}
}
//======================================================================
void main()
{
port_c_pullups(0xff);
output_a(0x00);
WHILE(true){
enable_interrupts(GLOBAL); //Habilita int. general
setup_timer_2(T2_DIV_BY_4,124,1);
if((input(BUTTON_1) == 0)){
char count; count = 0;
while(true){ //push-button pressed
if((input(BUTTON_1) == 0)) delay_ms(10); //debounce
if((input(BUTTON_1) == 0))
count++;
else
count = 0;
if(count == 1)
break; delay_ms(10);
}
while(true){ //push-button loosed
if (input(BUTTON_1)) delay_ms(10); //debounce
if(input(BUTTON_1))
count++;
else
count = 0;
if(count == 1)
break; delay_ms(30);
}
int8 a1;
if(a1==0){
a1=1;
enable_interrupts(INT_TIMER2);}
else {
a1=0;
disable_interrupts(INT_TIMER2);
output_low(LED_GREEN);}
} //if green
} //while principal
} //void main |
Thank you for your comments.
|
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 554 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Aug 20, 2019 12:54 pm |
|
|
Interesting topic. Years ago, I was creating show control for a haunted house attraction using VenueMagic software. Initially, the place was wired up with pressure mats that could be used to trigger sounds and effects in various rooms.
Later, they needed to have a way to start and stop the attraction from the entrance. We wired a button into a pressure mat and then did exactly this -- short presses (people just walking by) did one thing, and long presses (the operator holding down the button for several seconds) did another. We called it the "Apple approach" because we were doing a bunch of stuff with one button.
Clever, indeed. Great suggestions and discussion here. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ? |
|
|
MassaM
Joined: 08 Jun 2019 Posts: 31
|
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Tue Sep 24, 2019 10:06 am |
|
|
Just because it's an interesting topic, I wrote a code that does what Petar_2010 wants to achieve.
1_switch.h
Code: |
#include <18F46K22.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
//#FUSES NOMCLR
#device ICD=TRUE
#use delay(internal=4000000)
|
1_switch.c
Code: |
// LED is turned on with logical 0
// switch shorts to GND
#include <1_switch.h>
#define FOSC getenv("CLOCK") // Get PIC oscillator frequency
// check if it is below or equal to 20MHz
#if(FOSC < 21000000)
#define TIMER0_PRELOAD (256 - (FOSC/4/256/100))
#else
#error Oscillator frequency is too high: FOSC
#endif
#define ENTER_switch PIN_B0 // change to whatever suits you
#define LED PIN_C6
int8 ENTER_switch_is_down = FALSE;
int16 TimeCounter = 0; // measures the time switch is pressed
enum {WAIT_PRESS, SWITCH_PRESSED, LED_ON};
int8 Read_Key = WAIT_PRESS;
int1 Blink = 0;
int8 BlinkCounter = 0;
int8 _Short = 0;
// ****************************************************************************
void timer0_init(void)
{
setup_timer_0(T0_INTERNAL | T0_DIV_256 | T0_8_BIT);
set_timer0(TIMER0_PRELOAD);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
}
// ****************************************************************************
#INT_TIMER0 // fires every 10ms
void TIMER0_isr(void)
{
set_rtcc(TIMER0_PRELOAD); // set for next interrupt after 10ms
// debounce
// presumes that 0 is read when the switch is pressed
int8 active_state_ENTER;
int8 previous_state_ENTER; // declare variables
active_state_ENTER = input(ENTER_switch); // Read the button
if((previous_state_ENTER == 1) && (active_state_ENTER == 0)){
ENTER_switch_is_down = TRUE; // switch pressed, raise "ENTER PRESSED" flag
} // must be cleared in software
previous_state_ENTER = active_state_ENTER; // Save current value for next time
TimeCounter++;
BlinkCounter++;
if(BlinkCounter == 50){
BlinkCounter = 0;
Blink = !Blink; // set the LED blinking rate of 500ms
}
}
// ****************************************************************************
void main(){
timer0_init(); // init timer0 for 10ms interrupt
// it works much more reliable with external pull-up
port_b_pullups(true);
enable_interrupts(GLOBAL);
while(TRUE){
// do the switch
switch (Read_Key){
// ----------------------------------------------------------------------------
// wait for the switch to be pressed
case WAIT_PRESS:{
if(ENTER_switch_is_down){ // button pressed
ENTER_switch_is_down = 0; // clear flag
TimeCounter = 1; // 10ms already passed
Read_Key = SWITCH_PRESSED; // measure for how long the key is pressed
}
break;
}
// ----------------------------------------------------------------------------
// switch was pressed, measure for how long
case SWITCH_PRESSED:{ // measure the time of the press
if(input_state(ENTER_switch)){ // switch is off before 1s elapses
Read_Key = LED_ON;
_Short = 1; // indicate short press
}
else{
if(TimeCounter > 100){
Read_Key = LED_ON; // switch pressed for more than 1s
_Short = 0; // indicate long press
}
}
break;
}
// ----------------------------------------------------------------------------
case LED_ON:{ // light the LED the way it has to be and wait for another key press to quit
// was switch pressed again to reset everything??
if(ENTER_switch_is_down){
ENTER_switch_is_down = 0;
output_high(LED); // turn off the LED
Read_Key = WAIT_PRESS; // reset
break;
}
// short press, turn LED on
if(_Short){
output_low(LED);
}
// long press, blink LED 500ms on, 500ms off
else{
if(Blink){
output_low(LED);
}
else{
output_high(LED);
}
}
break;
}
// ------------------------- end cases ----------------------------------------
} // switch brace
} // while true brace
} // main brace
|
|
|
|
barbiani
Joined: 02 Feb 2013 Posts: 7
|
|
|
|
|
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
|