SW bug has ME stumped!!!

We have a telescoping arm that extends buy pushing a plastic E-chain up its center with a globe motor

to tell when we are at the limits we put white paint on both ends of the black plastic chain, and use a banner sensor to see the white spots.

We have a variable that we use to remember whether we were going up or down the last time the chain was moved, so when we see the paint we know whether to restrict it from going up or down.

it all works fine except for one thing - we initialize that variable on powerup to say we were going down - and we power up the bot with the chain down, so the sensor is on

but after powerup the SW thinks the arm is all the way up instead - it wont let it go up, only down

if we power the bot up with the chain between the white spots, everything works fine. (this is what we have been doing)

I totally stumped by this one, and so are the SW students on our team - we cant see anything wrong with the code

is it possible the RC puts out invalid OI signals on powerup? on the first few loops of the SW could it be getting active switch inputs for OI switches that are open? Thats the only thing I can think of that would throw our code off and make it think it was going up after power on?

the code is below - if you draw a flowchart its easier to understand:


/*578 telescope control */
/*banner sensor is on rc_dig_in04 - 0=end of chain*/
	pwm04=127;			/*default to off*/ 
	if(p4_sw_aux1)			/*if up switch is on*/
	{
		if (rc_dig_in04)	/*if not end of chain*/
		{
			pwm04= 150;  	/*move up 1/4 speed*/
			teleDirection = 1;  /*last direction is up*/
		}
		else if (teleDirection==0) pwm04= 150; /*was going down, ok to move up*/ 
	}
	if(p4_sw_aux2)			/*if down switch is on*/
	{
		if (rc_dig_in04)	/*if not end of chain*/
		{
			pwm04= 104;	/*move down 1/4 speed*/
			teleDirection = 0;	/*last direction is down*/
		}
		else if (teleDirection==1) pwm04= 104; /*was going up, ok to move down*/ 
	}


teleDirection is initialzed to 0 = down and the only way it could get to be 1 is if the inputs read that the up switch is on and the banner sensor is off - neither of which are true when the bot is powered up with the chain all the way down.

Im totally stumped by this one! :ahh:

BTW- the chain does not move on power up, no glitches or anything, and we can use it the way it is by pulling the arm slightly off the paint spot

but it bugs me that its not doing what it should be - the code is doing something we dont understand or its doing something unpredictable, which leaves you with a sick feeling that something is not right with the system.

It sounds like the ultimate goal of this code is to allow the operator to move the arm up or down as (s)he pleases, while restricting it from traveling too far. If these are the only requirements, then does the software really need to know which way it’s going? It doesn’t seem like it to me. Why not just set the PWM output to either move up or down based off the OI control, unless either light sensor sees the white paint - then clamp the PWM to 127.

because there is only one light sensor, not two

when we turn a switch on to move and the light sensor is on, we have no way of knowing which end of the chain it sees, unless we rememeber which way we were moving the last time the chain was moved.

Ah yes, I should have read the code more closely. For some reason I thought you were using 2 sensors (although, thinking more about it, I guess it wouldn’t have worked in that case either).

Have you tried a bunch of printfs all over the place to try to pinpoint the time at which it changes? If so, is the teleDirection variable wrong immediately, on the first loop? It would also help to print out the raw p4_sw_auxX and rc_dig_inXX variables if you haven’t tried that yet. That should tell you if you’re simply reacting to invalid data or if there’s some other kind of bug. Are you certain that this is the only code that can modify the teleDirection variable?

yes we searched on the variable to makesure it was not initialized somewhere else to a different value, or changed somewhere else in the code

we didnt have any time to debug it at the pittsburgh regional - to busy fixing things that needed fixin

I guess we could put printf statements in and see what the inputs and variables are on powerup - or maybe put a poweron counter in the code that increments for a second on powerup, blocking this code until the link has booted?

cause if the input switches from the OI are invalid on powerup, then the diable signal would be invalid too - you wouldnt even be able to skip the code while the bot is disabled, cause all it takes is one invalid cycle and our variable will be changed.

BTW our bot is in a crate somewhere between pittsburgh and cleveland, so I have no way to test this until next thrusday - Im hoping someone would be able to explain the erratic ways of the input signals at powerup, or spot a bug in our code.

I’d have to see the code that does the initialization – in context – to make an informed suggestion about what might be going on.

You might try getting a little fancier. Use +1 as an indication you were going up, and -1 as an indication you were going down. Then you can initialize to zero, and your operator should have complete authority to move the chain either direction once until the mark is seen.

ok, here is where teleDirection is both declared and initialzed, right at the top of user_routines.c:


/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/
/* EXAMPLES: (see MPLAB C18 User's Guide, p.9 for all types)
unsigned char wheel_revolutions = 0; (can vary from 0 to 255)
unsigned int  delay_count = 7;       (can vary from 0 to 65,535)
int           angle_deviation = 142; (can vary from -32,768 to 32,767)
unsigned long very_big_counter = 0;  (can vary from 0 to 4,294,967,295)
*/
unsigned int  armPosition = 0;		/*arm position read from pot*/
/*---bunch of variables deleted for readability in this post---*/
unsigned int  armErrorLast = 0;		/* armError last time through */
unsigned int  teleDirection = 0;	/* telescope last direction moved - 0=down */

and here is where its explicitly initialized with the rest of the variables in user_rountine.c:


/* FIFTH: Set your PWM output types for PWM OUTPUTS 13-16.
  /*   Choose from these parameters for PWM 13-16 respectively:               */
  /*     IFI_PWM  - Standard IFI PWM output generated with Generate_Pwms(...) */
  /*     USER_CCP - User can use PWM pin as digital I/O or CCP pin.           */
  Setup_PWM_Output_Type(IFI_PWM,IFI_PWM,IFI_PWM,IFI_PWM);

  /* Add any other initialization code here. */
/*578 initialize drivermode & autonmode variables */
armPosition = 0;		/*arm position read from pot*/
gyroData = 0;			/*signal read from yaw rate sensor*/
/*more variable deleted for readability in this post*/
teleDirection = 0;		/* telescope last direction moved - 0=down */


if we used different values the problem would still be the same - the only place in the code where the variable can be changed is where I pointed out above, so whatever value we use for up or down, the SW cant tell if the switch inputs from the OI are valid or some sort of OI power up mess?

I and others have run into initially invalid digital inputs on RC startup /t/digital-inputs-not-valid-just-after-initialization/49057/1

We delayed the checking of external digital inputs.

ok so that would explain the banner sensor input being invalid for a short period after power up, in fact, the banner sensor itself probabally takes some time to get up and running and output valid data

but what about the switches from the OI? can they also be invalid on powerup? I find that hard to believe because your bot could do some strange things if the operator switches were read in as random states when the bot is first turned on

and my code can only change teleDirection if it sees one of the operator input switches in the active (closed) position (not the robot rc_dig_inxx switches)

?!?!

Too many players in the loop. The IFI initialization code on both the OI and the RC as well as the interface to our code. There are opportunities all along the line for slip-ups in the initial values.

I’d say treat at least the first radio packet as suspect.

Normal competition has everyone at the disabled state for the first minute or so. Enough time to mask the issue for most teams.

[edit]Saw your edit, we need a chat room.
My thinking is that the inputs on the OI are locally [font=Verdana]susceptible the same way the RC_dig_inxxx’s are.[/font]

ok, then the best fix I can think of would be to write a ‘warm up’ count - something that counts 38 or 76 loops through the 38Hz code loop while compmode is disabled, then sets a flag

and the flag allows the telearm-code to run

this is funny in a way, when I was a kid, if you wanted to watch TV you had to turn it on 10 minutes early to let the tubes warm up before you could watch anything

and now here we are with our solid state devices, and you still have to let computers boot up for 10 minutes, and even our robots have to ‘warm up’ before the inputs are valid!

OK - If thats the way it is we will have to get creative with the powerup timing

thats to everyone for your input - its good to know that the strange behaviour of the code is at least explainable. :^)

It could just be the master proc aligning itself with the packets.

Yea, yea, luxury. “In my day we had to listen to the radio and draw our own pictures” (no I’m not quite that old).

It’s all part of our rush-rush society. Milliseconds of warm-up time on the robot isn’t good enough for us.
To be fair the computers can start up pretty fast. I blame software for bloated OS’s. The machine’s faster so we should do more, right? That’s why my old computers at home all seem to boot as fast as the newest machine (as long as I freeze the old machines with an old OS).

I think I’ve got it…You’re not looking for a state change in the sensor. The first program loop runs with the UP switch on, teledirection is set to 1, the next loop, the sensor is still on, and the program thinks that the chain is at its limit…Making sure the sensor changes states should take care of it.

Sean - I think you are right if the bot is turned on with the UpSwitch turned on - then our code would be lost because the chain is at the bottom

the thing that has us stumped is we make sure the UP and Down switches are both off when we turn the bot on

but for some reason, it wont go up after that - it will go down, then up, (on the wrong side of the bottom paint mark) but not up - and not past the bottom mark.

Logically the only thing that can be happening is the OI is saying the upswitch is on for a loop or two at powerup, when its actully not on.

the code is a little tricky cause it has to do different things if the switch is on or off, and if the sensor is on or off - so we do catch the change of state by setting the variable only when the paint is not seen, and not changing it when the paint is seen

that way we know the ‘state’ of the motion the last time the chain was free to move - when we were not at the end.

I should have posted a flowchart with the code :^)