Skip to content

Commit a475aed

Browse files
author
JLJu
committed
Merge branch 'master' of https://github.com/JLJu/AirDataComputer
2 parents 2ce8751 + 4acd208 commit a475aed

11 files changed

Lines changed: 182 additions & 450 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
![Asgard ADC](http://www.basicairdata.eu/wp-content/uploads/sites/1/nggallery/adc-asgard-build-2/IMGP5610.JPG)
33

44
## Description
5-
An air data computer (ADC) is an essential avionics component found in modern cockpits. This unit can determine True Airspeed, Mach number, Altitude, and common air properties from a pitot-static probe data and an outside air temperature probe.
5+
An air data computer (ADC) is an essential avionics component found in modern aircraft. This unit can determine True Airspeed, Mach number, Altitude, and common air properties from a pitot-static probe data and an outside air temperature probe.
66

77
This repository, together with the media published on the BasicAirData website, contains the information to build from scratch a recreational grade DIY Air Data Computer. This device can transmit data via USB serial port and Bluetooth, and log all data on a MicroSD.
88

Software/Microcontroller/Firmware/AsgardADC/AsgardADC.ino

Lines changed: 86 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Work in progress Asgard ADC Firmware Relase 0.4.0 14/01/2018
1+
/* Work in progress Asgard ADC Firmware Relase 0.4.0 16/01/2018
22
This is a preliminary release, work in progress. Misbehaviour is plausible.
33
AsgardADC.ino - Air Data Computer Firmware
44
Conform to ADC Common Mesage Set 0.4
@@ -21,24 +21,27 @@
2121

2222
#include <TimeLib.h>
2323
#include <Metro.h>
24-
2524
#include <AirDC.h>
2625
#include <SD.h>
2726
#include <SPI.h>
2827
#include <SD_t3.h>
2928
#include <i2c_t3.h> // Library for second I2C
3029
#include <SSC.h> // Library for SSC series sensors, support two bus I2C
3130

31+
#define ADC_NAME "ASGARD" // The name of the ADC device
32+
#define PROTOCOL_VERSION "0.4" // The version of the communication protocol
33+
3234
#define BUFFERLENGTH 512 // The length of string buffers
3335
#define DELIMITER '\n'
3436
#define SEPARATOR ","
3537
#define LEAVE_AS_IS "="
36-
#define ADC_NAME "ASGARD" // The name of the ADC device
37-
#define PROTOCOL_VERSION "0.4" // The version of the communication protocol
3838
#define DEFAULT_LOGFILE "DATALOG.CSV" // The default log file name
3939
#define DEFAULT_CONFIGFILE "CONFIG.CFG" // The configuration file name
4040

41-
const int chipSelect = BUILTIN_SDCARD; // HW pin for micro SD adaptor CS
41+
const int ledPin = 13; // The led is ON when the application is logging on SD
42+
const int TsensorPin = A0; // The input pin for the analog Temperature sensor
43+
const int chipSelect = BUILTIN_SDCARD; // HW pin for micro SD adaptor CS
44+
4245
File dataFile; // The file on SD
4346
File configFile; // The setup configuration file on SD
4447
bool isSDCardPresent; // The presence of a (formatted) card into the slot of SD
@@ -47,15 +50,14 @@ Sd2Card card; // The SD Card
4750
SdVolume volume; // The volume (partition) on SD
4851
double iTAS, ip1TAS, res, iof; // Accessory variables for Air Data calculations
4952

50-
AirDC AirDataComputer(1);
53+
AirDC AirDataComputer(1); // The Air Data Computer
5154

5255
SSC diffp(0x28, 0); // Create an SSC sensor with I2C address 0x28 on I2C bus 0
5356
SSC absp(0x28, 1); // Create an SSC sensor with I2C address 0x28 on I2C bus 1
5457

5558
String message_BT; // string that stores the incoming BT message
5659
String message_COM; // string that stores the incoming COM message
5760
String message_CFG; // string that stores the configuration messages
58-
const int ledPin = 13; // The led is ON when the application is logging on SD
5961

6062
float acquisition_freq = 1; // The minimum frequency of acquisition = 1 Hz (1 s)
6163
float sendtoserial_freq = 0; // The frequency of sendtoserial = NOT ACTIVE
@@ -80,7 +82,6 @@ bool sendtosd_needs_acquisition = true; // The check that the aquisiti
8082

8183
char Data[2][BUFFERLENGTH]; // The strings containing the data message
8284
char *p_Data; // The pointer to the current valid data string
83-
int TsensorPin = A0; // The input pin for the analog Temperature sensor
8485

8586

8687

@@ -128,7 +129,7 @@ void setup() {
128129
strcpy(Data[1],"\0"); // Initialize the Data
129130
p_Data = &Data[1][0]; // The current valid status index is 1
130131

131-
if (isSDCardPresent) { // Searches the configuration file
132+
if (isSDCardPresent) { // Searches the configuration file
132133
configFile = SD.open(DEFAULT_CONFIGFILE);
133134
if (configFile) loadConfiguration = true;
134135
}
@@ -139,7 +140,7 @@ void setup() {
139140
void SDCardCheck()
140141
{
141142
if (!isSDCardPresent) {
142-
isSDCardPresent = card.init(SPI_HALF_SPEED, chipSelect);
143+
isSDCardPresent = card.init(SPI_FULL_SPEED, chipSelect);
143144
if (isSDCardPresent) SD.begin(chipSelect);
144145
}
145146
isSDCardPresent = volume.init(card);
@@ -189,7 +190,40 @@ void acquisition()
189190

190191
// 2) Calculations
191192

192-
computation();
193+
// Init
194+
AirDataComputer.RhoAir(1); // Calculates the air density
195+
AirDataComputer.Viscosity(1); // Calculates the dynamic viscosity, Algorithm 2 (UOM Pas1e-6)
196+
AirDataComputer.CalibrationFactor(1); // Calibration factor set to 1
197+
AirDataComputer.IAS(1); // Calculates IAS method 1
198+
AirDataComputer._TAS = AirDataComputer._IAS;
199+
AirDataComputer.Mach(1); // Calculates Mach No
200+
AirDataComputer.OAT(1); // Outside Air Temperature
201+
// Wild iteration
202+
iof = 1;
203+
while ((res > 0.05) || (iof < 10)) {
204+
AirDataComputer.RhoAir(1); // Calculates the air density
205+
AirDataComputer.Viscosity(1); // Calculates the dynamic viscosity, Algorithm 2 (UOM Pas1e-6)
206+
AirDataComputer.CalibrationFactor(2); // Update calibration fator vat at TAS
207+
AirDataComputer.IAS(1); // IAS
208+
AirDataComputer.CAS(1); // CAS
209+
AirDataComputer.TAS(1); // True Air Speed
210+
AirDataComputer.Mach(1); // Update Mach No
211+
iTAS = AirDataComputer._TAS; // Store TAS value
212+
AirDataComputer.OAT(1); // Update outside Air Temperature
213+
AirDataComputer.RhoAir(1); // Calculates the air density
214+
AirDataComputer.Viscosity(1); // Calculates the dynamic viscosity, Algorithm 2 (UOM Pas1e-6)
215+
AirDataComputer.CalibrationFactor(2); // Update calibration fator vat at TAS
216+
AirDataComputer.TAS(1); // Update TAS
217+
AirDataComputer.Mach(1); // Update Mach No
218+
AirDataComputer.OAT(1); // Update outside Air Temperature
219+
ip1TAS = AirDataComputer._TAS;
220+
res = abs(ip1TAS - iTAS) / iTAS;
221+
iof++;
222+
}
223+
// Uncorrected ISA Altitude _h
224+
AirDataComputer.ISAAltitude(1);
225+
AirDataComputer._d = 8e-3;
226+
AirDataComputer.Red(1);
193227

194228

195229
// 3) $DTA message update
@@ -255,50 +289,9 @@ void acquisition()
255289
sendtoserial_needs_acquisition = false; // The aquisition has been updated since the last $DTA
256290
sendtobluetooth_needs_acquisition = false; // The aquisition has been updated since the last $DTA
257291
sendtosd_needs_acquisition = false; // The aquisition has been updated since the last $DTA
258-
259-
//Serial.println("*"); // Debug for computation frequency;
260292
}
261293

262294

263-
void computation() {
264-
// Init
265-
AirDataComputer.RhoAir(1); // Calculates the air density
266-
AirDataComputer.Viscosity(1); // Calculates the dynamic viscosity, Algorithm 2 (UOM Pas1e-6)
267-
AirDataComputer.CalibrationFactor(1); // Calibration factor set to 1
268-
AirDataComputer.IAS(1); // Calculates IAS method 1
269-
AirDataComputer._TAS = AirDataComputer._IAS;
270-
AirDataComputer.Mach(1); // Calculates Mach No
271-
AirDataComputer.OAT(1); // Outside Air Temperature
272-
273-
// Wild iteration
274-
iof = 1;
275-
while ((res > 0.05) || (iof < 10)) {
276-
AirDataComputer.RhoAir(1); // Calculates the air density
277-
AirDataComputer.Viscosity(1); // Calculates the dynamic viscosity, Algorithm 2 (UOM Pas1e-6)
278-
AirDataComputer.CalibrationFactor(2); // Update calibration fator vat at TAS
279-
AirDataComputer.IAS(1); // IAS
280-
AirDataComputer.CAS(1); // CAS
281-
AirDataComputer.TAS(1); // True Air Speed
282-
AirDataComputer.Mach(1); // Update Mach No
283-
iTAS = AirDataComputer._TAS; // Store TAS value
284-
AirDataComputer.OAT(1); // Update outside Air Temperature
285-
AirDataComputer.RhoAir(1); // Calculates the air density
286-
AirDataComputer.Viscosity(1); // Calculates the dynamic viscosity, Algorithm 2 (UOM Pas1e-6)
287-
AirDataComputer.CalibrationFactor(2); // Update calibration fator vat at TAS
288-
AirDataComputer.TAS(1); // Update TAS
289-
AirDataComputer.Mach(1); // Update Mach No
290-
AirDataComputer.OAT(1); // Update outside Air Temperature
291-
ip1TAS = AirDataComputer._TAS;
292-
res = abs(ip1TAS - iTAS) / iTAS;
293-
iof++;
294-
}
295-
296-
// Uncorrected ISA Altitude _h
297-
AirDataComputer.ISAAltitude(1);
298-
AirDataComputer._d = 8e-3;
299-
AirDataComputer.Red(1);
300-
}
301-
302295

303296

304297
void sendtoserial(void)
@@ -337,14 +330,14 @@ void loop() {
337330
bool endmsg_CFG = false; // it becomes true when a message is received from CONFIGURATION FILE
338331
char workbuff[BUFFERLENGTH] = ""; // General purpose buffer, used for itoa conversion
339332
char Message[BUFFERLENGTH] = ""; // it contains the message to be processed
340-
char Answer[BUFFERLENGTH] = "";
333+
char Answer[BUFFERLENGTH] = ""; // it contains the answer to the message
341334

342335

343336
// 0) Check Metro Timers:
344337

345-
if ((acquisition_freq > 0) && (acquisitionTimer.check() == 1)) acquisition();
338+
if ((acquisition_freq > 0) && (acquisitionTimer.check() == 1)) acquisition();
346339

347-
if ((sendtoserial_freq > 0) && (sendtoserialTimer.check() == 1)) {
340+
if ((sendtoserial_freq > 0) && (sendtoserialTimer.check() == 1)) {
348341
if (sendtoserial_needs_acquisition) {
349342
acquisition();
350343
acquisitionTimer.reset();
@@ -360,7 +353,7 @@ void loop() {
360353
sendtobluetooth();
361354
}
362355

363-
if ((sendtosd_freq > 0) && (sendtosdTimer.check() == 1)) {
356+
if ((sendtosd_freq > 0) && (sendtosdTimer.check() == 1)) {
364357
if (sendtosd_needs_acquisition) {
365358
acquisition();
366359
acquisitionTimer.reset();
@@ -372,45 +365,46 @@ void loop() {
372365
// 1) Read input from Configuration file, Serial, and Bluetooth:
373366

374367
if (loadConfiguration) {
375-
while (configFile.available() && !endmsg_CFG) {
368+
while (configFile.available()) {
376369
char ch = configFile.read();
377-
if ((ch != DELIMITER) && (ch != '\r')) message_CFG += char(ch); // Store string from CFG file
378-
else endmsg_CFG = true;
379-
}
380-
if (!configFile.available()) {
381-
loadConfiguration = false;
382-
configFile.close();
383-
endmsg_CFG = true;
370+
if (ch == DELIMITER) {
371+
endmsg_CFG = true;
372+
message_CFG.toCharArray (Message, BUFFERLENGTH-1);
373+
message_CFG = "";
374+
goto endread;
375+
} else if (ch != '\r') message_CFG += char(ch); // Store string from CONFIG file
384376
}
377+
loadConfiguration = false;
378+
configFile.close();
379+
endmsg_CFG = true;
385380
message_CFG.toCharArray (Message, BUFFERLENGTH-1);
386381
message_CFG = "";
387-
} else {
388-
while (Serial.available()) { // while there is SERIAL data available
389-
char ch = Serial.read();
390-
if (ch != DELIMITER) message_COM += char(ch); // Store string from serial command
391-
else endmsg_COM = true;
392-
}
393-
if (endmsg_COM) { // This comes from the Serial port (USB)
394-
if (message_COM != "") { // if data is available
395-
message_COM.toCharArray (Message, BUFFERLENGTH-1);
396-
message_COM = "";
397-
}
398-
}
399-
if (!endmsg_COM) {
400-
while (Serial1.available()) { // while there is BLUETOOTH data available
401-
char ch = Serial1.read();
402-
if (ch != DELIMITER) message_BT += char(ch); // Store string from BT command
403-
else endmsg_BT = true;
404-
}
405-
if (endmsg_BT) { // This comes from the bluetooth device (such as phone)
406-
if (message_BT != "") { // if data is available
407-
message_BT.toCharArray (Message, BUFFERLENGTH-1);
408-
message_BT = "";
409-
}
410-
}
411-
}
382+
goto endread;
383+
}
384+
385+
while (Serial.available()) {
386+
char ch = Serial.read();
387+
if (ch == DELIMITER) {
388+
endmsg_COM = true;
389+
message_COM.toCharArray (Message, BUFFERLENGTH-1);
390+
message_COM = "";
391+
goto endread;
392+
} else if (ch != '\r') message_COM += char(ch); // Store string from serial command
393+
}
394+
395+
while (Serial1.available()) {
396+
char ch = Serial1.read();
397+
if (ch == DELIMITER) {
398+
endmsg_BT = true;
399+
message_BT.toCharArray (Message, BUFFERLENGTH-1);
400+
message_BT = "";
401+
goto endread;
402+
} else if (ch != '\r') message_BT += char(ch); // Store string from bluetooth command
412403
}
413404

405+
endread:
406+
407+
414408
// 2) Process messages
415409

416410
if (endmsg_COM || endmsg_BT || endmsg_CFG) {
@@ -589,7 +583,6 @@ void loop() {
589583
break;
590584
default: // IT DOES NOTHING
591585
break;
592-
593586
}
594587
}
595588
}
@@ -667,7 +660,7 @@ void loop() {
667660
}
668661
SDCardCheck();
669662
if (isSDCardPresent) {
670-
if (SD.exists(command)) // Only if the file exist is set as current, #13 reply
663+
if (SD.exists(command)) // Only if the file exists is set as current, #13 reply
671664
{
672665
if (isSDCardPresent) {
673666
dataFile.close();
@@ -680,8 +673,7 @@ void loop() {
680673
AirDataComputer._status[AIRDC_STATUS_SD] = '0'; // SD Card not present
681674
goto endeval;
682675
}
683-
}
684-
676+
}
685677
AirDataComputer._status[AIRDC_STATUS_SD] = '1'; // SD Card present
686678
}
687679
}
@@ -962,6 +954,7 @@ void loop() {
962954

963955
endeval:
964956

957+
965958
// 3) In case answers to the right applicant
966959

967960
if (strcmp(Answer, "")) {

Software/Microcontroller/Libraries/AirDC/AirDC.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ AirDC::AirDC(int pid)
5151
_uT=0; //To be calculated
5252
_uRH=0.05;
5353
_uqc=5.0;
54-
_uIAS=0.0;//To be calculated, 0 default value
55-
_uTAT=0.0;//To be calculated, 0 default value
54+
_uIAS=0.0;//0 default value
55+
_uTAT=0.25;//From sensor specs 0 default value
5656
//Inertial Unit
5757
_Ip=0;
5858
_Iq=3;
@@ -176,14 +176,7 @@ void AirDC::IAS(int mode)
176176
_qc=-1*_qc;
177177
}
178178
_IAS=1.27775310604201*sqrt(_qc);
179-
/* if (_qc>0)
180-
{
181-
_uIAS=0.638876553021004/(sqrt(_qc))*_uqc;
182-
}
183-
else
184-
{
185-
_uIAS=0;
186-
}*/
179+
_uIAS=0.638876553021004/(sqrt(abs(_qc))*_uqc;
187180
break;
188181
}
189182
}
@@ -260,7 +253,7 @@ void AirDC::ISAAltitude(int mode)
260253
{
261254
double Ps,h;
262255
Ps=_p*0.000295299875080277;//Pa to inHg Conversion
263-
_h=(pow(29.92126,0.190255)-pow(Ps,0.190255))*76189.2339431570; //Using Goodrich 4081 Air data handbook formula, US atmosphere 1962
256+
_h=(pow(29.92126,0.190255)-pow(Ps,0.190255))*76189.2339431570; //Conform to Goodrich 4081 Air data handbook formula, US atmosphere 1962
264257
_h=_h*0.3048;//Back to SI
265258
_uh=4418.19264813511*pow(Ps,-0.809745)*_up*0.000295299875080277;
266259
break;
@@ -285,7 +278,7 @@ void AirDC::ISAAltitude(int mode)
285278
i=i+1;
286279
}
287280
_h=t1;
288-
_uh=0; //<- Need to be completed
281+
_uh=erralt+4418.19264813511*pow(Ps,-0.809745)*_up*0.000295299875080277;
289282
break;
290283
}
291284
}

Software/Microcontroller/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
## Introduction
55
Within "Hardware Integration Test" folder you find a sketch for test the hardware of a Asgard ADC.
66
Firmware folder will contain the sketch that need to ve uploaded to ADC. The firmware supports Bluetooth and SD card.
7-
Libraries folder contains the libraries you need to place in your library Arduino IDE folder to be able to compile the ADC sketch.
7+
Libraries folder contains the libraries you need to place in your Arduino IDE library folder to be able to compile the ADC sketch.

0 commit comments

Comments
 (0)