-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathodometer.c
More file actions
100 lines (90 loc) · 2.52 KB
/
Copy pathodometer.c
File metadata and controls
100 lines (90 loc) · 2.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
* odometer.c
*
* Created: 20/10/2017 6:28:25 PM
* Author: Fiona
*/
///////////[Includes]///////////////////////////////////////////////////////////////////////////////
#include <stdint.h>
#include <avr/io.h>
#include "timer.h"
#include "odometer.h"
///////////[Functions]//////////////////////////////////////////////////////////////////////////////
//Initialise the Pins for the odometer sensors
void odoInit(void)
{
odoLedOn;
odoEnable;
odoObjectBuild(&odoLeft, ADC_ODO_L);
odoObjectBuild(&odoRight, ADC_ODO_R);
}
//Constructor for initialising new odometer sensor objects
void odoObjectBuild(OdometerData *x, AdcChannels adcChannel)
{
x->adcChannel = adcChannel;
x->maxValue = 0;
x->minValue = 1023;
x->midValue = 512;
x->hysteresis = 128;
x->pollInterval = 250;
x->lastPollTime = 0;
x->encStepsConv = 1000;
x->rpm = 0;
x->counts = 0;
x->curState = ODO_LOW;
x->prevState = ODO_LOW;
}
//See if new data is available and update the states of the sensors
uint8_t odoUpdateSensor(OdometerData *x)
{
uint8_t rangeShift = 0; //Indicates if calibration data has been updated
//If new ADC data available for the sensor
if(adcNewData(x->adcChannel))
{
//Retrieve the data from the ADC driver
x->rawData = adcGetData(x->adcChannel);
//Perform self calibration if necessary
if(x->rawData > x->maxValue)
{
x->maxValue = x->rawData;
rangeShift = 1;
}
if(x->rawData < x->minValue)
{
x->minValue = x->rawData;
rangeShift = 1;
}
if(rangeShift)
{
x->midValue = (x->minValue + x->maxValue)/2;
x->hysteresis = (x->maxValue - x->midValue)/2;
//[Perhaps a routine to store the updated data in EEPROM should go here]
}
//Update the previous state
x->prevState = x->curState;
//See if there has been a state change, and if so update current state
if(x->rawData > (x->midValue + x->hysteresis))
x->curState = ODO_HIGH;
if(x->rawData < (x->midValue - x->hysteresis))
x->curState = ODO_LOW;
//Increment the counts if rising edge or falling edge detected
if(x->curState != x->prevState)
x->counts++;
}
//If the poll interval has elapsed, then calculate a new revs per second value
uint32_t timestamp = timerGetTimestamp();
if(timestamp > (x->lastPollTime + x->pollInterval))
{
x->rpm = (x->counts*x->encStepsConv)/(timestamp - x->lastPollTime);
x->dCounts = x->counts;
x->counts = 0;
x->lastPollTime = timestamp;
}
return 0;
}
//Will poll all odometer sensors for new data
inline void odoPollAllSensors(void)
{
odoUpdateSensor(&odoLeft);
odoUpdateSensor(&odoRight);
}