Skip to content

Commit

Permalink
Calibration fix
Browse files Browse the repository at this point in the history
Better fit for gauge readings.
  • Loading branch information
tomcourt authored and tomcourt committed Sep 1, 2017
1 parent f252c55 commit e8aff25
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 98 deletions.
Binary file modified CurveFit.numbers
Binary file not shown.
Binary file added MagnetoP-Lead.numbers
Binary file not shown.
35 changes: 29 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,28 +150,51 @@ The Leonardo is rated to run from 6-20 volts although they suggest keeping it be

The supply is rated for 1000 ma. The Leonardo uses 82 mA (confirmed by testing). Connected to the Aux display with most segments lit power consumed is about 140 mA. Pull ups will add some to this.

**Leonardo Pins Mapping to ATmega 32U4**
**Leonardo/Yún Pin Mapping to Enguino Prototype**

| Arduino | 32U4 | Use |IRQ|Analog|Counter| Assign |
|---------|-------|-------------|---|------|-------|---------|
| D0 | PD2 | Serial RX | * | | | Tach |
| D1 | PD3 | Serial TX | * | | | Fuel-F |
| D0 | PD2 | Yún RX | * | | | Tach |
| D1 | PD3 | Yún TX | * | | | Fuel-F |
| D2 | PD1 | SDA | * | | | Aux-SDA |
| D3 | PD0 | SCL/PWM | * | | | Aux-SCL |
| D4 | PD4 | TC Mux A0 | | A6 | * | |
| D4 | PD4 | TC Mux A0 | | A6 | | |
| D5 | PC6 | TC Mux A1 | | | | |
| D6 | PD7 | TC Mux A2 | | A7 | * | |
| D7 | PE6 | TC Mux EN | * | | | |
| D8 | PB4 | Analog 8 | | A8 | | MAP |
| D9 | PB5 | TC CS | | A9 | | |
| D10 | PB6 | Ether CS | | A10 | | |
| D11 | PB7 | PWM | | | | Aux-Sw |
| D12 | PD6 | TC MISO | | A11 | | |
| D12 | PD6 | TC MISO | | A11 | * | |
| D13 | PC7 | TC SCLK/LED | | | | ||

The SD card on the Leonardo can not be used with the thermocouple board attached as they both use pin D4. The thermocouple board also interferes with 4 of the analog inputs. The Leonardo itself also interferes with one of the analog inputs.

The D6 and D12 pins support counters which would be useful for the tach and fuel flow. But the thermocouple board also conflicts with this. Interrupt pins will be used instead. With the tach, assume 2 pulses per revolution at 2700 RPM the tach will max out at 90/cps so as long as IRQ disable time is <11ms no error should be expected. For the fuel flow with a k-factor of 68,000 and 13GPH it will max out at 250/cps so IRQ disable time must be <4ms.
**Leonardo/Yún Pin Mapping to Enguino Production**

| Arduino | 32U4 | Use |IRQ|Analog|Counter| Assign Leo | Assign Yún |
|---------|-------|--------------|---|------|-------|------------|------------|
| D0 | PD2 | Serial RX | * | | | Tach-1 | reserved |
| D1 | PD3 | Serial TX | * | | | Tach-2 | reserved |
| D2 | PD1 | SDA | * | | | SDA | Tach-1 |
| D3 | PD0 | SCL | * | | | SCL | Tach-2 |
| D4 | PD4 | Analog 6 | | A6 | | Volt divide| Volt divide|
| D5 | PC6 | | | | | | SDA |
| D6 | PD7 |Analog 6/Count| | A7 | * | MAP | Fuel-F |
| D7 | PE6 |Handshake(Yún)| * | | | Fuel-F | reserved |
| D8 | PB4 | Analog 8 | | A8 | | Generic | Generic |
| D9 | PB5 | Analog 9 | | A9 | | Generic | Generic |
| D10 | PB6 | Ethernet(Leo)| | A10 | | reserved | MAP |
| D11 | PB7 | | | | | | SCL |
| D12 | PD6 | Analog 11 | | A11 | * | Ammeter | Ammeter |
| D13 | PC7 | LED | | | | | ||

* Leonardo ETH needs D10 for communications
* Yún needs D0, D1 and D7 for communication
* Leonardo uses IRQ for fuel flow, Yún uses hardware counter instead

With the tach, assume 2 pulses per revolution at 2700 RPM the tach will max out at 90/cps so as long as IRQ disable time is <11ms no error should be expected. For the fuel flow with a k-factor of 68,000 and 13GPH it will max out at 250/cps so IRQ disable time must be <4ms.

### Software

Expand Down
25 changes: 12 additions & 13 deletions enguino/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,25 @@ const bool longAverageByPin[12] = { false, false, false, false, true, true, fals
// sensor-type range
// -------------- --------
// st_r240to33 0 - 1000 proportional on resistance of sensor forming resistor divider
// st_v240to33 0 - 1000 proportional on voltage of sensor forming resistor divider
// st_thermistorC 0 - 1500 degrees C. in tenths
// st_thermistorF 320- 2732 degrees F. in tenths
// st_volts 0 - 1000 5 mV/per count
// st_thermistor -/+ xxxx degrees either F or C.
// st_volts1 0 - 1000 1 mV/per count
// st_volts5 0 - 1000 5 mV/per count
// st_k_type_tcC 0 - 4000 0-1000 degrees C. in quarters
// st_j_type_tcC 0 - 4000 0-1000 degrees C. in quarters
// st_k_type_tcF 0 - 4000 32-1832 degrees F. in quarters
// st_j_type_tcF 0 - 4000 32-1832 degrees F. in quarters
// st_unit unit values, RPM, fuel flow, hobbs

// sensor-type, pin, decimal, voffset, vfactor, goffset, gfactor,lowWarning,lowCaution,highCaution,highWarning
const Sensor voltS = { st_volts, 0, 1, 0, SCALE(.200), GMIN(100*fromV), GRNG(60*fromV), 110, 130, 9999, 160 };
const Sensor oilpS = { st_v240to33, 1, 0, 0, SCALE(.100), 0, SCALE(1.), 25, 55, 9999, 95 };
const Sensor oiltS = { st_thermistorF, 2, 0, 0, SCALE(.100), GMIN(50*10), GRNG(200*10), -1, 140, 9999, 250 };
const Sensor fuelpS = { st_v240to33, 3, 1, 0, SCALE(.150), 0, SCALE(150./100.), 5, 20, 60, 80 };
const Sensor fuellS = { st_v240to33, DUAL(4), 1, 0, SCALE(.160), 0, SCALE(1.), 25, 50, 9999, 999 };
const Sensor tachS = { st_unit, TACH_SENSOR, 0, 0, SCALE(1.), GMIN(0), GRNG(3000), -1, 500, 9999, 2700 };
const Sensor mapS = { st_volts, 8, 1, 102, SCALE(.32811), GMIN(210),GRNG(1000*25/32.811), -1, -1, 9999, 9999 };
const Sensor chtS = { st_k_type_tcF, 16, 0, 0, SCALE(.25), GMIN(100*4), GRNG(400*4), -1, 150, 400, 500 };
const Sensor voltS = { st_volts5, 0, 1, 0, SCALE(.200), GMIN(100*fromV), GRNG(60*fromV), 110, 130, 9999, 160 };
const Sensor oilpS = { st_volts5, 1, 0, -436, SCALE(-.310), -436, SCALE(-3.095), 25, 55, 9999, 95 };
const Sensor oiltS = { st_thermistor, 2, 0, 0, SCALE(1.), GMIN(50), GRNG(200), -1, 140, 9999, 245 };
const Sensor fuelpS = { st_volts1, 3, 1, -626, SCALE(-.395), -626, SCALE(-2.634), 5, 20, 60, 80 };
const Sensor fuellS = { st_volts5, DUAL(4), 1, -490, SCALE(-.402), -490, SCALE(-2.512), 25, 50, 9999, 999 };
const Sensor mapS = { st_volts5, 8, 1, 102, SCALE(.32811), GMIN(210),GRNG(1000*25/32.811), -1, -1, 9999, 9999 };
const Sensor chtS = { st_k_type_tcF, 16, 0, 0, SCALE(.25), GMIN(100*4), GRNG(400*4), -1, 150, 400, 495 };
const Sensor egtS = { st_k_type_tcF, 20, 0, 0, SCALE(.25), GMIN(1000*4), GRNG(600*4), -1, -1, 9999, 9999 };
const Sensor tachS = { st_unit, TACH_SENSOR, 0, 0, SCALE(1.), GMIN(0), GRNG(3000), -1, 500, 9999, 2700 };
const Sensor fuelfS = { st_unit, FUELF_SENSOR, 1, 0, SCALE(1.), GMIN(0), GRNG(150), -1, -1, 9999, 9999 };
const Sensor fuelrS = { st_unit, FUELR_SENSOR, 1, 0, SCALE(1.), GMIN(0), GRNG(400), -1, -1, 9999, 9999 };
const Sensor hobbsS = { st_unit, HOBBS_SENSOR, 1, 0, SCALE(1.), GMIN(0), GRNG(1000), -1, -1, 9999, 9999 };
Expand All @@ -97,7 +96,7 @@ const short egtLP[] = { HSEG(150./600.), HSEG(300./600.), HSEG(450./600.) };
string oilpRC[] = { red, yellow, green, red };
short oilpRP[] = { VSEG(25./100.), VSEG(55./100.), VSEG(95./100.), VSEG(1) };
string oiltRC[] = { yellow, green, red };
short oiltRP[] = { VSEG(40./200.), VSEG(196./200.), VSEG(1) }; // offset and range offset by 50 deg-F
short oiltRP[] = { VSEG(90./200.), VSEG(195./200.), VSEG(1) }; // offset and range offset by 50 deg-F
string voltRC[] = { red, yellow, green, yellow, red };
short voltRP[] = { VSEG(1./6.), VSEG(3./6.), VSEG(5./6.), VSEG(5.9/6.), VSEG(1) }; // offset and range offset by 10 volts
string fuelpRC[] = { red, yellow, green, yellow, red };
Expand Down
2 changes: 1 addition & 1 deletion enguino/egTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ typedef struct {
const short *result;
} InterpolateTable;

enum SensorType {st_r240to33, st_v240to33, st_thermistorF, st_thermistorC, st_volts, st_k_type_tcF, st_j_type_tcF, st_k_type_tcC, st_j_type_tcC, st_unit};
enum SensorType {st_r240to33, st_thermistor, st_volts1, st_volts5, st_k_type_tcF, st_j_type_tcF, st_k_type_tcC, st_j_type_tcC, st_unit};

typedef struct {
SensorType type;
Expand Down
16 changes: 8 additions & 8 deletions enguino/enguino.ino
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,22 @@
// You should have received a copy of the GNU General Public License
// along with Enguino. If not, see <http:https://www.gnu.org/licenses/>.

#include <SPI.h> // required for ethernet2
#include <Ethernet2.h>

EthernetServer server(80); // Port 80 is HTTP
EthernetClient client;

#include <SPI.h> // required for ethernet2
#include <Ethernet2.h>
#include <EEPROM.h> // required for persit.h
#include <string.h>
#include <avr/pgmspace.h> // storing strings in Flash to save RAM

// Temporary chang this your local network's IP range for testing
// Temporary change this your local network's IP range for testing
IPAddress ip(192, 168, 0, 111); // http:https://192.168.0.111 is link to Enguino

// fictitious MAC address. Only real critera is the first byte's 2 lsb must be 1 (for local) and 0 (for unicast).
byte mac[] = { 0xDE, 0x15, 0x24, 0x33, 0x42, 0x51 };

EthernetServer server(80); // Port 80 is HTTP
EthernetClient client;

// #define DEBUG_RAM_USE // checks maximum RAM usage
// #define CALIBRATION_TEST // show calibration values instead of fuel flow/lean info panel
// #define SIMULATE_SENSORS 3 // number of simulated sensor 'states', press enter in serial monitor to advace state
Expand Down Expand Up @@ -81,10 +80,11 @@ void setup() {
// ; // wait for serial port to connect. Stops here until Serial Monitor is started. Good for debugging setup

sensorSetup();

// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();

eeInit();

tcTempSetup();
Expand Down Expand Up @@ -117,7 +117,7 @@ void loop() {
pollForHttpRequest();

if (eighthSecond) {
eighthSecond = false;
eighthSecond = false; // this can fall behind due to a long event like responding to a http request

updateADC();

Expand Down
6 changes: 2 additions & 4 deletions enguino/printGauges.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ void printInfoBox() {
print_P(F("<rect x='0' y='0' width='1600' height='2800' fill='none' stroke='orange'/>\n"));
#endif
#ifdef CALIBRATION_TEST
print_P(F("<text x='0' y='0' text-anchor='start' font-size='250px'>_____RV____R___5V</text>"));
print_P(F("<text x='0' y='0' text-anchor='start' font-size='250px'>_____R___5V</text>"));
for (byte i=1; i<6; i++) {
print_P(F("<text x='0' y='"));
print(i*275);
Expand All @@ -348,11 +348,9 @@ void printInfoBox() {
s.pin = i;
print(i);
print("-");
s.type = st_v240to33;
printFixed(readSensor((const Sensor *)&s));
s.type = st_r240to33;
printFixed(readSensor((const Sensor *)&s));
s.type = st_volts;
s.type = st_volts5;
printFixed(readSensor((const Sensor *)&s));
print_text_close();
}
Expand Down
5 changes: 5 additions & 0 deletions enguino/printWeb.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ void pollForHttpRequest() {
"Connection: close\n" // the connection will be closed after completion of the response
"\n"
));

// Serial.print("SERVE UP ");
// Serial.println(url);
serveUpWebPage(url, var, num);
flush();
break;
Expand All @@ -215,6 +218,8 @@ void pollForHttpRequest() {
}
break;
case '?':
if (token == '/')
continue; // hold state
url = token; // either a ? or the url
break;
case ' ':
Expand Down
121 changes: 58 additions & 63 deletions enguino/sensors.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
#define FUELF_SIGNAL 1
#define TACH_SIGNAL 0

#define RVoff -512 // 512 ADC units is when ADC when gauge reads 0, using a 240-33 ohm sensor and a 240 ohm divider
#define RVscale (1000.0/(124+RVoff)) // 124 ADC units is when ADC when gauge reads max, using same

#define HOBBS_COUNT_INTERVAL (3600/40) // update hobbs 40 times an hour

extern volatile short tcTemp[9]; // in quarter deg. C, tcTemp[8] is the interal reference temp, disable IRQ's to access these
Expand Down Expand Up @@ -51,20 +48,21 @@ byte hobbsCount = HOBBS_COUNT_INTERVAL/2; // in order to prevent cumulative hob


static const byte thermistorBS[] = {
3,3,3,3,3,3,4,4,
4,4,4,4,4,5,5,5,
5,5,6,6,7,6,6,5,
5,5,5,4,4,4,4
4,4,4,4,
4,5,5,5,
5,5,5,5,
5,5,4,4
};

static const short thermistorYV[] = {
1500,1438,1384,1336,1293,1254,1219,1155,
1100,1051,1008,968,932,898,838,784,
736,692,650,575,505,375,310,241,
204,164,121,72,44,14,-19,-58
static const short thermistorYV[] = {
303,280,262,248,
236,224,205,188,
173,158,144,128,
112,93,69,53,
31
};

const InterpolateTable thermistor = { 64, 32, thermistorBS, thermistorYV };
const InterpolateTable thermistor = { 64, 17, thermistorBS, thermistorYV };

static const byte r240to33BS[] = {
5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
Expand Down Expand Up @@ -152,6 +150,8 @@ inline void updateRPM() {
if (tachCount) {
unsigned long interval = latestTach_uS-savedTach_uS;
rpm10 = ((60*1000000L/TACH_DIVIDER/10)*tachCount + interval/2) / interval;
if (rpm10 < 0)
rpm10 = 0;
}
else
rpm10 = 0;
Expand Down Expand Up @@ -226,56 +226,51 @@ short readSensor(const Sensor *s, byte n = 0) {
#if SIMULATE_SENSORS
return simulate[simState][p&(DUAL_BIT-1)];
#else
short v;
p &= 0x1f;

short t = s->type;
short toF = 0;
if (p == HOBBS_SENSOR) { // Hobbs hours*10 (lowest 4 digits)
v = ee_status.hobbs >> 2;
}
else if (p == FUELF_SENSOR) { // Fuel flow GPH*10
noInterrupts();
v = short((multiply(fflowRate, int(10*3600L/40/2)) + (ee_settings.kFactor>>1)) / ee_settings.kFactor);
interrupts();
}
else if (p == FUELR_SENSOR) { // Fuel remaining Gallons*10 (totalizer)
noInterrupts();
v = ee_status.fuel >> 2;
interrupts();
}
else if (p == TACH_SENSOR) { // RPM's
v = average4(adcSample[12].moving) * 10;
}
else if (p < 16) {
if (longAverageByPin[p])
v = adcSample[p].accumulate/LONG_AVERAGE_LENGTH;
else
v = average4(adcSample[p].moving);
if (t == st_r240to33)
v = interpolate(&r240to33, v);
else if (t == st_v240to33)
v = multiplyAndScale(SCALE(RVscale),v+RVoff, divisor);
else if (t == st_thermistorC || t == st_thermistorF) {
v = interpolate(&thermistor, v);
if (t == st_thermistorF)
toF = 32 * 10;
}
else if (t == st_volts)
v = multiplyAndScale(v,1000,10);
}
else if (p < 24) {
noInterrupts();
v = tcTemp[p-16];
interrupts();
if (t == st_j_type_tcC || t == st_j_type_tcF)
v = multiplyAndScale(v - tcTemp[8], 25599, 15) + tcTemp[8];
if (t == st_k_type_tcF || t == st_j_type_tcF)
toF = 32 * 4;
}
if (toF && v != FAULT)
v = (v*9)/5 + toF;
return v;
short v;
p &= 0x1f;

byte t = s->type;
if (p == HOBBS_SENSOR) { // Hobbs hours*10 (lowest 4 digits)
v = ee_status.hobbs >> 2;
}
else if (p == FUELF_SENSOR) { // Fuel flow GPH*10
noInterrupts();
v = short((multiply(fflowRate, int(10*3600L/40/2)) + (ee_settings.kFactor>>1)) / ee_settings.kFactor);
interrupts();
}
else if (p == FUELR_SENSOR) { // Fuel remaining Gallons*10 (totalizer)
noInterrupts();
v = ee_status.fuel >> 2;
interrupts();
}
else if (p == TACH_SENSOR) { // RPM's
v = average4(adcSample[12].moving) * 10;
}
else if (p < 16) {
if (longAverageByPin[p])
v = adcSample[p].accumulate/LONG_AVERAGE_LENGTH;
else
v = average4(adcSample[p].moving);
/* if (t == st_r240to33)
v = interpolate(&r240to33, v);
else */
if (t == st_thermistor)
v = interpolate(&thermistor, v);
else if (t == st_volts5)
v = multiplyAndScale(v,1000,10); // change from 0-1023 to 0-999
else if (t == st_volts1)
v = multiplyAndScale(v,5000,10); // change from 0-204 to 0-999
}
else if (p < 24) {
noInterrupts();
v = tcTemp[p-16];
interrupts();
if (t == st_j_type_tcC || t == st_j_type_tcF)
v = multiplyAndScale(v - tcTemp[8], 25599, 15) + tcTemp[8];
if (v != FAULT && (t == st_k_type_tcF || t == st_j_type_tcF))
v = (v*9)/5 + 32*4;
}
return v;
#endif
}

Expand Down
6 changes: 3 additions & 3 deletions enguino/tcTemp.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,21 @@ SIGNAL(TIMER0_COMPA_vect)
if (rawTC & 1) {
if (rawIT & 7)
tempC = FAULT;
}
}
tcTemp[ch] = tempC;

if (++ch == 8) {
tcTemp[8] = rawIT / 64; // internal temperature reduced to quarter degree C
ch = 0;
}
ms = 255; // ++ will make this 0
ms = 255; // final ++ will make this 0 for next time around

eighthSecond = true;
halfSecond++;
wholeSecond++;

if (halfSecond == 4) // every half second
updateFuelFlow();
updateFuelFlow(); // fuel flow has to be sampled at accurate intervals for accurate readings
}
ms++;
}

0 comments on commit e8aff25

Please sign in to comment.