const byte camSensorPin = 2; // Interrupt pin for cam sensor
const byte pwmPin1 = 9; // PWM output pin 1
const byte pwmPin2 = 10; // PWM output pin 2
volatile unsigned long lastToothTime = 0;
volatile unsigned long toothInterval = 0;
volatile byte toothCount = 0;
void setup() {
Serial.begin(9600);
pinMode(camSensorPin, INPUT);
pinMode(pwmPin1, OUTPUT);
pinMode(pwmPin2, OUTPUT);
attachInterrupt(digitalPinToInterrupt(camSensorPin), toothDetected, RISING);
}
void loop() {
noInterrupts();
unsigned long interval = toothInterval;
byte count = toothCount;
interrupts();
if (interval > 0) {
float crankshaftRPM = calculateCrankshaftRPM(interval, count);
Serial.println(crankshaftRPM);
// Map RPM to PWM duty cycle
int pwmValue = mapRPMToPWM(crankshaftRPM);
analogWrite(pwmPin1, pwmValue);
analogWrite(pwmPin2, pwmValue);
}
delay(100); // Adjust as needed
}
void toothDetected() {
unsigned long currentTime = micros();
toothInterval = currentTime - lastToothTime;
lastToothTime = currentTime;
// Increment tooth count and reset if it exceeds 4
toothCount++;
if (toothCount > 4) {
toothCount = 1;
}
}
float calculateCrankshaftRPM(unsigned long interval, byte count) {
// Example calculation assuming specific configuration
float timeBetweenTeeth;
switch (count) {
case 1: // Tooth 1 (reference tooth)
case 3: // Tooth 3 (opposite to tooth 1)
timeBetweenTeeth = interval; // Regular intervals for teeth 1 and 3
break;
case 2: // Tooth 2 (60 degrees from tooth 1)
case 4: // Tooth 4 (60 degrees from tooth 3)
timeBetweenTeeth = interval / (360.0 / 60.0); // Adjust for 60 degree positioning
break;
default:
timeBetweenTeeth = interval; // Default case
}
// Conversion to crankshaft RPM: (1000000 / interval) * 60 / number of teeth per revolution
// Here, we multiply by 2 because the crankshaft speed is twice the camshaft speed.
return (1000000.0 / timeBetweenTeeth) * 60 / 4 * 2;
}
int mapRPMToPWM(float rpm) {
// Map RPM to PWM duty cycle (0-255)
int pwmValue = map(rpm, 0, 4000, 242, 102); // 95% of 255 is 242, 40% of 255 is 102
pwmValue = constrain(pwmValue, 102, 242); // Ensure the value stays within the valid range
return pwmValue;
}
[code]