-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoffroading-computer.ino
More file actions
308 lines (223 loc) · 6.94 KB
/
Copy pathoffroading-computer.ino
File metadata and controls
308 lines (223 loc) · 6.94 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
#include <Adafruit_10DOF.h>
#include <Adafruit_BMP085_U.h>
#include <Adafruit_L3GD20_U.h>
#include <Adafruit_LSM303_U.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <stdlib.h>
#include <LiquidCrystal_I2C.h>
#include <RunningAverageEA.h>
#include <OneWire.h>
#include <avr/eeprom.h>
#include <math.h>
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
Adafruit_L3GD20_Unified gyro = Adafruit_L3GD20_Unified(20);
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345);
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(54321);
#define ALT_ADJUSTMENT_ADDRESS 3
OneWire ds(2); // DS18S20 Temperature chip i/o
byte outsideTempAddr[8];
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
unsigned long timer;
float outsideTempCelsius = 0;
float GYRO_SENSITIVITY = 0.7;
float xAngle = 0;
float yAngle = 0;
int yOffset = 0;
int xOffset = 10;
float altAdjustment = 0;
RunningAverageEA altitudeRA(30);
RunningAverageEA accelerationRA(30);
RunningAverageEA pitchRA(10);
RunningAverageEA rollRA(10); //more resposive gyros
void setup(void)
{
Serial.begin(9600);
lcd.begin(20,4);
//printWelcomeMessage();
gyro.enableAutoRange(true);
gyro.begin();
bmp.begin();
mag.enableAutoRange(true);
mag.begin();
accel.begin();
if ( !ds.search(outsideTempAddr)) {
ds.reset_search();
}
ds.reset();
ds.select(outsideTempAddr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
altAdjustment = eeprom_read_dword((uint32_t *) ALT_ADJUSTMENT_ADDRESS );
}
void loop(void)
{
timer = micros();
String altitude = getAltitude();
String temperature = getTemperature();
String gyroX = getGyroPitch();
String gyroY = getGyroRoll();
String heading = getCompass();
String acceleration = getAcceleration();
String outsideTemp = getOutsideTemp();
if (digitalRead(4) == HIGH){
lcd.clear();
delay(1000); //to allow button to be unpressed
altAdjustment = -getFloatAltitude();
altitudeRA.clear();
delay(1000); //to allow button to be unpressed
if (digitalRead(4) == HIGH){
addAltitude();
}
altitudeRA.clear();
eeprom_write_dword((uint32_t *) ALT_ADJUSTMENT_ADDRESS, altAdjustment );
}
if(timer % 5 == 0)
{
printScreen(altitude, temperature, gyroX, gyroY, heading, acceleration, outsideTemp);
}
timer = micros();
}
void addAltitude(void) {
while (digitalRead(4) == HIGH){
altAdjustment += 100;
float alt = getFloatAltitude();
char altitudeString[4];
dtostrf( alt + altAdjustment ,4,0,altitudeString);
printScreen(altitudeString, "-", "-", "-", "-", "-", "-");
delay(300);
}
}
String getAltitude(void)
{
float altitudeInFeet = getFloatAltitude();
int temp = altitudeInFeet + altAdjustment;
altitudeRA.addValue(temp);
char altitudeString[10];
dtostrf(altitudeRA.getAverage(),4,0,altitudeString);
return altitudeString;
}
float getFloatAltitude(void)
{
sensors_event_t bmpEvent;
bmp.getEvent(&bmpEvent);
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
float altitudeInFeet = bmp.pressureToAltitude(seaLevelPressure, bmpEvent.pressure, outsideTempCelsius);
altitudeInFeet = (altitudeInFeet * 3.28) ;
return altitudeInFeet;
}
String getTemperature(void)
{
sensors_event_t bmpEvent;
bmp.getEvent(&bmpEvent);
float temperature;
bmp.getTemperature(&temperature);
temperature = (temperature * 2) +32;
char temperatureString[4];
dtostrf(temperature,4,0,temperatureString);
return temperatureString;
}
String getOutsideTemp(void)
{
byte outsideTempData[12];
ds.reset();
ds.select(outsideTempAddr);
ds.write(0xBE);
for (byte i = 0; i < 9; i++) {
outsideTempData[i] = ds.read();
}
int HighByte, LowByte, TReading, SignBit, Tc_100, whole, fract;
LowByte = outsideTempData[0];
HighByte = outsideTempData[1];
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000;
if (SignBit) // negative
{
TReading = (TReading ^ 0xffff) + 1; // 2's comp
}
Tc_100 = (6 * TReading) + TReading / 4;
float outsideTemp = Tc_100;
outsideTemp = (outsideTemp / 100);
outsideTempCelsius = outsideTemp;
outsideTemp = (outsideTemp * 2) + 32;
ds.reset();
ds.select(outsideTempAddr);
ds.write(0x44,1);
char outsideTempString[4];
dtostrf(outsideTemp, 3, 1, outsideTempString);
return outsideTempString;
}
float smoothGyroX;
float smoothAccelX;
String getGyroPitch(void)
{
sensors_event_t gyroEvent;
gyro.getEvent(&gyroEvent);
sensors_event_t acclEvent;
accel.getEvent(&acclEvent);
float accZ=float(acclEvent.acceleration.z) * 0.01;
float accY=float(acclEvent.acceleration.y) * 0.01;
float accelX = atan2(accY,accZ);
float gyroValueX = float(gyroEvent.gyro.x) * 0.5;
smoothAccelX = gyroSmooth(accelX, GYRO_SENSITIVITY , smoothAccelX);
smoothGyroX = gyroSmooth(gyroValueX, GYRO_SENSITIVITY, smoothGyroX);
int loopTime = (micros() - timer);
xAngle = kalmanCalculate(smoothAccelX, smoothGyroX, loopTime, xAngle);
xAngle = (xAngle * -60) - 5;
pitchRA.addValue(xAngle);
char gyroXString[4];
dtostrf(pitchRA.getAverage() , 4,0, gyroXString);
return gyroXString;
}
float smoothGyroY;
float smoothAccelY;
String getGyroRoll(void)
{
sensors_event_t gyroEvent;
gyro.getEvent(&gyroEvent);
sensors_event_t acclEvent;
accel.getEvent(&acclEvent);
float accZ = float(acclEvent.acceleration.z) * 0.01;
float accX = float(acclEvent.acceleration.x) * 0.01;
float accelY = atan2(accX,accZ);
float gyroValueY = float(gyroEvent.gyro.y) * 0.5;
smoothAccelY = gyroSmooth(accelY, GYRO_SENSITIVITY , smoothAccelY);
smoothGyroY = gyroSmooth(gyroValueY, GYRO_SENSITIVITY, smoothGyroY);
int loopTime = (micros() - timer);
yAngle = kalmanCalculate(smoothAccelY, smoothGyroY, loopTime, yAngle);
yAngle = yAngle * 60;
rollRA.addValue(yAngle);
char gyroYString[4];
dtostrf(rollRA.getAverage(), 4,0, gyroYString);
return gyroYString;
}
String getCompass(void)
{
sensors_event_t magEvent;
mag.getEvent(&magEvent);
float heading = (atan2(magEvent.magnetic.y,magEvent.magnetic.x) * 180) / PI;
heading = heading + 90 + 14; // orientation and declanation
if (heading < 0)
{
heading = 360 + heading;
}
char compassString[4];
dtostrf(heading, 4,0,compassString);
return compassString;
}
String getAcceleration(void)
{
sensors_event_t acclEvent;
accel.getEvent(&acclEvent);
float value = pow(abs( acclEvent.acceleration.y ), 2.5);
accelerationRA.addValue(value);
char accelerationString[4];
dtostrf( accelerationRA.getStandardDeviation() * 100, 4,0,accelerationString);
return accelerationString;
}
float gyroSmooth(float data, float filterVal, float smoothedVal){
if(abs(data - smoothedVal) > 1){ // throw out outliers
return smoothedVal;
}
smoothedVal = (data * (1 - filterVal)) + (smoothedVal * filterVal);
return smoothedVal;
}