View Full Version : New C18 3.0+ Compatible FRC Code
bronxbomber92
18-01-2008, 16:48
Is it recommended to use this code over the default, or should teams wait to use until it's out of its beta stages?
Kevin,
what changes should be made to the Vex C templates to run under 3.10? I'm getting library errors.
Kevin Watson
18-01-2008, 18:41
Kevin,
what changes should be made to the Vex C templates to run under 3.10? I'm getting library errors.The library needs to be built with the new compiler. Until then we're stuck with C18 2.4.
-Kevin
Loki1989
19-01-2008, 14:23
Can we use MPlab 8.0 to use 3.10 to compile? I need to know Because I cant find 7.21
Can we use MPlab 8.0 to use 3.10 to compile? I need to know Because I cant find 7.21
Yes. That's the exact setup I'm using.
Ok, I have a question (more of a comment really), but I was hoping someone could either verify my understanding, or explain what I'm missing.
It seems the current gyro code as well as some things others have mentioned depend on putting processing code inside one of the Spin functions.
Generally speaking, the spin function will be executed at a very high rate (essentially only processor-limited). However, at roughly 38Hz, the spin function is going to get delayed by however long it takes to run your general execution code, e.g., Teleop(). If this code is simple and runs quickly, this isn't likely to be too much of a problem.
However, there is still going to be some delay associated with this code, let's call it T_d. Now, the frequency, 1/T_d is going to be important because it's actually the maximum frequency we can count on our spin function to run at over any arbitrary time interval.
Right now it looks like we are processing our Gyro at 50Hz? (800Hz / 16 samples per update). This means we need to make sure that T_d < 20ms or else we will occasionally miss gyro samples.
I agree that if T_d is pushing 20ms, you're probably going to have other problems since that's a lot of computation going on. I mostly wanted to clarify this in the case someone was thinking about trying to sample an analog signal at a data rate higher than 1/T_d (probably somewhere in the 800Hz - 6400Hz range), and still do the processing in the spin loop. In this case they might start seeing data go missing every once in a while.
I guess my question then is why do we count on the spin code to do our processing since it's timing seems potentially sporadic. Wouldn't it be better to just do the gyro processing in the ISR alongside the analog-to-digital conversion? Then we would have high-frequency reliable processing of the gyro (or whatever other analog sensor we are processing), without having to worry about anything other than keeping our Teleop() execution time a decent amount under the theoretical limit of 26 ms.
Kevin Watson
19-01-2008, 17:44
Right now it looks like we are processing our Gyro at 50Hz? (800Hz / 16 samples per update). This means we need to make sure that T_d < 20ms or else we will occasionally miss gyro samples.Your average does need to be less than 20ms over time, but it's 40ms before you actually miss data. I agree that if T_d is pushing 20ms, you're probably going to have other problems since that's a lot of computation going on.Agreed. If the execution rate is somewhere between five and ten million instructions per second, you can, on average, execute somewhere between 100,000 and 200,000 instructions per Teleop() loop even with the ISR overhead. If you're trying to execute 100,000 instructions in the Teleop() loop, missing an occasional ADC update is the least of your problems. I didn't point this out in the documentation, but you can determine if you're dropping data by testing the value returned by Get_ADC_Result_Count(). If it's two or greater, you're dropping data.
I mostly wanted to clarify this in the case someone was thinking about trying to sample an analog signal at a data rate higher than 1/T_d (probably somewhere in the 800Hz - 6400Hz range), and still do the processing in the spin loop. In this case they might start seeing data go missing every once in a while.As I've stated elsewhere, I test the code with the ADC running at 6400Hz/4 samples per update, one encoder generating several hundred interrupts per second, several printfs generating a lot of telemetry in the Teleop() loop and as far as I can tell, everything works just fine (with the old 2.4 compiler I do see an occasional corrupted telemetry packet for reasons I don't fully understand; code generated with the 3.1 compiler doesn't have this problem).
I guess my question then is why do we count on the spin code to do our processing since it's timing seems potentially sporadic.Like I said above, I think (er, hope :) ) it's a non-problem.
Wouldn't it be better to just do the gyro processing in the ISR alongside the analog-to-digital conversion?This is how my code worked originally. The downside is that it's a lot of code to execute in a ISR and the ADC was dedicated to the gyro and nothing else could be sampled. After getting many requests, I split the ADC code away from the gyro code and provided a API to the ADC so that other sensors can be used alongside the gyro.
-Kevin
Thanks for the response Kevin. Sounds like my fear (and interpretation of the code) was mostly right, but as I was hoping, also completely unjustified :)
This looks like a great set of code and I'm very excited about getting a chance to play with it soon -- things have come a long ways from where they were in 2002... I think we were screwing around with PBASIC back then.
I'm missing most of the competition, but I'll be hanging around my old team for their last week and a half or so. Plenty of time for last-minute debugging of the software.
Kind of funny... doesn't seem to matter what robotics project I'm helping out with: DARPA Grand Challenge, or FIRST robotics... Kevin Watson manages to be involved and giving advice :)
Kevin Watson
19-01-2008, 21:43
This looks like a great set of code and I'm very excited about getting a chance to play with it soon -- things have come a long ways from where they were in 2002... I think we were screwing around with PBASIC back then.After a bit of tuning, you can get fairly spectacular results with the robot controller. As an example, I have a Silicon Sensing Systems' CRS03-02 gyro attached to a servo which is programmed to rotate such that the gyro will always point in the same direction (here's a low quality movie of it in action (http://kevin.org/frc/gyro.mov)). Anyway, the cool part is that it ran for nearly two hours today and the gyro only drifted a maximum of two degrees over that period. It's kinda neat.
Kind of funny... doesn't seem to matter what robotics project I'm helping out with: DARPA Grand Challenge, or FIRST robotics... Kevin Watson manages to be involved and giving advice :)Hey, say hi to your Dad for me. We had a nice discussion at the San Jose regional a few years ago <grin>.
-Kevin
Kevin,
Upgraded to the final 3.0 version....now I get a RLOD with just 1 encoder enabled.....what can produce this condition?
Kevin Watson
20-01-2008, 14:02
Kevin,
Upgraded to the final 3.0 version....now I get a RLOD with just 1 encoder enabled.....what can produce this condition?Did you enable the ISR in ifi_frc.h?
-Kevin
Did you enable the ISR in ifi_frc.h?
-Kevin
Nope.....I knew we were missing something!
Thanx!
Guy Davidson
20-01-2008, 22:38
Kevin,
Upgraded to the final 3.0 version....now I get a RLOD with just 1 encoder enabled.....what can produce this condition?
Yeah, we got this same issue today when enabling another encoder. Maybe a comment next to the #define ENABLE_ENCODER_# is in order to remind people to enable the ISR in ifi_frc.h?
comphappy
21-01-2008, 12:51
I must be missing something simple. I am using your code that is a couple of versions back, and when i enable the gyro code, all i get is this:
Gyro Bias=-1
Gyro Rate=0
Gyro Angle=0
after it has initialized
I then pulled your most recent code enabled the adc and the gyro in both spin and teleop the code compiles correctly, but soon as i load it, i get a code error.
Kevin Watson
21-01-2008, 13:13
I must be missing something simple. I am using your code that is a couple of versions back, and when i enable the gyro code, all i get is this:
Gyro Bias=-1
Gyro Rate=0
Gyro Angle=0
after it has initialized
I then pulled your most recent code enabled the adc and the gyro in both spin and teleop the code compiles correctly, but soon as i load it, i get a code error.Did you follow the instructions in readme.txt step by step?
-Kevin
comphappy
21-01-2008, 13:22
I got my code to work, there was an ifdef that i had written that blocked out part of the init, but the new code still fails to load.
Kevin Watson
21-01-2008, 13:30
I got my code to work, there was an ifdef that i had written that blocked out part of the init, but the new code still fails to load.Can you send me your code?
-Kevin
comphappy
21-01-2008, 15:19
The code that I cannot get to load is the code off of your webpage 1/20/08 both with and without the gyro enabled
My code based off of the older version is working fine.
Kevin Watson
21-01-2008, 15:30
The code that I cannot get to load is the code off of your webpage 1/20/08 both with and without the gyro enabled
My code based off of the older version is working fine.When you say "I cannot get to load is the code..." are you getting the red-light-of-death, the LEDs are green, but nothing happens, or is it just not compiling?
Make sure you're performing all the steps documented in readme.txt.
-Kevin
comphappy
21-01-2008, 15:53
Red light of death. Code compiles fine. I then go into programming mode open the loader give it the hex file and it attempts of load. The file is loaded in, but the code error light stays solid, reset, same thing. It is not really an issue for me, as I am sticking with the old code (early version of the v3 compiler), but I do not quite get what is going on. Do you want the hex file that i generate?
Kevin Watson
21-01-2008, 16:03
Red light of death. Code compiles fine. I then go into programming mode open the loader give it the hex file and it attempts of load. The file is loaded in, but the code error light stays solid, reset, same thing. It is not really an issue for me, as I am sticking with the old code (early version of the v3 compiler), but I do not quite get what is going on. Do you want the hex file that i generate?Make sure you have enabled the timer 4 interrupt in ifi_frc.h. Not doing this will cause the RLOD. Can you zip up your code and send it to me?
-Kevin
Guy Davidson
21-01-2008, 18:25
Okay, here is a snapshot of the current build that includes support for encoders and gyro:
http://kevin.org/frc/ifi_frc_beta_4.zip
*Please* help me out and have a look at the code and documentation (start with readme.txt) and provide feedback before I go public with the code on my website, which I'd like to do on Friday or early Saturday. If you can, follow the directions in readme.txt to build the code and test with your encoder(s) and/or gyro and report any problems here. Thanks.
-Kevin
The link is broken. I'll be happy to test beta 4 once I can get my hands on it.
-Guy Davidson
billbo911
21-01-2008, 20:09
The link is broken. I'll be happy to test beta 4 once I can get my hands on it.
-Guy Davidson
New and edited link on the first page. Or, go to his web site. The full and simple versions are up.
Kevin,
Now that I enabled the ISR's (grin) everything works fine. No need to include sonar code this year as the MaxBotix sensors have an analog output.
comphappy
21-01-2008, 21:48
Hmmm i dont know what the issue was, (i did have ISR enabled) I just now recompiled the code and loaded it, no issues. Serial communications issue on the load... I dont know.
Hello, this is my first year doing the programming on my team and we are having a very confusing problem. We are using an unmodified version of Kevin’s 2008 beta code with mplab v8 and c18 v3.1 and the code compiles fine and loads onto the robot fine, and it seems run on the robot, but the robot doesn't react at all. Its equally frustrating because when we load a copy of the 2007 code it works fine. It seems that no one else has had this problem (that I saw), though it seemed that Kevin referenced it in one of his posts.
the LEDs are green, but nothing happens
Any help we could get would be much appreciated.
comphappy
22-01-2008, 19:51
With out any code that is going to be hard to help you with, are you in teleop mode? What code do you have in your teleop function?
Kevin Watson
22-01-2008, 21:06
Hello, this is my first year doing the programming on my team and we are having a very confusing problem. We are using an unmodified version of Kevin’s 2008 beta code with mplab v8 and c18 v3.1 and the code compiles fine and loads onto the robot fine, and it seems run on the robot, but the robot doesn't react at all. Its equally frustrating because when we load a copy of the 2007 code it works fine. It seems that no one else has had this problem (that I saw), though it seemed that Kevin referenced it in one of his posts.
Any help we could get would be much appreciated.Because I don't know how you have your robot configured, you need to write this code yourself. Just open up teleop.c and scroll down to the teleop() function. Once there, you can map joystick inputs to motor outputs like this:
// map y-axis of the joystick on operator interface port #1 to the
// motor controlled by the Victor 883 attached to PWM output #1
pwm01 = p1_y;
// map y-axis of the joystick on operator interface port #2 to the
// motor controlled by the Victor 883 attached to PWM output #2
pwm02 = p2_y;
You can also use IFI's default robot code by uncommenting (remove the double slashes) in front of the call to Default_Routine() at the bottom of Teleop(). The code for Default_Routine() is located in ifi_code.c.
-Kevin
I'm having a variety of problems, with the new code(http://www.kevin.org/frc/ifi_frc_sensor_30.zip), and the old encoder code (http://www.kevin.org/frc/frc_encoder.zip).
First off, I'll talk about the problems we were having with frc_encoder. When I had MPLAB 7.20 installed and was using v2.4 of the C18 compiler, everything compiled, and the encoders worked great on the robot. Here was the problem... there seemed to be about a 1/2 second delay between the robot receiving data from the OI, so I would move a joystick, then it would take 1/2 a second for the motors to start moving. I would release the joystick, and it would take 1/2 a second to stop (I almost had a bad incident with our new 80lb robot running me over).
Okay, now for the 3.0 compatible code.
I have MPLAB 8.00 installed and version 3.10 of the C18 compiler.
I can compile the code as it is downloaded no problem, but when I try to initialize encoder 1 and encoder 2 using the code where i take out the //, it fails at the link step:
MPLINK 4.1, Linker
Copyright (c) 2006 Microchip Technology Inc.
Error - could not find definition of symbol 'Initialize_Encoder_2' in file 'C:\Robot Code\2008\ifi_frc_sensor_30\teleop.o'.
Errors : 1
If I comment out "Initialize_Encoder_2" it will say the same thing about encoder 1.
Is my MPLINK out of date, since it says 2006?
Here are some snapshots of MPLAB with my horrible hand-eye coordination with my trackpad: :D
6102
6107
The other 4 errors are with this part of code:
// Remove the // below to initialize encoder #1
Initialize_Encoder_1();
// Remove the // below to initialize encoder #2
Initialize_Encoder_2();
//Skipped a bunch of code here to save you time reading this. The code exists in my version.
if(i == 37 && j >= 191)
{
Encoder_Count = Get_Encoder_1_Count();
printf("E1=%d\r\n",(int)Encoder_Count);
Encoder_Count = Get_Encoder_2_Count();
printf("E2=%d\r\n",(int)Encoder_Count);
/* Encoder_Count = Get_Encoder_3_Count();
printf("E3=%d\r\n",(int)Encoder_Count);
Encoder_Count = Get_Encoder_4_Count();
printf("E4=%d\r\n",(int)Encoder_Count);
Encoder_Count = Get_Encoder_5_Count();
printf("E5=%d\r\n",(int)Encoder_Count);
Encoder_Count = Get_Encoder_6_Count();
printf("E6=%d\r\n\r\n",(int)Encoder_Count); */
}
Hopefully this gives you enough information to solve my problem.
Kevin Watson
23-01-2008, 14:30
First off, I'll talk about the problems we were having with frc_encoder. When I had MPLAB 7.20 installed and was using v2.4 of the C18 compiler, everything compiled, and the encoders worked great on the robot. Here was the problem... there seemed to be about a 1/2 second delay between the robot receiving data from the OI, so I would move a joystick, then it would take 1/2 a second for the motors to start moving. I would release the joystick, and it would take 1/2 a second to stop (I almost had a bad incident with our new 80lb robot running me over).
I'm not sure what you want me to do about this.
Hopefully this gives you enough information to solve my problem.Yep, it appears you didn't follow the detailed instructions in readme.txt :rolleyes:.
-Kevin
Oops, I never saw the pesky README. :D I already see what I did wrong, and I will edit this post a bit later to tell you if I got it working.
Also, the link to the beta4 software doesn't want to work.
Thanks for the quick response though... I was hectically trying to get this code working because our programming mentor is about to go to Indonesia on business.
EDIT: I got it working! Thanks a bunch!
If I get the sense teams will use the new code, I'll create versions with support for some sensors.
-Kevin
We'll be using ultrasonic sensors as well as a gear count. Though, I don't think that teams that are already modifying your code should have too much of a problem reading data from the digital inputs.
Thanks a lot for the code, saves a great deal of time.
I think I've found a bug in the Gyro code....
I know... it seems unlikely considering how long it's been in service, but this problem has been bugging me for a while and I finally got the clues I needed to locate it. Here is the function.
int Get_Gyro_Rate(void)
{
// Return the calculated gyro rate to the caller.
return((int)((((long)gyro_rate * GYRO_SENSITIVITY * 5L) / ADC_RANGE)) * GYRO_CAL_FACTOR);
}
I was calling this function and displaying the return value, but it never got above 32 or below -32, and it seemed to flip signs at the oddest times.
I think the problem is that GYRO_CAL_FACTOR is defined as 1000/1000, but the multiplication is being done AFTER the prior expression is cast to an integer... Therefore if ((((long)gyro_rate * GYRO_SENSITIVITY * 5L) / ADC_RANGE)) calculates to anything above 32 or below -32, then multiplying it by 1000 will cause the number to exceed the valid range of an integer.
I think the second to last bracket is misplaced... I think it should be:
return((int)((((long)gyro_rate * GYRO_SENSITIVITY * 5L) / ADC_RANGE) * GYRO_CAL_FACTOR));
I'm going to try it tomorrow...
I'm just greatful I didn't have to write this code....
Thankyou Kevin... really.
Phil.
Kevin Watson
24-01-2008, 03:04
I think I've found a bug in the Gyro code....Okay, I'll have a look at it. I'm working on what I hope is the final release, so now is a good time to fix any bugs. Assuming it's a real bug, thanks for finding it.
I know... it seems unlikely considering how long it's been in service.It's not too suprising. I think most, if not all, people are using the the Get_Gyro_Angle() function, which wouldn't be effected by a bug in the Get_Gyro_Rate function.
-Kevin
Kevin,
Would it be too much to ask for an updated library for the EDU-RC? ;)
I just discovered something else interesting about the gyro code... specifically the way the angle resolution relates to the analog input scaling.
I detected this as I was logging heading data as I was driving around and around our track.
On my system I have 4 Analog inputs, that I'm running 4 amples per update at 1600 Hz... This give me a Gyro update rate of 100 updates per second, and an ADC Range of 2048 and
In the Gyro code... for an ADXRS150 I have
#define GYRO_SENSITIVITY_RAD 1396L // in units of milliradians/sec/volt
And finally I have
long Get_Gyro_Angle(void)
{
// Return the calculated gyro angle to the caller.
return(((gyro_angle * GYRO_SENSITIVITY * 5L) / (ADC_RANGE * ADC_UPDATE_RATE)) * GYRO_CAL_FACTOR);
}
So, since I've been caught before on this one.. I calculated the value of the divisor of this expression. ADC_RANGE * ADC_UPDATE_RATE = 2048 * 100 = 204800. So I'm dividing a "Long" by this number.... I should be able to calculate the maximum result I can get...
Max Long is 2147483648 so if I divide this by 204800 I get 10485 ... Which, in theory is the maximum result I can get...
But wait, this is millirads so the maximum angle I can measue is... just over 1.6 full rotations...
Oops... Either I did my math wrong, or I have to reduce my update rate.
In fact, this does reflect what I see in my log data... after getting to 10485 mRad, the angle starts counting down again...
So I need to reduce my ADC range/rate, or reduce my measurement accuracy (like changing to tenth of a degree.)
No wonder my bot corrected in the wrong direction on evey second lap :)
No wonder my bot corrected in the wrong direction on evey second lap :)
Just to make sure we didn't have odd problems like this, our code looked something like
void Read_Yaw(void) {
phi=Get_Gyro_Angle();
phi=phi%6283L; // Avoid unneccesary wraparound
}
Kevin Watson
24-01-2008, 16:38
I detected this as I was logging heading data as I was driving around and around our track.Well, you have to assume something is gonna break if you do enough loop de loops :).
-Kevin
cdennisxlx2
24-01-2008, 18:21
Sorry if this has been addressed before I don’t have time to go through all 288 posts but we are having an issue when we compile. Here is what our output looks like, if anyone can help it would be greatly appreciated. Thank you
Clean: Deleting intermediary and output files.
Clean: Deleted file "C:\FRC2008\2008 Code\ifi_frc_simple_30\ifi_frc.mcs".
Clean: Done.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "autonomous.c" -fo="autonomous.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\FRC2008\2008 Code\ifi_frc_simple_30\ifi_frc.h:31:Error [1027] unable to locate 'p18cxxx.h'
C:\FRC2008\2008 Code\ifi_frc_simple_30\serial_ports.h:48:Error [1027] unable to locate 'stdio.h'
Halting build on first failure as requested.
BUILD FAILED: Thu Jan 24 15:12:09 2008
comphappy
24-01-2008, 20:17
You need to go to the project menu then build options then project
On the directory tab select Header Search Path (i dont have mplab infront of me right now but it is the header one), create a new one that points to the mcc18\include folder where ever that may be, it might be in C:\Program Files\ or just under C:\
Seeing as that variable is off you may also need to set the Library Search Path to mcc18\lib folder
Kevin Watson
24-01-2008, 20:23
Sorry if this has been addressed before I don’t have time to go through all 288 posts but we are having an issue when we compile. Here is what our output looks like, if anyone can help it would be greatly appreciated. Thank you
Clean: Deleting intermediary and output files.
Clean: Deleted file "C:\FRC2008\2008 Code\ifi_frc_simple_30\ifi_frc.mcs".
Clean: Done.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "autonomous.c" -fo="autonomous.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\FRC2008\2008 Code\ifi_frc_simple_30\ifi_frc.h:31:Error [1027] unable to locate 'p18cxxx.h'
C:\FRC2008\2008 Code\ifi_frc_simple_30\serial_ports.h:48:Error [1027] unable to locate 'stdio.h'
Halting build on first failure as requested.
BUILD FAILED: Thu Jan 24 15:12:09 2008
It looks like MPLAB doesn't know where to find the C18 header files (it seems to me that if you just sneeze while MPLAB is running, it'll forget all kinds of vital information <grin>). Anyway, go to Project > Build Options > Directories tab > Include Search Path and then point it to c:\mcc18\h.
-Kevin
Kevin Watson
24-01-2008, 21:22
Would it be too much to ask for an updated library for the EDU-RC? ;)Yes, at some point I'll port code to the EDU-RC (and maybe Vex too).
-Kevin
cdennisxlx2
24-01-2008, 22:16
It looks like MPLAB doesn't know where to find the C18 header files (it seems to me that if you just sneeze while MPLAB is running, it'll forget all kinds of vital information <grin>). Anyway, go to Project > Build Options > Directories tab > Include Search Path and then point it to c:\mcc18\h.
-Kevin
well my first errors are gone but now i get these...
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "autonomous.c" -fo="autonomous.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "disabled.c" -fo="disabled.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "ifi_code.c" -fo="ifi_code.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "ifi_frc.c" -fo="ifi_frc.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "interrupts.c" -fo="interrupts.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "pwm.c" -fo="pwm.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "serial_ports.c" -fo="serial_ports.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "teleop.c" -fo="teleop.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\FRC2008\2008 Code\ifi_frc_simple_30\teleop.c:105:Warning [2066] type qualifier mismatch in assignment
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 /i"C:\mcc18\h" "timers.c" -fo="timers.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Executing: "C:\mcc18\bin\mplink.exe" /l"C:\Program Files\microchip\mcc18\lib" "C:\FRC2008\2008 Code\ifi_frc_simple_30\18f8722.lkr" "C:\FRC2008\2008 Code\ifi_frc_simple_30\autonomous.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\disabled.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\ifi_code.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\ifi_frc.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\interrupts.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\pwm.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\serial_ports.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\teleop.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\timers.o" "C:\FRC2008\2008 Code\ifi_frc_simple_30\ifi_frc_8722.lib" /m"ifi_frc.map" /w /o"ifi_frc.cof"
MPLINK 4.1, Linker
Copyright (c) 2006 Microchip Technology Inc.
Error - could not find file 'clib.lib'.
Errors : 1
Link step failed.
BUILD FAILED: Thu Jan 24 19:11:44 2008
Kevin Watson
25-01-2008, 00:53
well my first errors are gone but now i get these...The first warning can be eliminated by changing the memory model to large: Project > Build Options > MPLAB C18 tab > Catagories: Memory Model > select large model for code and data.
The clib.lib error is due to MPLAB not knowing where your compiler libraries are installed: Project > Build Options > Directories tab > Library Search Path
-Kevin
cdennisxlx2
25-01-2008, 01:05
cool, it all works now, thank you very much :)
Kevin Watson
25-01-2008, 02:58
Just FYI, I believe that I have a single version of the code that will work with all robot controllers from 2004 on and can be built with C18 2.4 or 3.1. After seeing if I can improve the gyro integration code (per Philbot's posting above), doing some additional testing, and writing a bit more documentation, I should be able to release the code in the next few days.
-Kevin
billbo911
25-01-2008, 10:05
Just FYI, I believe that I have a single version of the code that will work with all robot controllers from 2004 on and can be built with C18 2.4 or 3.1. After seeing if I can improve the gyro integration code (per Philbot's posting above), doing some additional testing, and writing a bit more documentation, I should be able to release the code in the next few days.
-Kevin
Kevin,
You truly are an example that all FIRSTers can look to, including myself. Thank you for your incredible efforts!!
stevethetinker
25-01-2008, 20:20
I do like the new code layout. I would like to see the code for C18 2.4. We do prototyping on previous years' robots and having both 3.15 and 2.4 on our machines seems a bit difficult to manage.
Kevin,
Now finding that the RC is stuck in Programming Mode at the end of download if adc is initialized.......any suggestions? (I did read the readmes!!!)
Jon Mittelman
1jbinder
26-01-2008, 18:28
Hi Kevin,
We keep on getting a error that ADC_CH0 is not defined. This happens when we try to use rc_ana_in_01. We looked in all of the header files including the complier file and could not find the definition but it is clearly used in ifi_frc.h.This might be a stupid error but please can someone help us.
Thanks,
Julan
Julan,
Did you define the number of channels in the adc.h file?
Kevin,
The code runs fine if called ifi_frc.hex.....if I change the project in the same subdirectory with all the same files, I get a stuck programming mode light.
So I won't every change the name, but I'd still like to know why this hapens!!
Jon
1jbinder
26-01-2008, 19:52
Yes I Did
sparrowkc
26-01-2008, 19:55
PLEASE I CANNOT TAKE THIS ANYMORE
Any functions I create return seemingly random numbers
for example I put the function
unsigned int Motor_Limit (int motor)
{
static unsigned int lmnewmotor;
if(motor >= 254)
{
lmnewmotor = 254;
}
if(motor <= 0)
{
lmnewmotor = 0;
}
}
In ifi_code.c and a prototype in ifi_code.h. I call it with
motor1 = Motor_Limit((int) motor1);
where motor1 is a pwm value that may be invalid.
IT ALWAYS RETURNS 1919!!!!
WHYYYYYYYYYY
Is this a bug, I have the sensors version and kevin's site said that it was relatively bug free.
We have a demo tomorrow and whenever I try to run my code the robot goes int a spasm.
Alan Anderson
26-01-2008, 20:05
IT ALWAYS RETURNS 1919!!!!
How do you know what the return value is? I once spent hours trying to debug a routine that seemed to be returning the wrong value, only to discover that the error was in the line of code that prints the value.
But upon further inspection, the problem with your code is rather obvious to someone who hasn't been staring at it for hours. You merely forgot to return the newly computed value. :P
sparrowkc
26-01-2008, 20:13
I cannot adequately express my frustration with myself and the people here who I asked to check this for error. Thank you for pointing out that I DIDNT HAVE IT RETURN ANYTHING AAAAAAAAAAAAA:ahh: :ahh:
I looked at the link that was provided for a version of C18 other than 3.15 but couldn't find it. Can someone point to me where it is? >.< Any help appreciated.
-- Hank
Joe Ross
27-01-2008, 10:11
I looked at the link that was provided for a version of C18 other than 3.15 but couldn't find it. Can someone point to me where it is? >.< Any help appreciated.
-- Hank
The link in the first post for C18 has both 3.10 and 3.15.
Joe Ross
27-01-2008, 10:22
And finally I have
long Get_Gyro_Angle(void)
{
// Return the calculated gyro angle to the caller.
return(((gyro_angle * GYRO_SENSITIVITY * 5L) / (ADC_RANGE * ADC_UPDATE_RATE)) * GYRO_CAL_FACTOR);
}
So, since I've been caught before on this one.. I calculated the value of the divisor of this expression. ADC_RANGE * ADC_UPDATE_RATE = 2048 * 100 = 204800. So I'm dividing a "Long" by this number.... I should be able to calculate the maximum result I can get...
Max Long is 2147483648 so if I divide this by 204800 I get 10485 ... Which, in theory is the maximum result I can get...
But wait, this is millirads so the maximum angle I can measue is... just over 1.6 full rotations...
Oops... Either I did my math wrong, or I have to reduce my update rate.
In fact, this does reflect what I see in my log data... after getting to 10485 mRad, the angle starts counting down again...
So I need to reduce my ADC range/rate, or reduce my measurement accuracy (like changing to tenth of a degree.)
No wonder my bot corrected in the wrong direction on evey second lap :)
If you move the multiply by 5L to the end of the expression, it should give you 5 times longer before it roles over.
Kevin Watson
27-01-2008, 13:32
No wonder my bot corrected in the wrong direction on evey second lap :)So I spent some time working on this yesterday, mostly just understanding how everything works (I wrote this code a few years ago). First, a bit of history: My first cut of the gyro code was included in the scripting code Rich Petras and I released in 2005 and the intent was to reset the gyro angle to zero, have the robot perform a turn, drive straight, reset the gyro angle to zero, execute another turn, etc. In this way, all turns are relative and I didn't need to worry about rollover.
Okay, so yesterday I modified the code to gain more headroom (ADXRS150 w/ default settings rolls over in just over five revolutions) and implemented a scheme where complete revolutions are detected, counted, and then subtracted from the total angle. In this way the number of revolutions is accounted for separately from the angle. The downside is that the code is somewhat bloated and convoluted. I guess I'd like to keep the status quo with additonal headroom and dump the loop counting code, but I'd like to get some feedback on what teams want.
-Kevin
billbo911
27-01-2008, 18:34
...Okay, so yesterday I modified the code to gain more headroom (ADXRS150 w/ default settings rolls over in just over five revolutions) and implemented a scheme where complete revolutions are detected, counted, and then subtracted from the total angle. In this way the number of revolutions is accounted for separately from the angle. The downside is that the code is somewhat bloated and convoluted. I guess I'd like to keep the status quo with additional headroom and dump the loop counting code, but I'd like to get some feedback on what teams want.
-Kevin
Thanks for the background description. It helps in understanding how and why the code operates the way it does.
As for feedback;
Honestly, currently we don't have a need to keep track of heading for up to five revolutions. In fact, this year we will really only be expecting the code to track up to one and a half revolutions. So, as it is now, it will work just fine. On another note, I am curious as to the outcome of the question/observation PhilBot had when he posted this"
I think the problem is that GYRO_CAL_FACTOR is defined as 1000/1000, but the multiplication is being done AFTER the prior expression is cast to an integer... Therefore if ((((long)gyro_rate * GYRO_SENSITIVITY * 5L) / ADC_RANGE)) calculates to anything above 32 or below -32, then multiplying it by 1000 will cause the number to exceed the valid range of an integer.
I think the second to last bracket is misplaced... I think it should be:
return((int)((((long)gyro_rate * GYRO_SENSITIVITY * 5L) / ADC_RANGE) * GYRO_CAL_FACTOR));
Is there a problem with the Get_Gyro_Rate() function? We will be depending on it heavily this year, and need it to function correctly.
Kevin Watson
27-01-2008, 20:17
Is there a problem with the Get_Gyro_Rate() function? We will be depending on it heavily this year, and need it to function correctly.Yes, Phil caught an error that would cause the function to overflow if you rotated your gyro fast enough. This is what the fixed code currently looks like:
return((int)(((((long)gyro_rate * GYRO_SENSITIVITY * 5L) / ADC_RANGE)) * GYRO_CAL_FACTOR));
-Kevin
billbo911
27-01-2008, 20:31
Yes, Phil caught an error that would cause the function to overflow if you rotated your gyro fast enough. This is what the fixed code currently looks like:
return((int)(((((long)gyro_rate * GYRO_SENSITIVITY * 5L) / ADC_RANGE)) * GYRO_CAL_FACTOR));
-Kevin
Excellent!! We will modify the code accordingly until an updated version comes out!
Thanks again Kevin. Your work is appreciated more than I can express.
And here is some code to remap gyro values to the standard format
rev = temp_gyro_angle/3600;
if (temp_gyro_angle < 0)
{
gyro = temp_gyro_angle - (3600*(rev));
if (gyro < 1800)
{
gyro+= 3600;
}
}
if (temp_gyro_angle > 0)
{
gyro = temp_gyro_angle - (3600*(rev));
if (gyro > 1800)
{
gyro-= 3600;
}
}
if (gyro > 1800)
{
gyro -= 3600;
}
We are trying to compile and down load the base 3.0 code using MPLab IDE 7.62 and the Upgrade version of C18 compiler to 3.10. We tried downloading to the 2006 and 2007 controllers (8722). However, we are getting a code error and the program light is flashing rapidly.
My question is a) can the 3.0 code work in the 2006/2007 controllers? If so, then what other situation may cause the program error to light and program light to blink rapidly?
Edited:
Found the problem. I had forgotten to uncomment the defines in ifi_frc.h; but I had uncommented everything else in the rest of the code. No error messages during the build, but immediately after the the download the controller was crashing.
Also, Kevin, thanks for the great work on the code this year.
D. Sean Kelly
Toltechs #499
MPLab IDE 7.62 C18-Compiler 3.10
Just FYI, I believe that I have a single version of the code that will work with all robot controllers from 2004 on and can be built with C18 2.4 or 3.1. After seeing if I can improve the gyro integration code (per Philbot's posting above), doing some additional testing, and writing a bit more documentation, I should be able to release the code in the next few days.
-Kevin
Hi Kevin,
I'd like to add my thanks for the great work on the new framework.
We use the 8520 for small groups prototyping code. I know you are working on a set of code that will work for all controllers, but I was wondering if the message you have in adc.c:
* This version will only work with PIC18F8722 based robot
* controllers. You should use version 0.3 of this software
* with a PIC18F8520 based robot controller.
is still valid. And if so, how would I go about getting version 0.3 of the adc.[ch]?
Thanks!
Kevin Watson
28-01-2008, 23:22
I was wondering if the message you have in adc.c:
* This version will only work with PIC18F8722 based robot
* controllers. You should use version 0.3 of this software
* with a PIC18F8520 based robot controller.
is still valid. And if so, how would I go about getting version 0.3 of the adc!Yes, that version will only work properly with the '8722. I'll be releasing a unified version soon that will work with both robot controllers and C18 2.4 & 3.0+. I'll release it when I'm finished with a major revision of the gyro code.
-Kevin
(If you can't wait and promise to report any bugs you find, here's a snapshot (http://kevin.org/frc/ifi_frc_sensor.zip) of the latest build without the gyro mods)
Kevin Watson
29-01-2008, 14:10
I've posted a snapshot of what I hope is the last build for a while. The changes are numerous and include improved gyro code. The documentation still needs some work, but the code should be complete. If you're willing to test it and provide feedback and/or bug report(s), you'll find it here: http://kevin.org/frc/ifi_frc_sensor.zip.
-Kevin
sparrowkc
29-01-2008, 16:20
when I call Get_Gyro_Rate() it tends to give occasional outliers and data that doesn't make sense. When I turn the gyro constantly one direction, jumps back and forth between positive numbers. Get_Gyro_Angle() works fine and is accurate. I am testing with last year's kit gyro.
Alan Anderson
29-01-2008, 16:29
when I call Get_Gyro_Rate() it tends to give occasional outliers and data that doesn't make. When I turn the gyro constantly one direction, jumps back and forth between positive numbers. Get_Gyro_Angle() works fine and is accurate. I am testing with last year's kit gyro.
You might be seeing the issue resolved here (http://www.chiefdelphi.com/forums/showpost.php?p=686933&postcount=311).
sparrowkc
29-01-2008, 16:31
I downloaded the Sensors code from Kevin's site just yesterday, was it not fixed then?
Kevin Watson
29-01-2008, 16:42
I downloaded the Sensors code from Kevin's site just yesterday, was it not fixed then?The public version on the website still has the bug. I hope to replace that version with the new version (link a few messages back) tonight after you guys (hopefully) try it out and report any issues.
-Kevin
Just transferring the new code over to my dev. code.
Noticed that the Get_Gyro_Bias_Status() function looks like a bad cut/paste from another function. No return value.
unsigned char Get_Gyro_Bias_Status(void)
{
// zero out gyro_angle
gyro_angle = 0L;
}
Guy Davidson
29-01-2008, 23:00
Other than the Get_Gyro_Bias_Status Phil noted above, I haven't found any problems with the latest code. I only messed around with the relativly simple stuff today - I'll be doing some more intensive encoder and gyro (maybe) based testing tomorrow, so I'll let you know about those after I do that.
Great work Kevin
had running a gyro, a MatBotrix Ultrasonic ranger and an encoder!!!!
To get values from the MatBotrix, I needed to use Get_ADC_Result and then Convert_ADC_to_mV....the Get_Analog_Value didn't work.
Kevin Watson
29-01-2008, 23:31
Just transferring the new code over to my dev. code.
Noticed that the Get_Gyro_Bias_Status() function looks like a bad cut/paste from another function. No return value.Ouch. Let me see what happened...
-Kevin
Kevin Watson
30-01-2008, 00:13
Other than the Get_Gyro_Bias_Status Phil noted above, I haven't found any problems with the latest code. I only messed around with the relativly simple stuff today - I'll be doing some more intensive encoder and gyro (maybe) based testing tomorrow, so I'll let you know about those after I do that.Thanks!
-Kevin
Kevin Watson
30-01-2008, 00:16
Just transferring the new code over to my dev. code.
Noticed that the Get_Gyro_Bias_Status() function looks like a bad cut/paste from another function. No return value.I don't know what I did, but the correct version should be on the server. Thanks again for your help.
-Kevin
Kevin Watson
30-01-2008, 00:29
...the Get_Analog_Value didn't work.I'm pretty sure you'll get corrupted data if you try to use Get_Analog_Value() while the ADC code is running in the background.
-Kevin
Lummis1647
30-01-2008, 18:38
I'm having a huge problem with the lastest code I just downloaded 2 hours ago. I'm using version 2.4 of the compiler. I followed all of the instructions in the readmes, but if I call Initialize_ADC(); and Initialize_Gyro(); in teleop/Initialization(), I'll get a blinking red and green light next to program state on the rc. On the output window, "IFI User Pr" shows up, making me think that it runs into an error in the middle of trying to print the printf:IFI User Processor Initialized ...\r\n. There are no problems when those 2 function calls are commented out(initialize gyro and adc). I've tried a combination of commenting and uncommenting the gyro code in teleop and the process_gyro_data function in teleop_spin. I don't get this problem with an earlier version of the 2.4 gyro beta code. I'm really not sure what to do. Any one else have this problem? Does this work for anyone using 2.4- the hex file builds and in ifi_frc.h I have USE_C18_24 #defined only. I'd really appreciate any suggestions. Thanks.
Kevin Watson
30-01-2008, 19:37
I'm having a huge problem with the lastest code I just downloaded 2 hours ago. I'm using version 2.4 of the compiler. I followed all of the instructions in the readmes, but if I call Initialize_ADC(); and Initialize_Gyro(); in teleop/Initialization(), I'll get a blinking red and green light next to program state on the rc. On the output window, "IFI User Pr" shows up, making me think that it runs into an error in the middle of trying to print the printf:IFI User Processor Initialized ...\r\n. There are no problems when those 2 function calls are commented out(initialize gyro and adc). I've tried a combination of commenting and uncommenting the gyro code in teleop and the process_gyro_data function in teleop_spin. I don't get this problem with an earlier version of the 2.4 gyro beta code. I'm really not sure what to do. Any one else have this problem? Does this work for anyone using 2.4- the hex file builds and in ifi_frc.h I have USE_C18_24 #defined only. I'd really appreciate any suggestions. Thanks.My guess is that you didn't enable the timer 4 ISR in ifi_frc.h.
-Kevin
SuspectZero
30-01-2008, 23:24
will the encoder code work with the US Digital E4P-250-250 encoder which is built-in on the Andy Mark Super Shifter transmission? also what kind of output should u expect from the encoder and the gyro?
Alan Anderson
31-01-2008, 00:24
will the encoder code work with the US Digital E4P-250-250 encoder which is built-in on the Andy Mark Super Shifter transmission?
The E4P is a standard quadrature encoder. I can assure you that it works perfectly with Kevin's encoder library for the standard IFI code, and I have very high confidence that it will work just as perfectly with his new framework.
Having the same problem with the new code as someone mentioned before.
When I build the project with Initialize_ADC() uncommented, it builds fine but encounters a code error.
When I build the project with ENABLE_TIMER_4 defined in timers.h, the linker encounters the error:
Error - symbol 'Timer_4_ISR' has multiple definitions.
I have tried commenting out the definition for Timer_4_ISR() in timers.c (because it does nothing) but we get back to the code error. Also, ENABLE_TIMER_4 is defined in ifi_frc.h.
Using a 2007 RC, MCC18 3.10;
Thanks!
-James
per Kevin's read-me
2) Enable the timer 4 interrupt service routine in ifi_frc.h
3) Make sure timer 4 is disabled at the top of timers.h.
Kevin Watson
03-02-2008, 12:38
I've written replacement code for IFI's Get_Analog_Value() function. It's now included with both builds of the new code on my website. You can also just grab the files (http://kevin.org/frc/quick_adc.zip) and drop then into your project.
-Kevin
So, per your documentation, to use your 'quickie' adc code, you shouldn't run them with the gyro code, right?
Kevin Watson
03-02-2008, 14:21
So, per your documentation, to use your 'quickie' adc code, you shouldn't run them with the gyro code, right?No, you shouldn't as they'll interfere with each other. You can always just increase the number of analog channels sampled by the adc.c code when using the gyro.
-Kevin
Code Monkey
06-02-2008, 19:18
I have gotten Timer0 to work as a clock for the code. A few misadventures (like not putting the initialize function in the Initialization.c in Teleop.c), but actually is very easy to implement in the new code with the prescaling.
I have not gotten the encoder 3 and 4 to work. no error messages, but get_encoderX_count always comes back 0. any ideas?
Kevin Watson
06-02-2008, 19:52
I have gotten Timer0 to work as a clock for the code. A few misadventures (like not putting the initialize function in the Initialization.c in Teleop.c), but actually is very easy to implement in the new code with the prescaling.
I have not gotten the encoder 3 and 4 to work. no error messages, but get_encoderX_count always comes back 0. any ideas?If it builds with no error messages it's probably because you didn't enable the call to the encoder ISRs at the top of ifi_frc.h.
I'm thinking about password protecting the project zip files with a password that's something like read_the_readme.txt_file_before_doing_anything :).
-Kevin
Okay, I'm having a little more trouble... I'm trying to get some potentiometers working on our robot, so I read the readme and did everything it told me to do:
My comments are in all capitals.
FROM README.TXT
By default the analog to digital and gyro software is disabled.
Perform these steps to get your gyro working:
1) Enable the Initialize_ADC() and Initialize_Gyro() functions in
teleop.c/Initialization(). CHECK, REMOVED THE // BEFORE INITIALIZE_ADC(), LEFT THE GYRO ALONE
2) Enable the timer 4 interrupt service routine in ifi_frc.h CHECK
3) Make sure timer 4 is disabled at the top of timers.h. CHECK, THE // WERE ALREADY THERE, NO CHANGE
4) Depending on the operating modes you will be using the gyro,
place calls to the Process_Gyro_Data() function in the disabled.c/
Disabled_Spin(), autonomous.c/Autonomous_Spin() and/or teleop.c/
Teleop_Spin() functions. DID NOT DO, NOT USING GYRO
5) Add gyro bias calibration code that will execute before you
use your gyro. Example calibration code has been placed in
disabled.c/Disabled() that can be used for the competition (this
requires that you use a mode dongle to emulate the field
controller, which will put you in disabled mode for a period of
time before transitioning to autonomous mode). For testing
purposes you can also use the example code in teleop.c/Teleop()
to make sure your gyro is working. DID NOT DO, NOT USING GYRO
6) Follow the instructions in adc_readme.txt, adc.h, gyro_readme.txt,
and gyro.h for information related to installation and calibration
of your gyro. CHECK, SEE BELOW
FROM ADC_README:
Usage notes:
1) A #include statement for the adc.h header file must be
included at the beginning of each source file that calls the
functions in adc.c. The statement should look like this:
#include "adc.h". ALREADY INCLUDED IN TELEOP.C, CHECK
2) Define the number of analog channels that you'd like this
software to track by opening adc.h and following the embedded
instructions above #define NUM_ADC_CHANNELS. CHANGED THE NUMBER FROM 1 TO 2 SINCE WE'RE USING 2 POTENTIOMETERS, CHECK
3) For advanced users, analog channels can be oversampled to
decrease noise and gain resolution in your analog measurements.
The oversampling ratio can be changed from the default x4
by commenting-out the line #define ADC_SAMPLES_PER_UPDATE_4
found in adc.h and then removing the // from in front of one
of the other options. Measurement range and resolution can be
determined from this table: I'M NOT ADVANCED, SO I LEFT THIS ALONE
ADC Samples Effective
Averaged Bits of Measurement Voltage
Per Update Resolution Range Per Bit
___________ __________ ___________ _________
1 10 0-1023 4.88 mV
2 10 0-1023 4.88 mV
4 11 0-2047 2.44 mV
8 11 0-2047 2.44 mV
16 12 0-4095 1.22 mV
32 12 0-4095 1.22 mV
64 13 0-8191 610 uV
128 13 0-8191 610 uV
256 14 0-16383 305 uV
4) Finally, pick the master sample rate by selecting one
of the available rates found in adc.h. The update rate can
be determined using this formula:
Update Rate =
Sample Rate / (Samples Per Update * Number Of Channels)
LOOKS LIKE YOU HAVE ALREADY DONE THIS USING THIS FORMULA, CHECK
I think I have done everything I needed to do, but when I try to build, it says C:\Robot Code\2008\ifi_frc_sensor_30\teleop.c:256:Error [1105] symbol 'ADC_CH0' has not been defined
Here is where it is saying this...
liftpos = Get_Analog_Value(rc_ana_in01);
I also tried the quick_adc, but I was having trouble, so I went back to this...
Update: I may have fixed it, but I'm unsure... Instead of Get_Analog_Value(rc_ana_in01), I used Get_ADC_Result(1). Will this work? I'm not going to be able to try this on our robot until Saturday as I'm going out of town for the next 2 days.
Kevin Watson
06-02-2008, 21:16
I also tried the quick_adc, but I was having trouble, so I went back to this...You just use a number from 1 to 16 to select the ADC channel. As an example:
liftpos = Get_Analog_Value(1); or liftpos = Quick_ADC(1);
Of course you'd probably want to #define these values in a header file and then the code would look like this:
// this goes at the top of the source file or in a header file like robot.h
#define ARM_ELBOW_POT 1 // analog input one
#define ARM_WRIST_POT 2 // analog input two
unsigned int elbow_pot;
unsigned int wrist_pot;
elbow_pot = quick_adc(ARM_ELBOW_POT);
wrist_pot = quick_adc(ARM_WRIST_POT);
Because it's simpler, I would use quick_adc() if you're only using potentiometers on your 'bot.
-Kevin
emersont49
06-02-2008, 21:53
We are using Kevin's code to read the gyro and control our steering. Our steering is connected to a 10K linear pot. We are reading the pot with get_ADC_value and feeding it to a PID function. The intent is to have servo controlled steering.
We are having a lot of trouble getting the servo to respond properly. We are working on tuning our PID loop and having some success.
Here is my question: We are calling the PID routine in Default_Routine so it executes very 26.2 ms. Should we be calling it in a fast loop?
Thanks again for the help. I found out why the quick_adc.c and quick_adc.h were not working... Even though I said add files to project, it never did copy them to the project folder, like I expected it would... Still getting used to MPLAB. It compiled without any error (just the way I like it :D) and I'm going to try it out hopefully Saturday.
Code Monkey
07-02-2008, 14:24
We had the enables in the IFI_FRC.h. The problem was in the format of the print statement (note to others- output from encoders is a long integer). The encoders were working just fine. Sometimes it really is just dumb stuff. (Thank you Kevin for being patient)
I just tried to build the ifi_frc_sensor project with MPLAB IDE v7.20 and C18 2.4 (had to use the project wizard to create new mcp/mcw files, as I was unable to open the ones that came with). After updating the ifi_frc.h header file to define the proper compiler macro (USE_C18_24), I now am getting these errors:
timers.c:72:Error [1205] unknown member 'PSA' in '__tag_216'
timers.c:72:Error [1131] type mismatch in assignment
Apparently the header file mcc18\p18f8722.h defines T0CON bit 3 as T0PS3, but the timers.c file references it as 'PSA' instead. Should the code read:
#ifdef USE_C18_24
T0CONbits.T0PS3 = 1;
#else
T0CONbits.PSA = 1;
#endif
??
Kevin Watson
08-02-2008, 01:48
I just tried to build the ifi_frc_sensor project with MPLAB IDE v7.20 and C18 2.4 (had to use the project wizard to create new mcp/mcw files, as I was unable to open the ones that came with). After updating the ifi_frc.h header file to define the proper compiler macro (USE_C18_24), I now am getting these errors:
timers.c:72:Error [1205] unknown member 'PSA' in '__tag_216'
timers.c:72:Error [1131] type mismatch in assignment
Apparently the header file mcc18\p18f8722.h defines T0CON bit 3 as T0PS3, but the timers.c file references it as 'PSA' instead. Should the code read:
#ifdef USE_C18_24
T0CONbits.T0PS3 = 1;
#else
T0CONbits.PSA = 1;
#endif
??Looks like another bug in their header file. Your options are to replace the 2.4 p18f8722.h with the 2.44 version in the Documentation folder included with my code, or you can update your compiler to 2.44, which is the same version I use. Here's the link to the secret copy I keep on my website: http://kevin.org/frc/c18_244_update.zip.
-Kevin
How many folks out there are using this code with MPLAB IDE v7.20 and MPLAB C18 2.4? I noticed a comment in encoder.h as follows:
This version is compatible with Microchip C18 3.0+ only
Is this still true?
Kevin Watson
08-02-2008, 17:36
How many folks out there are using this code with MPLAB IDE v7.20 and MPLAB C18 2.4? I noticed a comment in encoder.h as follows:
This version is compatible with Microchip C18 3.0+ only
Is this still true?Ugh. Um, I guess I was a knucklehead and forgot to delete that comment. The code works file with 2.4.
-Kevin
That's what I had guessed, thanks for clarification. Note that this comment also appears in at least one other file as well (interrupts.h), possibly others, too.
David Doerr
08-02-2008, 22:01
Another ADC and Gyro question :)
We want to use the gyro as well as other analog sensors. It appears that using Process_Gyro_Data() in Teleop_Spin(), for example, will check for ADC result count, read the ADC gyro channel only and then reset the ADC result count without reading any other ADC channels. Is that a problem?
The 2007 Process_Gyro_Data() didn't check for ADC result count or do a reset inside the function, so we read our other channels just after Process_Gyro_Data() and before the reset.
Where should ADC channels for our other sensors be read? Do they need to be read in the fast loop at the same time as the gyro channel is read? (Should we insert more Get_Analog_Result()s in Process_Gyro_Data to read the other channels?)
We're using pots with a PID to control steering etc., and ultrasonic sensors.
Thanks...
Kevin Watson
08-02-2008, 22:27
We want to use the gyro as well as other analog sensors. It appears that using Process_Gyro_Data() in Teleop_Spin(), for example, will check for ADC result count, read the ADC gyro channel only and then reset the ADC result count without reading any other ADC channels. Is that a problem?Yes it is. I would modify Process_Gyro_Data() to not reset the the ADC result count, but make sure it does get reset after processing all your other sensor data. I think I'll modify Process_Gyro_Data() to accept a TRUE/FALSE parameter to determine how it behaves in this regard. Thanks for catching another knuckleheaded mistake on my part <grin>.
-Kevin
ldeffenb
09-02-2008, 07:20
Yes it is. I would modify Process_Gyro_Data() to not reset the the ADC result count, but make sure it does get reset after processing all your other sensor data.
We've already done this, but why the recommendation to "reset after processing...other...data"? We simply remember the last count and make sure it has changed before processing more data. That way we are sure to be processing fresh stuff and don't need to tie it all together to get a reset when everyone has had their chance at the latest readings....
Lynn (D) - Team Voltage 386 Software
ldeffenb
09-02-2008, 07:26
And I've been remiss in sending "Thanks" to Kevin, but our software group is LOVING the new code format. It is much more understandable than the earlier default code.
One change we've made is to add a few "always" functions. We hooked them in to the main program and they're called "Always_Spin", "Always_Before", and "Always_After". They get called regardless of the current operating mode. The *_Before and *_After routine get called before and after the invocations of the mode's command packet processing routine.
We did this after we found ourselves adding the same invocations to Disabled_Spin, Teleop_Spin, and Autonomous_Spin for the third time. Always_Spin makes it easy.
Always_After is a handy place to get a last chance to reverse any PWM values for opposing drive motors without having to remember to do it everywhere else. Positive logic rules with the ability to override it for reality where necessary. (Robots shouldn't go forwards when you set PWMs to 0, but when mechanical mounts opposing motors and controls wants red to red to positive consistency, it falls to software to make it all work right).
Lynn (D) - Team Voltage 386 Software
Kevin Watson
09-02-2008, 12:41
We've already done this, but why the recommendation to "reset after processing...other...data"? We simply remember the last count and make sure it has changed before processing more data. That way we are sure to be processing fresh stuff and don't need to tie it all together to get a reset when everyone has had their chance at the latest readings....
Lynn (D) - Team Voltage 386 SoftwareYes, this works too, but keep in mind that the value returned by ADC_Result_Count will roll over at some point, so make sure to use the != operator instead of > in your test (I know you know this Lynn; I'm just mentioning this so others won't make a mistake).
-Kevin
mandrews281
09-02-2008, 14:06
I'm having trouble with the Gyro bias calculation in the code posted on 2/2. If I use the previous code (without the circular buffer), I get a gyro bias of ~2080. With the newer code, I get a gyro bias of ~1660. This make the code think the gyro is spinning continuously. Is there an OBO (off by one) error lurking somewhere? Is anyone else having problems with the updated code?
3dude_2231
09-02-2008, 16:27
btw
I had a problem, I was trying to declare a variable in "interrupts.c",
and use it also in "autonomous.c,"
no matter what i've tried, it didn't work
(nope, trying to redeclare it as an extern in the header didn't work either),
strangely enough, after wasting an hour like an idiot :D,
I've declared it in autonomous.c and it worked like a charm.
incredibly weird..
Kevin
What is the difference in master code from the 2007 controller and the 2008 controller... is there a procedure to update a 2007 controller to the current master code?? I understand that the hardware is 100% the same...
thanks...
Kevin Watson
09-02-2008, 20:12
Kevin
What is the difference in master code from the 2007 controller and the 2008 controller... is there a procedure to update a 2007 controller to the current master code?? I understand that the hardware is 100% the same...
thanks...There is no difference in the hardware or firmware between the 2007 and 2008 robot controllers. The latest revision of the master firmware is version 15, available here:
http://www.ifirobotics.com/docs/frc-master-ver15.zip
You use the IFI loader to send it to the robot controller (the boot loader intercepts it and sends it to the master).
-Kevin
ldeffenb
09-02-2008, 21:27
Kevin,
We just uncovered (and fixed) a potential gotcha in the invocation of Teleop_Init() from main. We tried to access the current state of the OI inputs from there and they weren't available!
We found that the Getdata() call was occurring AFTER the Teleop_Init(). We moved it BEFORE the if(teleop_init_flag) test and it corrected our problem.
On further inspection as I'm writing this, the same issue would plague the other two *_Init() invocations. Simply moving the Getdata call will make the current OI data available to those functions.
Lynn (D) - Team Voltage 386 Software
Kevin Watson
09-02-2008, 22:35
Kevin,
We just uncovered (and fixed) a potential gotcha in the invocation of Teleop_Init() from main. We tried to access the current state of the OI inputs from there and they weren't available!
We found that the Getdata() call was occurring AFTER the Teleop_Init(). We moved it BEFORE the if(teleop_init_flag) test and it corrected our problem.
On further inspection as I'm writing this, the same issue would plague the other two *_Init() invocations. Simply moving the Getdata call will make the current OI data available to those functions.
Lynn (D) - Team Voltage 386 SoftwareHmmm... I'll have a look at it later tonight.
Edit: I'll change it when I make the changes mentioned above, but I don't see where this could cause a ploblem as the OI data from the previous Getdata() should be valid. What problem were you having?
-Kevin
-Kevin
1jbinder
09-02-2008, 23:51
Hi Kevin,
Our robot this year is using four different omnis that need 4 different encoders. The problem is we need to use four encoders this year. We used the encoders 3-6. We noticed that 3-4 were working but 5-6 only gave 0's and 1's. After looking at the ISR's for the encoders 5 and 6 i realized that 3 and 4 only worked on rising edge interrupt but 5 and 6 worked on both. After i changed 5 and 6 to be like 3 and 4 they worked but i do not understand why. there are four variables that i am using, two of which you use that are not declared anywhere. They are Encoder_3_State, Encoder_4_State, Encoder_5_State, and Encoder_6_State. Do you know where these variables are declared. Also why are the encoder 3-4 ISR's different from the encoder 5-6 ISR's.
Thanks in advance,
Julian
ldeffenb
10-02-2008, 00:09
...They are Encoder_3_State, Encoder_4_State, Encoder_5_State, and Encoder_6_State. Do you know where these variables are declared.
Look at lines 70-86 (at least in my copy) of encoder.c. You'll see the declarations there.
.
Also why are the encoder 3-4 ISR's different from the encoder 5-6 ISR's.
From Kevin's encoder_readme.txt from 2 years ago:
Encoder channels one and two are optimized for velocity control
and will generate the least number of interrupts per encoder
count (one per encoder count). These channels may have problems
in position control applications because they can be fooled
into thinking that the encoder shaft is rotating if the shaft
happens to stop very near a phase-A transition and then wobbles
back and forth across that transition.
Encoder channels three and four are optimized for position
control. For these channels, software examines both transitions
of phase-A and can't be fooled into miscounting the number
of encoder counts. The downside to using these channels is that
for a given encoder, they will generate twice the number of
interrupts as channels one and two (two per encoder count).
Encoder channels five and six are just like channels three and
four, but offer the bonus of increasing the precision of your
encoder by a factor of two for free. Unlike channels one
through four, which will increment or decrement on each rising
(zero to one) transition, these two channels will increment or
decrement on both transitions of phase-A. In other words, if
you attach a 64 count-per-revolution encoder to one of these
two channels, you'll read 128 counts when you rotate the shaft
exactly one revolution.
Have you resolved this issue? We're having the same problem, but with the C18 V3.10 compiler & beta code.
There seems to be something amiss when using the combination of MPLAB 8.0, C18 V2.4, the V2.4 beta code and the MPLAB SIM debugger. I think that's a "legal" combination, right? The simulator seems to be going off into the weeds when it hits line 373 (serial port enable) of serial_ports.c. The odd thing is that if you step through it it hangs up on that line, but if you let it run it instead hangs up on line 427 of ifi_frc.c, which is _do_cinit();
Is this just a question of the beta code not supporting MPLAB SIM? I don't think I've seen any _SIMULATOR definitions in either the 2.4 or the 3.1 beta code.
Edit: The same thing happens when I run the 3.1 beta code with C18 v3.1. Maybe I'm the only one trying to use MPLAB SIM? It worked like a champ with last year's code.
mandrews281
10-02-2008, 22:58
First, I really like the new code organization (that seems to be a common theme). One suggestion though. I'd like to see the *_Init routines called whenever the mode switches. This probably won't affect the matches where things are always: disable->autonomous->teleop->disable. But we were chasing a bug in our autonomous because we were forgetting to reset the robot between runs, and the Autonomous_Init() routine wasn't getting called (we were continuously toggling between disabled and autonomous.
Anyway, back to autonomous programming.
Kevin Watson
11-02-2008, 03:21
Just FYI, I've updated the code to address these three minor issues:
http://www.chiefdelphi.com/forums/showpost.php?p=694788&postcount=348
http://www.chiefdelphi.com/forums/showpost.php?p=694921&postcount=351
http://www.chiefdelphi.com/forums/showpost.php?p=695531&postcount=360
-Kevin
Kevin Watson
11-02-2008, 03:28
Have you resolved this issue? We're having the same problem, but with the C18 V3.10 compiler & beta code.For some unknown reason (yes, I've checked the RCON register) the simulated processor is resetting when serial port one gets enabled. This causes the 32 entry call stack to overflow (which shouldn't happen in real hardware). This seems to be a problem with the simulator and not something I can fix.
-Kevin
For some unknown reason (yes, I've checked the RCON register) the simulated processor is resetting when serial port one gets enabled. This causes the 32 entry call stack to overflow (which shouldn't happen in real hardware). This seems to be a problem with the simulator and not something I can fix.
-Kevin
Is there a workaround? Why is this happening this year and not last year? Thanks for your help.
Ann
Joe Ross
11-02-2008, 13:12
I'm having trouble with the Gyro bias calculation in the code posted on 2/2. If I use the previous code (without the circular buffer), I get a gyro bias of ~2080. With the newer code, I get a gyro bias of ~1660. This make the code think the gyro is spinning continuously. Is there an OBO (off by one) error lurking somewhere? Is anyone else having problems with the updated code?
I heavily modified the ADC code and was having issues with the data in the gyro bias buffer being corrupted. In the process of trying to figure that out, I looked at the bias calculation heavily and did not find any logic errors in it.
I never did solve my problem, though, so there might be a problem lurking in that code.
Joe Ross
11-02-2008, 13:14
Is there a workaround? Why is this happening this year and not last year? Thanks for your help.
Ann
See if the solution in this thread helps: http://www.chiefdelphi.com/forums/showthread.php?t=62816
ldeffenb
11-02-2008, 13:55
but I don't see where this could cause a ploblem as the OI data from the previous Getdata() should be valid. What problem were you having?
Here's the deal. When the robot powers up in teleop, as is normal outside of competition, the first routine of ours that gets called is teleop_init, before (at least originally) the first call to getdata (except for the getdata before initialization, which I suspect doesn't include OI data).
We were grabbing some switch values in teleop_init into a static variable to detect when/if the operator changes those switches during the normal teleop(). We do this to avoid moving some of our appendages on first power up until someone at the control panel asks them to move (safety considerations).
Since telop_init() was only invoked once, before the first (real) getdata, we didn't see the real OI switches and concluded that the operator had, in fact, moved them when teleop got called after the getdata invocation.
Thanks for considering the changes, and check out my next post. It's going to point out another 26.2msec issue in this same area of the code.
Lynn (D) - Team Voltage 386 Software
ldeffenb
11-02-2008, 14:01
Kevin,
Given the structure of the code in main() surrounding the modal invocations and the position of the getdata() calls, it appears to me that the new code structure actually invokes the previous mode with the new mode's getdata() results immediately after a mode switch.
Consider: robot is in disable, rcdata has that fact recorded, hybrid begins. main() detects disabled mode, detects that new data is available, calls getdata() receiving the new autonomous flag but invokes disabled() anway. Autonomous_init() and Autonomous() doesn't get called until the NEXT command packet, 26.2msec later.
I've not done it yet, but I'm planning to restructure our main() to something like this (just pseudo code, not real code):
main loop:
if (new data available)
{ getdata();
set newdata flag;
}
if (...mode...)
{
all of the existing mode_init and mode() calls here, but no getdata or putdata() calls
}
if (newdata flag)
{ putdata();
}
goto main loop:
With this structure, the newly gotten mode is the one checked and invoked with the getdata() packet.
I hope to first prove this with a mode-checking printf in one (or all) of the _init() routine that check if the mode we're in is reflected in rcdata (hidden by the #defines for the mode flags). I suspect it is not.
Lynn (D) - Team Voltage 386 Software
PS. This also makes our new always_before(), always_after(), and always_spin MUCH easier to hook in, now that I've written it out! always_before() right after the getdata(), always_after() just before the putdata(), and always_spin, well, always in the loop!
Dave Flowerday
11-02-2008, 15:04
Kevin,
We discovered a side effect of the new code setup that I thought I should point out. I've only read this thread sporadically, so maybe it's already been mentioned - if so apologies for bringing it up again.
We had some feedback code that we implemented in the _Spin() functions since we wanted it to execute faster than the 26.2ms rate. The side effect that we found was that if you do something which causes your Autonomous() code (for instance) to take longer than 26.2ms to execute, then Autonomous_Spin() will never execute. The problem this caused for us was that our feedback was obviously not running when this occurred.
Anyway, I don't consider this a flaw in the code or anything, merely a behavior that I wanted to make sure others were aware of. We will probably modify ifi_frc.c and remove the "else" blocks around the _Spin() functions, which will ensure that the _Spin() code gets executed at least once per main loop.
Maybe it would be worth a note in the comment blocks before each _Spin() function noting that those functions will only be called if there's extra time left over after processing the new command packet.
Dave
Kevin Watson
12-02-2008, 04:17
...we found was that if you do something which causes your Autonomous() code (for instance) to take longer than 26.2ms to execute, then Autonomous_Spin() will never execute. The problem this caused for us was that our feedback was obviously not running when this occurred.Dave,
Thanks for catching this. IFI's code behaves the way you describe, so I went ahead and removed the three surrounding else statements. I also added support for the MPLAB simulation tool. The code is up on my website now.
-Kevin
Guy Davidson
12-02-2008, 14:34
Kevin,
What is the procedure for adding additional analog sensors with the gyro code? I changed the number of ADC channels, plugged the (pots, in my case) in to channels 2 and 3, and added the code to read them in the Process_Gyro_Data function.
While I've been able to read the values (by converting the number to milivolts, as otherwise I'm not exactly sure what I'm seeing), the gyro has since been going crazy. I wired the gyro to an oscilloscope, and it still works, but the code (after given time to initialize and computing the bias) sees crazy values. Any idea what I'm doing wrong? Is there any readme to using the gyro with other analog values I'm missing?
Thanks.
billbo911
12-02-2008, 14:58
Kevin,
What is the procedure for adding additional analog sensors with the gyro code? I changed the number of ADC channels, plugged the (pots, in my case) in to channels 2 and 3, and added the code to read them in the Process_Gyro_Data function.
..the gyro has since been going crazy. I wired the gyro to an oscilloscope, and it still works, but the code (after given time to initialize and computing the bias) sees crazy values ...
Thanks.
Just a thought, here is a quote from the header of the gyro.c/Process_Gyro_Data
FUNCTION: Process_Gyro_Data()
*
* PURPOSE: Manages ADC data and does gyro rate integration
*
* CALLED FROM: ifi_frc.c/Disabled_Spin(),
* ifi_frc.c/Autonomous_Spin(),
* ifi_frc.c/Teleop_Spin()
*
* PARAMETERS: Unsigned char with a value of zero will prevent this
* function from calling Reset_ADC_Result_Count() when
* ADC data has been processed. If you do use this mode
* of operation you must call Reset_ADC_Result_Count()
* from your own code. Failure to do this will cause
* the gyro to stop functioning.
Are you calling Reset_ADC_Result_Count() from your code?
Guy Davidson
12-02-2008, 15:50
Just a thought, here is a quote from the header of the gyro.c/Process_Gyro_Data
Here's the code to my Process_Gyro_Data (it isn't the latest revision with the input character):
void Process_Gyro_Data(void)
{
int temp_gyro_rate;
// fresh ADC data available?
if(Get_ADC_Result_Count())
{
// should the completed sample set be used to calculate the gyro bias?
if(calc_gyro_bias == 1)
{
// put the ADC reading on the circular queue
Gyro_Queue[Gyro_Queue_Index] = Get_ADC_Result(GYRO_CHANNEL);
// increment the write pointer
Gyro_Queue_Index++;
// is the circular queue now full?
if(Gyro_Queue_Index == GYRO_QUEUE_SIZE-1)
{
// update the gyro bias status
Gyro_Bias_Status = GYRO_BIAS_BUFFER_FULL;
}
// If the index pointer overflowed, cut-off the high-order bit. Doing this
// every time is quicker than checking for overflow every time with an if()
// statement and only then occasionally setting it back to zero. For this
// to work, the queue size must be a power of 2 (e.g., 16,32,64,128).
Gyro_Queue_Index &= GYRO_QUEUE_INDEX_MASK;
}
else
{
// get the latest measured gyro rate
temp_gyro_rate = (int)Get_ADC_Result(GYRO_CHANNEL) - gyro_bias;
// update reported gyro rate and angle only if
// measured gyro rate lies outside the deadband
if(temp_gyro_rate < -GYRO_DEADBAND || temp_gyro_rate > GYRO_DEADBAND)
{
// update the gyro rate
gyro_rate = temp_gyro_rate;
// integrate the gyro rate to derive the heading
gyro_angle += (long)temp_gyro_rate;
}
else
{
gyro_rate = 0;
}
}
left_pot_value = Convert_ADC_to_mV(Get_ADC_Result(2));
right_pot_value = Convert_ADC_to_mV(Get_ADC_Result(3));
Reset_ADC_Result_Count();
}
}
Kevin Watson
12-02-2008, 17:06
Kevin,
What is the procedure for adding additional analog sensors with the gyro code? I changed the number of ADC channels, plugged the (pots, in my case) in to channels 2 and 3, and added the code to read them in the Process_Gyro_Data function.
While I've been able to read the values (by converting the number to milivolts, as otherwise I'm not exactly sure what I'm seeing), the gyro has since been going crazy. I wired the gyro to an oscilloscope, and it still works, but the code (after given time to initialize and computing the bias) sees crazy values. Any idea what I'm doing wrong? Is there any readme to using the gyro with other analog values I'm missing?
Thanks.Yeah, I'm a knucklehead for changing how Process_Gyro_Data() works. I'll post some code to show you how to use the other ADC channels. While waiting, you should go grab a copy of the code Bill mentions above.
-Kevin
Kevin Watson
12-02-2008, 22:05
Kevin,
What is the procedure for adding additional analog sensors with the gyro code? I changed the number of ADC channels, plugged the (pots, in my case) in to channels 2 and 3, and added the code to read them in the Process_Gyro_Data function.
While I've been able to read the values (by converting the number to milivolts, as otherwise I'm not exactly sure what I'm seeing), the gyro has since been going crazy. I wired the gyro to an oscilloscope, and it still works, but the code (after given time to initialize and computing the bias) sees crazy values. Any idea what I'm doing wrong? Is there any readme to using the gyro with other analog values I'm missing?
Thanks.This code works for me:
void Teleop_Spin(void)
{
Process_Gyro_Data(FALSE); // <- Note the change to "FALSE"
// fresh ADC data available?
if(Get_ADC_Result_Count())
{
left_pot_value = Convert_ADC_to_mV(Get_ADC_Result(2));
right_pot_value = Convert_ADC_to_mV(Get_ADC_Result(3));
Reset_ADC_Result_Count();// <- Make sure to call this when finished
}
}
-Kevin
Joe Ross
13-02-2008, 13:03
It looks like C18 3.16 has been released. The release notes claim to have fixed the ADC header file issue.
Kevin Watson
13-02-2008, 13:10
It looks like C18 3.16 has been released. The release notes claim to have fixed the ADC header file issue.I haven't done much testing, but my code builds with 3.16.
-Kevin
Ken Streeter
13-02-2008, 17:10
Sub-Subject: Using PWM() for a 100Hz Control Loop
I'm trying to understand how to use the PWM() function in order to implement a 100Hz PID control loop (rather than the default ~38.2 Hz).
I believe I understand the previous postings, but I'm getting stuck on when (and how often) PWM() needs to be called in order to generate output values. I have five questions below, buried in the posting. Answers (or any help, for that matter) to these questions would greatly aid my understanding. Thanks!
The "pwm_readme.txt" file says the following:
PWM()
Each time this function is called, one and only one pulse is
generated on each of the four outputs. This function is
called from ifi_frc.c/main() with an update rate of just over
thirty-eight hertz. PWM() can be called from other sections
of your code for higher control rates...
Looking into the code in PWM.c, I see where the pulse is commenced near the end of PWM():
// setup CCP hardware for compare mode (each PWM output
// transitions from low to high at this point)
CCP2CON = 0x09;
CCP3CON = 0x09;
CCP4CON = 0x09;
CCP5CON = 0x09;
However, I don't see where the transition from high to low occurs. (I know nothing about "CCP".) Is the high-low transition performed automatically somehow at a later time? (Q#1) Is there an interrupt service routine associated with the timer being used (timer3) or is no ISR needed for this style of usage? (Q#2)
Assuming that the high-low transition is occurring automatically with the CCP hardware, when does the next low-high transition occur? (Q#3)
It sounds from the one line in the pwm_readme.txt that the next low-high transition will not occur until PWM() is again called. This implies that I need to call PWM() repeatedly, even if we aren't changing the pwm values. Could we just call PWM() as fast we possibly can? (i.e. in every loop in Teleop_Spin() or Autonomous_Spin()) (Q#4).
If it would be bad to call PWM() as fast as we possibly can (because something would break), then presumably we need to call PWM() from Teleop_Spin() and/or Autonomous_Spin() at no more than about a 100Hz rate. If so, then do we need to take out the calls to PWM() in ifi_frc.c so that we're not actually calling PWM() 138 times a second? (Q#5) (100 times from our 100Hz section of *_Spin() and an additional 38 times a second in the block of code in ifi_frc.c which calls Autonomous() or Teleop())
I realize that these are almost surely "newbie" questions for anybody experienced with CCP, but that's where I am in my understanding of this right now. I ask your forgiveness for the "newbie" questions but don't know where else to turn to help, as I'm having trouble finding these answers in the documentation.
Thanks,
--ken
Ken Streeter
13-02-2008, 17:33
In a previous message in this thread regarding the setup of a timer for a 100Hz loop, the following question was asked:
EDIT 2: Timer 0 does not seem to have the support to run to a predetermined value like timers 2,3,4. Should we use timer 2 instead? Another question. None of these timers actually allow us to run a 100hz cycle, even with 1:16 pre- and post-scalers. The slowest we can do is 150hz. Am I missing a way to do it, without using a second flag, or should we just use 150hz (or a double flag)?
I looked through the thread for an answer to this question, but couldn't find one. Does anybody have a code snippet which configures a timer for 100Hz?
Thanks!
--ken
Kevin Watson
13-02-2008, 18:07
In a previous message in this thread regarding the setup of a timer for a 100Hz loop, the following question was asked:
I looked through the thread for an answer to this question, but couldn't find one. Does anybody have a code snippet which configures a timer for 100Hz?
Thanks!
--kenYes, this is certainly possible. Set a timer to go off at 100Hz, but don't set the interrupt enable bit to one. Now craft a piece of code that will execute in one or more of the fast loops. In that code you should test to see if the timer interrupt flag gets raised, and if so, do your PID calculations and then call PWM() at the end. You'll need to comment out the call to PWM() in main() if you're using my code.
-Kevin
Kevin Watson
15-02-2008, 00:56
I've created drop-in replacement code for timer.c and timer.h that implements a millisecond system clock using timer 2. The code is available here: http://kevin.org/frc/ifi_clock.zip.
-Kevin
cliff451
15-02-2008, 17:54
We have been using the new code with great success, but whenever we set NUM_ADC_CHANNELS above 3, the analog input values including the gyro become unreliable. We also tried to adjust the sampling rates some, but this did not seem to help the problem. What have we missed?
Guy Davidson
15-02-2008, 18:04
We have been using the new code with great success, but whenever we set NUM_ADC_CHANNELS above 3, the analog input values including the gyro become unreliable. We also tried to adjust the sampling rates some, but this did not seem to help the problem. What have we missed?
We've been running into a similar issue - the gyro seems to drift way more when additional ADC channels are enabled. Is there any workaround?
Kevin Watson
16-02-2008, 12:57
We have been using the new code with great success, but whenever we set NUM_ADC_CHANNELS above 3, the analog input values including the gyro become unreliable. We also tried to adjust the sampling rates some, but this did not seem to help the problem. What have we missed?
We've been running into a similar issue - the gyro seems to drift way more when additional ADC channels are enabled. Is there any workaround?
I suspect the KOP gyro can't drive the sample-and-hold capacitor fast enough. If you have additional channels, those channels could drive the capacitor to very different voltages than what you gyro is sending out. When the ADC circuit switches to the gyro input, the gyro has very little time to push or pull charge into or out of the capacitor. The end result could be inaccurate gyro readings. As an experiment, sample the additional channels, but don't connect anything to those inputs. If the gyro works better, my theory starts looking good. Assuming my theory is correct, try using the adc_8520.c code instead as it should give the gyro additional time to charge the capacitor before the analog to digital conversion begins. If you're handy building circuits, you can also try using a very simple op-amp based voltage follower to better drive the capacitance. If you try these potential solutions, please report back here with your results.
EDIT: Another possibility is that you're not allowing enough time to calculate the bias. See my next message.
-Kevin
Hey Kevin, I'm testing the 2007 gyro with your latest code. It works great when NUM_ADC_CHANNELS is one. But when I set it to four, I get a gyro bias of like 1660 - instead of the usual 2080- and then a constant rate when it's not moving. I don't have anything besides the gyro connected to the RC i'm testing it with. Is it possible this has something to do with the calculation of the gyro bias?
Edit: Could it be because I'm using the default gyro testing code in teleop.c which does not have enough time to fill the Gyro_Queue. I plan to test this theory tomorrow, and is there any reason why I shouldn't make the ADC_SAMPLE_RATE 3200HZ?
Kevin Watson
17-02-2008, 23:51
Is it possible this has something to do with the calculation of the gyro bias?Possibly. What may be happening is that you've added four channels, which means it takes four times longer to acquire the 64 updates (remember update rate = sample rate/samples per update) necessary to calculate the bias. Use the Get_Gyro_Bias_Status()
function to determine when it's safe to call Stop_Gyro_Bias_Calc() function. Here's info from the header:
/************************************************** *****************************
*
* FUNCTION: Get_Gyro_Bias_Status()
*
* PURPOSE: Returns status of a gyro bias calculation.
*
* CALLED FROM:
*
* PARAMETERS: None
*
* RETURNS: GYRO_BIAS_NOT_DONE if a gyro bias has not been calculated.
*
* GYRO_BIAS_IN_PROCESS after Start_Gyro_Bias_Calc() has been
* called and data is being collected
*
* GYRO_BIAS_BUFFER_FULL if the circular buffer is full,
* indicating that it is safe to call Stop_Gyro_Bias_Calc().
*
* GYRO_BIAS_READY if a gyro bias has been calculated.
*
* COMMENTS:
*
************************************************** *****************************/
-Kevin
I think that's it because I just did the calculations for a 800hz sampling rate and 16 samples per update. It takes 5.12 seconds to fill the gyro queue and the testing code only calculates the bias for 4 seconds. If I'm just reading some pots during the 26.2 ms loop, is there any reason I should reset adc result count in my own code as opposed to doing in the gyro code?
Edit:
Would the bias be any more accurate if the gyro_queue replaced some of it's first values it got from start up?
CardcaptorRLH85
18-02-2008, 16:43
I'm in a bit of a bind...I'm having a bit of a problem integrating the PID code available at http://www.kevin.org/frc/2005/ with this new code. I've been looking through the PID code and I have absolutely no idea where to start trying to make them work with one another. I'd greatly appreciate any help I can get here....
Kevin.
I'm trying to get the camera code going with the new 3.0 code. I'm not receiving ACKs or NCKs so it fails at init state 3 return value 131. serial_ports.h/c looks ready to go for port2 9600 baud and interrupts.
Integrated camera.c terminal.c and tracking.c without any issues.
Anything obvious come to mind reagrding serial port initialization?
Chad
David Doerr
19-02-2008, 07:59
Kevin.
I'm trying to get the camera code going with the new 3.0 code... Anything obvious come to mind reagrding serial port initialization?
Chad,
Try setting serial port 2 to 115200 baud.
Dave
Guy Davidson
19-02-2008, 20:04
I've been running into an odd problem with encoders.
Encoder 1 works perfectly fine during the teleop period, but does not give me anything during the autonomous one. Encoder 2 works in both teleop and autonomous. The initialization functions is called during both the autonomous and disabled initialization routines.
I am running your latest code build, as far I as know, with MPLAB 8 and C18 3.10. While the robot is shipped already, I'd love to hear if you have any suggestions for what to try.
It could be that the encoder is working, and is giving the correct signals, but is always printing a zero in my debug statement, and the code that is executing makes me believe that it is seeing a zero (as the count). But when I print out the count in the teleop mode, I get numbers that make sense.
Kevin
Do you have access to an Explorer 16 board from Microchip??
pogenwurst
20-02-2008, 00:32
I've been running into an odd problem with encoders.
Encoder 1 works perfectly fine during the teleop period, but does not give me anything during the autonomous one. Encoder 2 works in both teleop and autonomous. The initialization functions is called during both the autonomous and disabled initialization routines.
I am running your latest code build, as far I as know, with MPLAB 8 and C18 3.10. While the robot is shipped already, I'd love to hear if you have any suggestions for what to try.
It could be that the encoder is working, and is giving the correct signals, but is always printing a zero in my debug statement, and the code that is executing makes me believe that it is seeing a zero (as the count). But when I print out the count in the teleop mode, I get numbers that make sense.
I had the same issue in autonomous, except with both encoder 1 and encoder 2. I never had the chance to check in teleop mode, though.
I'll try with last year's board, if I can get the time (we removed our encoders from the bot for this reason).
Kevin Watson
20-02-2008, 01:29
Kevin.
I'm trying to get the camera code going with the new 3.0 code. I'm not receiving ACKs or NCKs so it fails at init state 3 return value 131. serial_ports.h/c looks ready to go for port2 9600 baud and interrupts.
Integrated camera.c terminal.c and tracking.c without any issues.
Anything obvious come to mind reagrding serial port initialization?
ChadI haven't done it, but I can't think of any reason it wouldn't work.
-Kevin
Kevin Watson
20-02-2008, 01:38
I've been running into an odd problem with encoders.
Encoder 1 works perfectly fine during the teleop period, but does not give me anything during the autonomous one. Encoder 2 works in both teleop and autonomous. The initialization functions is called during both the autonomous and disabled initialization routines.
I am running your latest code build, as far I as know, with MPLAB 8 and C18 3.10. While the robot is shipped already, I'd love to hear if you have any suggestions for what to try.
It could be that the encoder is working, and is giving the correct signals, but is always printing a zero in my debug statement, and the code that is executing makes me believe that it is seeing a zero (as the count). But when I print out the count in the teleop mode, I get numbers that make sense.A common reason for this is the wrong printf() format parameter is used. Use %ld instead of %d.
-Kevin
Kevin Watson
20-02-2008, 01:42
Kevin
Do you have access to an Explorer 16 board from Microchip??No, most of my experience is with x86, PPC, Cell BE, TI DSP plus lots of FPGA work. My only real experience with PIC is side work using IFI hardware. Why do you ask?
-Kevin
Guy Davidson
20-02-2008, 01:49
A common reason for this is the wrong printf() format parameter is used. Use %ld instead of %d.
-Kevin
That would make sense, I guess. The DEBUG I use in the teleoperated code casts the variables to integers in the DEBUG, while the one I have in autonomous does not. But something's still lacking. In this case, why would encoder channel 2 print out properly, while one was not? I also tried connection the two encoders to the opposite channels (i.e. the left one was previously connected to 1, and I moved it to 2, and vice versa with the right encoder). When I did that, the signs flipped, but encoder 2 still changed and 1 still remained constant, while both worked in teleop, I believe.
Another weird thing with my autonomous code, is that unless I have a DEBUG in the PWM() function body, the robot doesn't move. I'm updating the PWM function every main loop, and I noticed that unless I have that DEBUG statement there, the robot doesn't move. Once I added it, or commented it in (when testing), the robot started moving again. Any ideas?
Thanks.
Kevin Watson
20-02-2008, 02:14
That would make sense, I guess. The DEBUG I use in the teleoperated code casts the variables to integers in the DEBUG, while the one I have in autonomous does not. But something's still lacking. In this case, why would encoder channel 2 print out properly, while one was not? I also tried connection the two encoders to the opposite channels (i.e. the left one was previously connected to 1, and I moved it to 2, and vice versa with the right encoder). When I did that, the signs flipped, but encoder 2 still changed and 1 still remained constant, while both worked in teleop, I believe.
Another weird thing with my autonomous code, is that unless I have a DEBUG in the PWM() function body, the robot doesn't move. I'm updating the PWM function every main loop, and I noticed that unless I have that DEBUG statement there, the robot doesn't move. Once I added it, or commented it in (when testing), the robot started moving again. Any ideas?
Thanks.Using the wrong format string can cause wacky behavior. I'll have a quick look if you zip up your code and e-mail it to me.
-Kevin
No, most of my experience is with x86, PPC, Cell BE, TI DSP plus lots of FPGA work. My only real experience with PIC is side work using IFI hardware. Why do you ask?
-Kevin
I have a early port of your ATD code working on the board with DMA, also have the serial drivers working with a few bugs...
this was done to gain experience with the tools and processors...
mandrews281
21-02-2008, 18:13
There is a later theme about not allowing enough time for the circular buffer to fill. I suspect that might be what I was doing wrong.
Just wanted to post a big THANK YOU to Kevin for his code...
Kevin Watson
03-03-2008, 17:06
Just wanted to post a big THANK YOU to Kevin for his code...You're welcome :). Of the teams that used my code last week, did any bugs pop up?
-Kevin
Guy Davidson
03-03-2008, 17:10
We used it. There was one wierd issue with something that used to happen in the initialization routine not happening any more (initializing two variables to values read from the ADC), but that could be connected to me disabling the gyro code, or something else. If I can't find it after I try to look for it harder, I'll let you know.
Overall though, the code worked fantastically well.
Bharat Nain
03-03-2008, 22:44
You're welcome :). Of the teams that used my code last week, did any bugs pop up?
-Kevin
While we did not use any of you gyro or encoder or any other fancy code, we did use your base new format. It was wonderful and easy to work with. We did not have any problems with the code itself and generally we are all very glad you made something like this. The Quick_ADC function was enough for our mast even though it was really fast (relatively). Thanks for the hard work to provide such a quality product.
Can anyone confirm that this code works when interfaced to the competition control?
I ran this code, compiled with the 3.0 compiler, with no issues prior to competition. During our first practice match at the Finger Lakes competition, the "code error" light came on and we have encountered a number of very strange issues with our team's RC since. These malfunctions disappear for a short while after reloading the "master code", but keep coming back.
Any ideas? It very well might not even be related to Kevin's libraries... but the default .hex file from IFI seems to work, so I'm stumped. I can't even find a 2.4 version of the compiler, so I hope to make this work.
Thanks!
billbo911
06-03-2008, 16:20
Can anyone confirm that this code works when interfaced to the competition control?
During our first practice match at the Finger Lakes competition, the "code error" light came on and we have encountered a number of very strange issues with our team's RC since. These malfunctions disappear for a short while after reloading the "master code", but keep coming back.
Thanks!
We tested it without issues at a local practice event. The competition port was used to control the systems.
From your description, it sound like you may be using a "While" loop.??
We did this and killed our selves. Once we realized what happened, we dropped the "While" loop and everything returned to normal.
Guy Davidson
06-03-2008, 16:23
It definitely works. We ran it at Portland.
Tom Bottiglieri
06-03-2008, 16:26
we have encountered a number of very strange issues with our team's RC since. These malfunctions disappear for a short while after reloading the "master code", but keep coming back.
What sort of malfunctions?
What sort of malfunctions?
The Green power light on RC flashes slowly. On the OI, the "No Data / Radio" light flashes and "Code Error" is on solid. If I keep playing with the reset and program buttons I can get it to run normally for a while and get it into program mode.
I just looked for while loops thinking maybe I mistakenly typed it instead of an "if" statement or something, but didn't find anything. Any other ideas on what may cause this?
Thanks for the help!
Kevin Watson
06-03-2008, 16:58
Can anyone confirm that this code works when interfaced to the competition control?
I ran this code, compiled with the 3.0 compiler, with no issues prior to competition. During our first practice match at the Finger Lakes competition, the "code error" light came on and we have encountered a number of very strange issues with our team's RC since. These malfunctions disappear for a short while after reloading the "master code", but keep coming back.
Any ideas? It very well might not even be related to Kevin's libraries... but the default .hex file from IFI seems to work, so I'm stumped. I can't even find a 2.4 version of the compiler, so I hope to make this work.
Thanks!I've received quite a few e-mails and PMs with positive feedback on the code (team 1024 used the code in Chicago last week and won). Two people have had problems, but one turned out to be a call to printf() inside an interrupt service routine that was quickly fixed. Tom Bottiglieri is having a weird issue with the RC occasionally throwing the red-light-of-death when it's cold booted, but it's not clear to me what is causing the problem.
If you want, you can zip up your code and send it to me for a quick look.
-Kevin
Edit: Whoops, 1024's master programmer just contacted me to point out that they used some of my other code, but not the 2008 base code.
ldeffenb
06-03-2008, 16:59
Any other ideas on what may cause this?
Thanks for the help!
Anything that causes your program to be slow at responding to the master processor during normal execution can cause a Code Error light (Red Light Of Death). Even an over-chatty set of printfs can cause this to occur.
If you are using interrupts for things like encoders and have too high resolution encoder (say 256 pulse per rotation) on a shaft that spins too quickly (say > 4 revolutions per second), then that encoder alone can generate >1000 interrupts per second. We use a guideline of no more than 4000 interrupts per second and very small, streamlined interrupt processing.
If you've configured a millisecond timer interrupt, then you've got 1000 per second occurring there also.
One indication that you're being a bit slow in responding to the master controller is a sluggish response to OI commands like joystick motion. That's the first indication, although you may not see it if the slow response occurs on some other event (like hitting a limit switch or turning on a motor to high speed that is being read by an encoder).
All things to think about. I hope you get it figured out!
Lynn (D) - Team Voltage 386 Software
The Green power light on RC flashes slowly. On the OI, the "No Data / Radio" light flashes and "Code Error" is on solid. If I keep playing with the reset and program buttons I can get it to run normally for a while and get it into program mode.
I just looked for while loops thinking maybe I mistakenly typed it instead of an "if" statement or something, but didn't find anything. Any other ideas on what may cause this?
Thanks for the help!
This sounds almost like your Master Processor is messing you up, especially since you say that the battery indicator LED flashes slowly. Try to first reload the master code using a different computer, a different serial port, and redownload the code, as some information may be getting messed up. Also start fresh, preferably with IFI's code and see if you encounter the same issues. If you don't have any issues, go back to the default version of Kevin's code, if that doesn't give you issues, then load your code to see if that gives you any issues.
Basically, go through some troubleshooting steps. Go back to what you know should work, and if it doesn't, then call IFI for them to fix your RC.
Nothing that you code should mess with the indicator lights on the RC... this is what leaves me to believe that your master code is corrupted.
I've received quite a few e-mails and PMs with positive feedback on the code (team 1024 used the code in Chicago last week and won). Two people have had problems, but one turned out to be a call to printf() inside an interrupt service routine that was quickly fixed. Tom Bottiglieri is having a weird issue with the RC occasionally throwing the red-light-of-death when it's cold booted, but it's not clear to me what is causing the problem.
If you want, you can zip up your code and send it to me for a quick look.
-Kevin
I'm sorry, I think my first post came across as more accusatory than I intended. Kevin, you did an awesome job with this code and your work is much appreciated. I've been using various bits of your code for years now with great success. My reason for posting was hope that someone else had encountered the same problem we hit and had a simple solution.
I'm still not sure exactly what is going on. Reloading the user program to our RC seems to briefly fix the problem, leading me to believe that this program is somehow becoming corrupt. I no longer believe Kevin's 3.0 compatible code to be contributing in any way (and I'm glad to be using it!)
Kevin, I'll still zip and send you our program.
Thanks all!
Greg
Can anyone confirm that this code works when interfaced to the competition control?
I ran this code, compiled with the 3.0 compiler, with no issues prior to competition. During our first practice match at the Finger Lakes competition, the "code error" light came on and we have encountered a number of very strange issues with our team's RC since. These malfunctions disappear for a short while after reloading the "master code", but keep coming back.
Any ideas? It very well might not even be related to Kevin's libraries... but the default .hex file from IFI seems to work, so I'm stumped. I can't even find a 2.4 version of the compiler, so I hope to make this work.
Thanks!
I've had the exact same problem you described, except I was using a competition dongle (practice time at home). The problem only happened three times, two with the flashing code error light. The other time, code error turned on steady and only a cold boot would fix it (resetting didn't do a thing).
The problem appeared to happen when we clicked the "set arm position" button, but all that does is change a variable's value, the function that sets it gets called every slow loop regardless of a button press. I couldn't replicate the problem in any way, I just noticed that it coincidentally happened when we pressed one of those buttons.
There's nothing too slow in my code (absolutely no for/while loops, only a few printfs, two 8 CPR home-made encoders and two analog channels reading - that's the heaviest section) and most of it is standard Kevin code. My "fix" to the steady code error light was a Master processor reprogramming (and updating the user code with the same code that was running before), and I haven't been able to replicate the problem. I didn't even think it was a big deal, but now that you may have the same problem there could be something wrong (and if there is, it's probably in this sequence: our code -> our RC hardware -> the PIC silicon -> Kevin's code ;) )
Hopefully it went away, but, once again, it was too sporadical to know for sure.
Kevin, I can send you my code if you want, but I really don't think there's anything wrong with it.
Once again thanks for writing it!
I've had the exact same problem you described, except I was using a competition dongle (practice time at home). The problem only happened three times, two with the flashing code error light. The other time, code error turned on steady and only a cold boot would fix it (resetting didn't do a thing)....
This sounds real close to what I keep seeing. It usually happens in response to a change in command input, but I can't figure out exactly what triggers it.
The fix I've discovered is to re-upload the master and user code (although sometimes just re-uploading the user code works). Not sure if this is relevant to the new 3.0 compatible code, maybe we should move to a different thread?
- Greg
Kevin Watson
06-03-2008, 22:04
I'm sorry, I think my first post came across as more accusatory than I intended. There's generally a lot of finger pointing in the engineering profession, so I'm used to it by now :D. In all seriousness, if someone thinks they've found a bug in my code, I'm very interested in hearing about it.
-Kevin
Was your battery fully charged at the time of the error?
Was your battery fully charged at the time of the error?
Now that you mention it, the battery was at 8.2 V ;)
No, really, we always had a charged battery and the 8.2V bug never appeared to us.
Kevin Watson
07-03-2008, 12:00
Can anyone confirm that this code works when interfaced to the competition control?
I ran this code, compiled with the 3.0 compiler, with no issues prior to competition. During our first practice match at the Finger Lakes competition, the "code error" light came on and we have encountered a number of very strange issues with our team's RC since. These malfunctions disappear for a short while after reloading the "master code", but keep coming back.
Any ideas? It very well might not even be related to Kevin's libraries... but the default .hex file from IFI seems to work, so I'm stumped. I can't even find a 2.4 version of the compiler, so I hope to make this work.
Thanks!Looking at your code... You've got a lot of calls to printf() that could very well be causing problems. While my serial port driver is fully buffered and non-blocking, if the buffer fills up, the code will have to resort to a blocking scheme to prevent data corruption. In blocking mode, your code won't execute until there is enough room in the Rx buffer for the string you're trying to send. A few things to consider doing:
1) Use the DEBUG() macro (see ifi_frc.h) so that it's easy to remove the printf() statements from your competition code.
2) You can also redirect the output to go nowhere by placing this line in teleop.c/Initialization:
stdout_serial_port = NUL;
This will prevent the stalling, but isn't optimal because the code associated with printf() will still execute.
3) Increase the RX1 buffer size in serial_ports.h to 64 or even 128 bytes.
I've also seen a few inconsistances in your code. Can you describe the 'bot a bit? I'm mostly interested in the sensors you're using and how they're attached to the robot controller.
-Kevin
Our issue was a bad RC. We swapped a loaner in this morning and everything has worked fine since. Our inability to reproduce the error made it really hard to diagnose, but we finally traced the problem to cold booting the RC (cold booting was causing the program to become corrupted).
Kevin - Thanks for taking the time to look at our code :) We're now running a kit gyro with your gyro driver and a pot (which is used to control the direction our steerable front wheels are pointed).
Thanks for the help everyone, and watch out for defective RC's.
Ken Streeter
08-03-2008, 07:42
Of the teams that used my code last week, did any bugs pop up? We used Kevin's code at the Week 1 BAE Systems Granite State Regional, and had no bugs at all pop up in Kevin's code! (Wish we could say the same for our code! :ahh:)
We used Kevin's beta 3.0+ code (as of 2 Feb 2008) with the following features / modules:
ADC usage to periodically sample absolute magnetic encoders on our primary drive wheels
ADC usage to periodically sample absolute magnetic encoders for steering position on our "Speed Racer" robot configuration
ADC usage to periodically sample a multi-turn potentiometer on our arm for our hurdling robot configuration ("Fezzik")
Gyro usage for current heading on both robot configurations
Our own "fast loop" at 100Hz running in Autonomous_Spin and Teleop_Spin for increased PID responsiveness, using a timer, as suggested by Kevin in another thread
All of the above worked beautifully! Autonomous modes on both robot configurations behaved very well, and we never had any troubles that we can attribute to Kevin's code. (We did, of course, have our share of problems, including tracking down a flaky magnetic encoder, our own bugs in our own code, and an IR board that lost its programming before our last qualifying match.)
Thanks, Kevin, for all of your work on the "new and improved" FRC code!
Kevin Watson
09-03-2008, 15:15
We used Kevin's code at the Week 1 BAE Systems Granite State Regional, and had no bugs at all pop up in Kevin's code!Cool! Thanks for letting me know.
Thanks, Kevin, for all of your work on the "new and improved" FRC code!You're welcome.
-Kevin
BotnEyedJoe
09-03-2008, 22:04
This new code is a wonderful improvement. I especially like its straightforward approach, and simplified way of inserting mission-specific code. It has been a joy to use. But there's still something I'm trying to figure out about it, so if anyone can help, I'd be grateful...
It started with trying to figure out something unexpected which happens when we hold down the "Disable" button on our competition port dongle while booting the RC. In the function main() in ifi_frc.c, the one-time initializations occur of couse, and the "while (TRUE)" loop is entered, but to our surprise, we see "Teleop_Init()" execute, where we would have expected "Disabled_Init()" to be chosen instead.
Now the first thing inside the "while (TRUE)" loop is the test "if (disabled_mode)...", where disabled_mode is a field inside rxdata. But I don't see where rxdata has been set at this point. It appears to be set later on through calls to Getdata(&rxdata), once statusflag.NEW_SPI_DATA becomes 1.
Could someone enlighten me as to what I'm missing about the initialization of rxdata, specifically fields disabled_mode and autonomous_mode? Or is this, like, maybe a problem?
If you've read this far, thanks, but while we are in this vicinity, I also have a question about "statusflag.NEW_SPI_DATA", which before the "while (TRUE)" loop is set to 0. I assume it is really "volatile" even though I can't find that in any of its declarations (again I'm missing something?), but if it isn't 1 by the time we go through that loop the first time, wouldn't a _Spin() function be called before its corresponding _Init()? Is there some mechanism preventing this, or do we need to take this possibility into account in programming the _Spin() functions?
Anyway and everyway possible, Kudos to Kevin, he has made our world more enjoyable through his efforts!
Kevin Watson
10-03-2008, 02:40
It started with trying to figure out something unexpected which happens when we hold down the "Disable" button on our competition port dongle while booting the RC. In the function main() in ifi_frc.c, the one-time initializations occur of couse, and the "while (TRUE)" loop is entered, but to our surprise, we see "Teleop_Init()" execute, where we would have expected "Disabled_Init()" to be chosen instead.
The problem is that the main loop is entered before the master processor has sent the first packet, and because neither the disabled or autonomous bits are set, the software first enters teleoperation mode. One quick way to get the behavior you describe would be to modify the code in main() to wait for the first packet before dumping into the while(TRUE) loop. Something like this should work:
statusflag.NEW_SPI_DATA =0;
while(statusflag.NEW_SPI_DATA ==0);
while(TRUE)
-Kevin
BotnEyedJoe
10-03-2008, 05:44
... And, once NEW_SPI_DATA becomes set, is a Getdata() call also needed, so that disabled_mode and autonomous_mode become set based on the contents of the newly-arrived packet?
Joe Ross
10-03-2008, 10:20
We ran your code successfully at the San Diego regional.
Kevin...
Team 812, The Midnight Mechanics from the Preuss School at UCSD used you code as the basis of there robot for the San Diego regionals and the team received the Chairman's Award.
Thank you very much for your contribution to the First Robotics Program.
rdaugherty
10-03-2008, 18:58
Kevin,
Just to add to the positive feedback, team 435 used your new code this year. (I think we are at least one version behind.) We had no problems which you have not already fixed. In addition to the base 3.0+ compatible code, we also used the EEPROM, tracking menu, and portions of the robot.c code from previous years.
The structure and starting sensor code has clearly been a great boon to the team's development of both teleop and automonous code.
So please take this as another great big thank you from another appreciative team.
Rich Daugherty
Programming Mentor - Team 435 RoboDogs
SE Raleigh High School - Raleigh, NC
Kevin Watson
10-03-2008, 21:44
... And, once NEW_SPI_DATA becomes set, is a Getdata() call also needed, so that disabled_mode and autonomous_mode become set based on the contents of the newly-arrived packet?Yes, I forgot to include that little detail <sheepish grin>.
-Kevin
XXShadowXX
13-03-2008, 13:08
does anyone know a site were i don't have 2 download anything to see the new code, because im at school and they won't let me save the kind of files that r posted on kevin:(
thnxs in advance
if you know the site just message me
thnxs again
I've had the exact same problem you described, except I was using a competition dongle (practice time at home). The problem only happened three times, two with the flashing code error light. The other time, code error turned on steady and only a cold boot would fix it (resetting didn't do a thing).
The problem appeared to happen when we clicked the "set arm position" button, but all that does is change a variable's value, the function that sets it gets called every slow loop regardless of a button press. I couldn't replicate the problem in any way, I just noticed that it coincidentally happened when we pressed one of those buttons.
There's nothing too slow in my code (absolutely no for/while loops, only a few printfs, two 8 CPR home-made encoders and two analog channels reading - that's the heaviest section) and most of it is standard Kevin code. My "fix" to the steady code error light was a Master processor reprogramming (and updating the user code with the same code that was running before), and I haven't been able to replicate the problem. I didn't even think it was a big deal, but now that you may have the same problem there could be something wrong (and if there is, it's probably in this sequence: our code -> our RC hardware -> the PIC silicon -> Kevin's code ;) )
Hopefully it went away, but, once again, it was too sporadical to know for sure.
Kevin, I can send you my code if you want, but I really don't think there's anything wrong with it.
Once again thanks for writing it!
Well, we were able to track down this problem today (on a regional practice day, what were the odds!). We have a custom made encoder in our robot and the perforated disk was in a position such that, in rare ocasions, it would trigger the IR receiver on and off continuously. That was generating several thousand interrupts per second and bogging the processor down. The problem only ocurred on a very specific position of the encoder, explaining why it was so intermittent (looking almost random).
In the end, it wasn't my code's fault, neither Kevin's (obviously ;) ). Great when you can blame the other guy for the hardware, heh?
In the end, it wasn't my code's fault, neither Kevin's (obviously ;) ). Great when you can blame the other guy for the hardware, heh?
This is a uncommon but great experience.:D
Kevin,
As the TechnoTicks (236) programming team's mentor, I want to thank you for your great code template. We were able to accomplish a great autonomous mode by running laps with the use of encoders as well as provide for controllable mecanum drive. The traditional view is that to control mecanum drives you need velocity feedback on each wheel; I argued (and proved) that a gyro would work as well.
Our programmers used EasyC last year and graduated to using MPLab this season. Your code provided a clean and logical template for them to start. It was a lot easier teaching the new members of our team as well!
BotnEyedJoe
17-03-2008, 20:30
"The proof of the pudding is in the eating"
Team 709 used Kevin's new code with gyro, A/D, encoders, and two serial ports all integrated as we battled hard at the Chesapeake Regional, and that software was rock solid, baby! We also integrated your ir_sensor module after our IR board died, and it basically dropped right in. Really nice and simple approach!
Can't wait for the Philly regional!
I think the students have just picked up on the flow of the software so easily and so well, compared to previous years, I just can't thank you enough for doing this!
veeveecai
26-03-2008, 13:04
Hello Kevin,
I'm Veevee from team 2036 and I've been scrolling through this thread and found somebody with the same issue, but apparently they could fix it...and I still can't seem to figure this out. Our team's IR board has fried so we're trying to implement your solution to it. Yeah, this is late I know, but our team doesn't necessarily need the IR board, we just recently decided we might as well try and get it to work though if we can. I'm relatively new to programming, but here's my issue:
I'm using MPLAB v8.00 and C18 v3.10, but we still get the tmpdata/pragma error that some other people had earlier but fixed by updating...I'm decently certain everything's up to date on my machine though...:
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\autonomous.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "autonomous.c" -fo="autonomous.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\disabled.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "disabled.c" -fo="disabled.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\ifi_code.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "ifi_code.c" -fo="ifi_code.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\ifi_frc.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "ifi_frc.c" -fo="ifi_frc.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Documents and Settings\Science\Desktop\ifi_frc\ifi_frc.c:263:War ning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\ifi_frc.c:266:Err or [1020] unexpected input following 'interrupt'
C:\Documents and Settings\Science\Desktop\ifi_frc\ifi_frc.c:392:War ning [2002] unknown pragma 'tmpdata'
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\interrupts.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "interrupts.c" -fo="interrupts.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\pwm.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "pwm.c" -fo="pwm.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "serial_ports.c" -fo="serial_ports.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.c:93 5:Warning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.c:10 02:Warning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.c:10 28:Warning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.c:10 95:Warning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.c:11 21:Warning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.c:11 61:Warning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.c:11 87:Warning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\serial_ports.c:12 27:Warning [2002] unknown pragma 'tmpdata'
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\teleop.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "teleop.c" -fo="teleop.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\timers.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "timers.c" -fo="timers.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\encoder.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "encoder.c" -fo="encoder.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\gyro.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "gyro.c" -fo="gyro.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Make: The target "C:\Documents and Settings\Science\Desktop\ifi_frc\adc.o" is out of date.
Executing: "C:\mcc18\bin\mcc18.exe" -p=18F8722 "adc.c" -fo="adc.o" -k -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Documents and Settings\Science\Desktop\ifi_frc\adc.c:387:Warning [2002] unknown pragma 'tmpdata'
C:\Documents and Settings\Science\Desktop\ifi_frc\adc.c:442:Warning [2002] unknown pragma 'tmpdata'
Skipping link step. Not all sources built successfully.
BUILD FAILED: Wed Mar 26 10:50:49 2008
None of thecode has been modified at all, I'm just trying to compile your original code so far. If you could help at all, thanks very much!
Kevin Sevcik
26-03-2008, 13:11
I have no idea if this will help, but can you open a command window, change directories to C:\mcc18\bin, and run "mcc18 -v"? This should confirm what version of C18 you're running, and I'm just curious if it's the right one.
veeveecai
26-03-2008, 13:26
Hmm...I tried reinstalling C18 v3.1 and now it seems to be working. Thanks for your help! (Last time I checked by going into the folder and clicking on the readme file for C18...and it said v3.10...perhaps it's different still though?)
Kevin Sevcik
27-03-2008, 12:27
Since it has to do with the 3.0+ code, I figure I'll post the question here:
quick_adc.c/h says it's incompatible with the adc.c/h code, but I think our 'bot very briefly needs the functionality. We're using a decade thumb wheel rigged as a voltage divider for an autonomous mode selector. (Delays, starting position, etc.) I really really don't want to waste 400-800 samples per second on an analog value we only need to read once after the RC initializes. Since the Quick_ADC(n) function seems just to be making a standard blocking ADC conversion, is there any reason we can't call this in our Initialization() code right before we call Initialize_ADC()? I realize the potential pitfalls with match restarts, etc., but I'll still feel silly burning that many cycles on something like this.
billbo911
27-03-2008, 15:30
Since the Quick_ADC(n) function seems just to be making a standard blocking ADC conversion, is there any reason we can't call this in our Initialization() code right before we call Initialize_ADC()?
That is exactly what I was going to suggest. I believe it "should" work.
Although, I think an answer from Kevin would be the most prudent considering he knows his code inside and out.:)
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.