#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define CKP_PIN 8
#define CMP_PIN 9
#define POT_PIN A0
#define BUTTON_LEFT 2
#define BUTTON_RIGHT 3
const char* pulseMenus[] = {"Mitsubishi", "Toyota", "Daihatsu"};
int menuIndex = 0;
int rpm = 0;
unsigned long previousMillis = 0;
const byte mitsubishiCKP[] = {1, 0, 1, 0, 1, 0, 1, 0};
const byte mitsubishiCMP[] = {1, 0, 0, 0, 1, 0, 0, 0};
const byte toyotaCKP[] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0};
const byte toyotaCMP[] = {1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const byte daihatsuCKP[] = {1, 0, 1, 0, 1, 0, 1, 0};
const byte daihatsuCMP[] = {1, 0, 0, 0, 1, 0, 0, 0};
const byte* currentCKP;
const byte* currentCMP;
int currentCKPLength;
int currentCMPLength;
void setup() {
pinMode(CKP_PIN, OUTPUT);
pinMode(CMP_PIN, OUTPUT);
pinMode(BUTTON_LEFT, INPUT_PULLUP);
pinMode(BUTTON_RIGHT, INPUT_PULLUP);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
attachInterrupt(digitalPinToInterrupt(BUTTON_LEFT), scrollLeft, FALLING);
attachInterrupt(digitalPinToInterrupt(BUTTON_RIGHT), scrollRight, FALLING);
selectMenu(menuIndex);
}
void loop() {
int potValue = analogRead(POT_PIN);
rpm = map(potValue, 0, 1023, 0, 12000);
unsigned long currentMillis = millis();
displayInfo();
if (rpm == 0) {
digitalWrite(CKP_PIN, LOW);
digitalWrite(CMP_PIN, LOW);
return;
}
int period = 60000 / rpm; // period in ms for one cycle at the given RPM
int stepTime = period / currentCKPLength;
if (currentMillis - previousMillis >= stepTime) {
previousMillis = currentMillis;
static int step = 0;
digitalWrite(CKP_PIN, currentCKP[step]);
digitalWrite(CMP_PIN, currentCMP[step % currentCMPLength]);
step = (step + 1) % currentCKPLength;
}
}
void displayInfo() {
display.clearDisplay();
display.setCursor(0, 0);
display.print("RPM: ");
display.print(rpm);
display.setCursor(0, 20);
display.print("Menu: ");
display.print(pulseMenus[menuIndex]);
display.display();
}
void selectMenu(int index) {
switch (index) {
case 0:
currentCKP = mitsubishiCKP;
currentCMP = mitsubishiCMP;
currentCKPLength = sizeof(mitsubishiCKP);
currentCMPLength = sizeof(mitsubishiCMP);
break;
case 1:
currentCKP = toyotaCKP;
currentCMP = toyotaCMP;
currentCKPLength = sizeof(toyotaCKP);
currentCMPLength = sizeof(toyotaCMP);
break;
case 2:
currentCKP = daihatsuCKP;
currentCMP = daihatsuCMP;
currentCKPLength = sizeof(daihatsuCKP);
currentCMPLength = sizeof(daihatsuCMP);
break;
}
}
void scrollLeft() {
menuIndex = (menuIndex - 1 + 3) % 3;
selectMenu(menuIndex);
}
void scrollRight() {
menuIndex = (menuIndex + 1) % 3;
selectMenu(menuIndex);
}