forked from deepsyx/arduino-tachometer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTach.ino
168 lines (130 loc) · 4.2 KB
/
Tach.ino
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
/* Display */
#include <Arduino.h>
#include <TM1637Display.h>
#define CLK 5
#define DIO 6
TM1637Display display(CLK, DIO);
/*
const uint8_t SEG_DONE[] = {
SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // O
SEG_C | SEG_E | SEG_G, // n
SEG_A | SEG_D | SEG_E | SEG_F | SEG_G // E
};
*/
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 };
/*
SIMPLE ARDUINO CAR TACHOMETER
*/
const int DATA_PIN = 4;
const int LED_GROUND_PIN = 8; // pin to use as negative for LEDs
// Vtec solenoid control pin (relay control)
const int VTEC_PIN = 3;
const int PINS_COUNT = 4; // set ammount of LEDs
const int LED_PINS[PINS_COUNT] = {9, 10, 11, 12}; // pins accociated to LEDs
const int LED_SWITCH_RPM[PINS_COUNT] = {1000, 1500, 2000, 2500}; // rpm at which turn on LED
const int REV_LIMITER_RPM = 3000; // turns on all LEDs "Shift light"
const int VTEC_RPM = 3500; // rpm at which engage VTEC relay
const int NUMBER_OF_CYLINDERS = 4;
const int LED_UPDATE_INTERVAL = 200;
/*
Last led state update time in ms, used to calculate the time from last update
*/
unsigned long lastUpdateTime = 0;
/*
Amount of spark fires in a single interval
*/
volatile int sparkFireCount = 0;
/*
Rpm value from last update
Used to average the last 2 rpms for smoother output
*/
int lastRpmValue = 0;
/*
Blinking rev limiter state
*/
bool revLimiterOn = true;
/*
*/
void incrementRpmCount () {
sparkFireCount++;
}
/*
Turns all leds on or off
*/
void setGlobalState(bool state) {
for (int i = 0; i < PINS_COUNT; i++) {
digitalWrite(LED_PINS[i], state);
}
}
/*
Turn on leds, based on input rpm
*/
void setLedState(int rpm) {
setGlobalState(LOW);
digitalWrite(VTEC_PIN,LOW);
// If rpm is over REV_LIMITER_RPM, all leds should be blinking at 200ms interval
if (rpm > REV_LIMITER_RPM) {
if (revLimiterOn) {
setGlobalState(LOW);
} else {
setGlobalState(HIGH);
}
revLimiterOn = !revLimiterOn;
return;
}
for (int i = 0; i < PINS_COUNT; i++) {
if (rpm > LED_SWITCH_RPM[i]) {
digitalWrite(LED_PINS[i], HIGH);
}
}
//-----------------------------------------------------
if (rpm < VTEC_RPM) {
digitalWrite(VTEC_PIN,HIGH);
}
}
/*
Defines led pins as output,
turns all leds on for 500ms when started
attach to serial if available
*/
void setup() {
// Define all led pins as outputs
for (int i = 0; i < PINS_COUNT; i++) {
pinMode(LED_PINS[i], OUTPUT);
}
pinMode(LED_GROUND_PIN, OUTPUT);
digitalWrite(LED_GROUND_PIN, LOW); // Use pin 8 as ground for the leds
setGlobalState(HIGH);
delay(500);
setGlobalState(LOW);
pinMode(DATA_PIN, INPUT_PULLUP);
attachInterrupt(1, incrementRpmCount, FALLING);
Serial.begin(9600);
pinMode(VTEC_PIN,OUTPUT);
}
// 4 stroke engine fires every spark in 2 revolutions
// so calculate at what degree interval sparks fires and divide 360 by it,
// to find the number of fires per rotation
const int FIRES_PER_REV = (360 / (720 / NUMBER_OF_CYLINDERS));
void loop() {
if ((millis() - lastUpdateTime) > LED_UPDATE_INTERVAL) {
// multiply the amount the spark fires in one interval by the number of intervals per
// second, to find the amount in one second
// then multiply the amount in one second by 60, to find the spark fires in one minute and
// divide the result by the number of fires per revolution to find the rpm
int currentRpm = (sparkFireCount * (1000 / LED_UPDATE_INTERVAL) * 60) / FIRES_PER_REV;
// average the current and last rpm for smoother results
int averagedRpm = (currentRpm + lastRpmValue) / 2;
setLedState(averagedRpm);
Serial.println(averagedRpm);
sparkFireCount = 0;
lastUpdateTime = millis();
lastRpmValue = currentRpm;
// Output rpm value on screen
display.setBrightness(0x0f);
display.showNumberDec(averagedRpm);
//delay(500);
}
}