Go Down

Topic: Multiple Solenoids triggered by Hall Effect Sensor (Read 2442 times) previous topic - next topic

PaulS

Quote
Obviously I was trying to tell it, that if the value is between rt*1 and rt*179 to fire solenoid 1 and 7.

If what value is between rt and rt * 179?

Unless both solenoids are connected to the same pin, you'll need multiple digitalWrite statements.

Newman180

Quote
If what value is between rt and rt * 179?

Unless both solenoids are connected to the same pin, you'll need multiple digitalWrite statements.


Thats my issue. I'm havnig trouble putting a value to that "value".

If the piston is in between 1 to 179 degrees of the stroke, I want it to fire said solenoids.
How do I write this? I know how long it takes to make a revolution, and I know how long it takes to make one degree inside that revolution...

Quote
Unless both solenoids are connected to the same pin, you'll need multiple digitalWrite statements.

Both solenoids are connected to the same pin

PaulS

Quote
I know how long it takes to make a revolution, and I know how long it takes to make one degree inside that revolution.

But, you don't have a point of reference for where you are in the cycle.

If you knew when the last interrupt fired, and what time it is now, and a very fast calculator, you could determine where the crankshaft is now.

To do this, you'll need to expand what happens in the ISR, to include recording when the interrupt fired. Keep in mind, though, that millis or micros return unsigned longs, and to ensure that the time variable does not get corrupted, interrupts will need to be disabled/re-enabled in the ISR.

Newman180

Quote
But, you don't have a point of reference for where you are in the cycle.

If you knew when the last interrupt fired, and what time it is now, and a very fast calculator, you could determine where the crankshaft is now.

To do this, you'll need to expand what happens in the ISR, to include recording when the interrupt fired. Keep in mind, though, that millis or micros return unsigned longs, and to ensure that the time variable does not get corrupted, interrupts will need to be disabled/re-enabled in the ISR.


Paul, I don't mean to be rude, but have you read my code?

I have already covered all of this except the disabling the interrupts which I will add in, in the future. Hence:
Code: [Select]
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
   
    timeold = micros();
    eventcount = 0;    
   
         


What I need help with is telling the microprocessor that, when its at a certain point of the revolution when to fire the valves.

I was trying to accomplish it like this
Code: [Select]
if (degree <= ( rt*179) || (degree >= rt*1) ) // If the piston is inbetween 1 to 179 degrees of revolution then...
 {
    digitalWrite(So17Pin, HIGH);

But realized that the variable degree does not equal anything


PaulS

Quote
Paul, I don't mean to be rude, but have you read my code?

Yes, I've read your code. You have on part of your code processing an interrupt when the hall-effect sensor sees a magnet. You have another part of your code calculating RPM and (trying to calculate) position. But, those two parts of code do not share a common reference (time).

Code: [Select]
rt = (micros() - timeold)/ eventcount; // Time Between Each Hall Pulse
This comment is wrong. Some number of events have occurred during some known amount of time. rt is calculating the average time to rotate the crankshaft once.

Code: [Select]
    rt = rt/360; // Time Between Each Hall Pulse Divided by ( 360 Degrees)--- Time for 1 degree of rotation
This comment is right. It IS calculating the time to rotate the crankshaft one degree.

But, so what? When you are doing this, you have no idea where the crankshaft is. The last eventcount increment could have been 3 degrees or 180 degrees or 350 degrees in the past.

In addition to recording that the hall effect sensor fired, you need to record WHEN it fired. Then, when you know how long it takes to travel one degree, you'll know when (assuming a (relatively) constant speed of rotation) the crankshaft will be at a given position. When it gets to be that time, change the state of the pin.

Newman180

Code: [Select]
But, so what? When you are doing this, you have no idea where the crankshaft is. The last eventcount increment could have been 3 degrees or 180 degrees or 350 degrees in the past.

The magnet is placed at TDC. If the event count is only once, and there is only one magnet, there will always be 360 degrees of revolution between each hall pulse. It will also dictate where TDC is for each pulse as well as give you a way to find in degrees where the pistons are through the rotation.

Code: [Select]
In addition to recording that the hall effect sensor fired, you need to record WHEN it fired. Then, when you know how long it takes to travel one degree, you'll know when (assuming a (relatively) constant speed of rotation) the crankshaft will be at a given position. When it gets to be that time, change the state of the pin.

I agree completely. After rt has been divided by 360, you multiple it my the desired degree. For example. It takes 1000us to make one revolution, 1000/360=  2.778us to make one degree. Say we want to know when its at 50 degrees
2.778 * 50 = 138.889 us

Again my issue is the actual command to tell my device that when the piston is between say 50 degrees and 60 degrees to change the pin state. I was trying to use an if >= and <= statement but couldn't manage to set it up the way I describe.

PaulS

Quote
The magnet is placed at TDC. If the event count is only once, and there is only one magnet, there will always be 360 degrees of revolution between each hall pulse.

You can't be sure that loop will complete everything it needs to be in one revolution.

You can't be sure that loop won't execute more than once per revolution of the crank.

You can't be sure WHEN the code in loop will execute relative to when the interrupt occurred last.

Newman180

Code: [Select]
You can't be sure that loop will complete everything it needs to be in one revolution.

You can't be sure that loop won't execute more than once per revolution of the crank.

You can't be sure WHEN the code in loop will execute relative to when the interrupt occurred last.

I appreciate the advice. I have come the conclusion that it will be a trial basis. If it isn't able to complete the loop etc. then I will continue with a different method, possibly multiple sensors.

I guess what I'm looking for at this moment is how to write my little script. Ignoring all the other possible issues, how do I write what I've been asking about telling the arduino to fire solenoids between rt and rt*179?

Thanks, I appreciate the help so far.

Go Up