PIC 16F1503 LED TURN SIGNAL/BRAKE C PROGRAM flash rate

Discussion in 'Embedded Systems and Microcontrollers' started by pcbenthusiast, May 13, 2017.

  1. pcbenthusiast

    Thread Starter Member

    Mar 24, 2017
    62
    0
    Hi all,

    i wrote a c program that can take in left turn (RC0), right turn (RC1) & brake signal (RC2)inputs and put out flashing signal at RC3 (right/brake) and RC4 (left/brake). Basically this code works but i am not able to change the flash rate to be in between 60-120 flashes per minute. Right now, i can play around with internal oscillator & prescalar to get the flash rate to be at 60 or at 120 but not in between. i have a variable "counter1" which is at 1 right now, but when i change it to 2 it stop flashing all together. this makes me wonder if my code is checking for "counter1>=1" too many times inside the code. i am not using any hard interrupt (i am a beginner and i dont know how to). any help is appreciated or how to write interrupt will be useful if thats the way to go. i am attaching the c code.

    OSCCON = 0b01010000; //Oscillator set to 500kHZ
    OPTION_REG = 0b00000111; //prescalar 256
     
  2. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,530
    1,521
    That is a heck of a lot of code for a fairly simple function but that doesn't mean it can't work.

    Set the timer 0 prescaler to 2:1 so the timer overflows more often then look for counter1 to be 128 instead of 1. Then you can fine tune the flash cycle time by changing the 128 number. As that 128 number will occur at several places in your code it will make changes much easier if you set a variable to 128 and then use the variable in the rest of your code for the comparison with counter1. You will also need to look carefully at the places where you reset counter1.
     
  3. pcbenthusiast

    Thread Starter Member

    Mar 24, 2017
    62
    0
     
  4. pcbenthusiast

    Thread Starter Member

    Mar 24, 2017
    62
    0
    Sorry yeah the code is long because the code kinda repeats for the sub routines- left, right, left plus brake and right plus brake and when they are all off.

    So I was not able to change the counter1 to anything other than 1 but I did not try 128 yet. For some reason it only flashes when counter1 is 1... when o commented out all other subroutines except "left turn", I could change counter1 to any value I wanted and it flashed accordingly...
     
  5. pcbenthusiast

    Thread Starter Member

    Mar 24, 2017
    62
    0
    Did you mean set the counter1 to 128 in the #define statement ? Or did you mean it to be just under the main{}?
    As below
    Main{
    --
    --
    Int counter1=128;
    --
    }
     
  6. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,530
    1,521
    Don't set counter1. define a different variable to use for comparison with counter1 so you only have to change the value in one place.

    Either
    int CountLimit = 128
    or
    #define COUNT_LIMIT 128

    then in your code
    if (counter1 >= CountLimit)...
    or
    if (counter1 >= COUNT_LIMIT)...
     
  7. pcbenthusiast

    Thread Starter Member

    Mar 24, 2017
    62
    0
    wait, i already have a rocker switch for "left/right turn", i have a brake switch too. you're saying i need a 3rd switch? sorry i'm pretty new to parallel switch state logic..
     
  8. pcbenthusiast

    Thread Starter Member

    Mar 24, 2017
    62
    0
    i thought The reason that i'm having problems is that i check multiple times for counter1 to be greater than or equal to 1 throughout the main{ } routine. If i change one of them, then the others are still checking for 1. In one of them, counter1 is cleared out if the value is greater or equal to 1 so that would affect my check for a value of 2 in another location. i really need to have one one check for counter1. I was hoping to add an interrupt outside the main loop which will only contain flash rate and it can be called from within the main routine, anyone have idea how to implement this
     
  9. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,530
    1,521
    At the top of the loop put the check of the overflow timer (just once, here).
    If the flag is set, clear it and increment counter1.
    If the counter has reached the magic number (only the one check, here)
    then clear counter1 (only here) and then check left/right flash states.

    When finished all that, copy the state of the brake input pin to the brake LED. (doesn't need to have anything to do with turning)
     
  10. pcbenthusiast

    Thread Starter Member

    Mar 24, 2017
    62
    0
    Thanks AlbertHall, Would you mind checking the code i have rearranged below? i only did it for LEFT TURN. your suggestion is marked in BOLD & ITALICS. the code thats moved to top of the loop (did you mean top of the main loop or a new interrupt?) is in UNDERLINE.

    feel free to rearrange the code if its not proper if you will... thanks a lot for the help, i will compile it after you chec.


    /*
    * File: xxx.c
    * Author: xxx
    * Created on xxx
    */
    // PIC16F1503 Configuration Bit Settings

    // 'C' source line config statements

    //Configuration bit settings
    // CONFIG1
    #pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
    #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
    #pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
    #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
    #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
    #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

    // CONFIG2
    #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
    #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
    #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
    #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)

    #include <xc.h>


    void main(void)
    {
    ANSELC = 0; //analog select register takes analog input only by default. making the bits 0 connects it to digital/port registers. See page 103 of datasheet.
    TRISC = 0b00000111; // set port C-RC0 (left sw in),RC1 (right sw in),RC2 (brake sw in) as inputs and RC3 (right led out), RC4 (left led out)
    //OPTION_REGbits.PSA = 0; //prescalar assigned to timer 0
    //OPTION_REGbits.TMR0CS = 0; // instruction cycle to FOSC/4
    //OPTION_REGbits.PS = 0b111; // set prescalar to 256

    OSCCON = 0b01010000; //Oscillator set to 500kHZ
    OPTION_REG = 0b00000111; //prescalar 256
    int counter1 = 0;


    while(1)
    {

    if (INTCONbits.TMR0IF == 1) //check to see if timer rolled over
    {
    counter1++; //increment counter
    INTCONbits.TMR0IF = 0; // clear timer 0 flag
    if (counter1 >= 1) //counts 1- timer roll-overs


    {
    //ALL OFF
    if (PORTC == 0)
    {
    PORTCbits.RC3 = 0;
    PORTCbits.RC4 = 0;
    }
    //LEFT TURN SIGNAL

    if (PORTCbits.RC0 == 1)
    {
    PORTCbits.RC3 = 0;

    /* MOVED TO TOP
    if (INTCONbits.TMR0IF == 1) //check to see if timer rolled over
    {
    counter1++; //increment counter
    INTCONbits.TMR0IF = 0; // clear timer 0 flag

    }
    if (counter1 >= 1) //counts 1- timer roll-overs
    {
    MOVED TO TOP */


    if (PORTCbits.RC4 == 1) // if LED is on
    {
    PORTCbits.RC4 = 0; // turn LED off
    }
    else
    {
    PORTCbits.RC4 = 1; // otherwise turn it on
    }
    }
    }
    else
    {
    PORTCbits.RC4 = 0; // This will set C4 low if the input C0 is not high
    counter1 = 0;
    }


    //RIGHT TURN SIGNAL

    if (PORTCbits.RC1 == 1) //check to see if there is input voltage at RC0
    {
    PORTCbits.RC4 = 0;
    if (INTCONbits.TMR0IF == 1) //check to see if timer rolled over
    {
    counter1++; //increment counter
    INTCONbits.TMR0IF = 0; // clear timer 0 flag
    }
    if (counter1 >= 1) //counts 1- timer rollovers
    {

    if (PORTCbits.RC3 == 1) // if LED is on
    {
    PORTCbits.RC3 = 0; // turn LED off
    }
    else
    {
    PORTCbits.RC3 = 1; // otherwise turn it on
    }
    }
    }
    else
    {
    PORTCbits.RC3 = 0; // This will set C3 low if the input C0 is not high
    counter1 = 0;
    }



    //LEFT TURN & BRAKE SIGNAL
    if (PORTCbits.RC0 == 1 & PORTCbits.RC2 == 1) //check to see if there is input voltage at RC0

    {
    PORTCbits.RC3 = 1;
    if (INTCONbits.TMR0IF == 1) //check to see if timer rolled over
    {
    counter1++; //increment counter
    INTCONbits.TMR0IF = 0; // clear timer 0 flag
    }
    if (counter1 >= 1) //counts 1- timer roll-overs
    {
    counter1 = 0; //reset counter
    if (PORTCbits.RC4 == 1) // if LED is on
    {
    PORTCbits.RC4 = 0; // turn LED off
    }
    else
    {
    PORTCbits.RC4 = 1; // otherwise turn it on
    }
    }
    }
    else
    {
    counter1 = 0;
    }

    //RIGHT TURN & BRAKE SIGNAL
    if (PORTCbits.RC1 == 1 & PORTCbits.RC2 == 1) //check to see if there is input voltage at RC0
    //if (PORTC == 0b00000101)
    {
    PORTCbits.RC4 = 1;
    if (INTCONbits.TMR0IF == 1) //check to see if timer rolled over
    {
    counter1++; //increment counter
    INTCONbits.TMR0IF = 0; // clear timer 0 flag
    }
    if (counter1 >= 1) //counts 1- timer roll-overs
    {
    counter1 = 0; //reset counter
    if (PORTCbits.RC3 == 1) // if LED is on
    {
    PORTCbits.RC3 = 0; // turn LED off
    }
    else
    {
    PORTCbits.RC3 = 1; // otherwise turn it on
    }
    }
    }
    else
    {

    counter1 = 0;
    }

    //BRAKE SIGNAL

    //check to see if there is input voltage at RC2
    if (PORTCbits.RC2 == 1 & PORTCbits.RC0 == 0)

    {
    if (PORTCbits.RC2 == 1 & PORTCbits.RC1 == 0)
    {
    PORTCbits.RC3 = 1; // otherwise turn RIGHT LED on
    PORTCbits.RC4 = 1; // otherwise turn LEFT LED on

    } }

    }}
     
  11. pcbenthusiast

    Thread Starter Member

    Mar 24, 2017
    62
    0
    alberhall,

    Your method worked great! see the code below- i'm able to change the flash rate how ever i want now for left and right signals BUT the "left/brake" and "right/brake" are still iffy. whats happening is when left/brake is pressed, the Brake portion of leds stay solid while the left leds are bliking very subtly-can hardly see them and blinking fast. its although two signals are working at the same time-one asking it to blink, another asking it to turn off.... sometimes ALL THE LIGHTS stay solid, no blinking.... same with right/brake.. hope i didnt confuse you! I'M DEFINITELY glad the flash rate is flexible now! i have kept it at 2MHZ with 256 prescalar at counter1=3 giving me approx 0.8s flash rate


    #include <xc.h>


    void main(void)
    {
    ANSELC = 0; //analog select register takes analog input only by default. making the bits 0 connects it to digital/port registers. See page 103 of datasheet.
    TRISC = 0b00000111; // set port C-RC0 (left sw in),RC1 (right sw in),RC2 (brake sw in) as inputs and RC3 (right led out), RC4 (left led out)
    OSCCON = 0b01100000; //Oscillator set to 2MHZ
    OPTION_REG = 0b00000111; //prescalar 256
    int counter1;
    int CountLimit = 3;
    TMR0IF = 0;


    while(1)
    {

    if (INTCONbits.TMR0IF == 1) //check to see if timer rolled over
    {
    counter1++; //increment counter
    INTCONbits.TMR0IF = 0; // clear timer 0 flag
    if (counter1 >= CountLimit) //counts 1- timer roll-overs
    {

    //ALL OFF

    if (PORTC == 0)
    {
    PORTCbits.RC3 = 0;
    PORTCbits.RC4 = 0;
    }

    //LEFT TURN SIGNAL

    if (PORTCbits.RC0 == 1)
    {
    PORTCbits.RC3 = 0;
    counter1 = 0; //reset counter
    if (PORTCbits.RC4 == 1) // if LED is on
    {
    PORTCbits.RC4 = 0; // turn LED off
    }
    else
    {
    PORTCbits.RC4 = 1; // otherwise turn it on
    }}
    else
    {
    PORTCbits.RC4 = 0; // This will set C4 low if the input C0 is not high
    }

    //RIGHT TURN SIGNAL


    if (PORTCbits.RC1 == 1) //check to see if there is input voltage at RC0
    {
    PORTCbits.RC4 = 0;
    counter1 = 0; //reset counter
    if (PORTCbits.RC3 == 1) // if LED is on
    {
    PORTCbits.RC3 = 0; // turn LED off
    }
    else
    {
    PORTCbits.RC3 = 1; // otherwise turn it on
    }

    }
    else
    {
    PORTCbits.RC3 = 0; // This will set C3 low if the input C0 is not high
    }

    //LEFT TURN & BRAKE SIGNAL

    if (PORTCbits.RC0 == 1 & PORTCbits.RC2 == 1) //check to see if there is input voltage at RC0
    {
    PORTCbits.RC3 = 1;
    counter1 = 0; //reset counter
    if (PORTCbits.RC4 == 1) // if LED is on
    {
    PORTCbits.RC4 = 0; // turn LED off
    }
    else
    {
    PORTCbits.RC4 = 1; // otherwise turn it on
    }
    }

    //RIGHT TURN & BRAKE SIGNAL

    if (PORTCbits.RC1 == 1 & PORTCbits.RC2 == 1) //check to see if there is input voltage at RC0
    {
    PORTCbits.RC4 = 1;
    counter1 = 0;
    if (PORTCbits.RC3 == 1) // if LED is on
    {
    PORTCbits.RC3 = 0; // turn LED off
    }
    else
    {
    PORTCbits.RC3 = 1; // otherwise turn it on
    }
    }

    //BRAKE SIGNAL

    if (PORTCbits.RC2 == 1 & PORTCbits.RC0 == 0) //check to see if there is input voltage at RC2
    {
    if (PORTCbits.RC2 == 1 & PORTCbits.RC1 == 0)
    {
    PORTCbits.RC3 = 1; // otherwise turn RIGHT LED on
    PORTCbits.RC4 = 1; // otherwise turn LEFT LED on

    } }

    }}}}
     
  12. MMcLaren

    Distinguished Member

    Feb 14, 2010
    837
    158
    Any chance you can show us a schematic of your circuit, please?
     
Loading...