Project

General

Profile

Revision 1924

Fixed line following readings, addded 1ms delay to fix the mux.

View differences:

analog.c
74 74
 *
75 75
 **/
76 76
void analog_init(int start_conversion) {
77
	start_conversion=0;                   //forces the analog loop off
78
	for (int i = 0; i < 11; i++) {
79
		an_val[i].adc10 = 0;
80
		an_val[i].adc8 = 0;
81
	}
77
    start_conversion=0;                   //forces the analog loop off
78
    for (int i = 0; i < 11; i++) {
79
        an_val[i].adc10 = 0;
80
        an_val[i].adc8 = 0;
81
    }
82 82

  
83
	// ADMUX register
84
	// Bit 7,6 - Set voltage reference to AVcc (0b01)
85
	// Bit 5 - ADLAR set to simplify moving from register
86
	// Bit 4 - X
87
	// Bit 3:0 - Sets the current channel
88
	// Initializes to read from AN1 first (AN0 is reservered for the BOM)
89
	ADMUX = 0;
90
	ADMUX |= ADMUX_OPT | _BV(MUX0);
83
    // ADMUX register
84
    // Bit 7,6 - Set voltage reference to AVcc (0b01)
85
    // Bit 5 - ADLAR set to simplify moving from register
86
    // Bit 4 - X
87
    // Bit 3:0 - Sets the current channel
88
    // Initializes to read from AN1 first (AN0 is reservered for the BOM)
89
    ADMUX = 0;
90
    ADMUX |= ADMUX_OPT | _BV(MUX0);
91 91

  
92
	// ADC Status Register A
93
	// Bit 7 - ADEN is set (enables analog)
94
	// Bit 6 - Start conversion bit is set (must be done once for free-running mode)
95
	// Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW
96
	// Bit 4 - ADC interrupt flag, 0
97
	// Bit 3 - Enable ADC Interrupt (required to run free-running mode)
98
	// Bits 2-0 - Set to create a clock divisor of 2, to make ADC clock != 8,000,000/64 = 125kHz (it runs at highest frequency)
99
	ADCSRA = 0;
100
	ADCSRA |= _BV(ADEN) | /*_BV(ADPS2) | _BV(ADPS1) |*/ _BV(ADPS0);
101
	
102
	// Set external mux lines to outputs
103
	DDRG |= 0x1C;
92
    // ADC Status Register A
93
    // Bit 7 - ADEN is set (enables analog)
94
    // Bit 6 - Start conversion bit is set (must be done once for free-running mode)
95
    // Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW
96
    // Bit 4 - ADC interrupt flag, 0
97
    // Bit 3 - Enable ADC Interrupt (required to run free-running mode)
98
    // Bits 2-0 - Set to create a clock divisor of 2, to make ADC clock != 8,000,000/64 = 125kHz (it runs at highest frequency)
99
    ADCSRA = 0;
100
    ADCSRA |= _BV(ADEN) | /*_BV(ADPS2) | _BV(ADPS1) |*/ _BV(ADPS0);
104 101

  
105
	// Set line sensor mux lines to output.  Uses LCD/SPI header
106
	DDRD |=0xE0;	
102
    // Set external mux lines to outputs
103
    DDRG |= 0x1C;
107 104

  
108
	// Set up first port for conversions
109
	set_adc_mux(0x00);
110
	adc_current_port = AN1;
105
    // Set line sensor mux lines to output.  Uses LCD/SPI header
106
    DDRD |=0xE0;	
111 107

  
112
	//Start the conversion loop if requested
113
	if (start_conversion)
114
		analog_start_loop();
115
		
116
	//Conversion loop disabled by default
108
    // Set up first port for conversions
109
    set_adc_mux(0x00);
110
    adc_current_port = AN1;
111

  
112
    //Start the conversion loop if requested
113
    if (start_conversion)
114
        analog_start_loop();
115

  
116
    //Conversion loop disabled by default
117 117
}	
118 118

  
119 119
/**
......
136 136
 * @see analog10, analog_get8, analog_get10
137 137
 **/
138 138
unsigned int analog8(int which) {
139
/*	if (which == BOM_PORT) {
140
		return 0;
141
	} else {
142
		return an_val[which - 1].adc8;
143
	}
144
*/
145
return analog_get8(which);
139
    /*	if (which == BOM_PORT) {
140
        return 0;
141
        } else {
142
        return an_val[which - 1].adc8;
143
        }
144
     */
145
    return analog_get8(which);
146 146
}
147 147

  
148 148
/**
......
165 165
 * @see analog8, analog_get8, analog_get10
166 166
 **/
167 167
unsigned int analog10(int which) {
168
/*	if (which == BOM_PORT) {
169
		return 0;
170
	} else {
171
		return an_val[which - 1].adc10;
172
	}
173
*/
174
return analog_get10(which);
168
    /*	if (which == BOM_PORT) {
169
        return 0;
170
        } else {
171
        return an_val[which - 1].adc10;
172
        }
173
     */
174
    return analog_get10(which);
175 175
}
176 176

  
177 177
/**
......
181 181
 * @see analog_stop_loop, analog_loop_status
182 182
 **/
183 183
void analog_start_loop(void) {
184
	if(adc_loop_status != ADC_LOOP_RUNNING){
185
		//Start the conversion, enable ADC interrupt
186
		ADCSRA |= _BV(ADIE);
187
		ADCSRA |= _BV(ADSC);
188
		adc_loop_status = ADC_LOOP_RUNNING;
189
	}
184
    if(adc_loop_status != ADC_LOOP_RUNNING){
185
        //Start the conversion, enable ADC interrupt
186
        ADCSRA |= _BV(ADIE);
187
        ADCSRA |= _BV(ADSC);
188
        adc_loop_status = ADC_LOOP_RUNNING;
189
    }
190 190
}
191 191

  
192 192
/**
......
198 198
 * @see analog_start_loop, analog_loop_status
199 199
 **/
200 200
void analog_stop_loop() {
201
	//Signal to stop after the next conversion
202
	adc_sig_stop_loop = 1;
201
    //Signal to stop after the next conversion
202
    adc_sig_stop_loop = 1;
203 203
}
204 204

  
205 205
/**
......
209 209
 * @see analog_start_loop, analog_stop_loop
210 210
 **/
211 211
int analog_loop_status(void) {
212
	return adc_loop_status;
212
    return adc_loop_status;
213 213
}
214 214

  
215 215
/**
......
230 230
 * analog_start_loop
231 231
 **/
232 232
unsigned int analog_get8(int which) {	
233
	// Let any previous conversion finish
234
	while (ADCSRA & _BV(ADSC));
235
	
236
	if(which < EXT_MUX) {
237
		ADMUX = ADMUX_OPT + which;
238
	} else {
239
		ADMUX = ADMUX_OPT + EXT_MUX;
240
		set_adc_mux(which - 8);
241
	}
242
	
243
	// Start the conversion
244
	ADCSRA |= _BV(ADSC);
233
    // Let any previous conversion finish
234
    while (ADCSRA & _BV(ADSC));
245 235

  
246
	// Wait for the conversion to finish
247
	while (ADCSRA & _BV(ADSC));
236
    if(which < EXT_MUX) {
237
        ADMUX = ADMUX_OPT + which;
238
    } else {
239
        ADMUX = ADMUX_OPT + EXT_MUX;
240
        set_adc_mux(which - 8);
241
    }
248 242

  
249
	return ADCH; //since we left aligned the data, ADCH is the 8 MSB.
243
    // Start the conversion
244
    ADCSRA |= _BV(ADSC);
245

  
246
    // Wait for the conversion to finish
247
    while (ADCSRA & _BV(ADSC));
248

  
249
    return ADCH; //since we left aligned the data, ADCH is the 8 MSB.
250 250
}
251 251

  
252 252
/**
......
268 268
 * analog_start_loop
269 269
 **/
270 270
unsigned int analog_get10(int which) {
271
	int adc_h;
272
	int adc_l;
273
	
274
	// Let any previous conversion finish
275
	while (ADCSRA & _BV(ADSC));
271
    int adc_h;
272
    int adc_l;
276 273

  
277
	if(which < EXT_MUX) {
278
		ADMUX = ADMUX_OPT + which;
279
	} else {
280
		ADMUX = ADMUX_OPT + EXT_MUX;
281
		set_adc_mux(which - 8);
282
	}
283
	
284
	// Start the conversion
285
	ADCSRA |= _BV(ADSC);
274
    // Let any previous conversion finish
275
    while (ADCSRA & _BV(ADSC));
286 276

  
287
	// Wait for the conversion to finish
288
	while (ADCSRA & _BV(ADSC));
289
	
290
	adc_l = ADCL;
291
	adc_h = ADCH;
277
    if(which < EXT_MUX) {
278
        ADMUX = ADMUX_OPT + which;
279
    } else {
280
        ADMUX = ADMUX_OPT + EXT_MUX;
281
        set_adc_mux(which - 8);
282
    }
292 283

  
293
	return ((adc_h << 2) | (adc_l >> 6));
284
    // Start the conversion
285
    ADCSRA |= _BV(ADSC);
286

  
287
    // Wait for the conversion to finish
288
    while (ADCSRA & _BV(ADSC));
289

  
290
    adc_l = ADCL;
291
    adc_h = ADCH;
292

  
293
    return ((adc_h << 2) | (adc_l >> 6));
294 294
}
295 295

  
296 296

  
297 297
/** Returns the 10 bit value from the line sensors **/
298 298
unsigned int read_line(int which) {
299
	int adc_h;
300
	int adc_l;
301
	
302
	// Let any previous conversion finish
303
	while (ADCSRA & _BV(ADSC));
299
    int adc_h;
300
    int adc_l;
304 301

  
305
	ADMUX = ADMUX_OPT + AN1;
302
    // Let any previous conversion finish
303
    while (ADCSRA & _BV(ADSC));
306 304

  
307
//	which = (which&1)<<2 + (which&2) + (which&4)>>2;
308
	
309
        // mask so only proper bits are possible.  
310
        PORTD = (PORTD & 0x1F) | ((which & 0x07) << 5);
311
	// Start the conversion
312
	ADCSRA |= _BV(ADSC);
305
    ADMUX = ADMUX_OPT + AN1;
313 306

  
314
	// Wait for the conversion to finish
315
	while (ADCSRA & _BV(ADSC));
316
	
317
	adc_l = ADCL;
318
	adc_h = ADCH;
307
     which = ((which&1)<<2) + ((which&2)) + ((which&4)>>2);
319 308

  
320
	return ((adc_h << 2) | (adc_l >> 6));
309
    // mask so only proper bits are possible.  
310
    PORTD = (PORTD & 0x1F) | ((which & 0x07) << 5);
321 311

  
312
    delay_ms(1);
313

  
314
    // Start the conversion
315
    ADCSRA |= _BV(ADSC);
316

  
317
    // Wait for the conversion to finish
318
    while (ADCSRA & _BV(ADSC));
319

  
320
    adc_l = ADCL;
321
    adc_h = ADCH;
322

  
323
    return ((adc_h << 2) | (adc_l >> 6));
324

  
322 325
}
323 326

  
324 327

  
......
335 338
 * @see analog_init
336 339
 **/
337 340
int wheel(void) {
338
	return analog8(WHEEL_PORT);
341
    return analog8(WHEEL_PORT);
339 342
}
340 343

  
341 344

  
......
354 357
 * @see analog_init
355 358
 **/
356 359
void set_adc_mux(int which) {  
357
  // mask so only proper bits are possible.  
358
  PORTG = (PORTG & 0xE3) | ((which & 0x03) << 3) | (which & 0x04);
360
    // mask so only proper bits are possible.  
361
    PORTG = (PORTG & 0xE3) | ((which & 0x03) << 3) | (which & 0x04);
359 362
}
360 363

  
361 364
/**@}**/ //end defgroup
362 365

  
363 366

  
364 367
ISR(ADC_vect) {
365
	int adc_h = 0;
366
	int adc_l = 0;
367
	
368
	if(adc_loop_status != ADC_LOOP_RUNNING) return;
368
    int adc_h = 0;
369
    int adc_l = 0;
369 370

  
370
	//Store the value only if this read isn't for the BOM
371
	if (ADMUX != BOM_PORT) {
372
		adc_l = ADCL;
373
		adc_h = ADCH;
374
	
375
		an_val[adc_current_port - 1].adc10 = (adc_h << 2) | (adc_l >> 6);
376
		an_val[adc_current_port - 1].adc8 = adc_h;
377
	}
378
	
379
	//Skip AN7 because it is not a real port
380
	if (adc_current_port == AN6) {
381
		ADMUX = ADMUX_OPT | EXT_MUX;
382
		set_adc_mux(AN8 - 8);
383
		adc_current_port = AN8;
384
	//Wrap around
385
	} else if (adc_current_port == AN11) {
386
		adc_current_port = AN1;
387
		ADMUX = ADMUX_OPT | adc_current_port;
388
	//Normal increment
389
	} else {
390
		adc_current_port++;
391
	
392
		if(adc_current_port < EXT_MUX) {
393
			ADMUX = ADMUX_OPT | adc_current_port;
394
		} else {
395
			ADMUX = ADMUX_OPT | EXT_MUX;
396
			set_adc_mux(adc_current_port - 8);
397
		}
398
	}
371
    if(adc_loop_status != ADC_LOOP_RUNNING) return;
399 372

  
400
	//Stop loop if signal is set
401
	if(adc_sig_stop_loop) {
402
		adc_sig_stop_loop = 0;
403
		adc_loop_status = ADC_LOOP_STOPPED;
404
		return;
405
	}
406
	
407
	//Start next conversion
408
	ADCSRA |= _BV(ADSC);
373
    //Store the value only if this read isn't for the BOM
374
    if (ADMUX != BOM_PORT) {
375
        adc_l = ADCL;
376
        adc_h = ADCH;
377

  
378
        an_val[adc_current_port - 1].adc10 = (adc_h << 2) | (adc_l >> 6);
379
        an_val[adc_current_port - 1].adc8 = adc_h;
380
    }
381

  
382
    //Skip AN7 because it is not a real port
383
    if (adc_current_port == AN6) {
384
        ADMUX = ADMUX_OPT | EXT_MUX;
385
        set_adc_mux(AN8 - 8);
386
        adc_current_port = AN8;
387
        //Wrap around
388
    } else if (adc_current_port == AN11) {
389
        adc_current_port = AN1;
390
        ADMUX = ADMUX_OPT | adc_current_port;
391
        //Normal increment
392
    } else {
393
        adc_current_port++;
394

  
395
        if(adc_current_port < EXT_MUX) {
396
            ADMUX = ADMUX_OPT | adc_current_port;
397
        } else {
398
            ADMUX = ADMUX_OPT | EXT_MUX;
399
            set_adc_mux(adc_current_port - 8);
400
        }
401
    }
402

  
403
    //Stop loop if signal is set
404
    if(adc_sig_stop_loop) {
405
        adc_sig_stop_loop = 0;
406
        adc_loop_status = ADC_LOOP_STOPPED;
407
        return;
408
    }
409

  
410
    //Start next conversion
411
    ADCSRA |= _BV(ADSC);
409 412
}
410 413

  

Also available in: Unified diff