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

Semaphore with push button for pedestrians

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



Joined: 13 Jul 2014
Posts: 2

View user's profile Send private message

Semaphore with push button for pedestrians
PostPosted: Sun Jul 13, 2014 11:44 am     Reply with quote

Hello everyone. I have a school project where the objective is to make semaphore. The semaphore is working ok, however I've been having problems with the interrupts that I'm using for the push buttons, which are needed for the pedestrians. Here is the code:

Code:
#include <16F887.h>

#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)
#define BOT1 pin_B0
#define CARRED1 pin_C1
#define CARYELLOW1 pin_C2
#define CARGREEN1 pin_C3
#define PEDRED1 pin_D1
#define PEDGREEN1 pin_D2

#define BOT2 pin_B4
#define CARRED2 pin_C5
#define CARYELLOW2 pin_D0
#define CARGREEN2 pin_D5
#define PEDRED2 pin_D4
#define PEDGREEN2 pin_D3


#int_ext
void ext_isr()
{

if (input(pin_b0)==0)
{
output_low (PEDRED1);
output_high (PEDGREEN1);
output_high (CARRED1);
output_low (CARYELLOW1);
output_low (CARGREEN1);
output_high (PEDRED2);
output_low (PEDGREEN2);
output_low (CARRED2);
output_low (CARYELLOW2);
output_high (CARGREEN2);
delay_ms(8000);
}
}
#use delay (clock=20000000)

#int_rb
void rb_isr()
{

if (input(pin_b4)==0)
{

output_high (PEDRED1);
output_low (PEDGREEN1);
output_low (CARRED1);
output_low (CARYELLOW1);
output_high (CARGREEN1);
output_low (PEDRED2);
output_high (PEDGREEN2);
output_high (CARRED2);
output_low (CARYELLOW2);
output_low (CARGREEN2);
delay_ms(8000);
}
}

#use delay (clock=20000000)
void main ()
{
 port_b_pullups(TRUE);
enable_interrupts(int_ext);
enable_interrupts(int_rb);
ext_int_edge(H_to_L);

enable_interrupts(GLOBAL);



set_tris_b(0x11);
set_tris_c(0x00);
set_tris_d(0x00);

while (TRUE)
{


output_high (PEDRED1);
output_low (PEDGREEN1);
output_high (CARRED1);
output_low (CARYELLOW1);
output_low (CARGREEN1);
output_high (PEDRED2);
output_low (PEDGREEN2);
output_high (CARRED2);
output_low (CARYELLOW2);
output_low (CARGREEN2);
delay_ms(2000);

output_high (PEDRED1);
output_low (PEDGREEN1);
output_low (CARRED1);
output_low (CARYELLOW1);
output_high (CARGREEN1);
output_low (PEDRED2);
output_high (PEDGREEN2);
output_high (CARRED2);
output_low (CARYELLOW2);
output_low (CARGREEN2);
delay_ms(2000);


output_high (PEDRED1);
output_low (PEDGREEN1);
output_low (CARRED1);
output_high (CARYELLOW1);
output_low (CARGREEN1);
output_low (PEDRED2);
output_high (PEDGREEN2);
output_high (CARRED2);
output_low (CARYELLOW2);
output_low (CARGREEN2);
delay_ms(2000);


output_low (PEDRED1);
output_high (PEDGREEN1);
output_high (CARRED1);
output_low (CARYELLOW1);
output_low (CARGREEN1);
output_high (PEDRED2);
output_low (PEDGREEN2);
output_low (CARRED2);
output_low (CARYELLOW2);
output_high (CARGREEN2);
delay_ms(2000);

output_low (PEDRED1);
output_high (PEDGREEN1);
output_high (CARRED1);
output_low (CARYELLOW1);
output_low (CARGREEN1);
output_high (PEDRED2);
output_low (PEDGREEN2);
output_low(CARRED2);
output_high (CARYELLOW2);
output_low (CARGREEN2);
delay_ms(2000);

}



}


Last edited by olimathus on Sun Jul 13, 2014 12:12 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Jul 13, 2014 11:57 am     Reply with quote

Two things:

Debounce.

Delays in the ISR.

Now the first problem is that switches don't produce nice clean 'on/off' pulses. They will often make several times. You don't want to accepts a single 'I am on' edge. This could be caused by somebody holding the button a long time, then releasing it and generating another set of these edges....

Then you have massive delays in the ISR.

Rethink.

Have a single 'tick' interrupt. A timer running out at perhaps 50* per second.
Then just test the buttons in this.
If a button is seen to be 'on', record this fact and exit.
If a timer is seen 'on', and has already been recorded as on, then accept it.
Cancel the recording whenever a button is off.

This way the button has to be 'on' and stable for two successive interrupts.

Then don't do your pedestrian sequences in the ISR. Instead use a 'state machine' in the main code - I suggest using an enum for the names of the states, and using a switch...case with this, so you have states like 'pedestrian_stop' etc..
Do the timings, by using a counter updated in the same tick. Have the tick code use:
Code:

//global variable
int16 wait=0;
#define SECS 50 //assuming the ISR is 50Hz

//Then in the ISR
   if (wait)
      --wait;

//Then in the main
   //to delay 5 seconds
   wait=SECS*5;

   while(wait); //Whatever code is here will execure for 5 seconds


I suspect you have seen where you can use multiple #use delay declarations to allow delays in an ISR, without interrupts being disabled in the main. True, but it is still c&*p programming, unless necessary, and won't solve the problems with the approach....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 13, 2014 12:02 pm     Reply with quote

You appear to have buttons on pins B0 and B4. I assume 'BOT' means
a button ? You didn't tell us.
Quote:

#define BOT1 pin_B0
#define CARRED1 pin_C1
#define CARYELLOW1 pin_C2
#define CARGREEN1 pin_C3
#define PEDRED1 pin_D1
#define PEDGREEN1 pin_D2

#define BOT2 pin_B4
#define CARRED2 pin_C5
#define CARYELLOW2 pin_D0
#define CARGREEN2 pin_D5
#define PEDRED2 pin_D4
#define PEDGREEN2 pin_D3


But then in your isr code, you are checking B0 and B1 (not B0 and B4).
What are the true connections for your buttons ?
Quote:

#int_ext
void ext_isr()
{

if (input(pin_b0)==0)
{
.
.
.
output_low (CARYELLOW2);
output_high (CARGREEN2);
delay_ms(8000);
}
}
#use delay (clock=20000000)

#int_rb
void rb_isr()
{

if (input(pin_b1)==0)
{
.
.
.
output_high (PEDRED1);
delay_ms(8000);
}
}
olimathus



Joined: 13 Jul 2014
Posts: 2

View user's profile Send private message

PostPosted: Sun Jul 13, 2014 12:11 pm     Reply with quote

PCM programmer wrote:
You appear to have buttons on pins B0 and B4. I assume 'BOT' means

Yes. BOT is for button

Quote:

But then in your isr code, you are checking B0 and B1 (not B0 and B4).
What are the true connections for your buttons ?

the buttons are in b4 and b0. My mistake, sorry
Mike Walne



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

View user's profile Send private message

PostPosted: Sun Jul 13, 2014 2:51 pm     Reply with quote

A few comments.

Please don't edit code after you've had replies.
The replies no longer make sense, the rest of us can't then follow the thread.

You've got a #use delay AFTER you've tried to use it.
Can't be good news, will probably confuse the compiler or produce strange results.

Indent your code to make it more readable.
As a guide, position each closing } below its opening {.

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jul 13, 2014 4:13 pm     Reply with quote

just a comment...
I find it easier to have 'same length ' variables if possible.
Using GRN for green and YEL for yellow makes them the same as RED for ,well red !
It's just a bit easier on my aging eyes and looks 'neater'.

also
you may have to read the entire PORTB inside the ISR to clear it.I can't be sure, not near the 'testPC' to confirm/deny but it sticks in my head that it's needed.

others will KNOW for sure !!

also when I did 'traffic light' programs(30 years ago !, when Motorola had a 1bit processor) we used NS for the 'north-south' lights, EW for the 'east-west' lights. It might have been a 'traffic standard' back then.It did make it easier to understand when we got into the 'real world'.


hth
jay
Mike Walne



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

View user's profile Send private message

Re: Semaphore with push button for pedestrians
PostPosted: Sun Jul 13, 2014 5:10 pm     Reply with quote

olimathus wrote:
Hello everyone. I have a school project where the objective is to make semaphore. The semaphore is working ok, however I've been having problems with the interrupts that I'm using for the push buttons, which are needed for the pedestrians. Here is the code:
Code:

set_tris_b(0x11);
set_tris_c(0x00);
set_tris_d(0x00);


Also

You do not generally need set_tris, the CCS compiler takes care of I/Os better than you.
You have neither explained exactly what you expect your code to do, nor what you perceive the real problem to be.
At this stage we are all having to second guess what's in your head.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Jul 14, 2014 12:40 am     Reply with quote

This is where a 'what has to happen' list comes in.

What seems to be attempted to be done, is far too simple for anything even approaching 'real'. Normally car lights have to go 'stop', and then a little later the pedestrian lights go green. As it stands the lights all change together, which given that cars take time to stop, would be pretty certain to lead to accidents.
Real sequence would have to be something like:

Car green
Wait for button pressed.
Car lights go red
Wait two seconds
Pedestrian lights go green
Beeper starts
Wait eight seconds
Pedestrian lights go off
Beeper stops
Wait two seconds
Pedestrian lights go red
Car lights go amber
Wait two seconds
Car lights go green

This is the sort of sequence used in the UK (times are very wrong), where there is an 'allowance' time, with cars allowed to progress under 'amber', if there is nobody on the crossing, and pedestrians are not allowed to start crossing.

In the real world there is more to it, with the button not simply starting the sequence, but measurements on the traffic, and how recently the button was last pushed, also being taken into account.

So start with such a list. The actual sequence wanted, and how it progresses.

As I've already said, this sequence should really be coded in the main. This way you can't have a situation where you are halfway through going to the car green state, and a button push immediately intercepts it. Instead the state has to be in the 'car green' mode, before a button is accepted.
Then the key debounce has to be handled, before a button is accepted.
It's worth realising that the keys on your keyboard have a debounce like this, which is why they actually work the way you expect. Without this 'oddities' will be the norm....
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