i want to blink LED in reverse order - Page 1
Forum section: electronics / general

author: ect_09
author_rank: Contributor
timestamp: October 31, 2014, 06:43:21 am
content: Hi;i want to reverse the code as it complete first time.for examplepin 1-pin 2-pin 3-pin 4 (its somplete)now it should run aspin 4-pin 3-pin 2-pin 1i write this code but its not working in reverse order.please guide me in this way.Code:#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 40000000void 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

author: miguelvp
author_rank: Super Contributor
timestamp: October 31, 2014, 07:23:34 am
content: 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 directionand other things you can try, but that main will do what you want.Code:void main(){TRISB=0x00;TRISD=0x00;// initialize ledchar a = 0;// define directionchar dir = 1;while(1){led_display(a);a = a + dir; // increment or decrement depending on directiondelay_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:#include <project.h>#define BRIGHTNESS_DECREASE (1024u)uint16 curPos;static int direction = 1;CY_ISR(InterruptHandler){// Clear TC InterruptPWM_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 InterruptPWM_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 InterruptPWM_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 InterruptPWM_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 InterruptPWM_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 InterruptPWM_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;elsePWM_5_WriteCompare2(input2 + BRIGHTNESS_DECREASE);}else{if(((input2-BRIGHTNESS_DECREASE)&0xFFFFu) > input2)direction = 1;elsePWM_5_WriteCompare2(input2 - BRIGHTNESS_DECREASE);}}int main(){CyDelay(50u);// Enable the global interruptCyGlobalIntEnable;// Enable the Interrupt component connected to interruptTC_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 componentsPWM_Start();PWM_1_Start();PWM_2_Start();PWM_3_Start();PWM_4_Start();PWM_5_Start();// Set periodsPWM_WritePeriod(65535u);PWM_1_WritePeriod(65535u);PWM_2_WritePeriod(65535u);PWM_3_WritePeriod(65535u);PWM_4_WritePeriod(65535u);PWM_5_WritePeriod(65535u);// Init dual PWMsPWM_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(;;){}}

author: miguelvp
author_rank: Super Contributor
timestamp: October 31, 2014, 08:05:32 am
content: A little revision.Code: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 directiona += 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;}}}

author: ect_09
author_rank: Contributor
timestamp: October 31, 2014, 10:35:02 am
content: 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

author: dannyf
author_rank: Super Contributor
timestamp: October 31, 2014, 01:18:42 pm
content: 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: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);}

author: ect_09
author_rank: Contributor
timestamp: October 31, 2014, 04:44:17 pm
content: now i want to turn on led in a sequence i.e1 3 2 4now what should i do???

author: miguelvp
author_rank: Super Contributor
timestamp: October 31, 2014, 05:04:15 pm
content: change the case statement entries, either the index or the code for that index.

author: ect_09
author_rank: Contributor
timestamp: October 31, 2014, 05:08:42 pm
content: actually i want to change the logic only..i understand your comment..i tried thisCode:void main(){TRISB=0x00;TRISD=0x00;// initialize ledchar a = 0;// define directionchar dir = 1;while(1){led_display(a);a = a + dir; // increment or decrement depending on directiondelay_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???

author: dannyf
author_rank: Super Contributor
timestamp: October 31, 2014, 05:32:30 pm
content: QuoteNot 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.

author: miguelvp
author_rank: Super Contributor
timestamp: October 31, 2014, 06:40:08 pm
content: I agreeit'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;