diff --git a/ArduinoFreevalve/ArduinoFreevalve.ino b/ArduinoFreevalve/ArduinoFreevalve.ino new file mode 100644 index 0000000..7b6bc10 --- /dev/null +++ b/ArduinoFreevalve/ArduinoFreevalve.ino @@ -0,0 +1,83 @@ +// An Arduino program for controlling valve timing on a 6.5HP Predator engine from Harbor Freight. +// +// License goes here. +// +// Wesley Kagan, 2020 +// Ric Allinson, 2020 + +// Pins assignment. +static const int HALL_MAGNET = 2; +static const int ROTATION_MAGNET = 3; +static const int EXHAUST_V = 12; +static const int INTAKE_V = 13; + +// Implementation constants (to be changed by implementer). +static const int NUM_STEPS = 60; + +// Control constants. +static const int STEPS_PER_ROTATION = NUM_STEPS - 1; // Number of interrupts in a half cycle for a zero based array. +static const int STEPS_PER_CYCLE = NUM_STEPS * 2; // Number of interrupts in the full cycle. + +// Runtime mapping variables. +bool intakeMap[STEPS_PER_CYCLE] = {}; // Intake open/close mapping is equal the total number of interrupts for two rotations. +bool exhaustMap[STEPS_PER_CYCLE] = {}; // Exhaust open/close mapping is equal the total number of interrupts for two rotations. + +// ISR variables. +volatile int hallCounter = 0; // The number of magnets after the last TDC. +volatile bool secondCycle = false; // "true" if the cam is on its second rotation. +volatile bool printLog = false; // Used to stop duplicate values from printing in the loop. + +void setup() { + Serial.begin(115200); + pinMode(HALL_MAGNET, INPUT); + attachInterrupt(0, rotationDetect, RISING); + attachInterrupt(1, magnetDetect, RISING); + pinMode(INTAKE_V, OUTPUT); + pinMode(EXHAUST_V, OUTPUT); + /* + Load mappings here. + */ + // intakeMap = ? + // exhaustMap = ? +} + +void loop() { + // This may not print the correct values. Only the most recent from the last magnetDetect() interrupt. + if(printLog){ + Serial.print(hallCounter); + Serial.println(secondCycle); + printLog = false; + } +} + +// This function is called once per rotation. +void rotationDetect() { + if (secondCycle) { + hallCounter = 0; // On the second cycle reset the hallCounter. + } else { + hallCounter = STEPS_PER_ROTATION; // Forcing the counter in case of drift over a rotation. + } + // Flip the secondCycle flag. + secondCycle = !secondCycle; +} + +// This function is called NUM_STEPS per rotation. +// This function will be called about every ~263.16usec at the maximum RPM of 3800. +// (1 rev / 60 pulses) * (1 min / 3800 rev) * (60 sec / min) = 1 / 3800 sec/pulse = ~263.16usec. +void magnetDetect() { + // Increment the counter to keep track of the position. + hallCounter++; + + // If the hallCounter is greater than the mapping index reset it. + // This would only happen when the rotationDetect() interrupt was NOT triggered. + if (hallCounter >= STEPS_PER_CYCLE) { + hallCounter = 0; + } + + // Use the intake/exhaust maps to open or close the valves. + digitalWrite(INTAKE_V, intakeMap[hallCounter]); + digitalWrite(EXHAUST_V, exhaustMap[hallCounter]); + + // Tells the loop() that the ISR variables have changed. + printLog = true; +} diff --git a/ArduinoHallEffect_good_code.ino b/ArduinoHallEffect_good_code.ino deleted file mode 100644 index 998dabe..0000000 --- a/ArduinoHallEffect_good_code.ino +++ /dev/null @@ -1,71 +0,0 @@ -//This code is full of test strings and is generally a conglomerate of code from stackexchange and -//bad form. If it looks stupid, I probably wrote it. -//Wesley Kagan, 2020 - -const int hall = 2; -int hallcounter = 0; -int hallstate = 0; -int lasthallstate = 0; -unsigned long triggerTime; -unsigned long last_triggerTime; -unsigned long timeGap; -unsigned long last_timeGap; -unsigned int degree; -unsigned int state; -int newstate; - - -void setup() { - pinMode(hall, INPUT); - Serial.begin(115200); - pinMode(13, OUTPUT); // sets the digital pin 13 as output - pinMode(12, OUTPUT); // sets the digital pin 12 as output - attachInterrupt(0, magnet_detect, RISING);//Initialize the intterrupt pin digital pin 2 - degree = 0; -} - - void loop() - { - //The compiler says this is needed otherwise the govt. takes my cat - } - -void magnet_detect() { - hallcounter ++; - triggerTime = millis(); - timeGap = triggerTime - last_triggerTime; - last_triggerTime = triggerTime; - - if (timeGap >= last_timeGap + last_timeGap / 2) - { - //Serial.println(state); - Serial.println("missing tooth"); - hallcounter = 1; - state++; //This right here is garbage and you know it. - } - - last_timeGap = timeGap; - //Serial.println(hallcounter); - - degree = hallcounter * 6; - if ((state % 2) == 0) { //Bool wasn't working so this dumpster fire got started. - Serial.print("STATE 1 "); - Serial.println(degree); - if (6 <= degree && degree <= 180) { //EDIT HERE INTAKE - digitalWrite(13, HIGH); // sets the digital pin 13 on - } - else { - digitalWrite(13, LOW); // sets the digital pin 13 off - } - } - if ((state % 2) == 1) { - Serial.print("STATE 2 "); - Serial.println(degree); - if (180 <= degree && degree <= 354) { //EDIT HERE EXHAUST - digitalWrite(12, HIGH); // sets the digital pin 13 on - } - else { - digitalWrite(12, LOW); // sets the digital pin 13 off - } - } - lasthallstate = hallstate; -} diff --git a/README.md b/README.md index 7eb36a2..568ec36 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,15 @@ +# Arduino Freevalve + +Repository for the Arduino Freevalve Project at www.youtube.com/c/wesleykagan + +## Overview + +This code is tested with the [Harbor Freight 6.5hp 212cc OHC Horizontal Shaft Gas Engine EPA&CARB](https://www.harborfreight.com/engines-generators/gasoline-engines/65-hp-212cc-ohv-horizontal-shaft-gas-engine-epacarb-69727.html) + +## Original README + # Freevalve_Arduino + Codebase for the Arduino Freevalve Project- found here: www.youtube.com/c/wesleykagan Okay, so this is a super early stage of this project, but as of this post, it does work in the @@ -25,4 +36,4 @@ Website: www.wesleykagan.com For promotional inquiries: wesley.kagan@gmail.com -USE AT YOUR OWN RISK! +USE AT YOUR OWN RISK! \ No newline at end of file