Project

General

Profile

Statistics
| Revision:

root / branches / encoders / code / projects / libdragonfly / encoders.c @ 773

History | View | Annotate | Download (7.63 KB)

1
#include "encoders.h"
2
#include "spi.h"
3
#include <dragonfly_lib.h>
4
#include "ring_buffer.h"
5

    
6
unsigned int left_data_buf;
7
unsigned int right_data_buf;
8
char buf_index;
9

    
10
unsigned int left_data;
11
unsigned int right_data;
12

    
13
unsigned int left_data_array[BUFFER_SIZE];
14
unsigned int right_data_array[BUFFER_SIZE];
15
int left_data_idx;
16
int right_data_idx;
17

    
18
int left_dx;
19
int right_dx;
20
long int timecount;
21

    
22
int left_v;
23
int right_v;
24

    
25
volatile int recv_count;
26

    
27
volatile short int data_ready;
28

    
29
void encoder_recv(char data);
30

    
31
//Helper Function Prototypes
32
inline void left_data_array_put(unsigned short int value);
33
inline unsigned int left_data_array_top(void);
34
inline unsigned int left_data_array_prev(void);
35
inline unsigned int left_data_array_bottom(void);
36

    
37
inline void right_data_array_put(unsigned short int value);
38
inline unsigned int right_data_array_top(void);
39
inline unsigned int right_data_array_prev(void);
40
inline unsigned int right_data_array_bottom(void);
41

    
42
//RING_BUFFER_NEW(enc_buffer, BUFFER_SIZE, short int);
43

    
44
void encoder_recv_complete(void);
45

    
46
void encoder_recv_complete(){
47

    
48
  int dx;
49

    
50
   //  usb_puts("[");usb_puti(left_dx);usb_puts(",");usb_puti(right_dx);usb_puts("]\r\n");
51
   //   usb_puts("\r\n");
52
  data_ready++;
53
  
54
  //delay_ms(ENCODER_DELAY);
55

    
56
   spi_transfer(5);
57
}
58

    
59
void put_bin(char data){
60
  int i;
61

    
62
  for(i=7;i>=0;i--)
63
    usb_puti((data>>i)&1);
64
  usb_puts(" ");
65
}
66

    
67
/**
68
 * Initializes the encoders variables
69
 **/
70
void encoders_init(void){
71
        int i;
72
        
73
        data_ready=0;
74

    
75
        spi_init(encoder_recv/*put_bin*/, encoder_recv_complete);
76
        buf_index = 0;
77
        left_data_buf = 0;
78
        right_data_buf= 0;
79
        left_data = -1;
80
        right_data = -1;
81
        
82
        recv_count=0;
83
        
84
        left_v=0;
85
        right_v=0;
86
        
87
        //RING_BUFFER_INIT(enc_buffer,BUFFER_SIZE);
88
        left_data_idx = 0;
89
        right_data_idx = 0;
90
        for(i = 0; i < BUFFER_SIZE; i++) {
91
                left_data_array[i] = 0;
92
        }
93
        for(i = 0; i < BUFFER_SIZE; i++) {
94
                right_data_array[i] = 0;
95
        }
96
        spi_transfer(5);
97
}
98

    
99
/**
100
 * Returns the specified encoders value
101
 *
102
 * @param encoder this is the encoder that you want to read. Valid arguments
103
 *          are LEFT and RIGHT
104
 *
105
 * @return the value of the specified encoder
106
 **/
107
int encoder_read(char encoder){
108
        if(encoder==LEFT)
109
                return left_data;
110
        else if(encoder==RIGHT)
111
                return right_data;
112
        else return -1;
113
}
114

    
115
int encoder_change(char encoder){
116
        return 0;
117
}
118

    
119
char encoder_direction(char encoder){
120
        return 0;
121
}
122
/**
123
 * Gets the velocity of the specified encoder.
124
 *
125
 * @param encoder the encoder that you want to read, use LEFT or RIGHT
126
 *
127
 * @return The velocity of the specified encoder.
128
 **/
129
int encoder_get_dx(char encoder) {
130
        if(encoder==LEFT)
131
                return left_dx;
132
        else if(encoder==RIGHT)
133
                return right_dx;
134
        else return -1;
135
}
136

    
137
/**
138
 * Resets the value of the velocity global variable for the specified
139
 *  encoder.
140
 *
141
 * @param encoder the encoder that you want to modify
142
 **/
143
void encoder_rst_dx(char encoder) {
144
        if(encoder==LEFT)
145
                left_dx = 0;
146
        else if(encoder==RIGHT)
147
                right_dx = 0;
148
}
149

    
150
/**
151
 * Returns the current time count for the encoders.
152
 **/
153
int encoder_get_tc(void) {
154
        return timecount;
155
}
156

    
157
/**
158
 * Resets the time count for the encoders.
159
 **/
160
void encoder_rst_tc(void) {
161
        timecount = 0;
162
}
163

    
164

    
165
int encoder_get_v(char encoder){
166
        int last, res=0;
167
        
168
        cli();
169
        
170
        if(encoder==LEFT){
171
                if(left_data_idx==0)
172
                        last = BUFFER_SIZE - 1;
173
                else
174
                        last = left_data_idx - 1;
175
                res = ((int)left_data_array[last]) - ((int)left_data_array[left_data_idx]);
176
        }
177
        if(encoder==RIGHT){
178
                if(right_data_idx==0)
179
                        last = BUFFER_SIZE - 1;
180
                else
181
                        last = right_data_idx - 1;
182
                res = ((int)right_data_array[right_data_idx]) - ((int)right_data_array[last]);
183
        }
184
        
185
        sei();
186

    
187
        while(res<MIN_V)//underflow
188
                res+=1024;
189
        while(res>MAX_V)//overflow
190
                res-=1024;
191

    
192
        return res;
193
}
194

    
195
void encoder_wait(int n){
196
        while(data_ready<n);
197
        data_ready=0;
198
}
199

    
200

    
201
//Full reads occur every 40 microseconds. This function should be called
202
//every 8 microseconds.
203
void encoder_recv(char data){
204
        //usb_puti(buf_index);
205
        short int dx;
206
        
207
        recv_count++;
208
        //if(++recv_count==ENCODER_DELAY){
209
                        
210
                recv_count=0;
211
                
212
                //Parse the encoder data, comes in over 5 bytes 16 bits per encoder,
213
                // second is offset by 1 bit.
214
                if(buf_index == 0)
215
                  right_data_buf |= ((short)data)<<8 & 0xff00;
216

    
217
                else if (buf_index == 1)
218
                  right_data_buf |= ((short)data) & 0xff;
219
                
220
                else if (buf_index == 2)
221
                        left_data_buf |= (((short)data) << 9) & (0x7F << 9);
222
                
223
                else if (buf_index == 3)
224
                        left_data_buf |= (((short)data) << 1) & (0xFF<<1);
225
                
226
                else if (buf_index == 4)
227
                        left_data_buf |= (((short)data)>>7) & 0x1;
228

    
229
                
230
                buf_index = (buf_index + 1) % 5;
231

    
232
                if(buf_index==0) {
233
                  if(left_data_buf & (COF | LIN) || !(left_data_buf & OCF)){
234
                                left_data = INVALID;
235
                  }
236
                        
237
                  else if(((left_data_buf & MagINCn) > 0)  && ((left_data_buf & MagDECn) > 0)){
238
                        left_data = MAGNET_FAILURE;
239
                  }
240
                  else{
241
                        left_data = (left_data_buf>>5) & 1023;
242
                  }
243
                        
244
                  if(right_data_buf & (COF | LIN) || !(right_data_buf & OCF)){
245
                        right_data = INVALID;
246
                  }
247
                  else if ( ((left_data_buf & MagINCn) > 0)  && ((left_data_buf & MagDECn) > 0)){
248
                        left_data = MAGNET_FAILURE;
249
                  }
250
                  else{
251
                        right_data = (right_data_buf>>5) & 1023;
252
                  }
253
                
254

    
255
                        //if(left_data!=INVALID || right_data!=INVALID){
256
                        //  usb_puts("{");usb_puti(left_data);usb_puts(",");usb_puti(right_data);usb_puts("}\r\n");
257
                        //}
258
                        
259
                          
260
  
261
                          left_data_buf = 0;
262
                        right_data_buf = 0;
263

    
264
                
265
                if(left_data < INVALID) {   //Valid? I have no idea what being less than invalid means - KWoo
266
                        //Put new data onto data array
267
                        left_data_array_put(left_data);
268

    
269
                        //Adjust left accumulator
270
                        //dx = left_data - left_data_array_prev();
271
                        dx = left_data_array_prev() - left_data;
272
                        
273
                        //Adjust velocity: save last dx
274
                        left_v = left_dx;
275

    
276
                        /*left dx was negative on robot 7, could just be that
277
                          the encoder is backwards, so this may need to change
278
                          back
279
                        */
280

    
281

    
282
                        if(left_data_array_prev()==0)
283
                          dx=0;
284

    
285
                        if(dx > 5) { //underflow
286
                                left_dx += dx - 1023;
287
                        }
288
                        else if(dx < -5) { //overflow
289
                                left_dx += dx + 1023;
290
                        }
291
                        else {
292
                                left_dx += dx;
293
                        }
294
                        
295
                        //Adjust velocity: update
296
                        left_v = left_dx - left_v;
297
                }
298

    
299
                if(right_data < INVALID) {
300
                        //Put new data onto data array
301
                        right_data_array_put(right_data);
302

    
303
                        //Adjust right accumulator
304
                        dx = right_data - right_data_array_prev();
305

    
306
                        if(right_data_array_prev()==0)
307
                          dx=0;
308

    
309
                        if(dx > 5) { //underflow
310
                                right_dx += dx - 1023;
311
                        }
312
                        else if(dx < -5) { //overflow
313
                                right_dx += dx + 1023;
314
                        }
315
                        else {
316
                                right_dx += dx;
317
                        }
318
                }
319
  
320
                
321
                }
322

    
323
                //Increment timecount accumulator
324
                timecount++;
325
                
326
        //}
327
}
328

    
329
//Helper Functions
330
inline void left_data_array_put(unsigned short int value) {
331
        if(left_data_idx == BUFFER_SIZE-1)
332
                left_data_idx = 0;
333
        else
334
                left_data_idx++;
335
        left_data_array[left_data_idx] = value;
336
}
337

    
338
inline unsigned int left_data_array_top(void) {
339
        return left_data_array[left_data_idx];
340
}
341

    
342
inline unsigned int left_data_array_prev(void) {
343
        if(left_data_idx == 0)
344
                return left_data_array[BUFFER_SIZE-1];
345
        else
346
                return left_data_array[left_data_idx - 1];
347
}
348

    
349
inline unsigned int left_data_array_bottom(void) {
350
        if(left_data_idx == BUFFER_SIZE-1)
351
                return left_data_array[0];
352
        else
353
                return left_data_array[left_data_idx + 1];
354
}
355

    
356
inline void right_data_array_put(unsigned short int value) {
357
        if(right_data_idx == BUFFER_SIZE-1)
358
                right_data_idx = 0;
359
        else
360
                right_data_idx++;
361
        right_data_array[right_data_idx] = value;
362
}
363

    
364
inline unsigned int right_data_array_top(void) {
365
        return right_data_array[right_data_idx];
366
}
367

    
368
inline unsigned int right_data_array_prev(void) {
369
        if(right_data_idx == 0)
370
                return right_data_array[BUFFER_SIZE-1];
371
        else
372
                return right_data_array[right_data_idx - 1];
373
}
374

    
375
inline unsigned int right_data_array_bottom(void) {
376
        if(right_data_idx == BUFFER_SIZE-1)
377
                return right_data_array[0];
378
        else
379
                return right_data_array[right_data_idx + 1];
380
}