PIC 16F877A traffic system

Thread Starter

Aamil

Joined Jan 2, 2015
23
I just pasted your code into MPLAB (with the additions noted above) . I saw exactly what you describe, after soon after RA2 turns on the watchdog timer expires. The watchdog will reset your PIC so the code starts all over so the observed sequence is RA0,RA1, RA2, RA0,RA1, RA2, and so on.

The fix for this was noted above, either turn the watchdog timer off, or reset it after each of the long delays using the "CLRWDT();" command you will find in the XC8 User's Guide.

Once you fix the watchdog you should see all 4 LEDs light.

Note the last state for all off has no delay so you will never see that happen.

Also note that "ADCON1=7;" is completely correct code. The default radix in C is base 10, so 7 is a binary 00000111. That is a bit different than the 00001111 posted.
Erniem,

I have turned the WDT off in configuration as in post #16... I still observe the issues as described in the post #16
 

Thread Starter

Aamil

Joined Jan 2, 2015
23
That makes sense, look at what
ADCON1 = 0b00001111;
does by looking, again, on page 128 in the datasheet. It commandeers the I/O function.
I think I should use ADCON1 = 0b00000111;

I read that I can also use ADCON1= 7;


Thats what I understood from page 128.. Correct me if I am wrong..
 

ErnieM

Joined Apr 24, 2011
8,377
It seems the code from post #16 gets the watchdog cleared, just fix the ADCON1 and it should work. Either way you wrote it in post #23 will work fine.
 
Last edited:

tshuck

Joined Oct 18, 2012
3,534
I think I should use ADCON1 = 0b00000111;

I read that I can also use ADCON1= 7;


Thats what I understood from page 128.. Correct me if I am wrong..
That is correct, however, 0b00000111 = 7. Since the compiler will default to a decimal notation for just "7", either will work.
 

ke5nnt

Joined Mar 1, 2009
384
ErnieM said:
Also note that "ADCON1=7;" is completely correct code. The default radix in C is base 10, so 7 is a binary 00000111. That is a bit different than the 00001111 posted.
Thanks for clearing that up Ernie. I'm not used to seeing registers defined in decimal form, so that bit caused me some confusion.

tshuck said:
That makes sense, look at what
ADCON1 = 0b00001111;
does by looking, again, on page 128 in the datasheet. It commandeers the I/O function.
You are correct. Lower nibble should be 0111, not 1111 as I originally stated. The initial "ADCON1 = 7;" will in fact work. My apologies for stating that wrong the first go through.

Aamil: The others are correct. Your watchdog is disabled now, correcting the mistake on the ADCON1 register should fix the issue you're having. Sorry for pointing you in the wrong direction initially.
 
Last edited:

Thread Starter

Aamil

Joined Jan 2, 2015
23
Thanks for clearing that up Ernie. I'm not used to seeing registers defined in decimal form, so that bit caused me some confusion.



You are correct. Lower nibble should be 0111, not 1111 as I originally stated. The initial "ADCON1 = 7;" will in fact work. My apologies for stating that wrong the first go through.

Aamil: The others are correct. Your watchdog is disabled now, correcting the mistake on the ADCON1 register should fix the issue you're having. Sorry for pointing you in the wrong direction initially.
Thanks all..Let me work through it...I have not tested it yet..I will update u all
 

Thread Starter

Aamil

Joined Jan 2, 2015
23
Dear all.

I was trying to drive 8 LEDs (4 pairs of Red and green ) for a traffic system.
I am using the following pins

Lane 1: RA0-Red, RA1-Green
Lane 2: RA2-Red, RA3-Green
Lane 3: RB1-Red, RB2-Green
Lane 4: RB4-Red, RB5-Green

I can drive all 8 LEDs one at a time . But I cannot drive Green and Red LEDs together as in below steps

Step 1: Green-Red-Red-Red
Step 2: Red-Green-Red-Red
Step 3: Red-Red-Green-Red
Step 4: Red-Red-Red-Green​

When I use following code, it goes through all four steps . But only Red LEDs are turning ON. Green is not working at all.
What will be the reason?

Code:
/*

#include <stdio.h>
#include <stdlib.h>

#define _XTAL_FREQ 2000000
#include <xc.h>

// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//END CONFIG

void main(void)
{
    TRISA = 0b00000000; //RA0 as Output PIN
    TRISB = 0b00000000; //RB0 as Output PIN
    PORTA=  0b00000000;
    PORTB=  0b00000000;
    ADCON1 = 0b00000111; // ADC disabled

  while(1)
  {

      // Lane 1: RA0-Red, RA1-Green
      // Lane 2: RA2-Red, RA3-Green
      // Lane 3: RB1-Red, RB2-Green
      // Lane 4: RB4-Red, RB5-Green

     
// Step 1: Green-Red-Red-Red
  RA0=0; //Red
  RA1=1; //Green ON
  RA2=1; //Red ON
  RA3=0; //Green
  RB1=1; //Red ON
  RB2=0; //Green
  RB4=1; //Red ON
  RB5=0; //Green
   __delay_ms(10000); // 1 Second Delay
   CLRWDT();
   // Step 2: Red-Green-Red-Red
  RA0=1; //Red ON
  RA1=0; //Green
  RA2=0; //Red
  RA3=1; //Green ON
  RB1=1; //Red ON
  RB2=0; //Green
  RB4=1; //Red ON
  RB5=0; //Green
 
    __delay_ms(10000); // 1 Second Delay
    CLRWDT();
//Step 3: Red-Red-Green-Red
  RA0=1; //Red ON
  RA1=0; //Green
  RA2=1; //Red ON
  RA3=0; //Green
  RB1=0; //Red
  RB2=1; //Green ON
  RB4=1; //Red ON
  RB5=0; //Green

    __delay_ms(10000); // 1 Second Delay
    CLRWDT();

    //Step 4:Red-Red-Red-Green
  RA0=0; //Red ON
  RA1=1; //Green
  RA2=1; //Red
  RA3=0; //Green ON
  RB1=1; //Red
  RB2=0; //Green
  RB4=1; //Red ON
  RB5=0; //Green

    __delay_ms(10000); // 1 Second Delay
    CLRWDT();




  }
}
When I use the above code, it goes through all four steps . But only Red LEDs are turning ON. Green is not turning on at all.
Your help is really appreciated
 

Thread Starter

Aamil

Joined Jan 2, 2015
23
I am using 5V from DC supply... LEDs are connected to ground using 1K resistor (considering 4 LEDs will be ON at a time ).
So the connection is ... PIC port -> LEDs -> Resistor -> Gnd
 

JohnInTX

Joined Jun 26, 2012
4,787
Consider writing your ports as a complete byte instead of flipping individual bits (disconnect any other outputs on PORTA/B for now):
Code:
//Step 1
PORTA = 0b 0000 0110; // spaces to show port connections only - remove to compile..
PORTB = 0b 00 01 0 01 0;
_delay_ms(10000);

//Step 2
PORTA = 0b00001001;
PORTB = 0b00010010;
_delay_ms(10000);

//Step 3
PORTA = 0b00000101;
PORTB = 0b00010101;
_delay_ms(10000);

//Step 4
PORTA = 0b00000110;
PORTB = 0b00010010;
_delay_ms(10000);
If that works, read the previous posts in this thread about shadowing your output ports to avoid a possible r-m-w problem.

Good luck!
 

tshuck

Joined Oct 18, 2012
3,534
I am using 5V from DC supply... LEDs are connected to ground using 1K resistor (considering 4 LEDs will be ON at a time ).
So the connection is ... PIC port -> LEDs -> Resistor -> Gnd
Do you mean one resistor per LED, or are you meaning one resistor for multiple LEDs?
 

Thread Starter

Aamil

Joined Jan 2, 2015
23
Consider writing your ports as a complete byte instead of flipping individual bits (disconnect any other outputs on PORTA/B for now):
Code:
//Step 1
PORTA = 0b 0000 0110; // spaces to show port connections only - remove to compile..
PORTB = 0b 00 01 0 01 0;
_delay_ms(10000);

//Step 2
PORTA = 0b00001001;
PORTB = 0b00010010;
_delay_ms(10000);

//Step 3
PORTA = 0b00000101;
PORTB = 0b00010101;
_delay_ms(10000);

//Step 4
PORTA = 0b00000110;
PORTB = 0b00010010;
_delay_ms(10000);
If that works, read the previous posts in this thread about shadowing your output ports to avoid a possible r-m-w problem.

Good luck!
Thanks for your support :) The problem was only resistors
 

Thread Starter

Aamil

Joined Jan 2, 2015
23
Folks..Traffic system worked ..:)
I gave individual resistors to each of 8 LEDs and it worked fine :) Thanks for your support..

But my project is a remote controlled traffic System

I have to RF remote control this traffic system.. that means.. I should be able to turn any lane green with a press of switch. (4 switches for 4 lanes..)..

Switch 1 pressed - Turn Lane 1 Green and all other lanes red
Switch 2 pressed - Turn Lane 2 Green and all other lanes red
Switch 3 pressed - Turn Lane 3 Green and all other lanes red
Switch 4 pressed - Turn Lane 4 Green and all other lanes red

Do you guys have any suggestions on how to implement this?:rolleyes::rolleyes:
 
Last edited:

tshuck

Joined Oct 18, 2012
3,534
I used one resistor for multiple LEDs. Does that matter?
Yes, the green LEDs have a higher forward voltage (Vf), which, when in parallel with a red LED of a lower Vf, will never light up, as you've seen.

Glad you figured it out, though! :)

[...]But my project is a remote controlled traffic System[...]
What are you going to control it with? A computer? Will you write the program to interface with it? A handheld remote? Will you build it?

There are many RF modules out there and many can work with your system.
 

Thread Starter

Aamil

Joined Jan 2, 2015
23
Thanks for the explanation on green and Red LED paralleling :)
Yes, the green LEDs have a higher forward voltage (Vf), which, when in parallel with a red LED of a lower Vf, will never light up, as you've seen.

Glad you figured it out, though! :)

What are you going to control it with? A computer? Will you write the program to interface with it? A handheld remote? Will you build it?

There are many RF modules out there and many can work with your system.
I am planning with RF remote (4 button). How do I write the interrupt routine :rolleyes::rolleyes::rolleyes: I have not written any interrupt codes yet
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
I am planning with RF remote (4 button). How do I write the interrupt routine :rolleyes::rolleyes::rolleyes: I have not written any interrupt codes yet
See if you really need to use an interrupt. Your controller has nothing else to do until it is told a new traffic pattern, so why not just check the inputs over and over? Using an interrupt just means you can spend more time in a loop that does nothing.

If you still insist on using an interrupt I would start with reading the compiler's manual on how it expects interrupts to work, thinking it over, then asking questions here.

Those questions should get their own thread, turning on LEDs and interrupt service routines don't fit in the same box.
 

Thread Starter

Aamil

Joined Jan 2, 2015
23
See if you really need to use an interrupt. Your controller has nothing else to do until it is told a new traffic pattern, so why not just check the inputs over and over? Using an interrupt just means you can spend more time in a loop that does nothing.

If you still insist on using an interrupt I would start with reading the compiler's manual on how it expects interrupts to work, thinking it over, then asking questions here.

Those questions should get their own thread, turning on LEDs and interrupt service routines don't fit in the same box.
I was planning to check inputs over and over. But i felt it complicated. As you mentioned, interrupt was prefered to spend more time in loop and for immediate response.
As you suggested, checking 4 inputs every time and jumping to the corresponding lane is also possible.. Let me try..
 

tshuck

Joined Oct 18, 2012
3,534
Thanks for the explanation on green and Red LED paralleling :)


I am planning with RF remote (4 button). How do I write the interrupt routine :rolleyes::rolleyes::rolleyes: I have not written any interrupt codes yet
You are getting ahead of yourself. You need to find a transmitter module, then write the method of communicating with it. Have you found one?

I am of a different opinion from Ernie - I think interrupts should be used. At the very least, they allow your main code to scale while maintaining the functionality the interrupt handles. Since we don't know what the end goal looks like, I would go with interrupts, but that's me.

Either way, you'll need to pick your transmitter before you can write code for it.
 
Top