View Full Version : Problems Combining Camera Code and Driving Code
cmurdoch
28-01-2006, 11:13
I have both the camera code and the driving code working independently :) , but I've been having some trouble combining them. I've added both user_SerialDrv.c and user_SerialDrv.h to the camera code and uncommented the IFI code in user_routines.c as well as in user_routines_fast.c. I've also tried to change the pwm output assignments of either our two drive motors or the camera servos. When I left the servos on pwm01 and pwm02 and changed the pwms for the motors the camera worked and the driving didn't. When I switched them the driving worked and the camera didn't, in fact, the camera just sat there and twitched. :ahh: Then, I assigned the servos to pwm01 and pwm02 and the motors to pwm05 and pwm06. The camera froze in home position and the driving worked for about 30 seconds before halting and displaying a code error. If anyone has any idea how I can fix this I'd really appreciate it.
Thanks
Kevin Watson
28-01-2006, 12:33
I have both the camera code and the driving code working independently :) , but I've been having some trouble combining them. I've added both user_SerialDrv.c and user_SerialDrv.h to the camera code and uncommented the IFI code in user_routines.c as well as in user_routines_fast.c. I've also tried to change the pwm output assignments of either our two drive motors or the camera servos. When I left the servos on pwm01 and pwm02 and changed the pwms for the motors the camera worked and the driving didn't. When I switched them the driving worked and the camera didn't, in fact, the camera just sat there and twitched. :ahh: Then, I assigned the servos to pwm01 and pwm02 and the motors to pwm05 and pwm06. The camera froze in home position and the driving worked for about 30 seconds before halting and displaying a code error. If anyone has any idea how I can fix this I'd really appreciate it.
Thanksuser_SerialDrv.c/.h will conflict with the serial port driver included with the camera code (this is documented in serial_ports_readme.txt). At the very least, you'll need to remove user_SerialDrv.c/.h.
-Kevin
Steve Orr
29-01-2006, 14:41
I'm kind of in the same boat, and will be working on combining them this week. If I discover the secrets, I'll post...
I'll be eager to see if you find anything out as well!
I have both the camera code and the driving code working independently :) , but I've been having some trouble combining them. I've added both user_SerialDrv.c and user_SerialDrv.h to the camera code and uncommented the IFI code in user_routines.c as well as in user_routines_fast.c. I've also tried to change the pwm output assignments of either our two drive motors or the camera servos. When I left the servos on pwm01 and pwm02 and changed the pwms for the motors the camera worked and the driving didn't. When I switched them the driving worked and the camera didn't, in fact, the camera just sat there and twitched. :ahh: Then, I assigned the servos to pwm01 and pwm02 and the motors to pwm05 and pwm06. The camera froze in home position and the driving worked for about 30 seconds before halting and displaying a code error. If anyone has any idea how I can fix this I'd really appreciate it.
I see two likely problems with what you are doing:
(1) As Kevin says, the camera's serial code needs serial.c and serial.h from his code, and not the user_SerialDrv.c/h. You need to remove those from the project.
(2) Similarly, Kevin's serial code requires the interrupt routines in user_routines_fast.c to be correct (if you don't have this correct, you'll get the red light of death). If you aren't using other special interrupt code (encoders or the gyro), just copy user_routines_fast.c from Kevin's camera code and try that. Otherwise, you'll have to make sure all the appropriate interrupt handlers are in place for all the codes you are using. This can be done, our bot's testbed code now has the camera, gyro, shaft encoders, and two additional ADC channels running at the same time, but it's tricky and requires careful reading of the adc_readme.txt, encoder_readme.txt, camera_readme.txt, etc. (And we didn't get it right the first time, as you can see if you look the other places I've posted).
Kevin Watson
29-01-2006, 18:57
This can be done, our bot's testbed code now has the camera, gyro, shaft encoders, and two additional ADC channels running at the same time, but it's tricky and requires careful reading of the adc_readme.txt, encoder_readme.txt, camera_readme.txt, etc. (And we didn't get it right the first time, as you can see if you look the other places I've posted).Was there any problems with the documentation that caused it to not work the first time? If so, what was it?
-Kevin
Was there any problems with the documentation that caused it to not work the first time? If so, what was it?
As far as I can tell, the documentation is fine and the problems were on our end (not saving .tmp_data one time, and neglecting to insert the timer2 interrupt another time, both of which were clearly noted in the readme files), so if one makes sure they follow the instructions carefully it should work.
cmurdoch
02-02-2006, 20:35
Thanks
The problem was definately with SerialDrv.c/.h I didn't have problems with user_routines_fast.c because I started with the camera code and adapted that for driving. Thanks for all your help. It works wonderfully now and the next challenge is getting the camera to track using the motor on our rotating turret. :cool: Thanks again and thanks for all the great code Kevin. You rock.
1594code
04-02-2006, 13:02
Thanks for sharing all this information-- it's been helpful. :D
We have followed the serial_ports_readme instructions, we're using Kevin's camera code user_routines_fast.c interrupt handlers, and we tried to remove user_serial_drv.c.
We had a problem with this last action-- the function breaker_tripped was called in user_routines.c, and it is declared in User_serial_drv.c, so we can't compile :confused:
Has this happened to anyone else? What did you do?
Kevin Watson
04-02-2006, 13:06
Thanks for sharing all this information-- it's been helpful. :D
We have followed the serial_ports_readme instructions, we're using Kevin's camera code user_routines_fast.c interrupt handlers, and we tried to remove user_serial_drv.c.
We had a problem with this last action-- the function breaker_tripped was called in user_routines.c, and it is declared in User_serial_drv.c, so we can't compile :confused:
Has this happened to anyone else? What did you do?If you aren't using the breaker panel, you can safely delete the function and user_serial_drv.c/.h from your project.
-Kevin
1594code
04-02-2006, 14:35
If you aren't using the breaker panel, you can safely delete the function and user_serial_drv.c/.h from your project.
-Kevin
Thank you for your reply! :D We have yet another question... We are using four circuit breakers: the maxi style circuit breaker panel, the 120 Hi-Amp circuit breaker, and two other circuit breaker panels that came with the KOP.
Is the circuit breaker you meant among those four?
Kevin Watson
04-02-2006, 14:56
Thank you for your reply! :D We have yet another question... We are using four circuit breakers: the maxi style circuit breaker panel, the 120 Hi-Amp circuit breaker, and two other circuit breaker panels that came with the KOP.
Is the circuit breaker you meant among those four?No, "breaker panel" refers to the circuit breaker panel distributed last year to teams. It sends out serial data to inform the robot controller that a breaker has tripped.
-Kevin
As far as I can tell, the documentation is fine and the problems were on our end (not saving .tmp_data one time, and neglecting to insert the timer2 interrupt another time, both of which were clearly noted in the readme files), so if one makes sure they follow the instructions carefully it should work.
When combining the camera and interrupt code, how many timer interrupts are required? Any other details? So far I'm still getting the RLOD!!!!
Jon Mittelman
Team236
When combining the camera and interrupt code, how many timer interrupts are required? Any other details? So far I'm still getting the RLOD!!!!
You should need an interrupt handler for tx1, rx1, tx2, and rx2, unless you are also using encoders, the adc code, or the gyro (which uses the adc code).
We do use all of those, and it's working fine. Here's our InterruptHandlerLow:
#pragma code
#pragma interruptlow InterruptHandlerLow save=PROD,section(".tmpdata")
void InterruptHandlerLow(void)
{
unsigned char Port_B;
unsigned char Port_B_Delta;
if(PIR1bits.RC1IF && PIE1bits.RC1IE) // rx1 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_ONE_RX
Rx_1_Int_Handler(); // call the rx1 interrupt handler (in serial_ports.c)
#endif
}
else if(PIR3bits.RC2IF && PIE3bits.RC2IE) // rx2 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_TWO_RX
Rx_2_Int_Handler(); // call the rx2 interrupt handler (in serial_ports.c)
#endif
}
else if(PIR1bits.TMR2IF && PIE1bits.TMR2IE) // timer 2 interrupt?
{
PIR1bits.TMR2IF = 0; // clear the timer 2 interrupt flag [92]
Timer_2_Int_Handler(); // call the timer 2 interrupt handler (in adc.c)
}
else if(PIR1bits.ADIF && PIE1bits.ADIE) // ADC interrupt
{
PIR1bits.ADIF = 0; // clear the ADC interrupt flag
ADC_Int_Handler(); // call the ADC interrupt handler (in adc.c)
}
else if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) // encoder 1 interrupt?
{
INTCON3bits.INT2IF = 0; // clear the interrupt flag
#ifdef ENABLE_ENCODER_1
Encoder_1_Int_Handler(); // call the left encoder interrupt handler (in encoder.c)
#endif
}
else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE) // encoder 2 interrupt?
{
INTCON3bits.INT3IF = 0; // clear the interrupt flag
#ifdef ENABLE_ENCODER_2
Encoder_2_Int_Handler(); // call right encoder interrupt handler (in encoder.c)
#endif
}
else if (INTCONbits.RBIF && INTCONbits.RBIE) // encoder 3-6 interrupt?
{
Port_B = PORTB; // remove the "mismatch condition" by reading port b
INTCONbits.RBIF = 0; // clear the interrupt flag
Port_B_Delta = Port_B ^ Old_Port_B; // determine which bits have changed
Old_Port_B = Port_B; // save a copy of port b for next time around
if(Port_B_Delta & 0x10) // did external interrupt 3 change state?
{
#ifdef ENABLE_ENCODER_3
Encoder_3_Int_Handler(Port_B & 0x10 ? 1 : 0); // call the encoder 3 interrupt handler (in encoder.c)
#endif
}
if(Port_B_Delta & 0x20) // did external interrupt 4 change state?
{
#ifdef ENABLE_ENCODER_4
Encoder_4_Int_Handler(Port_B & 0x20 ? 1 : 0); // call the encoder 4 interrupt handler (in encoder.c)
#endif
}
if(Port_B_Delta & 0x40) // did external interrupt 5 change state?
{
#ifdef ENABLE_ENCODER_5
Encoder_5_Int_Handler(Port_B & 0x40 ? 1 : 0); // call the encoder 5 interrupt handler (in encoder.c)
#endif
}
if(Port_B_Delta & 0x80) // did external interrupt 6 change state?
{
#ifdef ENABLE_ENCODER_6
Encoder_6_Int_Handler(Port_B & 0x80 ? 1 : 0); // call the encoder 6 interrupt handler (in encoder.c)
#endif
}
}
else if(PIR1bits.TX1IF && PIE1bits.TX1IE) // tx1 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_ONE_TX
Tx_1_Int_Handler(); // call the tx1 interrupt handler (in serial_ports.c)
#endif
}
else if(PIR3bits.TX2IF && PIE3bits.TX2IE) // tx2 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_TWO_TX
Tx_2_Int_Handler(); // call the tx2 interrupt handler (in serial_ports.c)
#endif
}
}
You should need an interrupt handler for tx1, rx1, tx2, and rx2, unless you are also using encoders, the adc code, or the gyro (which uses the adc code).
We do use all of those, and it's working fine. Here's our InterruptHandlerLow:
#pragma code
#pragma interruptlow InterruptHandlerLow save=PROD,section(".tmpdata")
void InterruptHandlerLow(void)
{
unsigned char Port_B;
unsigned char Port_B_Delta;
if(PIR1bits.RC1IF && PIE1bits.RC1IE) // rx1 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_ONE_RX
Rx_1_Int_Handler(); // call the rx1 interrupt handler (in serial_ports.c)
#endif
}
else if(PIR3bits.RC2IF && PIE3bits.RC2IE) // rx2 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_TWO_RX
Rx_2_Int_Handler(); // call the rx2 interrupt handler (in serial_ports.c)
#endif
}
else if(PIR1bits.TMR2IF && PIE1bits.TMR2IE) // timer 2 interrupt?
{
PIR1bits.TMR2IF = 0; // clear the timer 2 interrupt flag [92]
Timer_2_Int_Handler(); // call the timer 2 interrupt handler (in adc.c)
}
else if(PIR1bits.ADIF && PIE1bits.ADIE) // ADC interrupt
{
PIR1bits.ADIF = 0; // clear the ADC interrupt flag
ADC_Int_Handler(); // call the ADC interrupt handler (in adc.c)
}
else if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) // encoder 1 interrupt?
{
INTCON3bits.INT2IF = 0; // clear the interrupt flag
#ifdef ENABLE_ENCODER_1
Encoder_1_Int_Handler(); // call the left encoder interrupt handler (in encoder.c)
#endif
}
else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE) // encoder 2 interrupt?
{
INTCON3bits.INT3IF = 0; // clear the interrupt flag
#ifdef ENABLE_ENCODER_2
Encoder_2_Int_Handler(); // call right encoder interrupt handler (in encoder.c)
#endif
}
else if (INTCONbits.RBIF && INTCONbits.RBIE) // encoder 3-6 interrupt?
{
Port_B = PORTB; // remove the "mismatch condition" by reading port b
INTCONbits.RBIF = 0; // clear the interrupt flag
Port_B_Delta = Port_B ^ Old_Port_B; // determine which bits have changed
Old_Port_B = Port_B; // save a copy of port b for next time around
if(Port_B_Delta & 0x10) // did external interrupt 3 change state?
{
#ifdef ENABLE_ENCODER_3
Encoder_3_Int_Handler(Port_B & 0x10 ? 1 : 0); // call the encoder 3 interrupt handler (in encoder.c)
#endif
}
if(Port_B_Delta & 0x20) // did external interrupt 4 change state?
{
#ifdef ENABLE_ENCODER_4
Encoder_4_Int_Handler(Port_B & 0x20 ? 1 : 0); // call the encoder 4 interrupt handler (in encoder.c)
#endif
}
if(Port_B_Delta & 0x40) // did external interrupt 5 change state?
{
#ifdef ENABLE_ENCODER_5
Encoder_5_Int_Handler(Port_B & 0x40 ? 1 : 0); // call the encoder 5 interrupt handler (in encoder.c)
#endif
}
if(Port_B_Delta & 0x80) // did external interrupt 6 change state?
{
#ifdef ENABLE_ENCODER_6
Encoder_6_Int_Handler(Port_B & 0x80 ? 1 : 0); // call the encoder 6 interrupt handler (in encoder.c)
#endif
}
}
else if(PIR1bits.TX1IF && PIE1bits.TX1IE) // tx1 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_ONE_TX
Tx_1_Int_Handler(); // call the tx1 interrupt handler (in serial_ports.c)
#endif
}
else if(PIR3bits.TX2IF && PIE3bits.TX2IE) // tx2 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_TWO_TX
Tx_2_Int_Handler(); // call the tx2 interrupt handler (in serial_ports.c)
#endif
}
}
I've made all of those changes and still get the RLOD. We use the interrupts, timers, rx1&2 tx1&2.
Any other thoughts?
Jon
I've made all of those changes and still get the RLOD. We use the interrupts, timers, rx1&2 tx1&2.
Any other thoughts?
Jon
Any more of your code you can share with us (the rest of user_routines_fast.c, for example)?
Any more of your code you can share with us (the rest of user_routines_fast.c, for example)?
Sure, here it is
Jon
Sure, here it is
Jon
Nothing obvious looks amiss here. You've got two handler routines for your sonar, so I'm going to guess that the problem is there. How much code are these? Interrupt code needs to be tight and minimal, if there is too much code it can't process the interrupt handler fast enough and you get RLOD.
Nothing obvious looks amiss here. You've got two handler routines for your sonar, so I'm going to guess that the problem is there. How much code are these? Interrupt code needs to be tight and minimal, if there is too much code it can't process the interrupt handler fast enough and you get RLOD.
I've been doing a sequential comment-out-and-test, ditching both sonar code and adc code....getting the same RLOD....figuring it's something really stupid, like an effect of a missed semicolon that the compiler didn't pick up on..
Jon
With gracious assistance from Kevin Watson, I have finally been able to get the camera, sonar, yaw sensor, quadrature encoders and gyro (with the ADC code) working. The attached zip file should help.....just add the rest of your control algorithms and presto!, a working robot.......now, if our build team would just finish............
Jon Mittelman
Team236 Programming Mentor
monkeyleader
09-02-2007, 00:48
I took the camera code and adjusted that for driving, but I've just been using the camera project so there already is no srl_dvr.c/h or whatever the exact name is. Everything works great except that p2_y does nothing and I cant figure out why. I commented out the camera stuff in Process_Data_From_Master_uP and now it works fine so i know they are conflicting, but i can't find where. I thought at first it was with the pwm's but I already changed the defaults to 5 and 6 for the camera as our motors use 1-4. I'm not really familiar with the tx and rx and interupt stuff you guys were talking about. I mean i know what tx and rx datas are, but idk what u guys are talking about messing with them, I just leave that stuff alone cuz im not quite that advanced.
paulcd2000
10-02-2007, 16:34
did you carefully follow all the steps in the readme? i see people not doing that a lot
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.