scoutece / forklift / code / analog.c @ beea48aa
History | View | Annotate | Download (2.04 KB)
1 | 048ed7e1 | Tom Mullins | #include <avr/io.h> |
---|---|---|---|
2 | 0bd4bb32 | Tom Mullins | #include "analog.h" |
3 | |||
4 | int line_threshold = 150; |
||
5 | 048ed7e1 | Tom Mullins | |
6 | void analog_init(void) |
||
7 | { |
||
8 | // ADMUX register
|
||
9 | // Bit 7,6 - Set voltage reference to AVcc (0b01)
|
||
10 | // Bit 5 - ADLAR not set
|
||
11 | // Bit 4 - X
|
||
12 | // Bit 3:0 - Current channel
|
||
13 | ADMUX = _BV(REFS0); |
||
14 | |||
15 | // ADC Status Register A
|
||
16 | // Bit 7 - ADEN analog enable set
|
||
17 | // Bit 6 - ADSC start conversion bit not set
|
||
18 | // Bit 5 - ADATE enable auto trigger (for free running mode) not set
|
||
19 | // Bit 4 - ADIF ADC interrupt flag
|
||
20 | // Bit 3 - ADIE enable ADC interrupt (required for free-running mode)
|
||
21 | // Bits 2-0 - ADPS set to 8 MHz / 64 = 125 kHz (should be 50-200 kHz)
|
||
22 | ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1); |
||
23 | |||
24 | // Set line sensor mux lines PD2, PD3, and PB3 (MOSI) to output
|
||
25 | DDRD |= _BV(DDD2) | _BV(DDD3); |
||
26 | DDRB |= _BV(DDB3); |
||
27 | } |
||
28 | |||
29 | int analog_read(int which) |
||
30 | { |
||
31 | ADMUX = (ADMUX & 0xF0) | (which & 0x0F); |
||
32 | |||
33 | // Start the conversion
|
||
34 | ADCSRA |= _BV(ADSC); |
||
35 | |||
36 | // Wait for the conversion to finish
|
||
37 | while (ADCSRA & _BV(ADSC));
|
||
38 | |||
39 | int adc_l = ADCL;
|
||
40 | int adc_h = ADCH;
|
||
41 | |||
42 | return ((adc_h << 8) | adc_l); |
||
43 | } |
||
44 | |||
45 | int line_read(int which) |
||
46 | { |
||
47 | PORTD = (PORTD & 0xF3) | ((which & 3) << 2); |
||
48 | PORTB = (PORTB & 0XF7) | ((which & 4) << 1); |
||
49 | |||
50 | // For loop is used only as a delay to allow mux to settle
|
||
51 | volatile int i; |
||
52 | for(i=0; i < 5; i++); |
||
53 | |||
54 | return analog_read(ADC_LINE);
|
||
55 | } |
||
56 | |||
57 | beea48aa | Tom Mullins | void line_update(char* values) |
58 | 048ed7e1 | Tom Mullins | { |
59 | int i;
|
||
60 | for(i = 0; i<5; i++) |
||
61 | beea48aa | Tom Mullins | values[i] = line_read(i) < line_threshold ? LBLACK : LWHITE; |
62 | 048ed7e1 | Tom Mullins | } |
63 | |||
64 | beea48aa | Tom Mullins | int line_locate(char* values) |
65 | 048ed7e1 | Tom Mullins | { |
66 | int i;
|
||
67 | int wsum = 0; |
||
68 | int count = 0; |
||
69 | |||
70 | for(i = 0; i < 5; i++) |
||
71 | { |
||
72 | count += values[i] / 2;
|
||
73 | wsum += i * values[i]; |
||
74 | } |
||
75 | if (count == 0) |
||
76 | return NOLINE;
|
||
77 | if (count == 5) |
||
78 | return FULL_LINE;
|
||
79 | return (wsum/count)-4; |
||
80 | } |
||
81 | |||
82 | int line_read_pos(void) |
||
83 | { |
||
84 | beea48aa | Tom Mullins | char values[5]; |
85 | 048ed7e1 | Tom Mullins | line_update(values); |
86 | return line_locate(values);
|
||
87 | } |
||
88 | 0bd4bb32 | Tom Mullins | |
89 | void line_set_threshold_high(uint8_t threshold)
|
||
90 | { |
||
91 | line_threshold = ((int)(threshold & 3) << 8) | (line_threshold & 0xFF); |
||
92 | } |
||
93 | |||
94 | void line_set_threshold_low(uint8_t threshold)
|
||
95 | { |
||
96 | line_threshold = (line_threshold & 0x300) | (uint16_t) threshold;
|
||
97 | } |