Skip to content

Commit

Permalink
tachometer added
Browse files Browse the repository at this point in the history
  • Loading branch information
tomcourt authored and tomcourt committed Jul 5, 2017
1 parent 85fdc77 commit 7a1176b
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 75 deletions.
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,22 @@ The supply is rated for 1000 ma. The Leonardo uses 82 mA (confirmed by testing).

**Leonardo Pins Mapping to ATmega 32U4**

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

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.

Expand Down Expand Up @@ -147,7 +147,7 @@ The tachometer measures RPM by recording the uS time whenever the pin has a risi

The auxiliary display consists of two lines of a 4 digit [7 segment LED displays]. Limited text would be shown on the s. Some letters are displayed in the wrong case, for example 't' instead of 'T'. The letters 'M', 'W' and 'X' can not be displayed in an any form. Others like 'V' end up looking the same as 'U'.

A caution/warning [bicolor LED] is reworked by soldering onto the 'colon' column of the top display. Red - warning(fix it now or land), yellow - alert(look into it before it becomes a problem), green - ok.
A caution/warning [bicolor LED] is reworked by soldering onto the 'colon' column of the top display. Red - warning(fix it now or land), yellow - alert(look into it before it becomes a problem), green - ok. The center of the LED goes to pin 7 (the colon's column), red (the flat side) to pin 4 (c segment), green to pin 2 (d segment). Display pins are in DIP order, from the display side, pins 1-7 along the bottom are in reading order, 8-14 in reverse order across the top.

An acknowledge pushbutton is also part of the display.

Expand Down Expand Up @@ -195,14 +195,14 @@ To prevent having to re-acknowledge warnings there would be both temporal and ra
* .025 square breakaway headers - Digikey 929834-04-36-ND (tin) or 929647-04-36-ND (gold) - will probably work well on the thermocouple board w/o a header extension.
* jack for auxiliary display 6 pin - Digikey 455-2271-ND
* header for auxiliary display 6 pin - Digikey 455-2218-ND
* contacts for header x 10 - Digikey 455-1135-1-ND
* 10 contacts for header - Digikey 455-1135-1-ND
* pushbutton switch - Digikey EG2015-ND
* K style thermocouple wire, 24-26 gauge, EBay
* Enclosure - Electrical box - B108R - Home Depot

### Future stuff
* Record engine data by having the Engiuno pipe text to a port on the Stratux. The startup script on the stratux starts netcat (nc) in the background to record the text to a file. The script would also truncate the file at on powerup to limit its growth.
* It may be possible to support 2 thermocouples without the thermocouple multiplexer shield by using the differential mode ADC, 40x gain and a thermistor. Only 8 bits are usable (the noisy lower bits help with oversampling though) with 40x. 488 uV per count works out to 21.5 deg. F resolution with a K type thermocouple. The 2.56 volt internal reference would double the resolution and oversampling could probably quadruple it (16x oversample).
* It may be possible to support 2 thermocouples without the thermocouple multiplexer shield by using the differential mode ADC, 40x gain and a thermistor. Only 8 bits are usable with 40x, the noisy lower bits help with oversampling though. 488 uV per count works out to 21.5 deg. F resolution with a K type thermocouple. The 2.56 volt internal reference would double the resolution and oversampling could probably quadruple it (16x oversample).
* The Arduino Yun would support airplanes lacking a Stratux. The code would need to use the 'bridge' objects instead of the ethernet objects. Use #ifdef AVR_YUN to flex the code.
* Themes - a dark theme could be created easily enough by adjusting the styles. A larger text theme for the gauges would involve more defines and stringizing them for the SVG.
* Warning lights instead of auxillary display? A board with 4 caution/warning LEDs (red/green common cathode [bicolor LED]). Turning red and green on produces yellow. Alternatively use a module like the [BOB-13884] to provide 3 RGB LED's.
Expand Down
8 changes: 4 additions & 4 deletions enguino/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const char *red = "red";
#define GMX(range) (int)(1000.0 / (range) * (1<<divisor) + 0.5)
#define GB(low) (int)(-((low) + 0.5))
#define ADCtoDivV (5.0/1023.0) // multiply this by adc input to get DC volts
#define ADCtoV10 (57 * ADCtoDivV) // Using 1:5.7 divider for now !!!
#define V10toADC (1/(57 * ADCtoDivV)) // Using 1:5.7 divider for now !!!
#define ADCtoV10 (40 * ADCtoDivV) // 1:4 voltage divider
#define V10toADC (1/(40 * ADCtoDivV)) // 1:4 voltage divide

// Sensor defintions and scaling
// -----------------------------
Expand All @@ -29,7 +29,7 @@ const Sensor otS = { st_thermistorF, 0, MX(.1), GB(50*10),
const Sensor vtS = { st_volts, 0, MX(ADCtoV10), GB(100*V10toADC), GMX(60*V10toADC), 0}; // 100 - 160 (10 - 16)
const Sensor fpS = { st_r240to33, 0, MX(0.1), 0, MX(1.0), 3}; // 0 - 100 (0 - 10)
const Sensor flS = { st_r240to33, 0, MX(0.16), 0, MX(1.0), 4}; // 0 - 160 (0 - 16)
const Sensor taS = { st_tachometer, 0, 12000, 0, 8008, -1}; // 0 - 3000
const Sensor taS = { st_tachometer, 0, MX(1.), 0, GMX(3000), 15}; // 0 - 3000
const Sensor maS = { st_volts, 100, 2000, 0, 8008, -1}; // 100 - 350 (10 - 35)
const Sensor chS = { st_k_type_tcF, 0, MX(.25), GB(100*4), GMX(400*4), 16}; // 100 - 500, input is .25 deg. F
const Sensor egS = { st_k_type_tcF, 0, MX(.25), GB(1000*4), GMX(600*4), 20}; // 1000 - 1600,input is .25 deg. F
Expand Down Expand Up @@ -88,6 +88,6 @@ const Gauge gauges[] = {
{100, 3200, gs_round, 1, "MP", "", "in-hg", 0, 0, 0, maRC, maRP, N(maRC), &maS},
{2950, 6150, gs_horiz, 0, "CHT", "", "", chLV, chLP, N(chLV), chRC, chRP, N(chRC), &chS},
{2950, 6150, gs_aux, 0, "EGT", "", "", egLV, egLP, N(egLV), 0, 0, 0, &egS},
{300, 6150, gs_infobox,0, "", "", "", 0, 0, 0, 0, 0, 0, 0}
{300, 6750, gs_infobox,0, "", "", "", 0, 0, 0, 0, 0, 0, 0}
};

53 changes: 42 additions & 11 deletions enguino/enguino.ino
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ int peakEGT[4];
byte hobbsCount = 90;
bool engineRunning;

volatile unsigned long lastTachTime;
volatile bool tachDidPulse;
volatile int rpm[4];
volatile byte rpmP;

// Performance 'print' functions to ethernet 'client' (includes flush)
#include "printEthernet.h"

Expand Down Expand Up @@ -96,7 +101,15 @@ int readSensor(const Sensor *s, byte n = 0) {

int t = s->type;
int toF = 0;
if (p < 16) {
if (p == 15) {
// RPM's are occasionaly screwed up because of IRQ latency.
// Throw out highest and lowest and average the middle 2
noInterrupts();
sort(rpm, sizeof(rpm)/sizeof(int));
v = (rpm[1]+rpm[2])>>1;
interrupts();
}
else if (p < 16) {
v = analogRead(p);
if (t == st_r240to33)
v = interpolate(&r240to33, v);
Expand Down Expand Up @@ -126,17 +139,17 @@ void serveUpWebPage(char url, char var, word num) {
switch(url) {
case '?': // lean/cancel/ button pressed or return from setup
switch (var) {
case 'l':
case 'l': // lean mode
leanMode = !leanMode;
if (leanMode)
memset(peakEGT,0,sizeof(peakEGT));
break;
case 'a':
case 'a': // add fuel
ee_status.fuel += num<<2;
if (ee_status.fuel > ee_settings.fullFuel)
ee_status.fuel = ee_settings.fullFuel;
goto eeStatus;
case 'h':
case 'h': // set hobbs
ee_status.hobbs1k = 0;
while (num >= 10000) {
num -= 10000;
Expand All @@ -146,10 +159,10 @@ void serveUpWebPage(char url, char var, word num) {
eeStatus:
eeUpdateStatus();
break;
case 'f':
case 'f': // set full fuel
ee_settings.fullFuel = num<<2;
goto eeSettings;
case 'k':
case 'k': // set k-factor
ee_settings.kFactor = num;
eeSettings:
eeUpdateSettings();
Expand All @@ -170,6 +183,14 @@ eeSettings:
}


void tachIRQ() {
unsigned long newTachTime = micros();
rpm[rpmP++ & 3] = (60000000L/24) / (newTachTime - lastTachTime);
lastTachTime = newTachTime;
tachDidPulse = true;
}



void setup() {
// Serial.begin(9600);
Expand All @@ -178,11 +199,14 @@ void setup() {

eeInit();
tcTempSetup();
// setup LED last to allow 1mS for HT16K33
printLEDSetup();
printLED(0,LED_TEXT(h,o,b,b));
printLED(1,ee_status.hobbs,1); // replace this with a value read from EEPROM
delay(1000); // replace this with LED self test sequence

delay(1000);
printLED(0,ee_status.hobbs>>2,1);
delay(1000);

attachInterrupt(digitalPinToInterrupt(2),tachIRQ,RISING);
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Expand Down Expand Up @@ -252,9 +276,16 @@ void loop() {
// close the connection:
client.stop();
}

if (eighthSecondCount >= 8) {
engineRunning = scaleValue(&vtS, readSensor(&vtS)) > 130; // greater than 13.0 volts means engine is running
if (tachDidPulse)
tachDidPulse = false;
else
memset(rpm, 0, sizeof(rpm));
engineRunning = scaleValue(&vtS, readSensor(&vtS)) > 130 || rpm > 0; // greater than 13.0 volts means engine is running

printLED(0,scaleValue(&taS, readSensor(&taS)),0);
// printLEDFuel(scaleValue(&flS, readSensor(&flS,0)), scaleValue(&flS, readSensor(&flS,1)));

if (engineRunning) {
if (--hobbsCount == 0) {
Expand Down
75 changes: 40 additions & 35 deletions enguino/printLED.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// lookup port mapping to pins here: https://www.arduino.cc/en/Reference/PortManipulation
#define SCL_PIN 7
#define SCL_PORT PORTB
#define SDA_PIN 0
#define SDA_PORT PORTD
#define SCL_PIN 0
#define SCL_PORT PORTD
#define SDA_PIN 7
#define SDA_PORT PORTB
#define I2C_SLOWMODE 1
#define I2C_TIMEOUT 10
#include "SoftI2CMaster.h"

Expand All @@ -17,16 +18,12 @@

#define HT16K33_CMD_BRIGHTNESS 0xE0
#define HT16K33_BRIGHT_MAX (HT16K33_CMD_BRIGHTNESS | 15)
#define HT16K33_BRIGHT_MIN (HT16K33_CMD_BRIGHTNESS | 1)
#define HT16K33_BRIGHT_MIN (HT16K33_CMD_BRIGHTNESS | 0)

#define SEVENSEG_DIGITS 5
#define COLON_LIT 2

#define I2C_ADDRESS 0x70 // second line is 0x71

static const byte digittable[] = { 2, 4, 8, 10 }; // skip the colon
#define I2C_ADDRESS (0x70<<1) // second line is 0x71

// segments are aranged as follows (values are hexadecimal)
//
// +--- 1 ---+
// | |
// 20 2
Expand All @@ -52,7 +49,6 @@ static const byte digittable[] = { 2, 4, 8, 10 }; // skip the colon

#define LED_DP 0x80 // decimal point
#define LED__ 0x40 // minus sign
#define LED_COLON 2

#define LED_A 0x77
#define LED_b 0x7c
Expand All @@ -71,16 +67,23 @@ static const byte digittable[] = { 2, 4, 8, 10 }; // skip the colon
#define LED_t 0x78
#define LED_U 0x3e

static const byte numbertable[] = { LED_0, LED_1, LED_2, LED_3, LED_4, LED_5, LED_6, LED_7, LED_8, LED_9 };
static const byte addressDigit[] = { 1, 3, 7, 9 }; // skip the colon
static const byte characterMap[] = { LED_0, LED_1, LED_2, LED_3, LED_4, LED_5, LED_6, LED_7, LED_8, LED_9 };

static byte ledBuffer[11]; // first byte is 0 for the address, 2 is first digit, 4 the second, etc.

byte colon; // used for showing alarm status by wiring a red/green LED onto the colon column
#define LED_COLON 2
#define STATUS_ALARM 0x4
#define STATUS_CAUTION 0xC
#define STATUS_NORMAL 0x8

void writeI2C(byte line, byte *buffer, byte len) {
if (!i2c_start((I2C_ADDRESS + line) | I2C_WRITE))
if (!i2c_start((I2C_ADDRESS | (line<<1)) | I2C_WRITE))
return;
while (len--) {
if (!i2c_write(*buffer++))
return false;
return;
}
i2c_stop();
}
Expand All @@ -91,22 +94,24 @@ void commandLED(byte line, byte command) {
}

void writeLED(byte line) {
writeI2C(line, buffer, 11);
writeI2C(line, ledBuffer, 11);
}

void printLEDRawDigits(byte offset, word val) {
while (--offset) {
ledBuffer[digittable[offset]] = numbertable[val%10];
while (offset--) {
ledBuffer[addressDigit[offset]] = characterMap[val%10];
val /= 10;
if (val == 0)
break;
}
}

// Number is clipped at 999 and has a decimal point at 1.
// Numbers greater than 99 are displayed whole, smaller in tenths
void printLEDRawHalfDigits(byte offset, word number) {
if (number == FAULT) {
ledBuffer[digittable[offset-1]] = LED__;
ledBuffer[digittable[offset-2]] = LED__;
ledBuffer[addressDigit[offset-1]] = LED__;
ledBuffer[addressDigit[offset-2]] = LED__;
}
else {
if (number < 0)
Expand All @@ -115,7 +120,7 @@ void printLEDRawHalfDigits(byte offset, word number) {
number = 999;
if (number < 100) {
printLEDRawDigits(offset, number);
ledBuffer[digittable[offset-2]] |= LED_DP; // decimal point
ledBuffer[addressDigit[offset-2]] |= LED_DP; // decimal point
}
else
printLEDRawDigits(offset, number/10);
Expand All @@ -127,7 +132,7 @@ void printLEDRawHalfDigits(byte offset, word number) {
void printLEDSetup() {
i2c_init();

for (byte line=0; line<2; line++) {
for (byte line=0; line<1; line++) {
commandLED(line, HT16K33_OSCILATOR_ON);
commandLED(line, HT16K33_BLINK_OFF);
commandLED(line, HT16K33_BRIGHT_MAX);
Expand All @@ -136,21 +141,21 @@ void printLEDSetup() {

// print a text message to the LED on line 0 or 1
void printLED(byte line, byte a, byte b, byte c, byte d) {
ledBuffer[2] = a;
ledBuffer[4] = b;
ledBuffer[6] = 0; // turn colon off
ledBuffer[8] = c;
ledBuffer[10] = d;
ledBuffer[1] = a;
ledBuffer[3] = b;
ledBuffer[5] = colon; // turn colon off
ledBuffer[7] = c;
ledBuffer[9] = d;
writeLED(line);
}

// print a text message to the LED on line 0 or 1
void printLED(byte line, byte *txt) {
ledBuffer[2] = txt[0];
ledBuffer[4] = txt[1];
ledBuffer[6] = 0; // turn colon off
ledBuffer[8] = txt[2];
ledBuffer[10] = txt[3];
ledBuffer[1] = txt[0];
ledBuffer[3] = txt[1];
ledBuffer[5] = colon; // turn colon off
ledBuffer[7] = txt[2];
ledBuffer[9] = txt[3];
writeLED(line);
}

Expand All @@ -159,8 +164,8 @@ void printLEDFuel(int left, int right) {
memset(ledBuffer, 0, sizeof(ledBuffer));
printLEDRawHalfDigits(4, right);
printLEDRawHalfDigits(2, right);
ledBuffer[6] = LED_COLON;
writeLED(1);
ledBuffer[5] = LED_COLON;
writeLED(1);
}

// print the 'number' to 'line' 0 or 1, place a decimal point 'decimal' digits to the left
Expand All @@ -176,7 +181,7 @@ void printLED(byte line, int number, byte decimal) {
memset(ledBuffer, 0, 11);
printLEDRawDigits(4, number);
if (decimal != 0)
ledBuffer[digittable[3-decimal]] |= LED_DP;
ledBuffer[addressDigit[3-decimal]] |= LED_DP;
}
writeLED(line);
}
Expand Down
10 changes: 5 additions & 5 deletions enguino/printWeb.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ void printHomePage() {
"<script type='text/javascript'>\n"
"function ajax(u) {\n"
"var xhttp = new XMLHttpRequest();\n"
"xhttp.open('GET',u,true);\n"
"xhttp.onreadystatechange = function() {\n"
"if (this.readyState == 4 && this.status == 200) {\n"
"document.getElementById('dyn').innerHTML =\n"
"this.responseText;\n"
"}\n"
"if (this.readyState == 4 && this.status==200)\n"
"document.getElementById('dyn').innerHTML=this.responseText;\n"
"};\n"
"xhttp.open('GET', u, true);\n"
"xhttp.ontimeout = function() { xhttp.abort() };\n"
"xhttp.timeout=900;\n"
"xhttp.send();\n"
"}\n"
"setInterval(function(){ajax('d')}, 1000);\n"
Expand Down
Loading

0 comments on commit 7a1176b

Please sign in to comment.