Melody is too long...??? - Page 1
Forum section: electronics / general

author: Tricka90
author_rank: Regular Contributor
timestamp: October 03, 2013, 04:38:51 pm
content: I'm trying to generate a little melody when my PIC 16F876 turns on. So I wrote in main(), before the while(1) cycle the following note sequence (I use MikroC):Code:Sound_Play(523,600);Sound_Play(262,200);Sound_Play(349,400);Sound_Play(523,600);Sound_Play(262,200);Sound_Play(294,200);Sound_Play(349,200);Sound_Play(523,200);Sound_Play(349,200);Sound_Play(294,400);Sound_Play(523,600);Sound_Play(233,200);Sound_Play(349,400);Sound_Play(466,600);Sound_Play(349,200);Sound_Play(233,400);Sound_Play(440,200);Sound_Play(349,200);Sound_Play(233,400);Sound_Play(440,1400);Delay_ms(1000);...but it doesn't play the melody just one time! It repeat it forever! Also every repetition it seems like a little bit of code goes on! It looks like a PIC malfunction because if I reduce the lenght of the melody it works PERFECTLY! To be precise, if I stop at note number nine (Sound_Play(349,200)all it's ok, the melody ends and the program goes on correctly. But if I try to add another note it repeats all the melody forever! Do you know why this happens? Do you know how to work around this strange problem?

author: c4757p
author_rank: Super Contributor
timestamp: October 03, 2013, 04:46:23 pm
content: Why would you not include the rest of the code?

author: dannyf
author_rank: Super Contributor
timestamp: October 03, 2013, 04:47:33 pm
content: QuoteYou didn't read the compiler manual.QuoteInsert a while loop at the end.

author: Tricka90
author_rank: Regular Contributor
timestamp: October 03, 2013, 05:02:03 pm
content: Quote from: c4757p on October 03, 2013, 04:46:23 pmIs very long. If you want to read it I include it:Code:void main();//VARIABLESint red = 20;int blue = 20;int green = 20;int adc = 0;int stato = 0;int mode_change = 0;int colore = 0;int clockON = 0;int pwm_rgb = 0;int mode = 1;int j = 0;int pwm = 0;int flash = 0;int lum = 20;int lum_provv;int clock = 0;int intro = 1;void interrupt(){if (INTCON.TMR0IF){if(mode == 5) {j++;if(j >= flash*30+80){if(pwm == 1){lum_provv = lum;lum=0;pwm = 0;}else{lum = lum_provv;pwm = 1;}j = 0;}}if(pwm_rgb >= 20){pwm_rgb = 0;}else{pwm_rgb++;}if(green >= pwm_rgb && green != 0){PORTB.RB1 = 1;}else{PORTB.RB1 = 0;}if(red >= pwm_rgb && red != 0){PORTB.RB0 = 1;}else{PORTB.RB0 = 0;}if(blue >= pwm_rgb && blue != 0){PORTB.RB2 = 1;}else{PORTB.RB2 = 0;}INTCON.TMR0IF = 0;}}void melody(){Sound_Play(523,600);Sound_Play(262,200);Sound_Play(349,400);Sound_Play(523,600);Sound_Play(262,200);Sound_Play(294,200);Sound_Play(349,200);Sound_Play(523,200);Sound_Play(349,200);Sound_Play(294,400);Sound_Play(523,600);Sound_Play(233,200);Sound_Play(349,400);Sound_Play(466,600);Sound_Play(349,200);Sound_Play(233,400);Sound_Play(440,200);Sound_Play(349,200);Sound_Play(233,400);Sound_Play(440,1400);Delay_ms(1000);}int RGB(int adc, int i) {if(adc >= 210) {if(adc <= 280) { Delay_ms(80); adc = ADC_Read(0); if(adc <= 290 && adc >= 220) {mode_change = 0;stato = 0;{ PORTC.RC3 = 0; PORTC.RC4 = 0; PORTC.RC5 = 1; }i = i-1;if(i <= 0){ i = 0;Sound_Play(659, 20); }Sound_Play(523, 20);}}else {if(adc >= 940) {{ PORTC.RC3 = 0; PORTC.RC4 = 1; PORTC.RC5 = 0; }i = i+1;if(i >= 20){ i = 20; Sound_Play(1319, 20); }Sound_Play(1046, 20);Delay_ms(80);}if(adc <= 840 && adc >= 320) {{ PORTC.RC3 = 1; PORTC.RC4 = 0; PORTC.RC5 = 0; stato = 1; }i = i;}}}if(adc <= 170){{ PORTC.RC3 = 0; PORTC.RC4 = 0; PORTC.RC5 = 0; }if(stato == 1){mode_change++;}if(mode_change == 1){clockON = 1;}stato = 0;}colore = i;return(colore);}void main(){ADCON0 = 0;ADCON1 = 0b00001110;//TRIS{TRISB = 0;PORTB = 0;TRISC = 0;PORTC = 0;TRISA = 0b00000001;PORTA = 0;PORTA.RA2 = 1;}Sound_Init(&PORTA, 1);//INTRO MUSICmelody();//CCP_PWM (RC2, RC1){PWM1_Init(5500);PWM1_Set_Duty(210);PWM1_Start();PWM2_Init(1000);PWM2_Set_Duty(lum*12+10);PWM2_Start();}//TIMER/INTERRUPT{OPTION_REG = 0b10000010;INTCON = 0b11100000;}while(1){adc = ADC_Read(0);if(clockON == 1){clock++;if(clock >= 6500){if(mode_change >= 2) { if(mode_change <= 4){if(mode_change == 2) {mode++;if(mode == 6){mode = 1;}}if(mode_change == 3 || mode_change == 4){mode -= 1;if(mode == 0){mode = 5;}}if(mode == 4){PORTB.RB4= 1;PORTA.RA5= 0;PORTB.RB5= 0;}if(mode == 5){PORTA.RA2= 0;PORTB.RB4= 0;PORTB.RB5= 1;}if(mode == 1){PORTA.RA2= 1;PORTA.RA3= 0;PORTB.RB5= 0;}if(mode == 2){PORTA.RA2= 0;PORTA.RA3= 1;PORTA.RA5= 0;}if(mode == 3){PORTA.RA5= 1;PORTA.RA3= 0;PORTB.RB4= 0;}mode_change = 0;Delay_ms(50);Sound_Play(1046, 60);Delay_ms(15);Sound_Play(1568, 60);Delay_ms(15);Sound_Play(1046, 60);Delay_ms(700);}}mode_change = 0;clock = 0;clockON = 0;}}switch(mode) {case 1:RGB(adc, lum);lum = colore;PWM2_Set_Duty(lum*12+10);break;case 2:RGB(adc, blue);blue = colore;break;case 3:RGB(adc, green);green = colore;break;case 4:RGB(adc, red);red = colore;break;case 5:RGB(adc, flash);flash = colore;PWM2_Set_Duty(lum*12+10);break;}}}Quote from: dannyf on October 03, 2013, 04:47:33 pmNo, I didn't found any useful information, I don't even know where to look for information about this issue in the compiler manual...Ok, I will try adding a while loop which lasts some time

author: Tricka90
author_rank: Regular Contributor
timestamp: October 03, 2013, 05:23:20 pm
content: I tried adding while(1) at the end of the melody and the melody does stop correctly!But of course I need my program to go on after the melody ends.So i tried adding a while which lasts some time:Code:long intro;while(intro <= 100000) {intro++;}But as soon as the while cycle ends the melody still repeats forever!

author: senso
author_rank: Frequent Contributor
timestamp: October 03, 2013, 06:51:31 pm
content: Sounds a bit like a stack overflow, too little ram?

author: Tricka90
author_rank: Regular Contributor
timestamp: October 03, 2013, 07:38:12 pm
content: When I compile it says RAM is 18% used, ROM 27%. Is it too much?

author: c4757p
author_rank: Super Contributor
timestamp: October 03, 2013, 08:32:56 pm
content: I don't think it's a stack overflow.INTCON = 0b11100000;This includes the PEIE bit - peripheral interrupts. There's some code missing (Sound_Init in particular) - make sure you're not setting any interrupts elsewhere, because you aren't clearing them in the handler.

author: Tricka90
author_rank: Regular Contributor
timestamp: October 03, 2013, 08:43:12 pm
content: So should I clear PEIE bit? I use timer0 overflow interrupt in the program as you can see, but the function melody() is called before the all interrupt function is even initialized.Sound_Init is not missing, it's just before melody() function call, you can see it.

author: c4757p
author_rank: Super Contributor
timestamp: October 03, 2013, 08:47:16 pm
content: Quote from: Tricka90 on October 03, 2013, 08:43:12 pmI missed the order.QuoteItscodeis missing, so I don't know what it does. Is it part of a library included with the compiler?

author: mariush
author_rank: Super Contributor
timestamp: October 03, 2013, 08:49:16 pm
content: Maybe you're doing something that resets the microcontroller after song finishes?Add a sort of counter or some logging through serial port so you see what happens.

author: dannyf
author_rank: Super Contributor
timestamp: October 03, 2013, 10:28:07 pm
content: QuoteIt is just one of the prices you pay for using libraries without access to the source code.QuoteWithout knowing how the sound functions work, it is not possible to tell where the problems may lie. For example, the sound routines could have used timer0; and your code in the while loop does call the sound function so what you observed could be right.Without comments, without a methodical approach to debugging, no one can tell for sure.

author: Psi
author_rank: Super Contributor
timestamp: October 03, 2013, 10:54:40 pm
content: I would just remove sections of code until you find whats causing the problem.Shouldn't take long.

author: Tricka90
author_rank: Regular Contributor
timestamp: October 04, 2013, 08:27:21 am
content: Quote from: dannyf on October 03, 2013, 10:28:07 pmIf it can help you can read all sound function steps for my melody in assembly:Code:_melody:;Lampada15.c,89 :: void melody();Lampada15.c,91 :: Sound_Play(523,600);MOVLW 11MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 2MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 88MOVWF FARG_Sound_Play_duration_ms+0MOVLW 2MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,92 :: Sound_Play(262,200);MOVLW 6MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,93 :: Sound_Play(349,400);MOVLW 93MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 144MOVWF FARG_Sound_Play_duration_ms+0MOVLW 1MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,94 :: Sound_Play(523,600);MOVLW 11MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 2MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 88MOVWF FARG_Sound_Play_duration_ms+0MOVLW 2MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,95 :: Sound_Play(262,200);MOVLW 6MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,96 :: Sound_Play(294,200);MOVLW 38MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,97 :: Sound_Play(349,200);MOVLW 93MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,98 :: Sound_Play(523,200);MOVLW 11MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 2MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,99 :: Sound_Play(349,200);MOVLW 93MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,100 :: Sound_Play(294,400);MOVLW 38MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 144MOVWF FARG_Sound_Play_duration_ms+0MOVLW 1MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,101 :: Sound_Play(523,600);MOVLW 11MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 2MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 88MOVWF FARG_Sound_Play_duration_ms+0MOVLW 2MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,102 :: Sound_Play(233,200);MOVLW 233MOVWF FARG_Sound_Play_freq_in_hz+0CLRF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,103 :: Sound_Play(349,400);MOVLW 93MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 144MOVWF FARG_Sound_Play_duration_ms+0MOVLW 1MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,104 :: Sound_Play(466,600);MOVLW 210MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 88MOVWF FARG_Sound_Play_duration_ms+0MOVLW 2MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,105 :: Sound_Play(349,200);MOVLW 93MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,106 :: Sound_Play(233,400);MOVLW 233MOVWF FARG_Sound_Play_freq_in_hz+0CLRF FARG_Sound_Play_freq_in_hz+1MOVLW 144MOVWF FARG_Sound_Play_duration_ms+0MOVLW 1MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,107 :: Sound_Play(440,200);MOVLW 184MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,108 :: Sound_Play(349,200);MOVLW 93MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 200MOVWF FARG_Sound_Play_duration_ms+0CLRF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,109 :: Sound_Play(233,400);MOVLW 233MOVWF FARG_Sound_Play_freq_in_hz+0CLRF FARG_Sound_Play_freq_in_hz+1MOVLW 144MOVWF FARG_Sound_Play_duration_ms+0MOVLW 1MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,110 :: Sound_Play(440,1400);MOVLW 184MOVWF FARG_Sound_Play_freq_in_hz+0MOVLW 1MOVWF FARG_Sound_Play_freq_in_hz+1MOVLW 120MOVWF FARG_Sound_Play_duration_ms+0MOVLW 5MOVWF FARG_Sound_Play_duration_ms+1CALL _Sound_Play+0;Lampada15.c,111 :: Delay_ms(1000);MOVLW 16MOVWF R11+0MOVLW 57MOVWF R12+0MOVLW 13MOVWF R13+0L_melody19:DECFSZ R13+0, 1GOTO L_melody19DECFSZ R12+0, 1GOTO L_melody19DECFSZ R11+0, 1GOTO L_melody19NOPNOP;Lampada15.c,113 :: }L_end_melody:RETURN; end of _melodyQuote from: Psi on October 03, 2013, 10:54:40 pmI've tried removing lots of setting like ADCON, the timer0 setting such as opition reg and intcon ecc but still no result.What would you advise to remove?The only thing I know is thatthe problem occurs just when melody is longer than a certain value.

author: Tricka90
author_rank: Regular Contributor
timestamp: October 04, 2013, 09:07:07 am
content: UPDATE: I think I found the reason of the issue.If I remove WHICHEVER function the melody just repeat once, so the problem is solved!For example when I remove the two PWM declarations (PWM_Init, PWM_Set_Duty and PWM_Start) the melody infinite repetition doesn't occurs!So i tried adding those functions later, inside the "while(1)" cycle, but the problem returns...Maybe is a memory problem, or a CPU issue, I don't know exactly. I think so because WHATEVER big function I remove the problem is solved (for example if I remove the void interrupt() function or the int RGB() function the problem doesn't occur).But RAM is just 18% used and ROM just 30%, that I can read on the compiler log...Do you know how I can work around the problem? Maybe with some code simplification (removing useless routines)?

author: Tricka90
author_rank: Regular Contributor
timestamp: October 04, 2013, 10:06:50 am
content: THE PROBLEM IS SOLVED!!!I found that the problem wasn't occurring when used ROM was less than 2050, so I just correct some "int" with "unsigned short" and do some other little corrections and I manage to make used ROM under 2000, now it works perfectly!!!But I still have a question: WHY the damn PIC start going crazy if the used ROM is just about 30%??? Do you know why?

author: Psi
author_rank: Super Contributor
timestamp: October 04, 2013, 01:13:31 pm
content: When you say 'used rom' do you mean program flash or sram?I've seen some IDE's give the wrong used ram percentage when the MCU in question has a external ram interface.The IDE seems to assume you're using external ram even when you're not.So the ram percentage shown is much lower than it really isEdit: re-reading your post and looking up your MCU i dont think this is your issue.

author: Tricka90
author_rank: Regular Contributor
timestamp: October 04, 2013, 06:26:03 pm
content: The RAM doesn't cause the problem, the ROM it does, or at least that's what I can see from the compiler log.I mean the program flash memory

author: PA0PBZ
author_rank: Super Contributor
timestamp: October 04, 2013, 06:55:30 pm
content: Quote from: Tricka90 on October 04, 2013, 10:06:50 amAccording to the datasheet the PIC PIC16F876 has 8K of program memory, so if you are talking HEX 2000 it makes sense since that is 8K. If you are talking decimal 2000 the 30% makes more sense but the problem doesn't.