Robot not doing what we need it to, and printfs aren't working

So, first of all, our printf’s aren’t working. MPlab displays a “type qualifier mismatch in assignment” error. Any ideas why they aren’t working? They also are not being displayed, which could be attributed to our next problem.

Our robot is not doing what we are telling it to do, at all.
We are running Kevin’s code.
teleop.c below.

/*******************************************************************************
*
*	TITLE:		teleop.c 
*
*	VERSION:	0.1 (Beta)                           
*
*	DATE:		31-Dec-2007
*
*	AUTHOR:		R. Kevin Watson
*				[email protected]
*
*	COMMENTS:	This file best viewed with tabs set to four.
*
*				You are free to use this source code for any non-commercial
*				use. Please do not make copies of this source code, modified
*				or un-modified, publicly available on the internet or elsewhere
*				without permission. Thanks.
*
*				Copyright ©2007-2008 R. Kevin Watson. All rights are reserved.
*
********************************************************************************
*
*	Change log:
*
*	DATE         REV  DESCRIPTION
*	-----------  ---  ----------------------------------------------------------
*	31-Dec-2007  0.1  RKW Original
*
*******************************************************************************/

#include <stdio.h>
#include "ifi_frc.h"
#include "pwm.h"
#include "timers.h"
#include "interrupts.h"
#include "serial_ports.h"
#include "ifi_code.h"
#include "teleop.h"

/*******************************************************************************
*
*	FUNCTION:		Initialization()
*
*	PURPOSE:		This function is called once when the robot controller
*					is cold or warm booted. You should initialize your code
*					here.		
* 
*	CALLED FROM:	main() in ifi_frc.c
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
* 
*	COMMENTS:
*
*******************************************************************************/
void Initialization(void)
{
	// Setup the digital I/O pins. Use "INPUT" to setup the pin
	// as an input and "OUTPUT" to setup the pin as an output.
	digital_io_01 = INPUT;
	digital_io_02 = INPUT;
	digital_io_03 = INPUT;
	digital_io_04 = INPUT;
	digital_io_05 = INPUT;
	digital_io_06 = INPUT;
	digital_io_07 = INPUT;
	digital_io_08 = INPUT;
	digital_io_09 = INPUT;
	digital_io_10 = INPUT;
	digital_io_11 = INPUT;
	digital_io_12 = INPUT;
	digital_io_13 = INPUT;
	digital_io_14 = INPUT;
	digital_io_15 = INPUT;
	digital_io_16 = INPUT;
	digital_io_17 = INPUT;
	digital_io_18 = INPUT;


	// Initialize the digital outputs. If the pin is configured
	// as an input above, it doesn't matter what state you
	// initialize it to here.
	rc_dig_out01 = 0;
	rc_dig_out02 = 0;
	rc_dig_out03 = 0;
	rc_dig_out04 = 0;
	rc_dig_out05 = 0;
	rc_dig_out06 = 0;
	rc_dig_out07 = 0;
	rc_dig_out08 = 0;
	rc_dig_out09 = 0;
	rc_dig_out10 = 0;
	rc_dig_out11 = 0;
	rc_dig_out12 = 0;
	rc_dig_out13 = 0;
	rc_dig_out14 = 0;
	rc_dig_out15 = 0;
	rc_dig_out16 = 0;
	rc_dig_out17 = 0;
	rc_dig_out18 = 0;

	// initialize timers and external interrupts here
	// (see timers.c/.h and interrupts.c/.h)


	printf("IFI User Processor Initialized ...
");
}

/*******************************************************************************
*
*	FUNCTION:		Teleop_Init()
*
*	PURPOSE:		This is where you put code that needs to execute
*					just once at the start of teleoperation mode.		
* 
*	CALLED FROM:	main() in ifi_frc.c
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
* 
*	COMMENTS:		While in this mode, all operator interface data is valid
*					and all robot controller outputs are enabled.
*
*******************************************************************************/
void Teleop_Init(void)
{

}

/*******************************************************************************
*
*	FUNCTION:		Teleop()
*
*	PURPOSE:		This is where you put code that you want to execute while
*					your robot is in teleoperation mode. While in teleoperation
*					mode, this function is called every	26.2ms after new data
*					is received from the master processor.		
* 
*	CALLED FROM:	main() in ifi_frc.c
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
* 
*	COMMENTS:		While in this mode, all operator interface data is valid
*					and all robot controller outputs are enabled.
*
*******************************************************************************/
void Teleop(void)
{
	if (p1_sw_trig == 1) {
	mechanum(); //execute mechanum code
	}
	else {
	tank();
	}

	Update_OI_LEDs();	// located in ifi_code.c
	button_map(); //button mapping
	cannon();
}

/*******************************************************************************
*
*	FUNCTION:		Teleop_Spin()
*
*	PURPOSE:		While in teleoperation mode, this function is called
*					continuously between calls to Teleop().		
* 
*	CALLED FROM:	main() in ifi_frc.c
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
* 
*	COMMENTS:		While in this mode, all operator interface data is valid
*					and all robot controller outputs are enabled.
*
*******************************************************************************/
void Teleop_Spin(void)
{

}


void mechanum()
{
      signed double wFL, wFR, wRL, wRR, velocity, rotation, strafe, wMax;

    velocity = (((int)p1_y) - 127);
    rotation = (((int)p1_x) - 127);
    strafe = (((int)p2_x) - 127);
   
    wFL = velocity - rotation - strafe;
    wFR = velocity + rotation + strafe;
    wRL = velocity - rotation + strafe;
    wRR = velocity + rotation - strafe;


    pwm01 = (int)wFL + 127;
    pwm02 = 127 - (int)wFR;
    pwm03 = (int)wRL + 127;
    pwm04 = 127 - (int)wRR;   


//printf("PWMS- pwm01: %d , pwm02: %d , pwm03: %d , pwm04: %d \r 
", pwm01, pwm02, pwm03, pwm04);
//printf("Wheels- FL: %d FR: %d RL: %d RR: %d \r 
", wFL, wFR, wRL, wRR);
//printf("Port 1 Y: %d , Port 1 X: %d , Port 2 X: %d \r", p1_y, p1_x, p2_x);
}

void button_map() 
{
	if (p3_sw_trig == 1) {
		relay1_fwd = 1;		
		relay1_rev = 0;
		}
	if (p3_sw_top == 1) {
		if (glow_state == 1) {
			glow_state = 0;
			relay2_fwd = 0;
			relay2_rev = 0;
			}
		else {
			glow_state = 1;
			relay2_fwd = 1;
			relay2_rev = 0;
		}
	}
}

void cannon() 
{
pwm05 = (p3_y/4);
}

void tank()
{
  p1_x = 255 - p1_y;
  p1_y = 255 - pwm05;
}

For testing, we added the mechanum/tank drive switch, and the robot did nothing in tank drive mode, and wouldn’t stop going in mechanum mode. It also wouldn’t switch out of mechanum mode.

The only uncommented printf is: printf("IFI User Processor Initialized …
");

The other ones are commented out. Does that error have a line number with it?

All of them give the error (when they are uncommented)

I commented most of them out when I started running into the error, as commenting them out gave me less errors, and made me happier. I kept t one so I knew when I had fixed it (which hasn’t happened, of course).

Which line does it say that error is on?

In your tank function, you don’t set any PWM values, therefore the PWMs will still be what they were before the function was called. When you first turn the robot on, it won’t move. Once the PWMs get set in the mecanum function, they will continue with the same value once you start calling the tank function again.

In the mecanum function, the calculations can very easily overflow a char. You’ll need to protect against that. I don’t know if that is the only problem, but it will definitely cause you problems.

And while you are at it, can you post the entire error message(s)?

Your print statements have mixed types where you attempt to print unsigned char (e.g., pwm01) and double (wFL) types as ints (%d). Typecast the arguments (int).

Statements such as:
pwm01 = (int)wFL + 127;
start with a double, typecast it to int, then assign it to unsigned char
as opposed to keeping your calculation as double then typecasting the result to unsigned char.
Are you doing that to speed things up? Just curious, not a problem.

The printf line (unsure specific number, but that line).

I don’t have the entire error anymore, but it said the error was “type qualifier mismatch in assignment” on the printf line in teleop.c.

In your tank function, you don’t set any PWM values, therefore the PWMs will still be what they were before the function was called. When you first turn the robot on, it won’t move. Once the PWMs get set in the mecanum function, they will continue with the same value once you start calling the tank function again.

In the mecanum function, the calculations can very easily overflow a char. You’ll need to protect against that. I don’t know if that is the only problem, but it will definitely cause you problems.

I’m really not terribly worried about the tank function, but thanks for pointing that out. We will try this if we can’t get mechanum to work.

That being said, this is almost the exact same mechanum code we used at the competition. It should work, but it isn’t.

How would we stop it from overflowing the chars?

Your print statements have mixed types where you attempt to print unsigned char (e.g., pwm01) and double (wFL) types as ints (%d). Typecast the arguments (int).

Statements such as:
pwm01 = (int)wFL + 127;
start with a double, typecast it to int, then assign it to unsigned char
as opposed to keeping your calculation as double then typecasting the result to unsigned char.
Are you doing that to speed things up? Just curious, not a problem.

On our last bot, we had some issues with the robot spitting out relatively random PWM values (usually like -16573 or something). We fixed those (from what I remember) by adding the int typecasts. This may be the same issue, but I can’t find out because the printfs aren’t working.

“type qualifier mismatch in assignment” is usually a warning not an error. Are you sure it is giving you an error? If it is just a warning sometimes it is OK to ignore it.

If the prinfts are still not working after ignoring the warnings, try printing something simple like printf(“Hello World”); Also your wFL values are floats so use %f instead of %d.

Just a reminder to everyone, please do not post copies of Kevin’s code (as the license says). It makes supporting his code difficult. I know the IFI code is old now but we should still be careful about this.