Problems Combining Camera Code and Driving Code

I have both the camera code and the driving code working independently :slight_smile: , 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

user_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

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 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).

Was there any problems with the documentation that caused it to not work the first time? If so, what was it?

-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.

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.

Thanks for sharing all this information-- it’s been helpful. :smiley:

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

Thank you for your reply! :smiley: 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

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

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

Any more of your code you can share with us (the rest of user_routines_fast.c, for example)?

Sure, here it is

Jon

user_routines_fast.c (8.79 KB)


user_routines_fast.c (8.79 KB)

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

CombinedSensors2006.zip (351 KB)


CombinedSensors2006.zip (351 KB)

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.