Project

General

Profile

Revision 494

made orbit branch

View differences:

branches/orbit/code/lib/src/libdragonfly/bom.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file bom.c
29
 * @brief Implementation for using the BOM
30
 *
31
 * Contains functions for using the Bearing and Orientation Module (BOM)
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
#include <dragonfly_lib.h>
37
#include "bom.h"
38
#include "dio.h"
39
#include "analog.h"
40

  
41
//constants
42
static const char lookup[16] = {7,6,5,0xe,1,4,3,2,0xf,0,0xd,8,0xc,0xb,9,0xa};
43

  
44
// internal function prototypes
45
static void bom_select(char which);
46

  
47
/*
48
 Bk R Y (Analog)
49
---------
50
 Green
51
 Blue
52
 White
53
---------
54
 Blue
55
 White
56
*/
57

  
58

  
59
/*
60
the analog pin definitions from dio.h DO NOT work here,
61
so we must use PF0 from avrgcc (as opposed to _PIN_F0).
62
BUT the dio pin definitions from dio.h must be used (no PE...).
63

  
64
also, _PIN_E2 is initialized to high for some reason,
65
which turns the BOM on when the robot is turned on.
66
WORK-AROUND: call digital_output(_PIN_E2,0) at some point.
67

  
68
*/
69

  
70
#define MONKI PF0         //analog (yellow)
71
//------------------------//
72
#define MONKL _PIN_E2     //green
73
#define MONK1 _PIN_E3     //blue
74
#define MONK0 _PIN_E4     //white
75
//------------------------//
76
#define MONK3 _PIN_E6     //blue
77
#define MONK2 _PIN_E7     //white
78

  
79
#define BOM_VALUE_THRESHOLD 200
80
#define NUM_BOM_LEDS 16
81

  
82

  
83
/**
84
 * @defgroup bom BOM (Bearing and Orientation Module)
85
 * @brief Functions for dealing with the BOM.
86
 *
87
 * The Bearing and Orientation Module / Barrel of Monkeys / BOM
88
 * is a custom sensor designed and built by the Colony Project.
89
 * It consists of a ring of 16 IR emitters and 16 IR detectors.
90
 * The BOM is most often use to determine the direction of other
91
 * robots. This module contains functions for controlling the BOM.
92
 *
93
 * Include bom.h to access these functions.
94
 *
95
 * @{
96
 **/
97

  
98
static unsigned int bom_val[NUM_BOM_LEDS];
99
static char bom_type = BOM;
100
  
101
/**
102
 * Initializes the BOM.
103
 * Call bom_init before reading bom values or turning bom leds.
104
 *
105
 * @bugs INCOMPLETE - need to fill in init routine for BOM15
106
 * 
107
 * @see bom_refresh, bom_leds_on, bom_leds_off
108
 **/
109
void bom_init(char type) {
110
    bom_type = type;
111
    
112
    switch(bom_type) {
113
    case BOM:
114
        break;
115
    case BOM15:
116
        break;
117
    case RBOM:
118
        break;
119
    //default:
120
    }
121
}
122

  
123
/**
124
 * Iterates through each bit in the bit_field. For each set bit, sets the corresponding bom select bits
125
 *    and updates the corresponding bom value with an analog_get8 reading.  analog_init and bom_init
126
 *    must be called for this to work.
127
 *
128
 *
129
 * @param bit_field specifies which elements in bom_val[] should be updated. Use BOM_ALL to refresh all values.
130
 *    Ex. if 0x0003 is passed, bom_val[0] and bom_val[1] will be updated.
131
 *
132
 * @see bom_get
133
 **/
134
void bom_refresh(int bit_field) {
135
    int i;
136
    
137
    analog_stop_loop();
138
    
139
    for(i = 0; i < NUM_BOM_LEDS; i++) {
140
        if(bit_field & 0x1) {
141
            bom_select(lookup[i]);
142
            bom_val[i] = analog_get8(MONKI);
143
        }
144
        bit_field = bit_field >> 1;
145
    }
146
    
147
    analog_start_loop();
148
}
149

  
150
/**
151
 * Gets the bom reading from bom_val[which].  Call bom_refresh beforehand to read new bom values.
152
 *
153
 * @param which which bom value to return
154
 *
155
 * @return the bom value
156
 *
157
 * see bom_refresh
158
 **/
159
int bom_get(int which) {
160
    return bom_val[which];
161
}
162

  
163
/** 
164
 * Compares all the values in bom_val[] and returns the index to the lowest (max) value element.
165
 *
166
 * @return index to the lowest (max) bom value element.  -1 if no value is lower than
167
 *    BOM_VALUE_THRESHOLD
168
 **/
169
int bom_get_max(void) {
170
    int i, lowest_val, lowest_i;
171
    lowest_i = -1;
172
    lowest_val = 255;
173
    for(i = 0; i < NUM_BOM_LEDS; i++) {
174
        if(bom_val[i] < lowest_val) {
175
            lowest_val = bom_val[i];
176
            lowest_i = i;
177
        }
178
    }
179
    
180
    if(lowest_val < BOM_VALUE_THRESHOLD)
181
        return lowest_i;
182
    else
183
        return -1;
184
}
185

  
186
/**
187
 * Iterates through each bit in the bit_field. For each set bit, turns on the corresponding bom led.
188
 *    bom_init must be called for this to work. Only works with BOM_ALL if using the original bom.
189
 *
190
 * @param bit_field specifies which leds should be turned on.  Use BOM_ALL to turn on all bom leds.
191
 *    Ex. if 0x0005 is passed, leds 0 and 2 will be turned on.
192
 **/
193
void bom_leds_on(int bit_field) {
194
    switch(bom_type) {
195
    case BOM:
196
        if(bit_field == BOM_ALL) {
197
            digital_output(MONKL, 1);
198
        }
199
        break;
200
    case BOM15:
201
        //add bom 1.5 code here
202
        break;
203
    case RBOM:
204
        //add rbom code here
205
        break;
206
    }
207
}
208

  
209
/**
210
 * Iterates through each bit in the bit_field. For each set bit, turns off the corresponding bom led.
211
 *    bom_init must be called for this to work. Only works with BOM_ALL if using the original bom.
212
 *
213
 * @param bit_field specifies which leds should be turned off.  Use BOM_ALL to turn off all bom leds.
214
 *    Ex. if 0x000B is passed, leds 0 and 3 will be turned off.
215
 **/
216
void bom_leds_off(int bit_field) {
217
    switch(bom_type) {
218
    case BOM:
219
        if(bit_field == BOM_ALL) {
220
            digital_output(MONKL, 0);
221
        }
222
        break;
223
    case BOM15:
224
        //add bom 1.5 code here
225
        break;
226
    case RBOM:
227
        //add rbom code here
228
        break;
229
    }
230
}
231

  
232

  
233
/**
234
 * (DEPRECATED) Returns the direction of the maximum BOM reading,
235
 * as an integer in the range 0-15. 0 indicates to the
236
 * robot's right, while the rest of the sensors are
237
 * numbered counterclockwise. This is useful for determining
238
 * the direction of a robot flashing its BOM, of only one
239
 * robot is currently doing so. analog_init must be called
240
 * before this function can be used.
241
 *
242
 * @return the direction of the maximum BOM reading
243
 *
244
 * @see analog_init
245
 **/
246
int get_max_bom(void) {
247
    bom_refresh(BOM_ALL);
248
    return bom_get_max();
249
}
250

  
251
/**
252
 * (DEPRECATED) Turns on all bom leds.
253
 * 
254
 * @see bom_off
255
 **/
256
void bom_on(void)
257
{
258
  bom_leds_on(BOM_ALL);
259
}
260

  
261
/**
262
 * (DEPRECATED) Turns off all bom leds.
263
 * 
264
 * @see bom_on
265
 **/
266
void bom_off(void)
267
{
268
    bom_leds_off(BOM_ALL);
269
}
270

  
271
/** @} **/ //end group
272
+static void bom_select(char which) {
273
      if (which&8)
274
        digital_output(MONK3, 1);
275
      else
276
        digital_output(MONK3, 0);
277

  
278
      if (which&4)
279
        digital_output(MONK2, 1);
280
      else
281
        digital_output(MONK2, 0);
282

  
283
      if (which&2)
284
        digital_output(MONK1, 1);
285
      else
286
        digital_output(MONK1, 0);
287

  
288
      if (which&1)
289
        digital_output(MONK0, 1);
290
      else
291
        digital_output(MONK0, 0);
292
}
branches/orbit/code/lib/src/libdragonfly/analog.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26
/**
27
 * @file analog.c
28
 * @brief Analog input and output
29
 *
30
 * Contains functions for manipulating the ADC on the Dragonfly board.
31
 * 
32
 * @author Colony Project, CMU Robotics Club
33
 * code mostly taken from fwr analog file (author: Tom Lauwers)
34
 **/
35

  
36
#include <util/delay.h>
37
#include <avr/interrupt.h>
38
#include "analog.h"
39
#include "serial.h"
40
// Internal Function Prototypes
41
void set_adc_mux(int which);
42

  
43
/**
44
 * @defgroup analog Analog
45
 * Functions for manipulation the ADC on the dragonfly board.
46
 * All definitions may be found in analog.h.
47
 *
48
 * @{
49
 **/
50

  
51
int adc_loop_running = 0;
52
int adc_current_port = 0;
53
adc_t an_val[11];
54

  
55
/**
56
 * Initializes the ADC.
57
 * Call analog_init before reading from the analog ports.
58
 *
59
 * @see analog8, analog10, analog_get8, analog_get10
60
 **/
61
void analog_init(int start_conversion) {
62
	for (int i = 0; i < 11; i++) {
63
		an_val[i].adc10 = 0;
64
		an_val[i].adc8 = 0;
65
	}
66

  
67
	//cli();
68
	// ADMUX register
69
	// Bit 7,6 - Set voltage reference to AVcc (0b01)
70
	// Bit 5 - ADLAR set to simplify moving from register
71
	// Bit 4 - X
72
	// Bit 3:0 - Sets the current channel
73
	// Initializes to read from AN1 first (AN0 is reservered for the BOM)
74
	ADMUX = 0;
75
	ADMUX |= ADMUX_OPT | _BV(MUX0);
76

  
77

  
78
	// ADC Status Register A
79
	// Bit 7 - ADEN is set (enables analog)
80
	// Bit 6 - Start conversion bit is set (must be done once for free-running mode)
81
	// Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW
82
	// Bit 4 - ADC interrupt flag, 0
83
	// Bit 3 - Enable ADC Interrupt (required to run free-running mode)
84
	// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz
85
	ADCSRA = 0;
86
	ADCSRA |= _BV(ADEN) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
87
	
88
	// Set external mux lines to outputs
89
	DDRG |= 0x1C;
90
	
91
	// Set up first port for conversions
92
	set_adc_mux(0x00);
93
	adc_current_port = AN1;
94

  
95
	//Start the conversion if requested
96
	if (start_conversion)
97
		analog_start_loop();
98
	else
99
		analog_stop_loop();
100
	//sei();
101
	
102
}	
103

  
104
unsigned int analog8(int which) {
105
	if (which == BOM_PORT) {
106
		return 0;
107
	} else {
108
		return an_val[which - 1].adc8;
109
	}
110
}
111

  
112
/**
113
 * Returns the 10-bit analog conversion of which from
114
 * the lookup table. If the requested port is the BOM_PORT
115
 * you will get an automatic 0 since the BOM_PORT is not
116
 * read in the loop and not stored. If you need that port
117
 * you should use the functions in bom.c. There is an analog_get10
118
 * function which for instant lookups but should be avoided.
119
 *
120
 * @param which the port that you want to read
121
 *
122
 * @bug may cause a seg fault if which is a larger value
123
 * than exists in an_val table. Not sure if we should fix
124
 * this or not since it would add overhead.
125
 *
126
 * @return 10-bit analog value for the which port requested
127
 *
128
 * @see analog8, analog_get8, analog_get10
129
 **/
130
unsigned int analog10(int which) {
131
	if (which == BOM_PORT) {
132
		return 0;
133
	} else {
134
		return an_val[which - 1].adc10;
135
	}
136
}
137

  
138

  
139
/**
140
 * Starts the analog update loop. Will continue to run
141
 * until analog_stop_loop is called.
142
 *
143
 * @see analog_stop_loop
144
 **/
145
void analog_start_loop(void) {
146
	//Start the conversion
147
	ADCSRA |= _BV(ADSC);
148
	adc_loop_running = 0x1;
149
}
150

  
151
/**
152
 * Stops the analog update loop. If there is a current
153
 * read, it will finish up and be stored before the loop
154
 * is interrupted. No further updates will be made until
155
 * the loop is started again.
156
 *
157
 * @see analog_start_loop
158
 **/
159
void analog_stop_loop(void) {
160
	//Stop the conversion
161
	adc_loop_running = 0x0;
162
}
163
/**
164
 * Reads an eight bit number from an analog port.
165
 * analog_init must be called before using this function.
166
 * 
167
 * @param which the analog port to read from. One of
168
 * the constants AN0 - AN7.
169
 *
170
 * @return the eight bit input to the specified port
171
 *
172
 * @see analog_init, analog10
173
 **/
174
unsigned int analog_get8(int which) {	
175
	// Let any previous conversion finish
176
	while (ADCSRA & _BV(ADSC));
177
	
178
	if(which < EXT_MUX) {
179
		ADMUX = ADMUX_OPT + which;
180
	} else {
181
		ADMUX = ADMUX_OPT + EXT_MUX;
182
		set_adc_mux(which - 8);
183
	}
184
	
185
	// Start the conversion
186
	ADCSRA |= _BV(ADSC);
187

  
188
	// Wait for the conversion to finish
189
	while (ADCSRA & _BV(ADSC));
190

  
191
	return ADCH; //since we left aligned the data, ADCH is the 8 MSB.
192
}
193

  
194
/**
195
 * Reads a ten bit number from the specified port.
196
 * analog_init must be called before using this function.
197
 * 
198
 *
199
 * @param which the analog port to read from. Typically
200
 * a constant, one of AN0 - AN7.
201
 *
202
 * @return the ten bit number input to the specified port
203
 * 
204
 * @see analog_init, analog8
205
 **/
206
unsigned int analog_get10(int which) {
207
	int adc_h;
208
	int adc_l;
209
	
210
	// Let any previous conversion finish
211
	while (ADCSRA & _BV(ADSC));
212

  
213
	if(which < EXT_MUX) {
214
		ADMUX = ADMUX_OPT + which;
215
	} else {
216
		ADMUX = ADMUX_OPT + EXT_MUX;
217
		set_adc_mux(which - 8);
218
	}
219
	
220
	// Start the conversion
221
	ADCSRA |= _BV(ADSC);
222

  
223
	// Wait for the conversion to finish
224
	while (ADCSRA & _BV(ADSC));
225
	
226
	adc_l = ADCL;
227
	adc_h = ADCH;
228

  
229
	return ((adc_h << 2) | (adc_l >> 6));
230
}
231

  
232
/**
233
 * Returns the current position of the wheel, as an integer
234
 * in the range 0 - 255.
235
 * analog_init must be called before using this function.
236
 *
237
 * @return the orientation of the wheel, as an integer in
238
 * the range 0 - 255.
239
 *
240
 * @see analog_init
241
 **/
242
int wheel(void) {
243
	return analog8(WHEEL_PORT);
244
}
245

  
246

  
247
/**
248
 * Sets the value of the external analog mux. Values are read
249
 * 	on AN7 physical port. (AN8 - AN15 are "virtual" ports).
250
 *
251
 * @param which which analog mux port (0-7) which corresponds
252
 * 		  to AN8-AN15.
253
 *
254
 * @bug FIX THIS IN THE NEXT BOARD REVISION:
255
 *		ADDR2 ADDR1 ADDR0
256
 *		G2.G4.G3 set mux to port 0-7 via vinary selection
257
 *		math would be much cleaner if it was G4.G3.G2
258
 *
259
 * @see analog_init
260
 **/
261
void set_adc_mux(int which) {  
262
  // mask so only proper bits are possible.  
263
  PORTG = (PORTG & 0xE3) | ((which & 0x03) << 3) | (which & 0x04);
264
}
265

  
266
/**@}**/ //end defgroup
267

  
268

  
269
ISR(ADC_vect) {
270
	static volatile int adc_prev_loop_running = 0; 
271
	int adc_h = 0;
272
	int adc_l = 0;
273

  
274
	//Store the value only if this read isn't for the BOM
275
	if (ADMUX != BOM_PORT) {
276
		adc_l = ADCL;
277
		adc_h = ADCH;
278
	
279
		an_val[adc_current_port - 1].adc10 = (adc_h << 2) | (adc_l >> 6);
280
		an_val[adc_current_port - 1].adc8 = adc_h;
281
	}
282
	
283
	//Save the result only if we just turned off the loop
284
	if (!adc_loop_running && !adc_prev_loop_running)
285
		return;
286
	
287
	adc_prev_loop_running = adc_loop_running;
288
	
289
	//Skip AN7 because it is not a real port
290
	if (adc_current_port == AN6) {
291
		ADMUX = ADMUX_OPT | EXT_MUX;
292
		set_adc_mux(AN8 - 8);
293
		adc_current_port = AN8;
294
	//Wrap around
295
	} else if (adc_current_port == AN11) {
296
		adc_current_port = AN1;
297
		ADMUX = ADMUX_OPT | adc_current_port;
298
	//Normal increment
299
	} else {
300
		adc_current_port++;
301
	
302
		if(adc_current_port < EXT_MUX) {
303
			ADMUX = ADMUX_OPT | adc_current_port;
304
		} else {
305
			ADMUX = ADMUX_OPT | EXT_MUX;
306
			set_adc_mux(adc_current_port - 8);
307
		}
308
	}
309

  
310
	//Initiate next conversion only if we are running a loop
311
	if (!adc_loop_running) {
312
		return;
313
    } else {
314
    	ADCSRA |= _BV(ADSC);
315
	}
316
		
317
	return;
318
}
319

  
branches/orbit/code/lib/src/libdragonfly/time.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file time.c
29
 * @brief Timer code
30
 *
31
 * Implementation of functions for timers.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
/*
37
  time.c
38
  anything that requires a delay
39
  mostly delay_ms
40

  
41
  author: Robotics Club, Colony Project
42

  
43
  Change Log:
44
  2.5.07 - Kevin
45
  Aaron fixed the orb/servo code and made them use timer3 but compare registers B and C. He hard set the prescaler
46
  to 8 so the RTC broke. Changed it so that we use a 8 prescaler which sets the compare match at 1/16th of a second.
47
  You now count how many 16ths of a second you want until you trigger your actual interrupt. Works. Changed defines
48
  for time so you can still call rtc_init with a scale but now it is defined in terms of actual time like second, quarter_second
49
  etc. Read that section in the time.h file for more information. Tested and works, though the clock drifts more than
50
  it used to
51
  1.30.07 - Kevin
52
  Modified the clock to run on timer3 on the Dragonfly. Works with decent accuracy. Using a prescaler of 256
53
  the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of
54
  256 change it by that multiple. Refer to the time.h file for all possible prescalers.
55
  The interrupt will call a specified function _rtc_func every pulse.
56
  All of it has been tested and it works.
57

  
58
*/
59
#include <avr/interrupt.h>
60
#include <util/delay.h>
61
#include <time.h>
62
#include <serial.h>
63

  
64
static volatile int _rtc_val = 0;
65
static volatile int _rtc_pulse = 0;
66
static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
67
static void (*_rtc_f)(void) = 0;
68

  
69
/**
70
 * @defgroup time Time
71
 * @brief Time functions
72
 * 
73
 * Functions dealing with time.
74
 * 
75
 * @{
76
 **/
77

  
78
/**
79
 * Delays for the specified number of milliseconds.
80
 * The accuracy of this function is unknown.
81
 *
82
 * @param ms the number of milliseconds to delay for
83
 **/
84
void delay_ms(int ms) {
85
  for(; ms > 15; ms-=15)
86
    _delay_ms(15);
87
  _delay_ms(ms);
88
}
89

  
90
/* 	Prescales defined in time.h. SECOND will give you 1 second.
91
	More scales are defined in the time.h file.
92
	rtc_func is the address to a function that you want called every clock tick. */
93
/**
94
 * Initializes the real time clock. Prescales are defined in time.h.
95
 * For example, SECOND will give 1 second. The specified function is
96
 * called every clock tick. For the real time clock to activate,
97
 * interrupts must be enabled. (through sei() )
98
 *
99
 * @param prescale_opt the period with which the timer is triggered
100
 * @param rtc_func the function called when the timer is triggered
101
 *
102
 * @see rtc_get, rtc_reset
103
 *
104
 **/
105
void rtc_init(int prescale_opt, void (*rtc_func)(void)) {
106
	
107
  //Clear timer register for Timer 3
108
  TCNT3 = 0;
109
	
110
  /* 	This sets the Waveform Generation Module to CTC (Clear Timer on Compare) Mode (100)
111
	See page135 in Atmega128 Docs for more modes and explanations */
112
  TCCR3B |= _BV(WGM32);
113
	
114
  /* 	This sets the prescaler for the system clock (8MHz) ie: divides the clock by some number.
115
	Currently set to a prescaler of 8 because that is what the orb and servos use (they are on this timer as well)
116
	See page137 in Atemga128 Docs for all the available prescalers */
117
  TCCR3B |= _BV(CS31);
118
	
119
  /* 	Sets the two regsiters that we compare against. So the timer counts up to this number and
120
	then resets back to 0 and calls the compare match interrupt.
121
	8x10^6 / 8 = 1/16 Second. All values are based off of this number. Do not change it unless you
122
	are l337*/
123
		
124
  OCR3A = 0xF424;	
125

  
126
  /* 	Enable Output Compare A Interrupt. When OCR3A is met by the timer TCNT3 this interrupt will be
127
	triggerd. (See page140 in Atmega128 Docs for more information */
128
  ETIMSK |= _BV(OCIE3A);
129
	
130
  /*	Store the pointer to the function to be used in the interrupt */
131
  _rtc_f = rtc_func;
132
	
133
  /*	Store how many 1/16ths of a second you want to let by before triggering an interrupt */
134
  _rtc_scale = prescale_opt;
135
}
136

  
137
/**
138
 * Returns the time elapsed in seconds since the last call to
139
 * rtc_init or rtc_reset.
140
 *
141
 * @return the number of seconds since the last call to rtc_init or rtc_reset
142
 *
143
 * @see rtc_init, rtc_reset
144
 **/
145
int rtc_get(void) {
146
  return _rtc_val;
147
}
148

  
149
/**
150
 * Resets the real time clock counter to 0.
151
 *
152
 * @see rtc_init, rtc_get
153
 **/
154
void rtc_reset(void) {
155
  _rtc_val = 0;
156
}
157

  
158
/** @} **/ //end defgroup
159

  
160
/*	Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated.
161
	Bascially, since the pulse is hard set at 1/16s  you want to count how many 16ths of a second have passed
162
	and when it reaches the amount of time you want, execute the code. */
163
SIGNAL(TIMER3_COMPA_vect) {
164

  
165
  if (_rtc_pulse ==  _rtc_scale) {
166
    //Increment the real time clock counter
167
    _rtc_val++;
168
		
169
    //Calls the function tied to the real time clock if defined
170
    if(_rtc_f != 0)
171
      _rtc_f();
172
		
173
    //Resets the pulse until the next scale is matched
174
    _rtc_pulse = 0;
175
  }	
176
	
177
  //Updates the amount of pulses seen since the last scale match
178
  _rtc_pulse++;
179
	
180
}
branches/orbit/code/lib/src/libdragonfly/motor.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file motor.c
29
 * @brief Motors
30
 *
31
 * Implementation of functions for controlling the motors.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 * Much of this is taken from FWR's library, author: Tom Lauwers
35
 **/
36

  
37
#include "motor.h"
38

  
39
/**
40
 * @defgroup motors Motors
41
 * @brief Functions for controlling the motors.
42
 * Functions for controlling the motors. Found in motor.h.
43
 * @{
44
 **/
45

  
46
/**
47
 * Initializes both motors so that they can be used with future
48
 * calls to motor1_set and motor2_set.
49
 *
50
 * @see motors_off, motor1_set, motor2_set
51
 **/
52
void motors_init( void ) {
53
  // Configure counter such that we use phase correct
54
  // PWM with 8-bit resolution
55
  PORTA &= 0x0F;
56
  DDRA |= 0xF0;
57
  DDRB |= 0x60;
58

  
59
  //timer 1A and 1B
60
  TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
61
  TCCR1B = _BV(WGM12) | _BV(CS10);
62
  //	TCCR1A = 0xA1;
63
  //	TCCR1B = 0x04;
64
  OCR1AH=0;
65
  OCR1AL=0;
66
  OCR1BH=0;
67
  OCR1BL=0;
68
}
69

  
70
/**
71
 * Sets the speed and direction of motor1.
72
 * motors_init must be called before this function can be used.
73
 *
74
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
75
 * @param speed The speed the motor will run at, in the range 0-255.
76
 * 
77
 * @see motor2_set, motors_init
78
 **/
79
void motor1_set(int direction, int speed) {
80

  
81
  if(direction == 0) {
82
    // turn off PWM first if switching directions
83
    if((PORTA & 0x30) != 0x10) {
84
      OCR1A = 0;
85
    }	
86
    PORTA = (PORTA & 0xCF) | 0x10;
87
    //		PORTD |= 0x10;
88
    //		PORTD &= 0xBF;
89
  } else {
90
    // turn off PWM first if switching directions
91
    if((PORTA & 0x30) != 0x20) {
92
      OCR1A = 0;
93
    }
94
    PORTA = (PORTA & 0xCF) | 0x20;
95
    //		PORTD |= 0x40;
96
    //		PORTD &= 0xEF;
97
  }
98
	
99
  // Set the timer to count up to speed, an 8-bit value
100
  OCR1AL = speed;
101
}
102

  
103
/**
104
 * Sets the speed and direction of motor2.
105
 * motors_init must be called before this function can be used.
106
 *
107
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
108
 * @param speed The speed the motor will run at, in the range 0-255.
109
 *
110
 * @see motor1_set, motors_init
111
 **/
112
void motor2_set(int direction, int speed) {
113
  if(direction == 0) {
114
    //		PORTD |= 0x20;
115
    //		PORTD &= 0x7F;
116
    // turn off PWM first if switching directions
117
    if((PORTA & 0xC0) != 0x80) {
118
      OCR1B = 0;
119
    }		
120
		
121
    PORTA = (PORTA & 0x3F) | 0x80;
122
  } else {
123
    //		PORTD |= 0x80;
124
    //		PORTD &= 0xDF;
125

  
126
    // turn off PWM first if switching directions
127
    if((PORTA & 0xC0) != 0x40) {
128
      OCR1B = 0;
129
    }		
130
		
131
    PORTA = (PORTA & 0x3F) | 0x40;
132
  }
133
  OCR1BL = speed;
134
}
135

  
136
/**
137
 * Turns off both motors.
138
 *
139
 * @see motors_init
140
 **/
141
void motors_off( void ) {
142
  OCR1AL = 0x0;
143
  OCR1BL = 0x0;
144
}
145

  
146
/**@}**///end defgroup
147

  
branches/orbit/code/lib/src/libdragonfly/lcd.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file lcd.c
29
 * @brief LCD
30
 *
31
 * Implementation of functions for using the LCD.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35
#include <avr/io.h>
36
#include <lcd.h>
37
#include <time.h>
38

  
39
//LCD defines
40
#define RST _BV(4)  // pd4 (GPIO)
41
#define SCE _BV(0)  // pb0 (~SS)
42
#define D_C _BV(5)  // pd5 (GPIO?)
43
#define SDI _BV(2)  // pb2 (MOSI)
44
#define SCK _BV(1) // pb1 (SCK)
45

  
46
#define LCDPORT PORTB
47
#define LCDDDR DDRB
48

  
49
#define LCDRESETPORT PORTD
50
#define LCDRESETDDR DDRD
51

  
52
void lcd_putbyte(unsigned char b);
53

  
54

  
55
//**************************************Old shit below!*****************
56
/*
57
  FontLookup - a lookup table for all characters
58
*/
59
static const unsigned char FontLookup [][5] =
60
  {
61
    { 0x00, 0x00, 0x00, 0x00, 0x00 },  // sp
62
    { 0x00, 0x00, 0x5f, 0x00, 0x00 },   // !
63
    { 0x00, 0x07, 0x00, 0x07, 0x00 },   // "
64
    { 0x14, 0x7f, 0x14, 0x7f, 0x14 },   // #
65
    { 0x24, 0x2a, 0x7f, 0x2a, 0x12 },   // $
66
    { 0x23, 0x13, 0x08, 0x64, 0x62 },   // %
67
    { 0x36, 0x49, 0x55, 0x22, 0x50 },   // &
68
    { 0x00, 0x05, 0x03, 0x00, 0x00 },   // '
69
    { 0x00, 0x1c, 0x22, 0x41, 0x00 },   // (
70
    { 0x00, 0x41, 0x22, 0x1c, 0x00 },   // )
71
    { 0x14, 0x08, 0x3E, 0x08, 0x14 },   // *
72
    { 0x08, 0x08, 0x3E, 0x08, 0x08 },   // +
73
    { 0x00, 0x00, 0x50, 0x30, 0x00 },   // ,
74
    { 0x10, 0x10, 0x10, 0x10, 0x10 },   // -
75
    { 0x00, 0x60, 0x60, 0x00, 0x00 },   // .
76
    { 0x20, 0x10, 0x08, 0x04, 0x02 },   // /
77
    { 0x3E, 0x51, 0x49, 0x45, 0x3E },   // 0
78
    { 0x00, 0x42, 0x7F, 0x40, 0x00 },   // 1
79
    { 0x42, 0x61, 0x51, 0x49, 0x46 },   // 2
80
    { 0x21, 0x41, 0x45, 0x4B, 0x31 },   // 3
81
    { 0x18, 0x14, 0x12, 0x7F, 0x10 },   // 4
82
    { 0x27, 0x45, 0x45, 0x45, 0x39 },   // 5
83
    { 0x3C, 0x4A, 0x49, 0x49, 0x30 },   // 6
84
    { 0x01, 0x71, 0x09, 0x05, 0x03 },   // 7
85
    { 0x36, 0x49, 0x49, 0x49, 0x36 },   // 8
86
    { 0x06, 0x49, 0x49, 0x29, 0x1E },   // 9
87
    { 0x00, 0x36, 0x36, 0x00, 0x00 },   // :
88
    { 0x00, 0x56, 0x36, 0x00, 0x00 },   // ;
89
    { 0x08, 0x14, 0x22, 0x41, 0x00 },   // <
90
    { 0x14, 0x14, 0x14, 0x14, 0x14 },   // =
91
    { 0x00, 0x41, 0x22, 0x14, 0x08 },   // >
92
    { 0x02, 0x01, 0x51, 0x09, 0x06 },   // ?
93
    { 0x32, 0x49, 0x59, 0x51, 0x3E },   // @
94
    { 0x7E, 0x11, 0x11, 0x11, 0x7E },   // A
95
    { 0x7F, 0x49, 0x49, 0x49, 0x36 },   // B
96
    { 0x3E, 0x41, 0x41, 0x41, 0x22 },   // C
97
    { 0x7F, 0x41, 0x41, 0x22, 0x1C },   // D
98
    { 0x7F, 0x49, 0x49, 0x49, 0x41 },   // E
99
    { 0x7F, 0x09, 0x09, 0x09, 0x01 },   // F
100
    { 0x3E, 0x41, 0x49, 0x49, 0x7A },   // G
101
    { 0x7F, 0x08, 0x08, 0x08, 0x7F },   // H
102
    { 0x00, 0x41, 0x7F, 0x41, 0x00 },   // I
103
    { 0x20, 0x40, 0x41, 0x3F, 0x01 },   // J
104
    { 0x7F, 0x08, 0x14, 0x22, 0x41 },   // K
105
    { 0x7F, 0x40, 0x40, 0x40, 0x40 },   // L
106
    { 0x7F, 0x02, 0x0C, 0x02, 0x7F },   // M
107
    { 0x7F, 0x04, 0x08, 0x10, 0x7F },   // N
108
    { 0x3E, 0x41, 0x41, 0x41, 0x3E },   // O
109
    { 0x7F, 0x09, 0x09, 0x09, 0x06 },   // P
110
    { 0x3E, 0x41, 0x51, 0x21, 0x5E },   // Q
111
    { 0x7F, 0x09, 0x19, 0x29, 0x46 },   // R
112
    { 0x46, 0x49, 0x49, 0x49, 0x31 },   // S
113
    { 0x01, 0x01, 0x7F, 0x01, 0x01 },   // T
114
    { 0x3F, 0x40, 0x40, 0x40, 0x3F },   // U
115
    { 0x1F, 0x20, 0x40, 0x20, 0x1F },   // V
116
    { 0x3F, 0x40, 0x38, 0x40, 0x3F },   // W
117
    { 0x63, 0x14, 0x08, 0x14, 0x63 },   // X
118
    { 0x07, 0x08, 0x70, 0x08, 0x07 },   // Y
119
    { 0x61, 0x51, 0x49, 0x45, 0x43 },   // Z
120
    { 0x00, 0x7F, 0x41, 0x41, 0x00 },   // [
121
    { 0x02, 0x04, 0x08, 0x10, 0x20 },   // backslash
122
    { 0x00, 0x41, 0x41, 0x7F, 0x00 },   // ]
123
    { 0x04, 0x02, 0x01, 0x02, 0x04 },   // ^
124
    { 0x40, 0x40, 0x40, 0x40, 0x40 },   // _
125
    { 0x00, 0x01, 0x02, 0x04, 0x00 },   // '
126
    { 0x20, 0x54, 0x54, 0x54, 0x78 },   // a
127
    { 0x7F, 0x48, 0x44, 0x44, 0x38 },   // b
128
    { 0x38, 0x44, 0x44, 0x44, 0x20 },   // c
129
    { 0x38, 0x44, 0x44, 0x48, 0x7F },   // d
130
    { 0x38, 0x54, 0x54, 0x54, 0x18 },   // e
131
    { 0x08, 0x7E, 0x09, 0x01, 0x02 },   // f
132
    { 0x0C, 0x52, 0x52, 0x52, 0x3E },   // g
133
    { 0x7F, 0x08, 0x04, 0x04, 0x78 },   // h
134
    { 0x00, 0x44, 0x7D, 0x40, 0x00 },   // i
135
    { 0x20, 0x40, 0x44, 0x3D, 0x00 },   // j
136
    { 0x7F, 0x10, 0x28, 0x44, 0x00 },   // k
137
    { 0x00, 0x41, 0x7F, 0x40, 0x00 },   // l
138
    { 0x7C, 0x04, 0x18, 0x04, 0x78 },   // m
139
    { 0x7C, 0x08, 0x04, 0x04, 0x78 },   // n
140
    { 0x38, 0x44, 0x44, 0x44, 0x38 },   // o
141
    { 0x7C, 0x14, 0x14, 0x14, 0x08 },   // p
142
    { 0x08, 0x14, 0x14, 0x18, 0x7C },   // q
143
    { 0x7C, 0x08, 0x04, 0x04, 0x08 },   // r
144
    { 0x48, 0x54, 0x54, 0x54, 0x20 },   // s
145
    { 0x04, 0x3F, 0x44, 0x40, 0x20 },   // t
146
    { 0x3C, 0x40, 0x40, 0x20, 0x7C },   // u
147
    { 0x1C, 0x20, 0x40, 0x20, 0x1C },   // v
148
    { 0x3C, 0x40, 0x30, 0x40, 0x3C },   // w
149
    { 0x44, 0x28, 0x10, 0x28, 0x44 },   // x
150
    { 0x0C, 0x50, 0x50, 0x50, 0x3C },   // y
151
    { 0x44, 0x64, 0x54, 0x4C, 0x44 },    // z
152
    { 0x00, 0x08, 0x36, 0x41, 0x41 },   // {
153
    { 0x00, 0x00, 0x7F, 0x00, 0x00 },   // |
154
    { 0x41, 0x41, 0x36, 0x08, 0x00 },   // }
155
    { 0x02, 0x01, 0x01, 0x02, 0x01 },   // ~
156
    { 0x55, 0x2A, 0x55, 0x2A, 0x55 },   // del
157
  };
158

  
159

  
160
/**
161
 * @defgroup lcd LCD
162
 * @brief Functions for the LCD
163
 * Functions for writing to the LCD.
164
 * All functions may be found in lcd.h.
165
 *
166
 * @{
167
 **/
168

  
169
/**
170
 * Initializes the LCD. Must be called before any other
171
 * LCD functions.
172
 **/
173
void lcd_init(void) {
174
  LCDDDR |= (SCE | SDI | SCK);
175
  LCDRESETDDR |= (RST|D_C);
176

  
177
  LCDPORT &= ~( SCE | SDI | SCK);
178
  LCDRESETPORT &=~(D_C);
179
  
180
  SPCR |= 0x50;//0b01010000; // no SPI int, SPI en, Master, sample on rising edge, fosc/2
181
  SPSR |= 0x01;       // a continuation of the above
182

  
183
  LCDRESETPORT |= RST;
184
  delay_ms(10);
185
  LCDRESETPORT &= (~RST);
186
  delay_ms(100);
187
  LCDRESETPORT |= RST;
188
	
189
  lcd_putbyte( 0x21 );  // LCD Extended Commands.
190
  lcd_putbyte( 0xC8 );  // Set LCD Vop (Contrast).
191
  lcd_putbyte( 0x06 );  // Set Temp coefficent.
192
  lcd_putbyte( 0x13 );  // LCD bias mode 1:48.
193
  lcd_putbyte( 0x20 );  // LCD Standard Commands, Horizontal addressing mode.
194
  lcd_putbyte( 0x0C );  // LCD in normal mode.
195
	
196
  LCDRESETPORT |= D_C;		//put it in init instead of main
197
	
198
  lcd_clear_screen();
199
}
200

  
201
/**
202
 * Clears the LCD screen. lcd_init must be called first.
203
 * 
204
 * @see lcd_init
205
 **/
206
void lcd_clear_screen( void ) {
207
  int i;
208
  for (i = 0; i < 504; i++)
209
    lcd_putbyte(0x0);
210
	
211
  lcd_gotoxy(0,0);
212
}
213

  
214
/**
215
 * Prints a character on the LCD screen. lcd_init
216
 * must be called before this function may be used.
217
 *
218
 * @param c the character to print
219
 *
220
 * @see lcd_init
221
 **/
222
void lcd_putc(char c) {
223
  int i;
224
	
225
  for (i = 0; i < 5; i++)
226
    lcd_putbyte(FontLookup[c-32][i]);
227
  lcd_putbyte(0);
228
}
229

  
230
/*
231
  print an entire string to the lcd
232
*/
233
void lcd_puts(char *s) {
234
  char *t = s;
235
  while (*t != 0) {
236
    lcd_putc(*t);
237
    t++;
238
  }
239
}
240

  
241
/*
242
  go to coordinate x, y
243
  y: vertically - 1 char
244
  x: horizontally - 1 pixel
245

  
246
  multiply x by 6 if want to move 1 entire character
247

  
248
  origin (0,0) is at top left corner of lcd screen
249
*/
250

  
251
/**
252
 * Move the current cursor position to the one specified.
253
 * lcd_init must be called before this function may be used.
254
 * 
255
 * @param x The x coordinate of the new position
256
 * @param y The y coordinate of the new position
257
 *
258
 * @see lcd_init
259
 **/
260
void lcd_gotoxy(int x, int y) {
261
  LCDRESETPORT &= ~(D_C);
262
  lcd_putbyte(0x40 | (y & 0x07));
263
  lcd_putbyte(0x80 | (x & 0x7f));
264
  LCDRESETPORT |= D_C;
265
}
266

  
267
/*
268
  prints an int to the lcd
269

  
270
  code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
271
*/
272

  
273
/**
274
 * Print an integer to the LCD screen.
275
 * lcd_init must be called before this function may be used.
276
 * 
277
 * @param value the integer to print
278
 *
279
 * @see lcd_init
280
 **/
281
void lcd_puti(int value ) {
282
  unsigned char lcd_data[6]={'0','0','0','0','0','0' }, position=sizeof(lcd_data), radix=10; 
283

  
284
  /* convert int to ascii  */ 
285
  if(value<0) { 
286
    lcd_putc('-'); 
287
    value=-value; 
288
  }    
289
  do { 
290
    position--; 
291
    *(lcd_data+position)=(value%radix)+'0'; 
292
    value/=radix;  
293
  } while(value); 
294

  
295
    
296
  /* start displaying the number */
297
  for(;position<=(sizeof(lcd_data)-1);position++)
298
    lcd_putc(lcd_data[position]);
299

  
300
  return;
301
}
302

  
303
/** @} **/ //end defgroup
304

  
305
void lcd_putbyte(unsigned char b) {
306
  SPDR = b;
307
  while (!(SPSR & 0x80)); /* Wait until SPI transaction is complete */
308
}
branches/orbit/code/lib/src/libdragonfly/move.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file move.c
29
 * @brief Functions for moving
30
 *
31
 * Implementation of functions for moving the robot.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
#include "dragonfly_lib.h"
37

  
38
#include "move.h"
39
#include "rangefinder.h"
40

  
41

  
42
// Internal prototypes
43
void translateAngulartoLinear (int velocity, int omega, int* vl, int* vr);
44

  
45
// global varaibles for move_avoid
46
int d1, d2, d3, d4, d5; 
47
/**
48
 * @defgroup move Movement
49
 * @brief Functions fo controlling robot motion
50
 * Higher level functions to control the movement of robots.
51
 * 
52
 * @{
53
 **/
54

  
55

  
56
/**
57
 * Causes the robot to move with the given translation and rotational velocities.
58
 * motors_init must be called before this function can be used.
59
 *
60
 * @param velocity the translational velocity of the robot, in the range -255 to 255.
61
 * A positive value indicates forward motion, while a negative value indicates
62
 * backwards motion.
63
 * 
64
 * @param omega the rotational velocity of the robot, in the range -255 to 255.
65
 * A positive value indicates a counterclockwise velocity, while a negative
66
 * value indicates a clockwise velocity.
67
 *
68
 * @see motors_init, motor1_set, motor2_set
69
 **/
70
void move (int velocity, int omega) {
71
  int vl = 0;
72
  int vr = 0;
73
  translateAngulartoLinear(velocity, omega, &vl , &vr );
74
  //
75
  
76
  if (vl < 0) {
77
    motor1_set(BACKWARD, -vl);
78
  } else {
79
    motor1_set(FORWARD, vl);
80
  }
81
  if (vr < 0) {
82
    motor2_set(BACKWARD, -vr);
83
  } else {
84
    motor2_set(FORWARD, vr);
85
  }
86
}
87

  
88

  
89
/**
90
 * Moves the robot with the given translational and angular velocities
91
 * while avoiding obstacles. To be effective, this function must be
92
 * called repeatedly throughout the motion. It relies on the IR
93
 * rangefinders to detect obstacles. Before calling this function,
94
 * motors_init and range_init must be called.
95
 *
96
 * @param velocity the translational velocity of the robot, in the
97
 * range -255 to 255. A positive value indicates forward motion.
98
 *
99
 * @param omega the rotational velocity of the robot, in the range
100
 * -255 to 255. A positive value indicates a counterclockwise velocity.
101
 *
102
 * @param strength the strength of the avoid behavior, in the range
103
 * 0 to 100.
104
 *
105
 * @see motors_init, range_init, move
106
 **/
107
void move_avoid(int velocity, int omega, int strength) {
108
  int pControl;
109
  int vl = 0;
110
  int vr = 0;
111
  int temp;
112
  
113
  temp=range_read_distance(IR1);
114
  d1 = (temp == -1) ? d1 : temp;
115
  
116
  temp=range_read_distance(IR2);
117
  d2=(temp == -1) ? d2 : temp;
118
  
119
  temp=range_read_distance(IR3);
120
  d3=(temp == -1) ? d3 : temp;
121
  
122
  temp=range_read_distance(IR4);
123
  d4=(temp == -1) ? d4 : temp;
124
  
125
  temp=range_read_distance(IR5);
126
  d5=(temp == -1) ? d5 : temp;
127
  
128
  /* Avoid obstacles ahead
129
     if(d2>170)
130
     v*=-1;
131
    
132
     Naturally slow down if there is something in the way.
133
     if(d2>150 || d1>180 || d3>180){
134
     v>>=1;
135
  */
136
  
137
  //pControl= (((d3-d1) + (d4-d5))*strength)/100;
138
  pControl= (((d5-d4))*strength)/100;
139
  omega = (omega*(100-strength))/100 + pControl;
140
  translateAngulartoLinear(velocity, omega, &vl , &vr );
141
  
142
  if (vl < 0) {
143
    motor1_set(BACKWARD, -vl);
144
  } else {
145
    motor1_set(FORWARD, vl);
146
  }
147
  if (vr < 0) {
148
    motor2_set(BACKWARD, -vr);
149
  } else {
150
    motor2_set(FORWARD, vr);
151
  }
152
}
153

  
154
/**@}**///end the motion group
155

  
156
void translateAngulartoLinear (int velocity, int omega, int* vl, int* vr) {
157
  //omega: angle measure, positive couter-clockwise from front.
158
  // -180 <= omega <= 180
159
  //velocity: -255 <= velocity <= 255
160
  
161
  long int vltemp, vrtemp;
162
  
163
  //make sure values are in bounds
164
  if (velocity < -255 || velocity >255 || omega < -255 || omega > 255) return;
165
	
166
  //compute
167
  vrtemp = velocity + omega * 3;
168
  vltemp = velocity - omega * 3;
169
	
170
  //check to see if max linear velocities have been exceeded.
171
  if (vrtemp > 255) {
172
    vltemp = 255 * vltemp / vrtemp;
173
    vrtemp = 255;
174
  }
175
  if (vltemp > 255) {	   
176
    vrtemp = 255 * vrtemp / vltemp;    
177
    vltemp = 255;  
178
  }
179
  if (vrtemp < -255) {
180
    vltemp = -255 * vltemp / vrtemp;
181
    vrtemp = -255;
182
  }
183
  if (vltemp < -255) {
184
    vrtemp = -255 * vrtemp / vltemp;
185
    vltemp = -255;
186
  }
187
  
188
  *vr = (int)vrtemp;
189
  *vl = (int)vltemp;
190
}
branches/orbit/code/lib/src/libdragonfly/battery.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file battery.c
29
 * @brief Implementation for reading battery level
30
 *
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff