United States
Offline
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #15 on: November 17, 2010, 12:01:03 am » |
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
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #16 on: November 17, 2010, 12:20:37 am » |
Man, what a challenge this is turning out to be :o
Once again, I appreciate your help thus far
|
|
|
|
|
Logged
|
|
|
|
|
United States
Offline
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #17 on: November 18, 2010, 12:03:39 am » |
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=1290052524Much help is needed and appreciated! Thanks
|
|
|
|
|
Logged
|
|
|
|
|
United States
Offline
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #18 on: November 18, 2010, 01:35:13 pm » |
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. //----------------------------------------------- #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
God Member
Karma: 16
Posts: 735
|
 |
« Reply #19 on: November 18, 2010, 01:50:32 pm » |
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
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #20 on: November 18, 2010, 02:01:01 pm » |
Thanks gardner, but unfortunately I need this to work much higher than 100 RPM.
|
|
|
|
|
Logged
|
|
|
|
|
United States
Offline
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #21 on: November 18, 2010, 02:03:13 pm » |
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
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #22 on: November 18, 2010, 02:23:56 pm » |
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
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #23 on: November 18, 2010, 02:40:48 pm » |
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
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #24 on: November 18, 2010, 04:50:54 pm » |
How does this look? /// /// /// ///
//----------------------------------------------- #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
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #25 on: November 18, 2010, 04:57:10 pm » |
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
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #27 on: November 18, 2010, 06:01:49 pm » |
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
Full Member
Karma: 0
Posts: 148
Learning
|
 |
« Reply #28 on: November 18, 2010, 06:06:49 pm » |
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? 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
Jr. Member
Karma: 0
Posts: 90
|
 |
« Reply #29 on: November 18, 2010, 06:10:13 pm » |
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
|
|
|
|
|