Skip to content

Instantly share code, notes, and snippets.

@Nikita240
Last active November 25, 2022 06:36
Show Gist options
  • Save Nikita240/5181eaed3e5dc2705c78edc335abc453 to your computer and use it in GitHub Desktop.
Save Nikita240/5181eaed3e5dc2705c78edc335abc453 to your computer and use it in GitHub Desktop.
arduino-tachometer
#include <Adafruit_NeoPixel.h>
const int LED_PIN = 6;
const int TACH_PIN = 2;
const int BRIGHTNESS = 100;
const int LED_COUNT = 80;
const int REDLINE = 7500;
const int WARN_RPM = 6000;
const int WARN_INTERVAL = 70;
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino LED_PIN number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.
bool blinkState = true;
unsigned long lastBlinkUpdate = 0;
volatile unsigned long lastIgnitionTime = 0;
void recordIgnition() {
detachInterrupt(digitalPinToInterrupt(TACH_PIN));
lastIgnitionTime = millis();
attachInterrupt(digitalPinToInterrupt(TACH_PIN), calculateRpm, RISING);
}
void calculateRpm() {
detachInterrupt(digitalPinToInterrupt(TACH_PIN));
unsigned long ignitionTimeDelta = millis() - lastIgnitionTime;
int rpm = 1000.0 / ignitionTimeDelta * 60 *2;
Serial.print("RPM: ");
Serial.println(rpm);
setRpm(rpm);
attachInterrupt(digitalPinToInterrupt(TACH_PIN), recordIgnition, RISING);
}
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
pinMode(TACH_PIN, INPUT);
strip.begin();
strip.setBrightness(BRIGHTNESS);
strip.show(); // Initialize all pixels to 'off'
attachInterrupt(digitalPinToInterrupt(TACH_PIN), recordIgnition, RISING);
}
void loop() {
}
void setRpm(int rpm) {
int rpmPerLed = REDLINE / LED_COUNT;
//blink for warn function
if(rpm >= WARN_RPM) {
unsigned long currentTime = millis();
if(currentTime - lastBlinkUpdate > WARN_INTERVAL) {
lastBlinkUpdate = currentTime;
blinkState = !blinkState;
}
}
else
blinkState = true;
for(int led = 0; led < LED_COUNT; led++) {
if(!blinkState && (led+2)*rpmPerLed > WARN_RPM) {
strip.setPixelColor(led, 0, 0, 0);
continue;
}
if((led+1)*rpmPerLed <= rpm)
strip.setPixelColor(led, getColor((led+1)*rpmPerLed, 1));
else if(led*rpmPerLed < rpm && (led+1)*rpmPerLed > rpm) {
strip.setPixelColor(led, getColor(rpm, (double)(rpm-(led)*rpmPerLed)/rpmPerLed));
}
else
strip.setPixelColor(led, 0, 0, 0);
}
strip.show();
}
uint32_t getColor(int rpm, double intensity) {
int red = rpm/(double)REDLINE * 255 * intensity;
int green = (1-rpm/(double)REDLINE) * 255 * intensity;
int blue = 0;
return strip.Color(red, green, blue);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment