Pages: 1 [2] 3 4 ... 9   Go Down
Author Topic: Driving Comp Air Engine with Solenoids and Arduino  (Read 7038 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

So, I think I have found a way to keep it to just one Uno.

Let me know if there are any issues with this setup:

Uno
LCD with Backpack (2 pins)
Hall Effect Sensor
Wingshield Screwshield
Thermocouple With Thermocouple breakout Board
Push Button Switch


My hopes are to run the 8 solenoids by reading the hall effect sensor, but at the same time use the LCD to display RPM and Temperature. The button would be used to change preset solenoid timings.

Can one UNO handle all that?
Thanks
Logged

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

Man, what a challenge this is turning out to be  :o

Once again, I appreciate your help thus far
Logged

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

If anyone is interested, I expanded this thread into the software forum for the code design.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1290052524

Much help is needed and appreciated!

Thanks
Logged

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

Quote
You can calculate RPM by measuring the time between pulses. And you can calculate position (in fractions of a degree if necessary) by dividing the period (the time between TDC) by 360.  Once you know where TDC is, and you know the RPM (or actually the time between TDC), then it is almost trivial to calculate (and adjust) the position and period of any solenoid opening.

I'm actually a bit confused with the position calculation. If you divide a time like 20 seconds by 360,   20/360, you get a decimal that is irrelevant to its position. Please explain.
Here is my current code to better illustrate.
Code:
//-----------------------------------------------
 #include <LiquidCrystal.h>
 LiquidCrystal lcd(7,8,9,10,11,12)
 volatile unsigned int eventcount;
 unsigned int degree; // Angle of rotation out of 360
 unsigned int rpm;
 unsigned long timeold;
 int So17Pin = 3 // Solenoids 1 and 7 assigned to Pin 3
 int So35Pin = 4 // Solenoids 3 and 5 assigned to Pin 4
 int So28Pin = 5 // Solenoids 2 and 8 assigned to Pin 5
 int So46Pin = 6 // Solenoids 4 and 6 assigned to Pin 6
 
 
 void setup()
 {
   Serial.begin(9600);
   pinMode (So17Pin, OUTPUT);
   pinMode (So35Pin, OUTPUT);
   pinMode (So28Pin, OUTPUT);
   pinMode (So46Pin, OUTPUT);
   attachInterrupt(0, rpm_count, RISING);
   eventcount = 0;
   degree = 0;
   rpm = 0;
   timeold = 0;
 }
 
  void rpm_count()
 {
   eventcount++;
   //Updated Count
 }
 
 void loop()
 {
   if (eventcount >= 1) {
    
     degree = (millis() - timeold) / 360;
     rpm = (millis() - timeold) / eventcount;
     rpm = 1000/rpm;
     rpm = rpm*60;
     timeold = millis();
     eventcount = 0;
     Serial.println(degree,DEC);
     Serial.println(rpm,DEC);
    
   }
   // Open for 80% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (degree <= 143.2) || (degree >= 1) {
     digitalWrite(So17, HIGH);
     digitalWrite(So46, HIGH);
     }
else {
  digitalWrite(So17, LOW);
  digitalWrite(So46, LOW);
}

  // Open for 80% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (degree <= 324.2) || (degree >= 181) {
     digitalWrite(So35, HIGH);
     digitalWrite(So28, HIGH);
     }
else {
  digitalWrite(So35, LOW);
  digitalWrite(So28, LOW);
}
//-----------------------------------------------
Logged

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

Quote
If you divide a time like 20 seconds by 360

20 secs is 20,000 milliseconds.  20,000/360 is about 56ms.  If you want to wait for the shaft to be half way around, you wait 10,000 ms.

If you have an interrupt attached to the TDC event, you can have it remember (1) the time at which TDC was seen and (2) the elapsed time for the most recent rotation.  Then at any time you can take the current time, subtract (1) and divide into (2) to see where the shaft is most likely at.

This would work okay up to about 100 RPM.  After that you'd have to harness the hardware timers directly.
Logged

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

Thanks gardner, but unfortunately I need this to work much higher than 100 RPM.
Logged

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

Quote
My original thoughts were based on using the micros() function.  The period of rotation will be some large number of microseconds, and you can use simple percentage (or degree angles, if you prefer) to calculate how many microseconds beyond TDC to open or close any particular solenoid.

Would you mind showing me an example in code?
I am following you, but can't quite grasp it.
« Last Edit: November 18, 2010, 02:03:34 pm by Newman180 » Logged

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

Thank you. I will work on implementing that into the code and post the results.

The speed will not be high initially. 250 to 500 RPM Max.
Logged

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

Quote
If you were making 2000 RPM, you would have 500us (microseconds) for each turn.

Excuse my ignorance, but isn't it 30,000us each revolution?

2000 RPM = 33.33333 RPS

So, theres 1 Revolution for every 1/33.3333 of a second

(1/33.3333)/(1,000,000) = 30,000us

Right?
Logged

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

How does this look?

Code:
///
///
///
///

//-----------------------------------------------
 #include <LiquidCrystal.h>
 LiquidCrystal lcd(7,8,9,10,11,12);
 volatile unsigned int eventcount;
 unsigned int valve; // Time Valve Open
 unsigned int rpm;
 unsigned int degree;
 unsigned long timeold;
 int So17Pin = 3; // Solenoids 1 and 7 assigned to Pin 3
 int So35Pin = 4; // Solenoids 3 and 5 assigned to Pin 4
 int So28Pin = 5;// Solenoids 2 and 8 assigned to Pin 5
 int So46Pin = 6; // Solenoids 4 and 6 assigned to Pin 6
 int buttonPin = 13; // Button For Switching %
 int buttonPushCounter = 0;   // counter for the number of button presses
 int buttonState = 0;         // current state of the button
 int lastButtonState = 0;     // previous state of the button
 
 
 void setup()
 {
   Serial.begin(9600);
   pinMode (So17Pin, OUTPUT);
   pinMode (So35Pin, OUTPUT);
   pinMode (So28Pin, OUTPUT);
   pinMode (So46Pin, OUTPUT);
   pinMode(buttonPin, INPUT);
   attachInterrupt(0, rpm_count, RISING); // Interrupt 0 is Pin 2 Hall Sensor
   eventcount = 0;
   valve = 0;
   rpm = 0;
   timeold = 0;
   degree = 0;
 }
 
  void rpm_count()
 {
   eventcount++;
   //Updated Count
 }
 
 void loop()
 {
   if (eventcount >= 1) {
    
     rpm = (micros() - timeold) / eventcount;
     rpm = 1000000/rpm;
     rpm = rpm*60;
     timeold = micros();
     eventcount = 0;
     degree = (60000000/rpm);
     degree = degree/360;
    
     Serial.println(degree,DEC);
     Serial.println(rpm,DEC);
    
   }
  
   if (buttonState != lastButtonState) {
    
    if (buttonState == HIGH) {
 
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter, DEC);
    }
    else {
         Serial.println("off");
    }
  }
    lastButtonState = buttonState;
  
   if (buttonPushCounter % 1 == 0) {
   // Open for 80% Stroke Intake (1 and 7) Exhaust (4 and 6)
   if (valve <= ( degree*143.2) || (valve >= degree*1) ){
     digitalWrite(So17Pin, HIGH);
     digitalWrite(So46Pin, HIGH);
     }
else {
  digitalWrite(So17Pin, LOW);
  digitalWrite(So46Pin, LOW);
}
  // Open for 80% Stroke Intake (3 and 5) Exhaust (2 and 8)
  if (valve <= (degree*324.2) || (valve >= (degree*181)) ){
     digitalWrite(So35Pin, HIGH);
     digitalWrite(So28Pin, HIGH);
     }
else {
  digitalWrite(So35Pin, LOW);
  digitalWrite(So28Pin, LOW);
}

}
 }
//-----------------------------------------------
Logged

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

How do I make a formula without multiplying and dividing? Example?

No the important part is not the readout, its controlling the solenoids.

Also, with the hall effect sensor, will I need a pull up or pull down resistor?
Logged

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

Unfortunately I don't know how to eliminate/reduce the degree and rpm variables...

Or would a float function work better ?http://www.arduino.cc/en/Reference/Float

My hall effect sensor is
http://search.digikey.com/scripts/DkSearch/dksus.dll?lang=en&site=US&WT.z_homepage_link=hp_go_button&KeyWords=US5881LUA&x=31&y=23
« Last Edit: November 18, 2010, 05:06:14 pm by Newman180 » Logged

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

Yes I defiantly see the difference with the milliseconds per rotation vs rpm.

Thank you for that source. I have found through a bit of research I should have done before hand that I need a 10K Pull up resistor.

When I search on digikey, radioshack, sparkfun, nothing comes up. Where do I find these or am I searching wrong?
Logged

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

Quote
Quote:
Unfortunately I don't know how to eliminate/reduce the ... rpm variables...

Think of speed as milliseconds per rotation.  RPM is simply an artificial convention for humans.

This would work better correct?
Code:
rpm = (micros() - timeold) / eventcount;
     rpm = 1000000/rpm;
     rpm = rpm*60;
     timeold = micros();
     eventcount = 0;
     degree = (1000000/(micros() - timeold) / eventcount);
     degree = degree/360;
Logged

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

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?! ;D
Logged

Resistance is Futile

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