Author Topic: i want to blink LED in reverse order  (Read 4370 times)

0 Members and 1 Guest are viewing this topic.

Offline ect_09Topic starter

  • Contributor
  • Posts: 17
i want to blink LED in reverse order
« on: October 31, 2014, 06:43:21 am »
Hi;
i want to reverse the code as it complete first time.
for example
pin 1-pin 2-pin 3-pin 4 (its somplete)
now it should run as
pin 4-pin 3-pin 2-pin 1

i write this code but its not working in reverse order.please guide me in this way.

Code: [Select]
#include<htc.h>

__CONFIG(1,OSCSDIS & HSPLL);
__CONFIG(2,BORDIS & PWRTDIS &WDTDIS);
__CONFIG(3,CCP2RC1);
__CONFIG(4,LVPDIS & STVREN);
__CONFIG(5,UNPROTECT);
__CONFIG(6,WRTEN);
__CONFIG(7,TRU);

#define _XTAL_FREQ   40000000


void delay_sec(unsigned char seconds)    // This function provides delay in terms of seconds
{
    unsigned char i,j;

    for(i=0;i<seconds;i++)
        for(j=0;j<100;j++)
            __delay_ms(10);
}
void led_display(char a)
{
switch(a)

{
case 0: PORTB=0x01;PORTD=0x08;  break;
case 1: PORTB=0x02;PORTD=0x04;  break;
case 2: PORTB=0x04;PORTD=0x02;  break;
case 3: PORTB=0x08;PORTD=0x01;  break;
}
}
void main()
{
   
TRISB=0x00;
TRISD=0x00;
char a,b;

while(1)
{
led_display(a);

a++;
delay_sec(1);
if(a==4)
{
a--;
}


}

}

am newbie with C . please correct my code :)
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: i want to blink LED in reverse order
« Reply #1 on: October 31, 2014, 07:23:34 am »
In main, you need to initialize a before you enter the loop and you don't need b, also you need a direction, and when you reach the end you need to reverse the direction and when you reach the first one you need to change the direction again.

This should do what you want, I kept it simple but you can use a += dir;
Also you can use if (!a) for comparing to 0.
also dir *= -1 will reverse direction
and other things you can try, but that main will do what you want.

Code: [Select]
void main()
{
  TRISB=0x00;
  TRISD=0x00;
  // initialize led
  char a = 0;
  // define direction
  char dir = 1;

  while(1)
  {
    led_display(a);

    a = a + dir; // increment or decrement depending on direction

    delay_sec(1);

    if(a==4)
    {
      dir = -1;
      // Edit: adjust index to be 3 so that the last LED will light up again.
      // change to a = 2 if you don't want the last LED to stay on for double
      // the amount of time as the rest.
      a--; 
    }
    if(a==-1)
    {
      dir = 1;
      // Edit: adjust index to 0 so the first LED  will light up again.
      // change to a = 1 if you don't want the first LED to stay on for double
      // the amount of time as the rest.
      a++;
    }
  }
}


But if you were doing PWMs and on a different chip (PSoC 4 in my case) and using interrupts instead of delays etc, this will do like a ping pong effect across 8 leds by bouncing an dark LED from one end to the other. Kind of like the Knight Rider TV show KITT but in reverse when only one dark spot moves around instead of a bright one. But because of the PWM it transitions in between LEDs so it looks continuous to your eye.

Code: [Select]
#include <project.h>

#define BRIGHTNESS_DECREASE         (1024u)

uint16 curPos;

static int direction = 1;
CY_ISR(InterruptHandler)
{
    // Clear TC Interrupt
    PWM_INTERRUPT_REQ_REG = PWM_INTR_MASK_TC;
   
    if (direction > 0)
    {
        PWM_COMP_CAP_REG = ((PWM_COMP_CAP_REG + BRIGHTNESS_DECREASE) & PWM_16BIT_MASK);
    }
    else
    {
        PWM_COMP_CAP_REG = ((PWM_COMP_CAP_REG - BRIGHTNESS_DECREASE) & PWM_16BIT_MASK);
    }
}

CY_ISR(InterruptHandler_1)
{
    // Clear TC Interrupt
    PWM_1_INTERRUPT_REQ_REG = PWM_1_INTR_MASK_TC;

    if (direction > 0)
    {
        PWM_1_COMP_CAP_REG = ((PWM_1_COMP_CAP_REG + BRIGHTNESS_DECREASE) & PWM_1_16BIT_MASK);
    }
    else
    {
        PWM_1_COMP_CAP_REG = ((PWM_1_COMP_CAP_REG - BRIGHTNESS_DECREASE) & PWM_1_16BIT_MASK);
    }
}

CY_ISR(InterruptHandler_2)
{
    // Clear TC Interrupt
    PWM_2_INTERRUPT_REQ_REG = PWM_2_INTR_MASK_TC;
   
    if (direction > 0)
    {
        PWM_2_COMP_CAP_REG = ((PWM_2_COMP_CAP_REG + BRIGHTNESS_DECREASE) & PWM_2_16BIT_MASK);
    }
    else
    {
        PWM_2_COMP_CAP_REG = ((PWM_2_COMP_CAP_REG - BRIGHTNESS_DECREASE) & PWM_2_16BIT_MASK);
    }
}

CY_ISR(InterruptHandler_3)
{
    // Clear TC Interrupt
    PWM_3_INTERRUPT_REQ_REG = PWM_3_INTR_MASK_TC;
     
    if (direction > 0)
    {
        PWM_3_COMP_CAP_REG = ((PWM_3_COMP_CAP_REG + BRIGHTNESS_DECREASE) & PWM_3_16BIT_MASK);
    }
    else
    {
        PWM_3_COMP_CAP_REG = ((PWM_3_COMP_CAP_REG - BRIGHTNESS_DECREASE) & PWM_3_16BIT_MASK);
    }
}

CY_ISR(InterruptHandler_4)
{
    uint16 input1, input2;
    // Clear TC Interrupt
    PWM_4_ReadStatusRegister();
   
    input1 = PWM_4_ReadCompare1();
    input2 = PWM_4_ReadCompare2();
    if (direction > 0)
    {
        PWM_4_WriteCompare1(input1 + BRIGHTNESS_DECREASE);
    }
    else
    {
        PWM_4_WriteCompare1(input1 - BRIGHTNESS_DECREASE);
    }
    if (direction > 0)
    {
        PWM_4_WriteCompare2(input2 + BRIGHTNESS_DECREASE);
    }
    else
    {
        PWM_4_WriteCompare2(input2 - BRIGHTNESS_DECREASE);
    }
}

CY_ISR(InterruptHandler_5)
{
    uint16 input1, input2;
    // Clear TC Interrupt
    PWM_5_ReadStatusRegister();
   
    input1 = PWM_5_ReadCompare1();
    input2 = PWM_5_ReadCompare2();
    if (direction > 0)
    {
        PWM_5_WriteCompare1(input1 + BRIGHTNESS_DECREASE);
    }
    else
    {
        PWM_5_WriteCompare1(input1 - BRIGHTNESS_DECREASE);
    }
    if (direction > 0)
    {
        if (((input2 + BRIGHTNESS_DECREASE)&0xFFFFu) < input2)
            direction = -1;
        else
            PWM_5_WriteCompare2(input2 + BRIGHTNESS_DECREASE);
    }
    else
    {
        if(((input2-BRIGHTNESS_DECREASE)&0xFFFFu) > input2)
            direction = 1;
        else
            PWM_5_WriteCompare2(input2 - BRIGHTNESS_DECREASE);
    }
}

int main()
{
    CyDelay(50u);
   
    // Enable the global interrupt
    CyGlobalIntEnable;
 
    // Enable the Interrupt component connected to interrupt
    TC_ISR_StartEx(InterruptHandler);
    TC_ISR_1_StartEx(InterruptHandler_1);
    TC_ISR_2_StartEx(InterruptHandler_2);
    TC_ISR_3_StartEx(InterruptHandler_3);
    TC_ISR_4_StartEx(InterruptHandler_4);
    TC_ISR_5_StartEx(InterruptHandler_5);
   
    // Start the components
    PWM_Start();
    PWM_1_Start();
    PWM_2_Start();
    PWM_3_Start();
    PWM_4_Start();
    PWM_5_Start();
    // Set periods
    PWM_WritePeriod(65535u);
    PWM_1_WritePeriod(65535u);
    PWM_2_WritePeriod(65535u);
    PWM_3_WritePeriod(65535u);
    PWM_4_WritePeriod(65535u);
    PWM_5_WritePeriod(65535u);

    // Init dual PWMs
    PWM_WriteCompare(BRIGHTNESS_DECREASE-1u);
    PWM_1_WriteCompare(8192u+(BRIGHTNESS_DECREASE-1u));
    PWM_2_WriteCompare(2*8192u+(BRIGHTNESS_DECREASE-1u));
    PWM_3_WriteCompare(3*8192u+(BRIGHTNESS_DECREASE-1u));
    PWM_4_WriteCompare1(4*8192u+(BRIGHTNESS_DECREASE-1u));
    PWM_4_WriteCompare2(5*8192u+(BRIGHTNESS_DECREASE-1u));
    PWM_5_WriteCompare1(6*8192u+(BRIGHTNESS_DECREASE-1u));
    PWM_5_WriteCompare2(7*8192u+(BRIGHTNESS_DECREASE-1u));

    for(;;)
    {
       
    }
}


« Last Edit: October 31, 2014, 07:59:12 am by miguelvp »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: i want to blink LED in reverse order
« Reply #2 on: October 31, 2014, 08:05:32 am »
A little revision.

Code: [Select]
void main()
{
  TRISB=0x00;
  TRISD=0x00;
  // initialize led (we pre-increment/decrement so -1 on a positive direction will end up as 0)
  char a = -1;
  // define direction, 1 forward, -1 backwards.
  char dir = 1;

  while(1)
  {
    // increment or decrement depending on direction
    a += dir;

    led_display(a);

    delay_sec(1);

    // reverse direction if we reach either the last LED (3) or the 1st one (0)
    if ((a==0)||(a==3))
    {
        dir *= -1;
    }
  }
}
 

Offline ect_09Topic starter

  • Contributor
  • Posts: 17
Re: i want to blink LED in reverse order
« Reply #3 on: October 31, 2014, 10:35:02 am »
Thank you so much . i ll try this.
actually these are early days for me to work with C.your help will make me experienced..i ll reply again as i test this code and run it..

Thank you  ^-^
 :-+
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: i want to blink LED in reverse order
« Reply #4 on: October 31, 2014, 01:18:42 pm »
It's not going to happen with your display routine: it presumes a certain data pattern.

Instead, turn off all digits and then just light up the digit you wish to light up.

Once that's done, alter the pattern of data to be displayed.

Something like this:

Code: [Select]
  for (pattern=0x01; pattern < 0x10; pattern = patter << 1) {led_display(pattern); delay_ms(LED_DLY);}
  for (pattern=0x08; pattern;            pattern = patter >> 1) {led_display(pattern); delay_ms(LED_DLY);}
================================
https://dannyelectronics.wordpress.com/
 

Offline ect_09Topic starter

  • Contributor
  • Posts: 17
Re: i want to blink LED in reverse order
« Reply #5 on: October 31, 2014, 04:44:17 pm »
now i want to turn on led in a sequence i.e
1 3 2 4

now what should i do???
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: i want to blink LED in reverse order
« Reply #6 on: October 31, 2014, 05:04:15 pm »
change the case statement entries, either the index or the code for that index.
 

Offline ect_09Topic starter

  • Contributor
  • Posts: 17
Re: i want to blink LED in reverse order
« Reply #7 on: October 31, 2014, 05:08:42 pm »
actually i want to change the logic only..
i understand your comment..

i tried this
Code: [Select]
void main()
{
  TRISB=0x00;
  TRISD=0x00;
  // initialize led
  char a = 0;
  // define direction
  char dir = 1;

  while(1)
  {
    led_display(a);

    a = a + dir; // increment or decrement depending on direction

    delay_sec(1);

    if(a==2)
    {
      dir = -1; // here a become a=2-1=1
      // Edit: adjust index to be 3 so that the last LED will light up again.
      // change to a = 2 if you don't want the last LED to stay on for double
      // the amount of time as the rest.
      a+=2;  // here a become 1+2=3
    }
 
}

what about my logic???
« Last Edit: October 31, 2014, 05:10:29 pm by ect_09 »
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: i want to blink LED in reverse order
« Reply #8 on: October 31, 2014, 05:32:30 pm »
Quote
what about my logic???

Not going to happen.

You will find that programming is a lot easier if you start simple. In this case, start by turning a pin on / off. Once you do that, we will go from there.
================================
https://dannyelectronics.wordpress.com/
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: i want to blink LED in reverse order
« Reply #9 on: October 31, 2014, 06:40:08 pm »
I agree
it's easier if you change your case statement, each one determines a state.

case 0: somecode_to_light_led1; break;
case 1: somecode_to_light_led2; break;
case 2: somecode_to_light_led3; break;
case 3: somecode_to_light_led4; break;

You can either change the case number:

case 0: somecode_to_light_led1; break;
case 2: somecode_to_light_led2; break;
case 1: somecode_to_light_led3; break;
case 3: somecode_to_light_led4; break;

Or the code for the case:

case 0: somecode_to_light_led1; break;
case 1: somecode_to_light_led3; break;
case 2: somecode_to_light_led2; break;
case 3: somecode_to_light_led4; break;
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf