Pages: 1 2 [3] 4 5 ... 9   Go Down
Author Topic: Driving Comp Air Engine with Solenoids and Arduino  (Read 7018 times)
0 Members and 1 Guest are viewing this topic.
United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It is just a 10k resistor 1/4 watt, 1/2 watt probably doesn't matter either. It is just called a pull up or pull down because of the way it is used to connect the wiring. Pull up resistor is wired to power, pull down it is wired to ground. You should be able to get about 100 10k resistors from anywhere for about $1 US. I think I even saw them at Walmart once?!
Shows u how much I know about electronics....  :-/

Thanks, I have a bunch on the way from Digikey anyways.
Logged

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
No, I don't think you are getting it.
We don't care about "RPM".
We don't care about "degrees".

The only things we care about are:
1) When is TDC?
2) How long has it been since the last TCD?  (in microseconds)
3) How far past TDC do we open solenoid x?  when do we close it? (in percentage of rotation)

By subtracting THIS TDC from the PREVIOUS TDC, we know the period of full rotation.
By knowing the percentage of rotation ("degrees" if you must) for solenoid x to open, we know how many microseconds past TDC we need to open it.
etc. etc.


Thanks I understand now. This is a completely different way of thinking then I'm used to. I will post an updated code later.
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 74
...blowing up boards one connection at a time
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... random comment - this is super interesting, thanks for keeping it public   _J
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 96
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
No, I don't think you are getting it.

I love how bitter and angry Richard gets. It's entertaining. He's why i love this forum!LOL

Logged

Resistance is Futile

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a slight worry...since I am using only one sensor, and using the time-timeold formula , technically every command to the solenoids is one rpm behind. This could be be bad if the engine rev'd up or down too quickly... Am I correct that it is in fact always one revolution delay?

This leads me to another research angle. If I were to count the magnets with the hall effect sensor it would give me more accurate readings. For example 2 magnets would give me a half rpm delay, 4 gives me a quarter.
I have learned that I can store data in the EEPROM. If I were to have 10 magnets (for example purposes) and told my sensor counter that after 10 counts reset to 1, Then after calibration I would know which magnet is TDC (for example #5). Right before shutting the arduino down, I would prompt EEPROM to store the last count. When turning the arduino back on, EEPROM will state the stored count. The arduino would pick up where it left off if the engine hasn't been touched, which would also allow it to start without any outside help. Sound feasible?
Logged

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Yes, that is true. But you still need one unique signal at TDC.  You must know BOTH speed AND position.

If your counter labeled the TDC magnet why would you need another unique signal? Your device would say that the #5 magnet (example) is always at the top of the stroke. Which as mentioned before the EEPROM would save that calibration for the next run.

Quote
Yes, that is true, but how much change do you anticipate between one revolution and another?  How much rotating mass and friction are we dealing with here? Even if you tried, you can't change the speed all that fast
There will be a lot torque generated by this engine.  Imagine that the engine is decelerating by 1 rpm but the code still says to accelerate by 1 rpm... The piston would be returning to the top of the stroke while the inlet was open. Disaster waiting to happen....
Logged

Ontario
Offline Offline
God Member
*****
Karma: 25
Posts: 887
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
decelerating by 1 rpm but the code still says to accelerate by 1 rpm

If it were turning 500 RPM at the time then you might see a 2 in 500 variation in speed from one turn to the next.  It really would be quite accurate to guess that since the last rotation actually took 2,000 microseconds, the one coming up will be within a few % of 2,000 microseconds too.

It is also only a few more lines of code to look at if the speed is trending up or down, and correct the estimated time for the upcoming rotation accordingly.

It should be possible to readily determine the position just using one position sensor and timing.
Logged

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If it were turning 500 RPM at the time then you might see a 2 in 500 variation in speed from one turn to the next.  It really would be quite accurate to guess that since the last rotation actually took 2,000 microseconds, the one coming up will be within a few % of 2,000 microseconds too.

It is also only a few more lines of code to look at if the speed is trending up or down, and correct the estimated time for the upcoming rotation accordingly.

You make an interesting point. Do you have an example of said code?


Another note, I realized I can manually start the engine without a starter motor. Since a compressed air engine has maximum torque at low RPM's I do not find it necessary to spin the engine to 500-600 rpm's just to get the sensors reading.
Since I can see the TDC with my own eyes, I can link the solenoids to 2 buttons controlling the 4 intake valves and 4 exhaust valves. Then just hit each button to get it to spin and let the arduino take over... Food for thought at least
Logged

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Maybe that is why most engines use "hardware" solutions like cam shafts?
As this is a senior design project, the mechanical systems were way out of my budget. I had one designed in a CAD program, but when it came to machining it was through the roof.

Quote
And gardner makes an excellent point about extrapolation and predictive algorithms. That is one of the nice things about using a micro-processor, you can do these kinds of things.

Since you have convinced me why not to use the eeprom method, I would like to move forward with the "extrapolation and predictive algorithms".  I have no idea how to program that.  :o I'm still learning the basics...  Any idea of how to write the code? If not how would I search for how to write the code?

Once again, you guys have been an invaluable source of help, and I thank you for that.
Logged

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry I never responded. I have been busy studying for two big exams before finals. I will research the formula's and talk to a few of my professors. Ill update you guys with the code in a few days.
Logged

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the latest update.
How do I make sure that the value of eventcount doesn't go over 1? If I'm not mistaken, with the eventcount++ it adds one to the last count, but in the ReadingRPM Playground, it acts like after 20 it resets. With my statement of if(eventcount >= 1) will that limit it to 1 and only 1?  Do I even need to include eventcount in my (time-timeold)/eventcount  if its always one?
Code:
///
///
///
///

//-----------------------------------------------
 volatile unsigned int eventcount; // Assinging the Count Feature
 unsigned int rt; // Rotation Time
 unsigned int degree; // Position of Piston
 unsigned int rpm; // RPM
 unsigned long timeold; // Previous time Hall Sensor Picked up
 const int So17Pin = 3; // Solenoids 1 and 7 assigned to Pin 3
 const int So35Pin = 4; // Solenoids 3 and 5 assigned to Pin 4
 const int So28Pin = 5; // Solenoids 2 and 8 assigned to Pin 5
 const int So46Pin = 6; // Solenoids 4 and 6 assigned to Pin 6
 const int buttonPin = 13; // Button For Switching "Valve Open Time" Percent
 const int button2Pin = 14; // Button For Start Mode Intake 1+7
 const int button3Pin = 15; // Button For Start Mode Intake 3+5
 int buttonPushCounter = 0;   // counter for the number of button presses--- used with button for "Valve Open Time" Percent
 int buttonState = 0;         // current state of the button
 int button2State = 0;        // current state of the button 2
 int button3State = 0;        // current state of  the button 3
 int lastButtonState = 0;     // previous state of the button
 int lastButton2State = 0;     // previous state of the button 2
 int lastButton3State = 0;     // previous state of the button 3
 
 void setup()
 {
   Serial.begin(9600); // Communicate to Serial Port
   pinMode (So17Pin, OUTPUT); // Solenoid 1+7 as Output
   pinMode (So35Pin, OUTPUT); // Solenoid 3+5 as Output
   pinMode (So28Pin, OUTPUT); // Solenoid 2+8 as Output
   pinMode (So46Pin, OUTPUT); // Solenoid 4+6 as Output
   pinMode(buttonPin, INPUT); // Button for "Valve Open Time" as Input
   pinMode(button2Pin, INPUT); // Button For Start Mode 1+7 Intake
   pinMode(button3Pin, INPUT); // Button For Start Mode 3+5 Intake
   attachInterrupt(0, event_count, RISING); // Interrupt 0 is Pin 2 Hall Effect Sensor
  
 }
   void loop()
 { if(eventcount >=1)
   // Calculate position of piston
     rt = (micros() - timeold)/ eventcount; // Time Between Each Hall Pulse
     rt = rt/360; // Time Between Each Hall Pulse Divided by ( 360 Degrees)--- Time for 1 degree of rotation
     rt = abs(rt); // Absolute value of found time--- To make sure every degree is a positive number ( with time-timeold and deceleration of rotation speed, there will be a negative number produced)
     timeold = micros();
     eventcount = 0;    
    
    // Calculate RPM
     rpm = (micros() - timeold) / eventcount;  // Time Between Each Hall Pulse
     rpm = 1000000/rpm;  // (Microseconds to Second) Divided by (Time Between Each Hall Pulse)
     rpm = rpm*60; //((Microseconds to Second) Divided by (Time Between Each Hall Pulse)) Times (Seconds to Minutes)
     timeold = micros();
     eventcount = 0;
          
     Serial.println(rpm,DEC); // Print RPM on Serial
    
   //-------------------------------------------------------------------------------------- START MODE
  
    if (rpm = 0) // If Device is not spinning then Enable the Button's 2 and 3. If it is spinning Disable the Button's 2 and 3
    {
    if (button2State != lastButton2State) // Start Mode Button2 Pressed--- Intake 1 and 7 Exhaust 4 and 6
    {
        if (button2State == HIGH) {
     digitalWrite(So17Pin, HIGH); // Fire Intake 1 and 7
     digitalWrite(So46Pin, HIGH); // Fire Exhaust 4 and  6
     Serial.println("Start In 1+7"); // Display Via Serial "Start In 1+7"
       }
     }
  
    {
    if (button3State != lastButton3State) // Start Mode Button3 Pressed--- Intake 3 and 5 Exhaust 2 and 8
    {
    
    if (button2State == HIGH) {
     digitalWrite(So35Pin, HIGH); // Fire Intake 3 and 5
     digitalWrite(So28Pin, HIGH); // Fire Exhaust 2 and 8
     Serial.println("Start In 3+5"); // Display Via Serial "Start In 1+7"
       }
     }
    }
   //------------------------------------------------------------------------------------ RUN MODE
     {
   }
  // Open for 100% Stroke Intake (1 and 7) Exhaust (4 and 6)
  if (degree <= ( rt*179) || (degree >= rt*1) ) // If the piston is inbetween 1 to 179 degrees of revolution then...
  {
     digitalWrite(So17Pin, HIGH); // Fire Solenoid 1 and 7 (Intake)
     digitalWrite(So46Pin, HIGH); // Fire Solenoid 4 and 6 (Exhaust)
     Serial.println("Intake (1,7) Exhaust (4,6) Fired 100%"); // Print Status and Percent of Valve Open
     }
else {
  digitalWrite(So17Pin, LOW); // Don't Fire Solenoid 1 and 7 (Intake)
  digitalWrite(So46Pin, LOW); // Don't Fire Solenoid 4 and 6 (Exhaust)
  }
  // Open for 100% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*359) || (degree >= (rt*181)) ) // If the piston is inbetween 181 to 359 degrees of revolution then...
  {
     digitalWrite(So35Pin, HIGH); // Fire Solenoid 3 and 5 (Intake)
     digitalWrite(So28Pin, HIGH); // Fire Solenoid 2 and 8 (Exhaust)
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 100%"); // Print Status and Percent of Valve Open
     }
else {
  digitalWrite(So35Pin, LOW); // Don't  Fire Solenoid 3 and 5 (Intake)
   digitalWrite(So28Pin, LOW); // Don't Fire Solenoid 2 and 8 (Exhaust)
}

}
 
  //------------------------------------------ Button Control--- Allows the Change of How Long Valve Stays Open Per Revolution
  
   if (buttonPushCounter <= 9){
   if (buttonState != lastButtonState) // "Percent of "Valve Open Time" " Button Pressed
   {
    
    if (buttonState == HIGH) {
       buttonPushCounter++; // Update Button Counter
      Serial.print("number of button pushes:  "); // Display Via Serial "number of button pushes: "
      Serial.println(buttonPushCounter, DEC); // Display Via Serial Button Push Count
    }
    else {          
     lastButtonState = buttonState; // Stay at last button state if Button is not Pressed
    }
   }
   else {
     buttonPushCounter = 0; // Resets to 0 if it has been pressed more than 9 times
   }
 
 //---------------- 90% Valve Open  
  if (buttonPushCounter == 1) // If button is pressed once
  {
    Serial.println("90%");
   // Open for 90% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*161.1) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
      Serial.println("Intake (1,7) Exhaust (4,6) Fired 90%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 90% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*342.1) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 90%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

//---------------- 80% Valve Open    
   if (buttonPushCounter == 2) {
     Serial.println("80%");
   // Open for 80% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*143.2) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
      Serial.println("Intake (1,7) Exhaust (4,6) Fired 80%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 80% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*324.2) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 80%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

//---------------- 70% Valve Open  
if (buttonPushCounter == 3) {
  Serial.println("70%");
   // Open for 70% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*125.3) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
      Serial.println("Intake (1,7) Exhaust (4,6) Fired 70%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 70% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*306.3) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 70%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

//---------------- 60% Valve Open  
if (buttonPushCounter == 4) {
  Serial.println("60%");
   // Open for 60% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*107.4) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
      Serial.println("Intake (1,7) Exhaust (4,6) Fired 60%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 60% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*288.4) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 60%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

//---------------- 50% Valve Open  
if (buttonPushCounter == 5) {
  Serial.println("50%");
   // Open for 50% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*89.5) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
    
Logged

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Continuation...
Code:
Serial.println("Intake (1,7) Exhaust (4,6) Fired 50%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 50% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*270.5) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 50%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

//---------------- 40% Valve Open  
if (buttonPushCounter == 6) {
  Serial.println("40%");
   // Open for 40% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*71.6) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
      Serial.println("Intake (1,7) Exhaust (4,6) Fired 40%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 40% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*252.6) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 40%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

//---------------- 30% Valve Open  
if (buttonPushCounter == 7) {
  Serial.println("30%");
   // Open for 30% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*53.7) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
      Serial.println("Intake (1,7) Exhaust (4,6) Fired 30%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 30% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*234.7) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 30%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

//---------------- 20% Valve Open  
if (buttonPushCounter == 8) {
  Serial.println("20%");
   // Open for 20% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*35.8) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
      Serial.println("Intake (1,7) Exhaust (4,6) Fired 20%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 20% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*216.8) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 20%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

//---------------- 10% Valve Open  
if (buttonPushCounter == 9) {
  Serial.println("10%");
   // Open for 10% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= ( rt*17.9) || (degree >= rt*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
      Serial.println("Intake (1,7) Exhaust (4,6) Fired 10%");
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 10% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= (rt*198.9) || (degree >= (rt*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     Serial.println("Intake (3,5) Exhaust (2,8) Fired 10%");
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}

   }
 }
  void event_count()
 {
   eventcount++; // Hall Effect Count Updater
 }


 
//-----------------------------------------------
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50115
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Enough of the cross-posting. Talk about hardware issues here, and software issues in your other thread in the software section.
Logged

United States
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Learning
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Enough of the cross-posting. Talk about hardware issues here, and software issues in your other thread in the software section.
I'm double posting because it adds a wider auidence and another set of eyes and suggestions. Also, there have been people in this post who have helped me with the code as well as the hardware.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure how far along you are at this point, but I figured I throw a wrench into the works.

My background is internal combustion, I've never given much thought on compressed air, so here's my assumptions about your project:

1) 4 cylinder engine
2) 1 intake solenoid, 1 exhaust solenoid per cylinder
3) Piston going down, intake is open, exhaust is closed
4) Piston going up, intake is closed, exhaust is open
5) 2 cylinders firing simultaneously

With regard to crank position sensing and rpm determination, most automotive engines have a crankshaft position sensor with 36 teeth - 1 missing tooth, typically located 10 degrees BTDC cyl 1.  Some use more teeth, I don't know of any that use less. In a typical 4 stroke engine this gives you position, but doesn't give you stroke.  In your application this is irrelevant so we won't worry about that.  I would recommend you go this route.  

Using this method you would receive a pulse every 10 degrees.  By determining the time between pulses you know rpm.  When the missing tooth comes along the time between pulses will be twice as long, this is your indicator that the missing tooth went by and you next pulse is TDC.  You could also accomplish this with a 2nd sensor facing the front  of the 36 tooth wheel that sensed a feature you added at TDC.  This would simplify the code, but software is free and you don't have to deal with selling additional sensors, brackets, and wiring to management.

To run your engine the easiest thing to do would be to synthesize a signal off of the wheel that drives your injectors.  Since you're not worried about valve timing, spark advance etc... this could be as simple as TDC comes around, set a flag high, 18 pulses later, set it low.   Flag is high, intake solenoid is on,  exhaust off or the other way around depending on where you are in the firing order.  

This of course would give you 100% duty cycle all the time, so you would probably want to calculate the period and determine an injector on time.  This gives you more flexibility than the 10% increments you've got now.  You could replace your button with a potentiometer and dial up the duty cycle as desired.

There was some discussion regarding the need to predict wether the engine was accelerating or decelerating.  This shouldn't matter.  You should only be firing the solenoids based on engine position, if the injector is open and TDC /BDC comes around, that should trigger closing the injector regardless of what any other calculations may be saying.  

Logged

Pages: 1 2 [3] 4 5 ... 9   Go Up
Jump to: