From df61ee825fb67df6a1151339c53f4f8b04f756cb Mon Sep 17 00:00:00 2001 From: Ta180m Date: Thu, 5 Mar 2020 15:19:11 -0600 Subject: Increased precision --- Detector_Building_v2/Detector_Building_v2.ino | 34 +++++++------- .../src/curveFitting.cpp | 54 +++++++++++----------- .../arduinoCurveFitting-master/src/curveFitting.h | 20 ++++---- .../detectorBuilding/src/detectorBuilding.cpp | 25 +++++----- libraries/detectorBuilding/src/detectorBuilding.h | 23 ++++----- 5 files changed, 79 insertions(+), 77 deletions(-) diff --git a/Detector_Building_v2/Detector_Building_v2.ino b/Detector_Building_v2/Detector_Building_v2.ino index df54c24..05f148b 100644 --- a/Detector_Building_v2/Detector_Building_v2.ino +++ b/Detector_Building_v2/Detector_Building_v2.ino @@ -16,13 +16,13 @@ const bool CALIB = false; // Calibration mode const int n = 17; // Number of data points const int m = 1; // Number of segments const int deg = 2; // Regression degree -double V[n] = { // Voltage measurements +ld V[n] = { // Voltage measurements 2.70, 3.39, 2.40, 2.31, 2.19, 1.94, 4.09, 4.11, 3.98, 3.92, 3.77, 3.53, 3.18, 3.07, 2.30, 2.53, 2.49 }; -double T[n] = { // Temperature measurements +ld T[n] = { // Temperature measurements 24.0, 44.4, 18.4, 13.9, 11.2, 8.6, 60.8, 62.0, 58.3, 53.9, 49.3, 44.9, 41.0, 37.3, 13.4, 19.1, 18.2 }; -double coeff[m][deg + 1]; +ld coeff[m][deg + 1]; void setup() { @@ -34,14 +34,14 @@ void setup() { sort(V, n); sort(T, n); - double x[n], y[n]; + ld x[n], y[n]; for (int i = 0; i < n; i++) x[i] = log(v2r(V[i])) - 7; for (int i = 0; i < n; i++) y[i] = 1000 / c2k(T[i]); for (int i = 0; i < n; i++) { Serial.print("("); - Serial.print(x[i], 12); + Serial.print((double)x[i], 12); Serial.print(", "); - Serial.print(y[i], 12); + Serial.print((double)y[i], 12); Serial.print(")"); Serial.println(); } @@ -53,7 +53,7 @@ void setup() { for (int j = 0; j <= deg; j++){ Serial.print(c++); Serial.print(": "); - Serial.print(coeff[i][j], 12); + Serial.print((double)coeff[i][j], 12); Serial.println(); } } @@ -63,13 +63,13 @@ void setup() { void loop() { int V_raw = analogRead(THERM); // Read in raw analog value - double V_out = a2d(V_raw); + ld V_out = a2d(V_raw); if (CALIB) { // Calibration mode Serial.print("Raw analog reading: "); Serial.print(V_raw); Serial.print(" Voltage (V): "); - Serial.print(V_out); + Serial.print((double)V_out); Serial.println(); delay(500); return; @@ -78,15 +78,15 @@ void loop() { int s = 0; while (s + 1 < m && V_out < (V[s * n / m - 1] + V[s * n / m]) / 2) s++; // Find correct segment - double logR = log(v2r(V_out)) - 7; - double sum = 0, prod = 1; + ld logR = log(v2r(V_out)) - 7; + ld sum = 0, prod = 1; for (int i = 0; i <= deg; i++) { sum += coeff[s][deg - i] * prod; prod *= logR; } - double K = 1000 / sum; - double C = k2c(K); - double F = c2f(C); + ld K = 1000 / sum; + ld C = k2c(K); + ld F = c2f(C); // LED stuff @@ -114,11 +114,11 @@ void loop() { // Output voltage, temperature Serial.print("Raw analog reading: "); - Serial.print(V_raw); + Serial.print((double)V_raw); Serial.print(" Voltage (V): "); - Serial.print(V_out); + Serial.print((double)V_out); Serial.print(" Temperature (°C): "); - Serial.print(C); + Serial.print((double)C); // For reference /*Serial.print(" Temperature (°F): "); Serial.print(F); diff --git a/libraries/arduinoCurveFitting-master/src/curveFitting.cpp b/libraries/arduinoCurveFitting-master/src/curveFitting.cpp index 5e526c0..7155675 100644 --- a/libraries/arduinoCurveFitting-master/src/curveFitting.cpp +++ b/libraries/arduinoCurveFitting-master/src/curveFitting.cpp @@ -9,7 +9,7 @@ #include #include "curveFitting.h" -void printMat(const char *s, double*m, int n){ +void printMat(const char *s, ld*m, int n){ Serial.println(s); char buf[40]; for (int i = 0; i < n; i++) { @@ -21,7 +21,7 @@ void printMat(const char *s, double*m, int n){ } } -void showmat(const char *s, double **m, int n){ +void showmat(const char *s, ld **m, int n){ Serial.println(s); char buf[40]; for (int i = 0; i < n; i++) { @@ -33,13 +33,13 @@ void showmat(const char *s, double **m, int n){ } } -void cpyArray(double *src, double*dest, int n){ +void cpyArray(ld *src, ld*dest, int n){ for (int i = 0; i < n*n; i++){ dest[i] = src[i]; } } -void subCol(double *mat, double* sub, uint8_t coln, uint8_t n){ +void subCol(ld *mat, ld* sub, uint8_t coln, uint8_t n){ if (coln >= n) return; for (int i = 0; i < n; i++){ mat[(i*n)+coln] = sub[i]; @@ -47,7 +47,7 @@ void subCol(double *mat, double* sub, uint8_t coln, uint8_t n){ } /*Determinant algorithm taken from https://codeforwin.org/2015/08/c-program-to-find-determinant-of-matrix.html */ -int trianglize(double **m, int n) +int trianglize(ld **m, int n) { int sign = 1; for (int i = 0; i < n; i++) { @@ -57,12 +57,12 @@ int trianglize(double **m, int n) max = row; if (max) { sign = -sign; - double *tmp = m[i]; + ld *tmp = m[i]; m[i] = m[max], m[max] = tmp; } if (!m[i][i]) return 0; for (int row = i + 1; row < n; row++) { - double r = m[row][i] / m[i][i]; + ld r = m[row][i] / m[i][i]; if (!r) continue; for (int col = i; col < n; col ++) m[row][col] -= m[i][col] * r; @@ -71,9 +71,9 @@ int trianglize(double **m, int n) return sign; } -double det(double *in, int n, uint8_t prnt) +ld det(ld *in, int n, uint8_t prnt) { - double *m[n]; + ld *m[n]; m[0] = in; for (int i = 1; i < n; i++) @@ -83,7 +83,7 @@ double det(double *in, int n, uint8_t prnt) if (!sign) return 0; if(prnt) showmat("Upper triangle", m, n); - double p = 1; + ld p = 1; for (int i = 0; i < n; i++) p *= m[i][i]; return p * sign; @@ -91,11 +91,11 @@ double det(double *in, int n, uint8_t prnt) /*End of Determinant algorithm*/ //Raise x to power -double curveFitPower(double base, int exponent){ +ld curveFitPower(ld base, int exponent){ if (exponent == 0){ return 1; } else { - double val = base; + ld val = base; for (int i = 1; i < exponent; i++){ val = val * base; } @@ -103,18 +103,18 @@ double curveFitPower(double base, int exponent){ } } -int fitCurve (int order, int nPoints, double py[], int nCoeffs, double *coeffs) { +int fitCurve (int order, int nPoints, ld py[], int nCoeffs, ld *coeffs) { uint8_t maxOrder = MAX_ORDER; if (nCoeffs != order + 1) return ORDER_AND_NCOEFFS_DO_NOT_MATCH; // no of coefficients is one larger than the order of the equation if (nCoeffs > maxOrder || nCoeffs < 2) return ORDER_INCORRECT; //matrix memory hard coded for max of 20 order, which is huge if (nPoints < 1) return NPOINTS_INCORRECT; //Npoints needs to be positive and nonzero int i, j; - double T[MAX_ORDER] = {0}; //Values to generate RHS of linear equation - double S[MAX_ORDER*2+1] = {0}; //Values for LHS and RHS of linear equation - double denom; //denominator for Cramer's rule, determinant of LHS linear equation - double x, y; + ld T[MAX_ORDER] = {0}; //Values to generate RHS of linear equation + ld S[MAX_ORDER*2+1] = {0}; //Values for LHS and RHS of linear equation + ld denom; //denominator for Cramer's rule, determinant of LHS linear equation + ld x, y; - double px[nPoints]; //Generate X values, from 0 to n + ld px[nPoints]; //Generate X values, from 0 to n for (i=0; i maxOrder || nCoeffs < 2) return ORDER_INCORRECT; //Matrix memory hard coded for max of 20 order, which is huge if (nPoints < 1) return NPOINTS_INCORRECT; //Npoints needs to be positive and nonzero int i, j; - double T[MAX_ORDER] = {0}; //Values to generate RHS of linear equation - double S[MAX_ORDER*2+1] = {0}; //Values for LHS and RHS of linear equation - double denom; //denominator for Cramer's rule, determinant of LHS linear equation - double x, y; + ld T[MAX_ORDER] = {0}; //Values to generate RHS of linear equation + ld S[MAX_ORDER*2+1] = {0}; //Values for LHS and RHS of linear equation + ld denom; //denominator for Cramer's rule, determinant of LHS linear equation + ld x, y; for (i=0; i #define MAX_ORDER 20 +typedef long double ld; + #ifndef CURVE_FIT_DEBUG #define CURVE_FIT_DEBUG 0 #endif @@ -24,17 +26,17 @@ enum curveFitERROR{ }; /* Matrix Helper Functions */ -void printMat(const char *s, double*m, int n); -void showmat(const char *s, double **m, int n); -void cpyArray(double *src, double*dest, int n); -void subCol(double *mat, double* sub, uint8_t coln, uint8_t n); -double curveFitPower(double base, int exponent); +void printMat(const char *s, ld*m, int n); +void showmat(const char *s, ld **m, int n); +void cpyArray(ld *src, ld*dest, int n); +void subCol(ld *mat, ld* sub, uint8_t coln, uint8_t n); +ld curveFitPower(ld base, int exponent); /* Determinant matrix functions */ -int trianglize(double **m, int n); -double det(double *in, int n, uint8_t prnt); +int trianglize(ld **m, int n); +ld det(ld *in, int n, uint8_t prnt); /* Curve fitting functions */ -int fitCurve (int order, int nPoints, double py[], int nCoeffs, double *coeffs); -int fitCurve (int order, int nPoints, double px[], double py[], int nCoeffs, double *coeffs); +int fitCurve (int order, int nPoints, ld py[], int nCoeffs, ld *coeffs); +int fitCurve (int order, int nPoints, ld px[], ld py[], int nCoeffs, ld *coeffs); #endif diff --git a/libraries/detectorBuilding/src/detectorBuilding.cpp b/libraries/detectorBuilding/src/detectorBuilding.cpp index 7b3fef7..c9367e1 100644 --- a/libraries/detectorBuilding/src/detectorBuilding.cpp +++ b/libraries/detectorBuilding/src/detectorBuilding.cpp @@ -8,35 +8,34 @@ #include "Arduino.h" #include "detectorBuilding.h" - // Temperature conversions -double f2c(double f) { return (f - 32) * 5 / 9; } // Fahrenheit to Celsius -double c2f(double c) { return c * 9 / 5 + 32; } // Celsius to Fahrenheit -double k2c(double k) { return k - 273.15; } // Kelvin to Celsius -double c2k(double c) { return c + 273.15; } // Celsius to Kelvin -double f2k(double f) { return c2k(f2c(f)); } // Fahrenheit to Kelvin -double k2f(double k) { return c2f(k2c(k)); } // Kelvin to Fahrenheit +ld f2c(ld f) { return (f - 32) * 5 / 9; } // Fahrenheit to Celsius +ld c2f(ld c) { return c * 9 / 5 + 32; } // Celsius to Fahrenheit +ld k2c(ld k) { return k - 273.15; } // Kelvin to Celsius +ld c2k(ld c) { return c + 273.15; } // Celsius to Kelvin +ld f2k(ld f) { return c2k(f2c(f)); } // Fahrenheit to Kelvin +ld k2f(ld k) { return c2f(k2c(k)); } // Kelvin to Fahrenheit // Analog to digital conversion -double a2d(int a) { return V_in * a / analog_max; } -int d2a(double d) { return d * analog_max / V_in; } +ld a2d(int a) { return V_in * a / analog_max; } +int d2a(ld d) { return d * analog_max / V_in; } // Voltage to resistance conversion -double v2r(double V_out) { return R_k * (V_in / V_out - 1); } +ld v2r(ld V_out) { return R_k * (V_in / V_out - 1); } // Utility functions // No C++ standard library :( -void sort(double a[], int n) { +void sort(ld a[], int n) { // Bubble sort // Slow but n < 30 so OK // Too lazy to implement a fast sort for (int i = 0; i < n; i++) { for (int j = 0; j < n - 1; j++) { if (a[j] > a[j + 1]) { - double tmp = a[j]; + ld tmp = a[j]; a[j] = a[j + 1]; a[j + 1] = tmp; } @@ -50,7 +49,7 @@ void sort(double a[], int n) { /*void calculate() { sort(V, n); sort(T, n); - double R[n], L[n], Y[n], G[n]; + ld R[n], L[n], Y[n], G[n]; for (int i = 0; i < n; i++) R[i] = R_k * (V_in / V[i] - 1); for (int i = 0; i < n; i++) L[i] = log(R[i]); for (int i = 0; i < n; i++) Y[i] = 1 / c2k(T[i]); diff --git a/libraries/detectorBuilding/src/detectorBuilding.h b/libraries/detectorBuilding/src/detectorBuilding.h index 4a268e8..cdb6890 100644 --- a/libraries/detectorBuilding/src/detectorBuilding.h +++ b/libraries/detectorBuilding/src/detectorBuilding.h @@ -8,23 +8,24 @@ #define detectorBuilding_h #include "Arduino.h" +typedef long double ld; const int LED_R = 8, LED_G = 10, LED_B = 12, THERM = 0; // Device component pins -const double R_k = 10000, V_in = 5, analog_max = 1023; // Device constants +const ld R_k = 10000, V_in = 5, analog_max = 1023; // Device constants -double f2c(double f); -double c2f(double c); -double k2c(double k); -double c2k(double c); -double f2k(double f); -double k2f(double k); +ld f2c(ld f); +ld c2f(ld c); +ld k2c(ld k); +ld c2k(ld c); +ld f2k(ld f); +ld k2f(ld k); -double a2d(int a); -int d2a(double d); +ld a2d(int a); +int d2a(ld d); -double v2r(double V_out); +ld v2r(ld V_out); -void sort(double a[], int n); +void sort(ld a[], int n); //void calculate(); -- cgit v1.2.3-70-g09d2