|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 28, 2008 4:45 pm |
|
|
I looked at your code a little bit. You have this variable, 'fl_left1', that
you test in btn1_check() to see if it's TRUE. But there is no place in your
code where 'fl_left1' is ever set = TRUE. So how can it work ?
What is your program supposed to do ? Have you tested it ? |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Mon Apr 28, 2008 5:07 pm |
|
|
PCM programmer wrote: | I looked at your code a little bit. You have this variable, 'fl_left1',... |
If you look at his first complete posting of INT_RDA (before he started simplifying it for debugging tests), you would see:
Code: |
#INT_RDA
void serial_isr()
{
rec=getc();
switch(rec)
{
case 'h': //base centre
fl_cen1 = TRUE;
fl_cen2 = TRUE;
fl_cen3 = TRUE;
fl_cen4 = TRUE;
rec = NULL;
break;
case 'q':
fl_right1 = TRUE;
rec = NULL;
break;
case 'a':
fl_left1 = TRUE;
rec = NULL;
break;
default:
break;
}
}
|
So fl_left1 is set when the character 'a' is received.
Robert Scott
Real-Time Specialties |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 28, 2008 5:56 pm |
|
|
Thanks. I put the "case 'a'" code back in.
I first compiled it with vs. 4.071 (the latest version), and it begins with
a pulse on pin C0. The frequency is 50 Hz and the pulse width is 1.46 ms.
When I press the 'a' key, the pulse reduces in length to 1.41 ms. As I
continue to press the 'a' key, the pulse eventually reduces to .648 ms.
It doesn't go below that.
At the same time as this, the program is sending numbers to the serial
terminal window. The numbers change when I turn the trimpot that
is connect to pin AN0.
I then installed the older vs. 4.017 and I got the same thing.
I hope that helps. |
|
|
soong2020
Joined: 13 Feb 2008 Posts: 25
|
|
Posted: Mon Apr 28, 2008 11:28 pm |
|
|
PCM programmer wrote: | Thanks. I put the "case 'a'" code back in.
I first compiled it with vs. 4.071 (the latest version), and it begins with
a pulse on pin C0. The frequency is 50 Hz and the pulse width is 1.46 ms.
When I press the 'a' key, the pulse reduces in length to 1.41 ms. As I
continue to press the 'a' key, the pulse eventually reduces to .648 ms.
It doesn't go below that.
At the same time as this, the program is sending numbers to the serial
terminal window. The numbers change when I turn the trimpot that
is connect to pin AN0.
I then installed the older vs. 4.017 and I got the same thing.
I hope that helps. |
Sorry, my mistake for mistaking the left and right flags. Thanks for running the program on your hardware. Yes it is supposed to do as what you have observed and when i use it with one PWM output and just 3 characters, 'q', 'a', and 'h', it worked perfectly.
But, the problem is, when I duplicate the same type of code for more PWM pins and more character inputs, the PIC does not react to the input characters. May I know why is this happening? |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Tue Apr 29, 2008 5:53 am |
|
|
soong2020 wrote: | ...But, the problem is, when I duplicate the same type of code for more PWM pins and more character inputs, the PIC does not react to the input characters. May I know why is this happening? |
I would guess that something about the way you duplicate the functionality for more PWM pins is introducing an interaction, either in timing, or in the shared use of a variable that was exclusively used for one PWM pin before.
By the way, the "problem" you describe keeps on changing every time you describe it. First you said that the PIC would not receive characters when it was also sending reports back to the PC. Then you said that some servo reaction to the characters was correct only about 3/10 times. And now you say that one PWM pin works perfectly, and things only start to fail when multiple PWM pins are enabled. In debugging it is very important to know what the problem is before you can solve it. I suggest doing more experiments until you know as close as possible exactly what is failing, by how much, and in what circumstances.
Robert Scott
Real-Time Specialties |
|
|
soong2020
Joined: 13 Feb 2008 Posts: 25
|
|
Posted: Tue Apr 29, 2008 6:42 am |
|
|
Sorry i forgot to tell that some changes that I made.
Code: |
#define LOOPCNT2 100
.........
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1) |
to this
Code: |
#define LOOPCNT2 10
..........
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8)
|
The character receiving became better after doing the timer changes if i'm working with only one PWM output. Once I increase it to work with 2 outputs and more char inputs, it becomes worse. |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Tue Apr 29, 2008 8:26 am |
|
|
soong2020 wrote: |
The character receiving became better after doing the timer changes if i'm working with only one PWM output. Once I increase it to work with 2 outputs and more char inputs, it becomes worse. |
Again, you are not saying what "worse" and "better" means. I thought we already established that character receiving is not the problem. You have to tell us what the real problem is.
Robert Scott
Real-Time Specialties |
|
|
Matro Guest
|
|
Posted: Tue Apr 29, 2008 8:47 am |
|
|
The main problem is that when you increase number of outputs or number of commands, your ISRs become longer and longer.
Be aware that when the PIC is treating an interrupt (is inside an ISR), it can't take care of another. With ISRs growing in size come a lot of problems like buffer overflow and so on.
The only way to achieve is to move all data processing from ISRs to main() and to control that by flags that are set/cleared in ISRs and checked in main() to run the expected data processing.
Matro |
|
|
soong2020
Joined: 13 Feb 2008 Posts: 25
|
|
Posted: Tue Apr 29, 2008 9:10 am |
|
|
Alright, regarding where the problem lies, I don't really know how to say cos I don't know where it lies actually. So I'll just describe what I observed. Now the latest scenario is like this:
1 PWM output, 1 ADC channel with data transmitting once every second, 3 char inputs, the rest of the outputs and char inputs are taken out:
- Data from ADC obtained correctly on time once every second. Char input works correctly. PWM output pin functions properly.
4 PWM output, 1 ADC channel with data transmitting, 9 char inputs
- Data from ADC obtained correctly every second. Char input does NOT work. Have to press and hold the input key on keyboard for a long period of time and only once a while one or two will manage to get through.
- PWM output pins function properly as the servos are in their home positions. But input char can't get through into PIC so the duty cycles do not change.
The way i write for multiple PWM outputs and more char inputs are the same as for singular output with 3 char inputs. I just change the flag names, variable names and input char alphabet that's all.
I'm just suspecting the "printf" function takes too much time to be executed which causes some of the interrupts to fail. In this case, the INT_RDA is the only interrupt failed to work as Timer2 and Timer1 works fine. I'm saying this because once i remove the "printf" command, the PIC CAN receive char input without failure. But I won't get to have data being displayed on the PC.
Besides that, do I need to set priority for the interrupts? If yes, what would the order be?
Is it necessary to post up the entire code here? |
|
|
Matro Guest
|
|
Posted: Tue Apr 29, 2008 9:15 am |
|
|
Could I assume that you have understood and applied my last post?
You can eventually post the whole code if it is well indented and commented.
Matro |
|
|
soong2020
Joined: 13 Feb 2008 Posts: 25
|
|
Posted: Tue Apr 29, 2008 9:21 am |
|
|
Matro wrote: | Could I assume that you have understood and applied my last post?
You can eventually post the whole code if it is well indented and commented.
Matro |
Oh sorry I missed out on your post as I was typing and testing the codes when you replied. The way i wrote the ISRs are only just to set flags and the main program will detect for the flag changes in a while(1) loop. Alright I'll try my best to make the code looks presentable and easy to read. It's gonna be long. |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Tue Apr 29, 2008 9:56 am |
|
|
soong2020 wrote: |
4 PWM output, 1 ADC channel with data transmitting, 9 char inputs
- Data from ADC obtained correctly every second. Char input does NOT work... |
No, you don't know that. You think the character input does not work, but then only evidence you have talked about as far as a failure of characters to work is their eventual effect on the servo. So don't assume that characters are not getting through unless you can prove it. It seems to me that characters are getting though just fine. The problem is elsewhere.
Quote: |
The way i write for multiple PWM outputs and more char inputs are the same as for singular output with 3 char inputs. I just change the flag names, variable names and input char alphabet that's all.
|
I agree. I don't think your interrupt code is taking too long. Your INT_RDA is very fast. By the way, I hope you are not using the variable "rec" anywhere else in your code. It should belong exclusively to the serial_isr(). Your Timer 2 ISR is also quite fast, but you also have set Timer 2 to interrupt very fast - every 50 usec. You should check to see if your TIMER2_isr() always finishes in less than 50 usec. I assume your PIC oscillator is 8 MHz, so 50 usec. gives you only 100 instruction times for TIMER2_isr entrance, all your code, and then the TIMER2_isr return. This also must count the CCS compiler's decision tree that determines which interrupt is interrupting. I think that may be the problem. You can test that theory by changing the Timer 2 setup so that it interrupts every 70 usec instead of 50 usec. This will make the PWM period longer, but at least you can see if TIMER2_isr() is the bottleneck. If you really need to run Timer 2 at a 50 usec. interrupt rate then you should do everything you can to speed up TIMER2_isr(). One thing is to use Fast IO, so the the setting of the output pins will not waste time setting the TRIS register. This is also consistent with your report that problems occur when you enable more PWM pins. More PWM pins means TIMER2_isr() has more things to check and more outputs to set.
Robert Scott
Real-Time Specialties |
|
|
soong2020
Joined: 13 Feb 2008 Posts: 25
|
|
Posted: Tue Apr 29, 2008 10:24 pm |
|
|
RLScott wrote: | soong2020 wrote: |
4 PWM output, 1 ADC channel with data transmitting, 9 char inputs
- Data from ADC obtained correctly every second. Char input does NOT work... |
No, you don't know that. You think the character input does not work, but then only evidence you have talked about as far as a failure of characters to work is their eventual effect on the servo. So don't assume that characters are not getting through unless you can prove it. It seems to me that characters are getting though just fine. The problem is elsewhere.
Quote: |
The way i write for multiple PWM outputs and more char inputs are the same as for singular output with 3 char inputs. I just change the flag names, variable names and input char alphabet that's all.
|
I agree. I don't think your interrupt code is taking too long. Your INT_RDA is very fast. By the way, I hope you are not using the variable "rec" anywhere else in your code. It should belong exclusively to the serial_isr(). Your Timer 2 ISR is also quite fast, but you also have set Timer 2 to interrupt very fast - every 50 usec. You should check to see if your TIMER2_isr() always finishes in less than 50 usec. I assume your PIC oscillator is 8 MHz, so 50 usec. gives you only 100 instruction times for TIMER2_isr entrance, all your code, and then the TIMER2_isr return. This also must count the CCS compiler's decision tree that determines which interrupt is interrupting. I think that may be the problem. You can test that theory by changing the Timer 2 setup so that it interrupts every 70 usec instead of 50 usec. This will make the PWM period longer, but at least you can see if TIMER2_isr() is the bottleneck. If you really need to run Timer 2 at a 50 usec. interrupt rate then you should do everything you can to speed up TIMER2_isr(). One thing is to use Fast IO, so the the setting of the output pins will not waste time setting the TRIS register. This is also consistent with your report that problems occur when you enable more PWM pins. More PWM pins means TIMER2_isr() has more things to check and more outputs to set.
Robert Scott
Real-Time Specialties |
Oh how could I not see that! Thanks Scott for this priceless advice. I've included fast_io, and changed the length of my full TIMER2 code and it worked! Finally problem solved.... Thanks a lot once again guys for everyone that helped here. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|