View Full Version : Printf has just entirely failed to do anything
JBotAlan
20-12-2006, 07:27
I started with the default camera code from Kevin Watson a few weeks ago, and I have been making my modifications happily--that is, until yesterday. First, I added two of my own files, which did all the camera calls, consolidating them into a single Camera Update function. Then, I pulled the camera update function calls out of user_routines.c and put my camera update function call into Process local IO. I had something like this working last week, but it refuses to send any bytes out the serial port now.
Things I have tried:
-tested my serial link. It is good-I can send programs down + read them back with device reader. I also see IFI> when I reset the bot
-tested with another RC. Same problem.
-unplugged camera TTL converter. Same problem
-Added printfs everywhere in my code. None of them work unless I comment out the #include for serial_ports.h (this breaks the camera functionality of course) And none of the printfs produce any output
-Replaced all the files that should never have been modified (serial_ports.c/.h, terminal.c/.h, camera.c/.h are the ones I overwrote with the ones out of Kevin's code). No effect.
I'm bashing my head on the wall right now.....please help!
JBot
PS. I will post the code tonight if you need it. I am using a school machine right now and don't have access to my code right now.
Mark McLeod
20-12-2006, 09:38
Which printf are you using?
The C18 library version that requires you to add "#include <stdio.h>" everywhere printf is called,
or one of the older printf_lib.c/h versions?
JBotAlan
20-12-2006, 12:35
I am using the stdio.h version where it won't compile unless I #include <stdio.h>.
It "Code error"ed out when I commented out the includes for Kevin Watson's serial port code. It worked then for about 5 seconds but it gave me a red light of death afterwards, presumably because I was bombarding it with tons of printfs.
JBot
JBotAlan
20-12-2006, 20:57
I really hate to do this, but since it is slowly creeping down the portal and I really need an answer...BUMP!
I am thinking about re-writing from scratch, but that would be ugly, so please, please tell me what I might be doing wrong...:mad:
JBot
Mark McLeod
20-12-2006, 22:23
Sorry, we've been racing robots all night. They're having a pushing contest now.
Probably need to attach or email your whole project to look at.
It's hard to guess what serial port resource conflict you might have. There are too many answers.
esquared
20-12-2006, 23:45
Sorry, we've been racing robots all night. They're having a pushing contest now.
Probably need to attach or email your whole project to look at.
It's hard to guess what serial port resource conflict you might have. There are too many answers.
Definitely zip up the project, there are a number of people out here on "the internets" who will take a look and give you a hand. Not being able to debug over the serial port leaves you with few options. The "Red Light of Doom" is typically caused by the same things that would cause a Windows-type program to either crash, or it went into an infinite/extremely long loop somewhere. The infinite/long loop would be the first thing I'd carefully check for in your code, it's easier to do than you'd think.
If you are indeed the lone programmer for your team (poor guy :yikes: ) you might want to force some code versioning on yourself. Things like CVS or SVN (check out wikipedia or google it yourself) CAN AND WILL SAVE YOUR BACON! It'll allow you to easily step back in time before you screwed something up, and will also provide an easier time of multiple people working on the project at once. This way you can try training an interested freshman without fear of him making changes you can't get rid of when your team leader asks you "is autonomous mode done yet?" :ahh: It takes some work to understand, but I promise (and every other user of some code versioning system will promise) it will be worth the effort.
--Eric
B.Johnston
21-12-2006, 14:11
I had the same sort of occurrence myself this week as I was trying to program one of the 2005 units.
Since you haven't mentioned which controller you're using this may not work.
If you have a 2005 CPU it's likely using a 8520 pic, which needs the following environment changes in mplab:
From the Configure >> Select Device... menu choose "PIC18F8520"
as the pic type
In your project use the "FRC_library.lib" for the 8520
(mine is named FRC_library_8520.lib) -To keep my sanity I
renamed it in the same
fashion as last years revised
libraries and linkers were.
Also In your project use the "18F8520.lkr" for the 8520
NOW the last ingredient for success in restoring printf's (in my case anyway)
Load the FRC_MASTER_V12.BIN and reload your first compiled code
(before all of your changes)
If you're using a pre 2006 CPU it's probably not been loaded with a FRC_MASTER_V12.BIN but an older version.
I'm just guessing (since it's now gone) but ours was probably using the V11 master code as distributed in April 2005.
Once the master code was updated my printf's worked fine (no more IFI> terminal freeze ups)
JBotAlan
21-12-2006, 22:46
OK, the code that is causing me problems is posted:
http://jbotalan.frih.net/07_code.zip
No printfs work anywhere.
I'm re-writing from the default user code. It will make for cleaner code. I would be interested in finding out why the heck this broke.
I'm going to try CVS.
JBot
Matt Krass
21-12-2006, 23:16
If you're using a pre 2006 CPU it's probably not been loaded with a FRC_MASTER_V12.BIN but an older version.
I'm just guessing (since it's now gone) but ours was probably using the V11 master code as distributed in April 2005.
Once the master code was updated my printf's worked fine (no more IFI> terminal freeze ups)
I'm not sure this is sound advice, I looked on IFIs website, and the latest update I see for a 2005 controller is v11. The v12 update is included with the 2006 controller code. This to me implies the update is built for the 2006 controller, and I'm not sure if it shares a master processor with the 2005. If it does share a master processor, it should work fine, but if they've changed them, such an update could make the RC...not work.
Does anyone know if the 2005 and 2006 controllers share a master processor model? Also did you actually do the Master version update on your 2005 controller? It's a little hard to understand as you speculate the controller in question was running v11.
Can someone clarify please?
JBotAlan
22-12-2006, 11:52
If you are indeed the lone programmer for your team (poor guy :yikes: ) you might want to force some code versioning on yourself. Things like CVS or SVN (check out wikipedia or google it yourself) CAN AND WILL SAVE YOUR BACON!
Thanks so much for suggesting CVS/SVN! I now have SVN set up on my machine, and I like the looks of it. It's really cool to look at the diff of two versions of one file. I can see how this would be great at robotics.
Oh, I like being the lone programmer! Nobody to fight with over how the code will work! I'm trying to train a freshman, but otherwise I'm it.
Thanks again. You learn something new every day. If only I learned something this cool every day...
JBot
esquared
22-12-2006, 17:14
OK, the code that is causing me problems is posted:
http://jbotalan.frih.net/07_code.zip
No printfs work anywhere.
I'm re-writing from the default user code. It will make for cleaner code. I would be interested in finding out why the heck this broke.
I'm going to try CVS.
JBot
Could you add the following to timer_handler.c in the InitializeTimer() function?
PIE1bits.TMR1IE = 0;
Since you don't have an interrupt handler for that timer, but you start it, it is wise to make sure it's set to not create an interrupt. It might start out that way by default, but this is much safer. An interrupt that is generated but not handled can do very bizarre things.
If i understand your original post correctly, it stopped working when you moved the function calls into your abstraction files?
I noticed you did not call "Initialize_Camera()" in your abstraction file (or anywhere in your project). Try adding that to user_routines.c in the User_Initialization() function.
Let me know if any of these work.
-Eric
JBotAlan
22-12-2006, 17:26
I'll be sure to let you know if these work. I won't be able to check until we get back (on the 4th I think). It's nice to know someone cares enough to pull down someone else's code to look at it. I wouldn't have been as generous before FIRST...
Thanks,
JBot
EDIT: I was under the impression that Camera_Handler() in camera.c was supposed to be calling Initialize_Camera(), and it is as far as I know. I can call it manually, but depending on the flags set in camera.c, it does get called if camera comms aren't working. Correct me if I'm wrong...
B.Johnston
22-12-2006, 20:48
Matt,
Sorry for leaving you confused.
The last step for success (in my eliminating the IFI> prompt freeze up while adding in printf's for my chosen variables) WAS the loading of the MASTER_V12.BIN from the 2006 default code.
You are absolutely correct when you mention that there is no explicit documentation of whether it's appropriate to try this.
But where is your sense of adventure.
The fact that IFI was doing FRC controller processor upgrades from ver 8520PICS to 8722PICS,
and Kevin Watson was releasing all kinds of code with instructions on how to load user programs written as enhancements for the 2006 base code onto 2005 processors.
Surely, if it were fatal to the processor somebody would have noticed by now that loading the MASTER_V12.BIN shouldnt be done on a 2005 controller.
Anyway it works, my 2005 controller is happily running MASTER_V12.BIN and both the FRC Default code and OUR 1114-1503-1680 Common base code that were teaching our programmers with.
Perhaps I should have actually read the IFI site for instructions on how to confirm which Master code we were running before I scrapped it, but I did save the bin file for posterity using device reader.
The only guessing going on was if it was v 10 or v11 not whether or not I fixed the freeze up at the IFI> stage.
Bruce
PS Jacob, I looked at your environment (8722PIC, lib & lkr) and you don't have the same printf freeze issue I had.
JBotAlan
22-12-2006, 21:39
But where is your sense of adventure.
...
Surely, if it were fatal to the processor somebody would have noticed by now that loading the MASTER_V12.BIN shouldnt be done on a 2005 controller.
Hmm. I'm glad someone else did this experimentation. It would be an interesting experience, to say the least, describing to our team leader exactly why the most expensive component of the robot has become a paperweight.
PS Jacob, I looked at your environment (8722PIC, lib & lkr) and you don't have the same printf freeze issue I had.
Thanks for trying. I really appreciate your help.
JBot
Matt Krass
23-12-2006, 00:54
Anyway it works, my 2005 controller is happily running MASTER_V12.BIN and both the FRC Default code and OUR 1114-1503-1680 Common base code that were teaching our programmers with.
Hmm. I'm glad someone else did this experimentation. It would be an interesting experience, to say the least, describing to our team leader exactly why the most expensive component of the robot has become a paperweight.
Thanks for trying. I really appreciate your help.
JBot
Yeah I was definitely not up to that adventure ;) Killing the RC my first year on 358 would have left a bad first impression :P
Thanks for the information, I've tucked it in with my 'useful things' section of the brain.
esquared
23-12-2006, 02:15
...
EDIT: I was under the impression that Camera_Handler() in camera.c was supposed to be calling Initialize_Camera(), and it is as far as I know. I can call it manually, but depending on the flags set in camera.c, it does get called if camera comms aren't working. Correct me if I'm wrong...
I missed that as well in camera.c :eek: so good call.
Aside from your efforts to start from the default code, I can send you a basic environment that has a working camera without too much of our robot-specific code in it just so you can verify its not the source you're building from.
Another possibility-what version of the IFI loader are you using? If you use the old version with code sizes> 32k (or whatever the max was for 2005's RC), you can get wicked crazy problems. That might explain why things stopped working as you added more functions/files.
-Eric
Mark McLeod
23-12-2006, 08:27
Good news & bad news...
I dropped your code as-is into one of our controllers and a printf I added to user_routines.c worked fine.
Master code v12
IFI_Loader v 1.1
I ran without the camera as a first test then connected the camera.
Which printf in what routine in particular were you having trouble with?
P.S. In the version you posted none of the camera code is ever called from anywhere, so there won't be any "uncalled for" printf's from any of that code.
I added a call to CAL_Update(); in Process_Data_From_Master_uP and uncommented the #include "camera_abstraction.h"
and I'm seeing the printf's from the camera code.
JBotAlan
23-12-2006, 12:01
I'm using IFI Loader 1.1.0. I see no printfs anywhere, at all when I put this code into my rc. I've verified it's not my terminal program, serial port, or the rc itself as I loaded old code and it showed all the printfs fine. I can't test anything until somewhere around the 4th because I can't get into the shop until then. I had added printfs directly into main() because nothing else was working, and even that wasn't working. I suppose I should update the master code because I am pretty sure nobody bothered to do so last year--I think we're running v11 still.
Thanks again
JBot
EDIT: Is that what the new master code was released for--a fix in printf? I knew there was new code out there but I don't remember ever updating. I even have the binary on my machine right now, I just need to upload it.
Mark McLeod
23-12-2006, 13:39
EDIT: Is that what the new master code was released for--a fix in printf? I knew there was new code out there but I don't remember ever updating. I even have the binary on my machine right now, I just need to upload it.
No such luck.
The master code revisions usually are just to match changes in the field control software. v11 was released to fix a random twitch in the pwm outputs for Victors, but nothing that affects the behavior of our User code. The Master version won't affect your printf.
I dumped v11 into my test controller just to eliminate that as a potential cause, and your code still works fine.
Your code is small enough to fit and run on the older PIC-based controllers, so the IFI_Loader version isn't a likely issue. But if you get a Vex kit as a present you'll be able to test your code at home!
I'd start with a close look at the simple solutions.
When you get back to the robot after the holidays double check that you're downloading the .hex file you think you are. I notice you're putting the .hex file in a different directory than the source code (C:\old_'07_Code), so check the date on the file IFI_Loader is pointing to and verify it's new.
Double check your C18 version (2.4). I'm sure you have the current version, but verify there aren't older versions or the Vex version conflicting.
What's the history of the PC you're using? Has it been used for several years? Has MPLAB/C18/etc. been reinstalled around the time your troubles began?
JBotAlan
23-12-2006, 15:48
No such luck.
The master code revisions usually are just to match changes in the field control software. v11 did fixed a random twitch in the pwm outputs for Victors, but nothing that affects the behavior of our User code. The Master version won't affect your printf.
I dumped v11 into my test controller just to eliminate that as a potential cause, and your code still works fine.
Ugh. Here we go.
Your code is small enough to fit and run on the older PIC-based controllers, so the IFI_Loader version isn't a likely issue. But if you get a Vex kit as a present you'll be able to test your code at home!
Not likely, but it would be nice. I think I'm going to ask the team leader if I can bring home the old controller, OI, some power source, and all the necessary testing hardware so I can get something done.
I'd start with a close look at the simple solutions.
When you get back to the robot after the holidays double check that you're downloading the .hex file you think you are. I notice you're putting the .hex file in a different directory than the source code (C:\old_'07_Code), so check the date on the file IFI_Loader is pointing to and verify it's new.
<scratches head> I looked at the project options again after you mentioned this, but I see the output directory is c:\old_'07_code, right where the source is. I verified that MPLAB is opening the right files. I have deleted the .hex file, recompiled, and yes, it shows up right where I expected it would, and I verified it was this .hex I downloaded.
Double check your C18 version (2.4). I'm sure you have the current version, but verify there aren't older versions or the Vex version conflicting.
What's the history of the PC you're using? Has it been used for several years? Has MPLAB/C18/etc. been reinstalled around the time your troubles began?
I installed this from the '06 disc in the KOP which only had 2.4 on it. I only bought this PC in July or August of this year, so it doesn't have an old version conflict. Also, I have never done Vex ever, so that's not a possibility. I never reinstalled MPLAB, but I'm thinking that's my next step.
It might work right now. I have no idea. I'll have to test it when we get back.
JBot
Mark McLeod
23-12-2006, 16:17
<scratches head> I looked at the project options again after you mentioned this, but I see the output directory is c:\old_'07_code, right where the source is.
I understand how you setup your project now. I unzipped your files to a folder on my computer that wasn't c:\old_'07_code. Removing the hardcoded paths for Output directory, Intermediates Directory, and Linker-Script Path let them default to whatever the current directory happens to be.
The MPLAB version won't matter much either. It's just an editing/organizing tool.
Don't sweat it until you're in a position to test again. It'll only drive you nuts. Right now what you've got looks good to me. I'll post the working hex file I compiled and you can use it to eliminate your PC/MPLAB/C18 as any kind of a suspect.
Here's the hex file and the camera initialization output printfs I'm seeing. (ignore the "MLM" that's my test printf from user_routines.c)
JBotAlan
23-12-2006, 19:45
Alright, thanks. Got the file, will try it when we get back.
Some of the characters in the output are interesting, but I won't worry about it right now.
Thanks
You deserve a candy bar...
Here you go:
http://www.nadf.com/images/3musketeers_c.gif
hehe...I'm going nuts already. Think of what the season is going to do...:yikes:
JBot
Kevin Sevcik
23-12-2006, 21:17
JBotAlan,
I think your problem is both obvious and simple to fix, luckily. Rearranging the Camera_Handler function etc, had nothing to do with it. Had you left the original code intact, you still would have broken the program by moving Camera_Handler() (or CAL_Update() in your program) from user_routines.c to Process_Data_From_Local_IO(). Move Camera_Handler() back where it belongs and everything will work wonderfully again.
Here's my reasoning. Process_Data_From_Local_IO(), as you know, runs stupidly fast, as it runs every loop in the user PIC. As opposed to every 26.2ms for Process_Data_From_Master_uP(). Camera_Handler() is a very complicated little function, and does tons of fun stuff like disabling serial interrupts briefly and using the inherent timing of the slow loop to get the timing of its initialization correct. Basically, with Camera_Handler() in your Process_Data_From_Local_IO(), things are happening waaay too fast and piling up and generally causing the horrible broken execution and code error lights that you're seeing.
To put it even more briefly, in the camera_readme.txt, Kevin Watson says you should call Camera_Handler() from Process_Data_From_Master_uP(). You really ought to listen to him unless you've initmately acquainted yourself with the operation of said function.
JBotAlan
24-12-2006, 08:07
Oh.
Maybe I should've read that readme.
I figured that it shouldn't be in the slow loop because by default that doesn't even execute during auton, where we need the camera the most. I will definitely read through that function and the camera readme and see if moving the function call back to process_data_from_up helps. That would make sense if it was disabling and re-enabling serial interrupts very quickly...
I never would've caught that.
Thanks
JBot
EDIT: Just glancing through camera.c, I don't happen to see where serial interrupts are disabled/enabled, but I haven't looked at all of the function calls either. I do notice a loop_count variable; that alone warrants moving it back into the slow loop. Like I said, I need it to execute in auton. I may well modify this function so that it can safely execute in the fast loop. I don't know; I don't have time today to deal with this but thanks for the help.
Mark McLeod
24-12-2006, 08:12
Kevin has a good point.
Although calling CAL_Update() from the fast loop (via Process_Data_From_Local_IO) would only prevent the camera from working properly.
It wouldn't lockup the controller or disable printfs. The camera code doesn't take very long to execute.
P.S.
Your autonomous code should also execute in a slow loop. It doesn't help to execute faster than you can deliver instructions to the pwms. If you check the IFI default code you'll see the autonomous section in user_routines_fast.c is really a slow loop by virtue of the line:
if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */
You just need to add your camera calls within that slow loop.
I'd advise you to pull all your autonomous code out of the user_routines_fast.c file anyway. The name of that file only confuses the issue and your freshmen programmers, since it's not true for the autonomous code.
JBotAlan
24-12-2006, 11:27
Your autonomous code should also execute in a slow loop. It doesn't help to execute faster than you can deliver instructions to the pwms.
At first, I thought that auton WAS a fast loop, but I looked at main() and now see otherwise. This brings up a few questions in my mind. Why is auton a slow loop? I had heard (but not tested) that the values we get from the OI are invalid during auton and to disregard them entirely. Is it that the master processor will only let me getdata and putdata every 26.2ms? Do PWMs update faster if I getdata and putdata every loop instead of only when NEW_SPI_DATA is 1? What will getdata do if there is no new data to get? Also, suppose I have a PID loop. It needs to execute fast (or so the whitepaper says). So I put it in local IO. It changes PWM values in between 26.2ms loops. Are the victors actually getting the updated values in between loops, or are they updated every 26.2ms? And are my sensor reads actually updating in between 26.2ms loops, or are they the same every loop? Sorry about all the questions...I don't really understand the architecture of the rc.
If you check the IFI default code you'll see the autonomous section in user_routines_fast.c is really a slow loop by virtue of the line:
if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */
You just need to add your camera calls within that slow loop.
I'd advise you to pull all your autonomous code out of the user_routines_fast.c file anyway. The name of that file only confuses the issue and your freshmen programmers, since it's not true for the autonomous code.
Wow, my basic assumption (based on the comments in the code...) was wrong.
* FUNCTION NAME: User_Autonomous_Code
* PURPOSE: Execute user's code during autonomous robot operation.
* You should modify this routine by adding code which you wish to run in
* autonomous mode. It will be executed every program loop, and not
* wait for or use any data from the Operator Interface.
So that comment is downright wrong? Sure looks like it by the looks of main()...I might shoot off an email to IFI just to let them know.
JBot
Kevin Sevcik
24-12-2006, 14:38
Kevin has a good point.
Although calling CAL_Update() from the fast loop (via Process_Data_From_Local_IO) would only prevent the camera from working properly.
It wouldn't lockup the controller or disable printfs. The camera code doesn't take very long to execute.
P.S.
Your autonomous code should also execute in a slow loop. It doesn't help to execute faster than you can deliver instructions to the pwms. If you check the IFI default code you'll see the autonomous section in user_routines_fast.c is really a slow loop by virtue of the line:
if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */
You just need to add your camera calls within that slow loop.
I'd advise you to pull all your autonomous code out of the user_routines_fast.c file anyway. The name of that file only confuses the issue and your freshmen programmers, since it's not true for the autonomous code.
Mark,
You're right about the camera code executing quickly, but I think that might be where the problem lies. The initialization process fires off atleast a few packets to the camera. If Debug is on, it will also fire several long strings to the terminal. If all of this is in the fast loop... Well I just think the most likely culprit is all of these serial writes stacking up and possibly overflowing queues and generally making a mess of things.
Mark McLeod
24-12-2006, 17:14
We're pretty much limited to updating the pwm outputs at the slow loop speed whether regular driver mode or autonomous. While there is the potential to update a few special pwm outputs at a faster rate, the devices attached to the pwm outputs, such as Victors, aren't designed to receive the updates very much faster than the current slow loop speed.
The Master processor enforces the playing field control overrides and filters our OI inputs as well as our pwm outputs, a la
OI -> Master Proc. -> User Proc. -> Master Proc -> PWM outputs
When it has us disabled the Master "neutalizes" our pwm outputs, when it has us in autonomous mode the Master "neutralizes" the OI inputs it passes to us.
I conjecture that calling getdata() extra times will just return a copy of the last packet the Master prepared and I don't believe the Master does anything with extraneous putdata's until after NEW_SPI_DATA is reset to 1. You'd have to test that theory to be sure. In any case the response of the downstream systems such as the Victors, motors, and drivetrain will lag and swallow the milliseconds we might save.
To work properly PID feedback control depends on regular feedback not just speed and to make correct decisions needs previous decisions to be acted upon. It'll quickly lose track of things if the outside world is ignoring 99% of it's requests for motor changes and only acting on a random 1%.
Typically, use the fast loop of Process_Data_From_Local_IO to sample sensors, especially polled sensors, and collect data for use in making decisions later in the slow loop.
Your decision logic based on OI inputs or resulting in pwm outputs don't need to be made any faster than we can tell the Master processor via getdata/putdata.
The default code slow loop in main() is just used to kickoff the separate autonomous slow loop. The way the autonomous slow loop is coded doesn't allow anything else, including the main.c loop, to run again until the Master signals the end of autonomous mode. We eliminate the separate autonomous loop and only allow the main loop.
...Well I just think the most likely culprit is all of these serial writes stacking up and possibly overflowing queues and generally making a mess of things.
That's a valid theory and can easily be tested, but that would also mean printfs would not work anywhere in the fast loop for the same reasons. We still complain when we see people printf-ing from interrupts, but they get printouts.
JBotAlan
24-12-2006, 18:29
We're pretty much limited to updating the pwm outputs at the slow loop speed whether regular driver mode or autonomous. While there is the potential to update a few special pwm outputs at a faster rate, the devices attached to the pwm outputs, such as Victors, aren't designed to receive the updates very much faster than the current slow loop speed.
Those "special outputs" are 13-16, right? The ones our code has to generate the PWM signal for?
In any case the response of the downstream systems such as the Victors, motors, and drivetrain will lag and swallow the milliseconds we might save.
OK. That makes sense, as setting an output to max for only 26.2ms outputs a pulse that barely tensions the chain, let alone moving the drivetrain. I just thought that polling the gyro really fast was a good idea, but I didn't realize how short 26.2ms is.
To work properly PID feedback control depends on regular feedback not just speed and to make correct decisions needs previous decisions to be acted upon. It'll quickly lose track of things if the outside world is ignoring 99% of it's requests for motor changes and only acting on a random 1%.
I knew this would be damaging to the algorithm if the victors weren't getting the updated signal, but I didn't think that they were only updated every slow loop. Now that I know this, I have a little more info on why our PID loop was so broken last year (it oscillated beyond control in about 3 seconds. I know how to tweak it now; I didn't then).
Typically, use the fast loop of Process_Data_From_Local_IO to sample sensors, especially polled sensors, and collect data for use in making decisions later in the slow loop.
So you mean poll the sensors if I want an average over that 26.2ms instead of an instantaneous reading during the slow loop?
The default code slow loop in main() is just used to kickoff the separate autonomous slow loop. The way the autonomous slow loop is coded doesn't allow anything else, including the main.c loop, to run again until the Master signals the end of autonomous mode. We eliminate the separate autonomous loop and only allow the main loop.
Oh, I forgot it was a separate loop. I ripped that out of last year's code, but in hindsight I could've left it just like it was. About the part that's bolded above: what do you mean? Do you mean that your team has ripped out the separate loop and let main() loop like normal?
Thanks
JBot
Mark McLeod
24-12-2006, 19:23
Those "special outputs" are 13-16, right? The ones our code has to generate the PWM signal for?
Yep. Be wary and stay away from them though. They don't work correctly as they are used in the default code. There is some extra work required for those. If you're interested a CD search will point you in the right direction.
I just thought that polling the gyro really fast was a good idea, but I didn't realize how short 26.2ms is.
...
So you mean poll the sensors if I want an average over that 26.2ms instead of an instantaneous reading during the slow loop?
Using the fast loop to poll the gyro is a really good idea, because you have to average the data to get a meaningful result.
Polling a pot on an arm usually isn't necessary, because it returns absolute position anyway.
Oh, I forgot it was a separate loop. I ripped that out of last year's code, but in hindsight I could've left it just like it was. About the part that's bolded above: what do you mean? Do you mean that your team has ripped out the separate loop and let main() loop like normal?
Sounds like we had similar solutions. We didn't like a software design that took control away from the main loop.
One of the advantages of ripping the loop out of User_Autonomous_Code is that Process_Data_From_Master_uP and Process_Data_From_Local_IO continue to get called normally from main() without any extra work or duplication of effort. We add a few other improvements to main() such as initial delays to allow the systems and sensors to stabilize on powerup and automatically resetting autonomous on disable. It's nice that these changes apply to every mode and don't have to be implemented again for that autonomous loop.
teh_pwnerer795
31-12-2006, 16:14
hmm i kind of got lost somewhere.... but ye .. if u still cant complie ur program with
#include <stdio.h>
just a quick question.. have u added
-nw=2066 in ur Alternate Settings in MPLAB C18?
and if its already fixed then dunn wrry:)
JBotAlan
31-12-2006, 16:42
hmm i kind of got lost somewhere.... but ye .. if u still cant complie ur program with
#include <stdio.h>
just a quick question.. have u added
-nw=2066 in ur Alternate Settings in MPLAB C18?
and if its already fixed then dunn wrry:)
No, I don't think I have it fixed yet.
The code compiles. There are no errors or warnings. I haven't modified the settings in MPLAB at all--I didn't know I was supposed to. It looks like the default code has that option set by default, as it is already there.
Thanks for the hints, though.
JBot
JBotAlan
04-01-2007, 23:17
OK--I just got back to the robot today (wow, Christmas break was like being locked in a small shed with no heat and snow all over the place, then getting back was like walking out of said shed into the sun). I did not try any of the old code/HEXes. I have been trying to get my new code working. It worked when I first put it on the controller, but problems showed up when I was trying to interface to a position sensor (like a pot, but has no mechanical limit; just snaps back around to 0). I was getting a good analog signal in; it ranged from about 16888 to 19000 (I think). At this point, everything was gravy. I decided to write up a quick program to watch the input, keep two static doubles, one min, one max, and check if the value coming in was out of range and adjust the according value, and printf both values every slow loop. I discovered either a compiler glitch or a printf bug, as both of my variables look like they have good data; I am getting good data back in the terminal for min, but not for max. For max, I either get 0 or -32767 (very suspicious, but I don't see where my code is overflowing and writing over one of the bits...). I put the printf on a separate line, instead of having a
printf("a is %d, b is %d\r\n",a,b);. At this point, the printed value was in the 18000's range, which is believable for that sensor, but the value coming in didn't go over 17000. I tried typecasting to double (which had no effect, I didn't expect it to).
Why is printf so buggy? and does Kevin Watson have something that works a little better?
Attached is the zip of my current code sans Kevin Watson's serial_ports.c/h and camera.c/h as he does not want these redistributed. Just plop them in the directory and it should work again.
Thanks for trying to help.
JBot
Tottanka
04-01-2007, 23:28
I ahvent used C for a year
but arent u supposed to write
Printf("a is %d",&A);
Seems like you forgot the &..if im wrong tell me why..
JBotAlan
04-01-2007, 23:34
I ahvent used C for a year
but arent u supposed to write
Printf("a is %d",&A);
Seems like you forgot the &..if im wrong tell me why..
I have never seen that syntax before. After looking it up, I found this:
from http://www.sysprog.net/cpointer.html:
An ampersand before a variable means that you are referring to the address of the variable, not its contents.
So no, I would guess that would pass printf the address of the variable instead of what (I think) it wants: the value to print. Then again, with my code breaking as fast as it is, I am beginning to wonder about some very basic assumptions...
Thanks,
JBot
esquared
05-01-2007, 00:07
Values in the 18000 range seem rather large for data coming back from an analog input. Analog input values should be in the 0-1023 range as they are 10-bit data. Time to unzip your source code i suppose...
Edit starts here---
Printf's formatting identifier '%d' is actually meant for signed integers, NOT doubles (fixed-point printing of a double is %f, which back in the day was 'float', or single-precision floating point vs double-precision floating point. I digress too far in these parenthesis, sorry). Looking at your source, your min, max, and "i" variable are all doubles. You will get rather wacky results using the wrong format identifier for a given variable type. For analog inputs, stick with a regular int to store/manipulate data. PWM values can be put into a character since they are 8 bit values (0 to 255).
No ampersand is needed for printf, unless what you wanted to print was the memory address of the variable. Sometimes thats useful for debugging pointers that don't seem to be in the right place :ahh:
--Eric
Kevin Watson
05-01-2007, 00:42
Why is printf so buggy? and does Kevin Watson have something that works a little better?You should define i, min and max to be type "unsigned int", not "double" and use "%u" instead of "%d" in your printf() calls.
-Kevin
Edit: Whoops, looks like esquared answered your question while I was composing my posting.
JBotAlan
05-01-2007, 07:20
Printf's formatting identifier '%d' is actually meant for signed integers, NOT doubles (fixed-point printing of a double is %f, which back in the day was 'float', or single-precision floating point vs double-precision floating point. I digress too far in these parenthesis, sorry).
You should define i, min and max to be type "unsigned int", not "double" and use "%u" instead of "%d" in your printf() calls.
So which is it, or are both valid? Ahh, I'll just look it up. %u or %f, I'm not quite sure. I'll probably try both.
EDIT: Just reread your post, Kevin. So it's %u for an unsigned int or a char, and %f for doubles? I'll test this either tomorrow or the next meeting.
I was wondering if it wasn't printf mangling what it was supposed to print...
Thanks
JBot
esquared
05-01-2007, 12:42
So which is it, or are both valid? Ahh, I'll just look it up. %u or %f, I'm not quite sure. I'll probably try both.
EDIT: Just reread your post, Kevin. So it's %u for an unsigned int or a char, and %f for doubles? I'll test this either tomorrow or the next meeting.
I was wondering if it wasn't printf mangling what it was supposed to print...
Thanks
JBot
%u for unsigned, %f for doubles is correct.
Using signed vs unsigned is somewhat a matter of preference for analog inputs. The advantage of signed is if you have calculations that have multiple steps and may temporarily take your integer value below zero. For example, you have a scaling function that has an offset in it, so that some positive value from the sensor still equates to zero after the calcs are done. Depending on how your code is written, this may not be necessary, but can make your code more readable.
The disadvantage of signed is taking your value and applying it to something like a PWM output, where you're dealing with unsigned values. Even then using an int you want to be sure you're not exceeding 255 when assigning to the PWM output.
--Eric
Kevin Watson
05-01-2007, 13:29
...%f for doubles? Microchip's implementation of printf() doesn't support %f. Unless you really need it, I'd stay away from floating-point operations because the underlying hardware doesn't support it (i.e., it has to be emulated in software).
-Kevin
esquared
05-01-2007, 15:14
\because the underlying hardware doesn't support it (i.e., it has to be emulated in software).
-Kevin
i.e. do not code a For loop of floating point divisions in an interrupt handler. :]
JBotAlan
05-01-2007, 21:25
I would like floating point accuracy, and I know there are ways of representing a floating-point number inside an int, but I haven't really sat down and thought it out. I don't know how I want to shorthand this. Any suggestions?
I will probably keep using floating-point until it gets so slow that I get a code error. I know that this is emulated; I've seen other threads on not using floating point variables, but aside from speed, I don't see any reason to change. And I know I'm not taking anywhere near 26ms to complete a loop right now.
I'll have to figure out an alternative to %f, though, and that might be the motivator to switch from floating point.
Thanks for your help.
JBot
I would like floating point accuracy, and I know there are ways of representing a floating-point number inside an int, but I haven't really sat down and thought it out. I don't know how I want to shorthand this. Any suggestions?
Fixed point arithmetic is good for this. Look at the white papers here on CD, especially if you're trying to do trig (look up "binary radians" or CORDIC to get some of the more useful stuff).
xrabohrok
09-01-2007, 17:32
First, think about what you are trying to printf to. The robot has no screen, so printf does not work. If you want to work from the command window from the IFI loader, then you must work with the concurring program.
I think that MP lab doesn't use printf anyway, I think they use something else...
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.