Go to Post "I need the adjustable hammer" "You mean that wren-" "No, it's a hammer" - Karibou [more]
Home
Go Back   Chief Delphi > Other > FIRST Tech Challenge
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 02-08-2006, 15:39
CircularLogic CircularLogic is offline
Registered User
FRC #1546 (Chaos Inc)
Team Role: Leadership
 
Join Date: Jan 2006
Rookie Year: 2005
Location: Baldwin
Posts: 38
CircularLogic will become famous soon enoughCircularLogic will become famous soon enough
Vex Encoder Code

Im just getting started on programming Vex with mplab. I have already worked with simple limit switches to control actions but now I would like to branch out into the more difficult realm of encoders.

I wrote a program that today that works but isnt correct.

Code:
void StartRightEncoder(void)
{

	oldstate = rc_dig_in05;
	 state = rc_dig_in05;
	if(oldstate != state)
	{
		rtick++;
	}
	oldstate = state;
}

It works to the extent that rtick increases, but I have a feeling that due to condition of incrementing rtick, I am missing many ticks from the encoder because it simply doesnt get the ticks quick enough. My emperical evidence is that when I set my motors to go when rtick is less than 270 (3 complete revolutions and with a wheel diam of approximately 3 inches, the code should make the bot go 9 inches give or take for round off error), the bot went more like 3 feet.

How does everyone else actually detect all the ticks? I checked the sample code on vexlabs but the encoder code isnt ready yet in the sample code download.
__________________
Team 1546 Chaos Incorporated
2005- SBPLI Rookie All Stars
2006- SBPLI Sportsmanship award.

Gotta hand it to the straight line autonomous mode, the most effective defense out there.

Proud beyond belief of the accomplishments of the second year, 20th ranked, 6 wins and 6 losses Chaos Incorporated.

Last edited by CircularLogic : 02-08-2006 at 15:42.
Reply With Quote
  #2   Spotlight this post!  
Unread 02-08-2006, 17:01
Mark McLeod's Avatar
Mark McLeod Mark McLeod is offline
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,830
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: Vex Encoder Code

Couple of issues.

The code you posted seems to be fundamentally flawed, because "oldstate" always equals "state".
Essentially, oldstate = state = rc_dig_in05;
rtick will only increase if the encoder happens to "tick" exactly between those first two lines of the setting of oldstate and the setting of state. That can happen sometimes, but it would be pretty random. You want to avoid "windows" like this in your logic where all the ticks happening outside those first two lines are being ignored.

I assume you are polling the encoder, but are maybe polling it from the code slow loop? It should be polled from the fast loop. If you are running autonomously that would mean you need to call your function from User_Autonomous_Code() right before the line:
Code:
	if (statusflag.NEW_SPI_DATA)	 /* 18.5ms loop area */
Make sure oldstate is a global variable (I imagine it is since it's not declared within your function), or declared static (meaning it sticks around), and it gets initialized to something, e.g.,
Code:
void StartRightEncoder(void)
{
	static unsigned char oldstate=0;
 
	 state = rc_dig_in05;
	if(oldstate != state)
	{
		rtick++;
	}
	oldstate = state;
}
There are two ways an encoder can be implemented: polling or interrupt.
You should try both ways to get the experience.

- Polling is just checking the encoder every software loop.
Polling works if the encoder updates are slow enough. To be safe you should calculate how many ticks per second you expect and compare that to how fast your code is polling. Polling the encoder should be performed in the fast loop, so you are less likely to miss a tick. Polling too slow will cause you to miss ticks and go further than you wanted. As a rough rule of thumb you want to poll at least twice as fast as the ticks will come in.
For instance, the slow loop in the vex controller runs at 18.5ms, so it makes 54 loops per second. The vex encoder is 90 ticks per revolution, so if it's more than a quarter revolution per second you'll be dropping counts as it moves. For your case if the robot covers the 9 inches in less than 11 seconds you'd be getting faulty counts. On the other hand the fast loop might give you on the order of a hundred thousand polls per second, so you could safely cover that same distance in 5.4 milliseconds without losing count!

-Interrupts are more reliable for higher speed ticks in that whenever the encoder state changes the PIC hardware immediately notifies your software - sort of like a good poke in the side. No matter what else your code is doing it will stop, add the tick, and go back to what it was doing before.
P.S. You still must calculate how fast you expect the ticks to arrive to be sure the interrupts don't happen too fast to handle. The danger to watch out for here is getting so many interrupts per second that the PIC gets overwhelmed.
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle

Last edited by Mark McLeod : 03-08-2006 at 08:21. Reason: Wanted to mention "window". There's always a window.
Reply With Quote
  #3   Spotlight this post!  
Unread 04-08-2006, 12:21
CircularLogic CircularLogic is offline
Registered User
FRC #1546 (Chaos Inc)
Team Role: Leadership
 
Join Date: Jan 2006
Rookie Year: 2005
Location: Baldwin
Posts: 38
CircularLogic will become famous soon enoughCircularLogic will become famous soon enough
Re: Vex Encoder Code

Alright, so I have fixed my StartEncoder functions to eliminate the window in my logic and I placed those function definitions in User_Routine_Fast. I actually want the effect of this function to happen during user control, so I have the call to StartRightEncoder() placed in User_Routine.

I placed all function definitions right before

Code:
void Process_Data_From_Local_IO(void)
After compiling all of this and running it, it still doesnt work as intended. If the motor is ran slowly (pwm = 154) then it goes about a quarter of a turn too far. However, if I put it at 255, it goes about three times too far (this is with the wheel coming directly off the motor).

I suspect that I am still not polling fast enough (due to the fact that I dont actually have anything in Process_Data_From_Local_IO) but when I placed my function definitions in Process_Data_From_Local_IO, I recieved a whole bunch of errors.

When I placed my call to StartRightEncoder() in Process_Data_From_Local_IO, I got a very odd pulsing of the motors (meaning they would run for a second, stop for a second, and then continue on in that pattern) when combined with the function

Code:
if(GetRightTick() <= 180) 
{
	

	pwm04 = 255;
	

}


Thanks for your help Mark, I know I ask a lot.
__________________
Team 1546 Chaos Incorporated
2005- SBPLI Rookie All Stars
2006- SBPLI Sportsmanship award.

Gotta hand it to the straight line autonomous mode, the most effective defense out there.

Proud beyond belief of the accomplishments of the second year, 20th ranked, 6 wins and 6 losses Chaos Incorporated.
Reply With Quote
  #4   Spotlight this post!  
Unread 06-08-2006, 10:52
Mark McLeod's Avatar
Mark McLeod Mark McLeod is offline
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,830
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: Vex Encoder Code

Your function definitions cannot be placed inside another function such as Process_Data_From_Local_IO(), so that's why you saw all those errors when you tried it. The function definitions can actually go in any file you like (even your own new file). Declaring your functions is like setting up a library of stuff you can call on to do. It's where and how you call them that's important.

Your description of the robot's behavior sounds clear enough. You're right that you have to call your polling function StartRightEncoder() from within Process_Data_From_Local_IO() to get the faster polling during regular user driving. So concentrate on fixing the odd pulsing you're seeing.

Offhand I'd say odd pulsing like that is the symptom of a variable overflow. pwm04=255 while GetRightTick() returns values of 0 to 179, then I assume you set pwm04=127 somewhere else. Because of momentum the robot continues to roll forward (or the wheels continue to spin) even though the motors are off. The momentum means you still get encoder counts, so rtick continues to get bigger and bigger. If rtick is declared as an unsigned char, for instance, then when the count tries to increase to 256, rtick will suddenly wrap around to be 0 again and your code will set pwm04=255. Hence, pulsing motors. The same thing will occur eventually with larger variable types as well, e.g., a signed int would buy you 91 feet of travel.

Your variable rtick needs to be a pretty large variable type. Large enough to hold the distances you're planning to cover. What type are all your variables?
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle

Last edited by Mark McLeod : 06-08-2006 at 14:59.
Reply With Quote
  #5   Spotlight this post!  
Unread 07-08-2006, 18:44
CircularLogic CircularLogic is offline
Registered User
FRC #1546 (Chaos Inc)
Team Role: Leadership
 
Join Date: Jan 2006
Rookie Year: 2005
Location: Baldwin
Posts: 38
CircularLogic will become famous soon enoughCircularLogic will become famous soon enough
Re: Vex Encoder Code

Both, rtick and ltick (for the StartLeftEncoder function) are unsigned ints.

If I use GetRightTick() (which returns rtick), the function works fine. However, if I use GetLeftTick(), I get the odd pulsing again. I cant see any differences in my code between the two functions besides the names and the variable returned.


Code:
void StartRightEncoder(void)
{
	state = rc_dig_in05;
	if(oldstate != state)
	{
		rtick ++;
	}
	oldstate = state;
}

unsigned int GetRightTick(void)
{
	return rtick;
}

void ClearRightTick(void)
{
	rtick = 0;
}

void ClearLeftTick(void)
{
	ltick = 0;
}

unsigned int GetLeftTick(void)
{
	return ltick;
}

void StartLeftEncoder(void)
{
    	

    state1 = rc_dig_in06;
	if(oldstate1 != state)
	{
		ltick++;
	}
	oldstate1 = state1;
}



void Process_Data_From_Local_IO(void)
{
  StartRightEncoder();
  StartLeftEncoder();

	/* Add code here that you want to be executed every program loop. */

}



Those are all my functions and are all placed in User_Routines_Fast


Code:
if(GetRightTick() <= 300)
{
	

	pwm04 = 255;
	pwm03 = 0;

}
And that is the code that uses those functions in User_Routines. If I use the code posted directly above, it works fine (and by that i mean the wheel spins and stops at logical points). But if I change the If statement to ahve GetLeftTick <= 300, the motors pulse again. I had that problem with GetRightTick(), but that problem was resolved for some reason unknown to me.




And then when I use GetRightTick(), if i want my wheel to spin twice (which should be 180 ticks), I have to set the tick number to 308 to get close to two spins.


Its times like these that I wish someone had a vex encoder function posted on the internet.
__________________
Team 1546 Chaos Incorporated
2005- SBPLI Rookie All Stars
2006- SBPLI Sportsmanship award.

Gotta hand it to the straight line autonomous mode, the most effective defense out there.

Proud beyond belief of the accomplishments of the second year, 20th ranked, 6 wins and 6 losses Chaos Incorporated.
Reply With Quote
  #6   Spotlight this post!  
Unread 07-08-2006, 19:23
Mark McLeod's Avatar
Mark McLeod Mark McLeod is offline
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,830
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: Vex Encoder Code

There's a typo in StartLeftEncoder.
state
gets used in the if check instead of state1.
I'd consider standardizing your naming convention, e.g., ltick and lstate and loldstate or all the other way. The typos might make themselves more obvious that way.

Consider adding an else to your "<= 300" of pwm04=127;pwm03=127; so it's explicit that the motors are being turned off.

I'd try adding a printf to watch what ltick and rtick do when you turn the encoder by hand one revolution.

You're learning so much more writing this yourself!
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle

Last edited by Mark McLeod : 07-08-2006 at 19:36.
Reply With Quote
  #7   Spotlight this post!  
Unread 09-08-2006, 19:34
CircularLogic CircularLogic is offline
Registered User
FRC #1546 (Chaos Inc)
Team Role: Leadership
 
Join Date: Jan 2006
Rookie Year: 2005
Location: Baldwin
Posts: 38
CircularLogic will become famous soon enoughCircularLogic will become famous soon enough
Re: Vex Encoder Code

Doh, darn typos.

I fixed that and the Left encoder functions work just as well as the right encoder functions.

I have tried to use some printf()'s but they dont actually print to anything. Nothing shows up in the ifi loader terminal. Am i missing something?
__________________
Team 1546 Chaos Incorporated
2005- SBPLI Rookie All Stars
2006- SBPLI Sportsmanship award.

Gotta hand it to the straight line autonomous mode, the most effective defense out there.

Proud beyond belief of the accomplishments of the second year, 20th ranked, 6 wins and 6 losses Chaos Incorporated.
Reply With Quote
  #8   Spotlight this post!  
Unread 09-08-2006, 22:12
Mark McLeod's Avatar
Mark McLeod Mark McLeod is offline
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,830
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: Vex Encoder Code

Quote:
Originally Posted by CircularLogic
I have tried to use some printf()'s but they dont actually print to anything. Nothing shows up in the ifi loader terminal. Am i missing something?
Every file that uses a printf() somewhere must also have
Code:
#include <stdio.h>
at the top. Otherwise, you won't see any output.
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Encoder Code Kevin Watson Programming 47 18-02-2008 12:56
VEX Shaft Encoder Kit jeffmorris FIRST Tech Challenge 1 19-05-2006 12:23
Issues with encoder code jgannon Programming 7 26-03-2006 15:12
FRC easy-c vex encoder function? Gdeaver Programming 2 23-01-2006 08:03
Updated Encoder Code Available Kevin Watson Programming 2 04-01-2005 01:00


All times are GMT -5. The time now is 02:56.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi