4 x engine IR RPM sensor

Hi everybody

I have been researching for days for the best approach for my project.

  • budget doesn't matter. the simpler the better though.
  • 4 engines running at variable speeds, (max 1800 rpm) need to be measured their RPM
  • The best RPM sensor for this looks like a simple default IR sensor: IR sensor with a piece of reflection tape on the shaft.
  • i need to compare the RPM of engine1 and engine2 with each other and the speed of engine 3 and engine 4
  • when the RPM difference (more than 10%) between 1 and 2 occurs for more than lets say 1 second, switch on relay 1. The same comparison between engine3 and engine4., switch on relay2.
  • these are the only tasks the Arduino needs to do.
  • the RPM's of engine 1 and engine 2 under normal circumstances are exactly the same, so the measurements need to be fairly accurate.
  • the timeframe on which actions need to taken are in the 500ms - 1s second range. preferably faster, but this range is acceptable.
  • In basics, because the relatively low rpm, max 1800 rpm, 30 pulses per second per sensor, the total pulses per second to be processed by the device would be no more than 120.
  • my question is, would a normal Arduino Mega with a 4 relay shield suffice? Or do I need to look at a totally different approach and solution?

any input or thought is greatly appreciated!
cheers!

That is certainly doable. Test you sensor on one engine and see what you get.

However, you need to expand your logic a bit. With no engine running, they will all have the same speed. Also, do you ever need to turn the relays off? What conditions? Your description asks about engine RPM, but then refer to a "shaft" not turning the engine RPM. Which one are you basing the control on?

Be sure the IR sensor can only see a reflection from the spot you put on the shaft and be sure it reflects IR.

Paul

Hi Paul

thank you for your reply.
ive already started to try and code something based upon another persons 1 IR sensor.
these are the conditions for the setup:

  • rpm engine1 and engine3 <=1 : all relays off
  • rpm engine1 >= 2 && (rpm engine1 - rpm engine2) <=5: relay1 on, relay2 off
  • rpm engine1 >= 2 && (rpm engine1 - rpm engine2) >=5; relay1 off, relay2 on
  • rpm engine3 >= 2 && (rpm engine3 - rpm engine4) <=5: relay3 on, relay4 off
  • rpm engine3 >= 2 && (rpm engine3 - rpm engine4) >=5; relay3 off, relay4 on
  • the engines are connected through a clutch, I’m monitoring the slip in the clutch with this setup … all rpm’s are measured on the shafts, while the shafts will be covered with black tape and a strip of reflecting silver tape will be on top of that to provide for the pulse on the IR sensor.

Tomorrow I hope to get the hardware in and start wiring up, for now, the code looks like this, based on other articles i’ve adjusted this to fit my setup, although i think the switch section only allows for one possibility whereas engine 1 and engine 3 can be run at the same time and have different “cases” and their outcome, so this probably needs changing to another way of handling

Then also, only when the slip occurs for more than 1 second the relays need to be switched on, so i need to evaluate the slip case and see if this is happening for more than a given time, in this case 1 second

// Source: http://elimelecsarduinoprojects.blogspot.nl/2013/06/measure-rpms-arduino.html
// read RPM

volatile int rpmcount1 = 0;
volatile int rpmcount2 = 0;
volatile int rpmcount3 = 0;
volatile int rpmcount4 = 0;



unsigned long lastmillis = 0;

int slipOld = 1;
int slipNew = 1;

int relayPin1 = 8;
int relayPin2 = 9;
int relayPin3 = 10;
int relayPin4 = 11; // NEED TO ADJUST THIS FOR THE 4-RELAY BOARD

void setup(){
 
 attachInterrupt(0, IRSensor1, FALLING);//interrupt 0 is on pin 2.
 attachInterrupt(1, IRSensor2, FALLING);//interrupt 1 is on pin 3.
 attachInterrupt(2, IRSensor3, FALLING);//interrupt 2 is on pin 21.
 attachInterrupt(3, IRSensor4, FALLING);//interrupt 3 is on pin 20.

 
 pinMode (relayPin1, OUTPUT);
 pinMode (relayPin2, OUTPUT);
 pinMode (relayPin3, OUTPUT);
 pinMode (relayPin4, OUTPUT);
 
 digitalWrite (relayPin1, LOW);
 digitalWrite (relayPin2, LOW);
 digitalWrite (relayPin3, LOW);
 digitalWrite (relayPin4, LOW);
 
}

void loop(){
 
 if (millis() - lastmillis >= 1000){
 
 noInterrupts();


 
 interrupts();
 
 if (rpmcount1 <= 2) {
  slipNew = 1;                                                    //Engine1 not running
 }
 else if (rpmcount1 >= 3 && (rpmcount1 - rpmcount2) <= 2)  { 
   slipNew = 2;                                                   //Engine1 running and SLIP
 }
 else if (rpmcount1 >= 3 && (rpmcount1 - rpmcount2) >= 3)  {
   slipNew = 3;                                                   //Engine1 running and SLIP
 }
 else if (rpmcount3 <=2)  {
   slipNew = 4;                                                   //Engine3 not running
 }
 else if (rpmcount3 >= 3 && (rpmcount3 - rpmcount4) <=2) {
   slipNew = 5;                                                   //Engine3 running and NO SLIP
 }
 else if (rpmcount3 >= 3 && (rpmcount3 - rpmcount4) >=3) {
   slipNew = 5;                                                   //Engine3 running and SLIP
 }
 
 switch (slipNew)  {
   case 1:
   if (slipOld == 1)  {     
   }   
   else  {
     digitalWrite (relayPin1, LOW);
     digitalWrite (relayPin2, LOW);
     slipOld = slipNew;
   }
   break;
   
   case 2:
   if (slipOld == 2)  {
   }
   else  {
   digitalWrite (relayPin1, HIGH);
   digitalWrite (relayPin2, LOW);
   slipOld = slipNew;
   }
   break;
   
   case 3:
   if (slipOld == 3)  {
   }
   else  {
     digitalWrite (relayPin1, LOW);
     digitalWrite (relayPin2, HIGH);
     slipOld = slipNew;
   }
   break;
   
   case 4:
   if (slipOld == 4)  {
   }
   else  {
     digitalWrite (relayPin3, LOW);
     digitalWrite (relayPin4, LOW);
     slipOld = slipNew;
   }
   break;
   
   case 5:
   if (slipOld == 5)  {
   }
   else  {
     digitalWrite (relayPin3, HIGH);
     digitalWrite (relayPin4, LOW);
     slipOld = slipNew;
   }
   break;  

   case 6:
   if (slipOld == 6)  {
   }
   else  {
     digitalWrite (relayPin3, LOW);
     digitalWrite (relayPin4, HIGH);
     slipOld = slipNew;
   }
   break; 
    
 }

 
 rpmcount1 = 0;
 rpmcount2 = 0;
 rpmcount3 = 0;
 rpmcount4 = 0;

 
 lastmillis = millis();
 }
}


void IRSensor1(){
  rpmcount1++;
}

void IRSensor2(){
  rpmcount2++;
}

void IRSensor3(){
  rpmcount3++;
}

void IRSensor4(){
  rpmcount4++;
}

What do you think, this is the right direction?

thanks

For Arduino, a regular Uno or Nano has all the inputs and outputs you need to do this (including the interrupts, if you want to go that route).

For your project, start with one and only one RPM sensor. Get that to work, make sure you measure the rpm accurately. When that works, wire up the other three. Finally add the relays and related logic.

At 1800 rpm you probably don't need to worry about interrupts. You do have a problem with the nointerrupts() and interrupts() statements, nothing in between, after which you start working on the rpmcountn variables... that's not how it's supposed to work.

A concern is however that you measure for rather short periods, 500 ms. The moment your speed drops below 120 rpm you may not have a single rotation. At higher speeds you have only 1-2 rotations in that period. You rally have to make sure your rpm probe triggers at the same point every time.