Project

General

Profile

Statistics
| Branch: | Revision:

scoutece / forklift / code / analog.c @ 048ed7e1

History | View | Annotate | Download (1.84 KB)

1
#include <avr/io.h>
2
#include "analog.h"
3

    
4
int line_read(int which);
5
void line_update(int* values);
6
int line_locate(int* values);
7

    
8
void analog_init(void)
9
{
10
  // ADMUX register
11
  // Bit 7,6 - Set voltage reference to AVcc (0b01)
12
  // Bit 5 - ADLAR not set
13
  // Bit 4 - X
14
  // Bit 3:0 - Current channel
15
  ADMUX = _BV(REFS0);
16

    
17
  // ADC Status Register A
18
  // Bit 7 - ADEN  analog enable set
19
  // Bit 6 - ADSC  start conversion bit not set
20
  // Bit 5 - ADATE enable auto trigger (for free running mode) not set
21
  // Bit 4 - ADIF  ADC interrupt flag
22
  // Bit 3 - ADIE  enable ADC interrupt (required for free-running mode)
23
  // Bits 2-0 - ADPS set to 8 MHz / 64 = 125 kHz (should be 50-200 kHz)
24
  ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1);
25

    
26
  // Set line sensor mux lines PD2, PD3, and PB3 (MOSI) to output
27
  DDRD |= _BV(DDD2) | _BV(DDD3);
28
  DDRB |= _BV(DDB3);
29
}
30

    
31
int analog_read(int which)
32
{
33
  ADMUX = (ADMUX & 0xF0) | (which & 0x0F);
34

    
35
  // Start the conversion
36
  ADCSRA |= _BV(ADSC);
37

    
38
  // Wait for the conversion to finish
39
  while (ADCSRA & _BV(ADSC));
40

    
41
  int adc_l = ADCL;
42
  int adc_h = ADCH;
43

    
44
  return ((adc_h << 8) | adc_l);
45
}
46

    
47
int line_read(int which)
48
{
49
  PORTD = (PORTD & 0xF3) | ((which & 3) << 2);
50
  PORTB = (PORTB & 0XF7) | ((which & 4) << 1);
51

    
52
  // For loop is used only as a delay to allow mux to settle
53
  volatile int i;
54
  for(i=0; i < 5; i++);
55
  
56
  return analog_read(ADC_LINE);
57
}
58

    
59
void line_update(int* values)
60
{
61
  int i;
62
  for(i = 0; i<5; i++)
63
    values[i] = line_read(i) < 150 ? LWHITE : LBLACK;
64
}
65

    
66
int line_locate(int* values)
67
{
68
  int i;
69
  int wsum = 0;
70
  int count = 0;
71

    
72
  for(i = 0; i < 5; i++)
73
  {
74
    count += values[i] / 2;
75
    wsum += i * values[i];
76
  }
77
  if (count == 0)
78
    return NOLINE;        
79
  if (count == 5)
80
    return FULL_LINE;
81
  return (wsum/count)-4;
82
}
83

    
84
int line_read_pos(void)
85
{
86
  int values[5];
87
  line_update(values);
88
  return line_locate(values);
89
}