Here is one way to code it. By putting the three sensor bits into a single number you get a single number that represents the current gear. It is then easy to act only on gear changes by comparing the current gear to the previous gear. The single number can also be used for a look-up table of gear names.
// Arduino Nano-based manual gear shifter detector & display using the TM1637 7-Segment LED module.
// 3x A3144 Hall Effect Sensors are connected via pins 2, 3 & 12, and when a magnet/s is present,
// will display gear One (pin 2), Gear Two (pin 3), Gear Three (pin 12), Gear Four (Pins 2 & 12),
// Gear Five (Pins 3 & 12), and Reverse (pins 2 & 3) - otherwise Neutral is displayed.
#include <TM1637Display.h>
const int CLK = 5; // Set the CLK pin connection to the display
const int DIO = 4; // Set the DIO pin connection to the display
const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00}; // Declares the value of "blank"
const uint8_t data[] = {0xff, 0xff, 0xff, 0xff}; // Declares "data" as all segments on
const uint8_t n[] = // Required segments to display the character "n"
{
SEG_C | SEG_E | SEG_G
};
const uint8_t r[] =
{
SEG_E | SEG_G
}; // Required segments to display the character "r"
TM1637Display display(CLK, DIO); //set up the 4-Digit Display.
// int TM1637Display(CLK, DIO);
const int FirstGearPin = 2;
const int SecondGearPin = 3;
const int UpperGearsPin = 12;
const int ledPin7 = 7;
const int ledPin8 = 8;
const int ledPin9 = 9;
const char * GearNames[8] =
{
"Neutral", // 0
"First Gear", // 1 (FirstGearPin)
"Second Gear", // 2 (SecondGearPin)
"Reverse", // 3 (FirstGearPin + SecondGearPin)
"Third Gear", // 4 (UpperGearsPin alone)
"Fourth Gear", // 5 (FirstGearPin + UpperGearsPin)
"Fifth Gear", // 6 (SecondGearPin + UpperGearsPin)
"INVALID" // 7 (FirstGearPin + SecondGearPin + UpperGearsPin)
};
enum Gears {Neutral, First, Second, Reverse, Third, Fourth, Fifth};
int counter = 0;
void setup()
{
Serial.begin(9600); // Setup serial monitor
pinMode(FirstGearPin, INPUT);
pinMode(SecondGearPin, INPUT);
pinMode(UpperGearsPin, INPUT);
pinMode(ledPin7, OUTPUT);
pinMode(ledPin8, OUTPUT);
pinMode(ledPin9, OUTPUT);
display.clear();
display.setBrightness(7); // Set the diplay to maximum brightness
display.setSegments(blank); // Clear display
}
void DisplayGear(enum Gears gear)
{
// Set the LEDs to match the sensor inputs.
digitalWrite(ledPin7, gear & 1);
digitalWrite(ledPin8, gear & 2);
digitalWrite(ledPin9, gear & 4);
printMessage(GearNames[gear]);
display.clear();
switch (gear)
{
case Neutral:
display.setSegments(n, 1, 3);
break;
case First:
case Second:
display.showNumberDec(gear, false, 4);
break;
case Reverse:
display.setSegments(r, 1, 3);
break;
case Third:
case Fourth:
case Fifth:
display.showNumberDec(gear - 1, false, 4);
break;
default:
break;
}
}
void loop()
{
static byte previousGear = 7;
byte currentGear = (digitalRead(FirstGearPin) == LOW)
+ ((digitalRead(SecondGearPin) == LOW) << 1)
+ ((digitalRead(UpperGearsPin) == LOW) << 2);
if (currentGear == previousGear)
return; // Nothing to do if the gear has not changed
previousGear = currentGear;
DisplayGear((enum Gears)currentGear);
}
void printMessage(String message)
{
counter++;
Serial.print(counter);
Serial.print(" ");
Serial.println(message);
//delay(200);
}