Project

General

Profile

Revision 1238

Encoder code for server added

View differences:

branches/encoders/code/behaviors/spline/server/encoders.c
1
#include "encoders.h"
2

  
3
char encoder_buf_index;
4

  
5
unsigned int left_data, right_data;
6

  
7
unsigned int left_data_array[BUFFER_SIZE];
8
unsigned int right_data_array[BUFFER_SIZE];
9
int left_data_idx;
10
int right_data_idx;
11

  
12
int left_dx;
13
int right_dx;
14
long int timecount;
15

  
16
volatile short int data_ready;
17

  
18
void encoder_recv(unsigned int, unsigned int);
19

  
20
//Helper Function Prototypes
21
inline void left_data_array_put(unsigned short int value);
22
inline unsigned int left_data_array_top(void);
23
inline unsigned int left_data_array_prev(void);
24
inline unsigned int left_data_array_bottom(void);
25

  
26
inline void right_data_array_put(unsigned short int value);
27
inline unsigned int right_data_array_top(void);
28
inline unsigned int right_data_array_prev(void);
29
inline unsigned int right_data_array_bottom(void);
30

  
31
/**
32
 * @brief Returns the specified encoders value
33
 *
34
 * @param encoder this is the encoder that you want to read. Valid arguments
35
 *          are LEFT and RIGHT
36
 *
37
 * @return the value of the specified encoder
38
 **/
39
int encoder_read(char encoder){
40
	
41
	if(encoder==LEFT) return left_data;
42
	else if(encoder==RIGHT) return right_data;
43
	else return -1;
44
}
45

  
46

  
47
/** 
48
* @brief Outputs encoder direction as FORWARD OR BACK
49
* A STUB! DO NOT use.
50
* 
51
* @param encoder The encoder you want the direction of.
52
* Valid arguments are right and left.
53
* 
54
* @return FORWARD or BACK (the constants)
55
*/
56
char encoder_direction(char encoder){
57
	return 0;
58
}
59

  
60
/**
61
 * Gets the total distance covered by the specified encoder (in encoder clicks)
62
 *
63
 * @param encoder the encoder that you want to read, use LEFT or RIGHT
64
 *
65
 * @return The distance covered by the specified encoder.
66
 **/
67
int encoder_get_dx(char encoder) {
68
	
69
	if(encoder==LEFT) return left_dx;
70
	else if(encoder==RIGHT) return right_dx;
71
	else return -1;
72
}
73

  
74
/**
75
 * Resets the distance accumulator for the specified
76
 *  encoder.
77
 *
78
 * @param encoder the encoder that you want to reset distance for
79
 **/
80
void encoder_rst_dx(char encoder) {
81
	
82
	if(encoder==LEFT) left_dx = 0;
83
	else if(encoder==RIGHT) right_dx = 0;
84
}
85

  
86
/** 
87
* @brief Returns the number of encoder reads that have occurred.
88
* 
89
* @return The time count.
90
*/
91
int encoder_get_tc(void) {
92
	return timecount;
93
}
94

  
95
/** 
96
* @brief Resets the encoder read counter.
97
*/
98
void encoder_rst_tc(void) {
99
	timecount = 0;
100
}
101

  
102

  
103
/** 
104
* @brief Returns the approximated instantaneous velocity of the robot
105
* in terms of encoder clicks.
106
* 
107
* @param encoder RIGHT or LEFT - the wheel you want the velocity for.
108
* 
109
* @return The instantaneous velocity for the given wheel.
110
*/
111
int encoder_get_v(char encoder){
112
	if (encoder == LEFT)
113
		return left_data_array_bottom() - left_data_array_top();
114

  
115
	if (encoder == RIGHT)
116
		return right_data_array_top() - right_data_array_bottom();
117

  
118
	return -1; /* TODO: velocity could be -1, use another value for error */
119
}
120

  
121

  
122
/** 
123
* @brief Waits until n encoder reads have occurred.
124
* Counter is reset on functions exit.
125
* 
126
* @param n 
127
*/
128
void encoder_wait(int n){
129
	while(data_ready<n);
130
	data_ready=0;
131
}
132

  
133

  
134
//Full reads occur every 40 microseconds. This function should be called
135
//every 8 microseconds.
136
void encoder_recv(unsigned int left_data_buf, unsigned int right_data_buf){
137
	short int dx;
138
  		
139
	left_data = left_data_buf;
140
	right_data = right_data_buf;
141

  
142
	/*Above 1023 is invalid data*/	
143
	if(!(left_data > 1023)) {
144
		left_data_array_put(left_data);
145

  
146
		//Adjust left accumulator
147
		dx = - left_data + left_data_array_prev();
148
		
149
		if(left_data_array_prev()==0)  dx=0;
150

  
151
		if(dx > 512) left_dx += dx - 1023; //Underflow
152
		else if(dx < -512) left_dx += dx + 1023; //Overflow
153
		else left_dx += dx;
154
	}
155

  
156
	/*Above 1023 is invalid data*/	
157
	if(!(right_data > 1023)) {
158
		right_data_array_put(right_data);
159

  
160
		//Adjust right accumulator
161
		dx = right_data - right_data_array_prev();
162

  
163
		if(right_data_array_prev()==0) dx=0;
164
		  
165
		if(dx > 512) right_dx += dx - 1023; //underflow
166
		else if(dx < -512) right_dx += dx + 1023; //overflow 
167
		else right_dx += dx;
168
	}
169

  
170

  
171
	//Increment timecount accumulator
172
	timecount++;
173
}
174

  
175

  
176
//Helper Functions
177
inline void left_data_array_put(unsigned short int value) {
178
	if(left_data_idx == BUFFER_SIZE-1)
179
		left_data_idx = 0;
180
	else
181
		left_data_idx++;
182
	left_data_array[left_data_idx] = value;
183
}
184

  
185
inline unsigned int left_data_array_top(void) {
186
	return left_data_array[left_data_idx];
187
}
188

  
189
inline unsigned int left_data_array_prev(void) {
190
	if(left_data_idx == 0)
191
		return left_data_array[BUFFER_SIZE-1];
192
	else
193
		return left_data_array[left_data_idx - 1];
194
}
195

  
196
inline unsigned int left_data_array_bottom(void) {
197
	if(left_data_idx == BUFFER_SIZE-1)
198
		return left_data_array[0];
199
	else
200
		return left_data_array[left_data_idx + 1];
201
}
202

  
203
inline void right_data_array_put(unsigned short int value) {
204
	if(right_data_idx == BUFFER_SIZE-1)
205
		right_data_idx = 0;
206
	else
207
		right_data_idx++;
208
	right_data_array[right_data_idx] = value;
209
}
210

  
211
inline unsigned int right_data_array_top(void) {
212
	return right_data_array[right_data_idx];
213
}
214

  
215
inline unsigned int right_data_array_prev(void) {
216
	if(right_data_idx == 0)
217
		return right_data_array[BUFFER_SIZE-1];
218
	else
219
		return right_data_array[right_data_idx - 1];
220
}
221

  
222
inline unsigned int right_data_array_bottom(void) {
223
	if(right_data_idx == BUFFER_SIZE-1)
224
		return right_data_array[0];
225
	else
226
		return right_data_array[right_data_idx + 1];
227
}
228

  
branches/encoders/code/behaviors/spline/server/encoders.h
1
/**
2
 * 
3
 * @file encoders.h
4
 * @brief Contains functions for reading encoder values.
5
 *
6
 * Contains high and low level functions for reading encoders
7
 * including reading out total distance covered, and 
8
 * eventually velocity.
9
 *	
10
 * @author Colony Project, CMU Robotics Club
11
*/
12

  
13
/**
14
 * @addtogroup encoders
15
 * @{
16
 **/
17

  
18
#ifndef __ENCODERS_H__
19
#define __ENCODERS_H__
20

  
21

  
22
#ifndef LEFT
23
	#define LEFT 0
24
#endif
25
#ifndef RIGHT
26
	#define RIGHT 1
27
#endif
28

  
29
/** @brief Magnet misaligned - likely distance from encoder problem. **/
30
#define ENCODER_MAGNET_FAILURE 1025
31
/** @brief Encoder misaligned - likely on XY plane. **/
32
#define ENCODER_MISALIGNED 1027
33
/** @brief Not enough time has passed - encoders not initialized in hardware. **/
34
#define ENCODER_DATA_NOT_READY 1026
35

  
36
//delay_ms argument after a full read is complete
37
#define ENCODER_DELAY 20
38

  
39
//Data invalid flags (hardware failure):
40
#define OCF _BV(4)
41
#define COF _BV(3)
42

  
43
//Data invalid alarm (May be invalid):
44
#define LIN _BV(2)
45

  
46
#define MagINCn _BV(1)
47
#define MagDECn _BV(0)
48

  
49
#define BUFFER_SIZE 23
50

  
51
/** @brief Initialize encoders. **/
52
void encoders_init(void);
53
/** @brief Read instantaneous encoder value. **/
54
int encoder_read(char);
55
/** @brief Currently a stub - DO NOT Use. **/
56
char encoder_direction(char encoder);
57

  
58
/** @brief Get total distance traveled. **/
59
int encoder_get_dx(char encoder);
60
/** @brief Reset distance counter. **/
61
void encoder_rst_dx(char encoder);
62
/** @brief Get time count: The number of encoder reads that have occurred. **/
63
int encoder_get_tc(void);
64
/** @brief Reset the time count. **/
65
void encoder_rst_tc(void);
66

  
67
/** @brief Still untested, so use at your own risk. **/
68
int encoder_get_v(char encoder);
69

  
70
/** @brief Waits for the next encoder reading, then returns. **/
71
void encoder_wait( int nReadings );
72

  
73
/**@}**/ //end group
74

  
75
#endif

Also available in: Unified diff