Go Down

Topic: Read RPM from ESC into arduino? (Read 1 time) previous topic - next topic

r3nrut

Hey guys,

I am trying to get an RPM reading from a ESC (Diagram attached) and was wondering if anybody could help me out? The ESC has a red, 3 pin connector that has signal with pulse output.

I tried plotting it in in the serial plotter and attached a sample of the output, I'm just having trouble converting ESC output to RPM. It's a 10 pole motor and I know output corresponds to RPM in a 2-pole configuration, but am not sure how to actually read it in as RPM.

Any thoughts?

Thanks!

MarkT

Count the pulses with an interrupt routine?  Its a digital output surely?
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

r3nrut

So I finally got it working and figured I'd put my code for it up for others' reference.

It's kind of a mess with the casting in the equation, but I tested it against the optical tach and it was spot on!

Attach the signal wire from the esc (see above diagram) to an interrupt pin and the ground to arduino ground.

Code: [Select]

//this should be interrupt
volatile byte pulse;
float rpm;
unsigned long timeStamp;
unsigned long newTime;
//cycle count
unsigned int count;
//if there's a new timestamp
bool newTimeStamp;
//sample threshold. arbitrary
const unsigned int THRESH = 20;
//arbitrary. how many cycles before serial printing the rpm value
const float CYCLESTOPRINT = 10;
//poles in motor
const float POLES = 10.0;
//milliseconds in a minute
const float MILTOMIN = 60000.0;

//must be an interrupt pin
const unsigned int PININ = 3;

void setup(){
 pulse = 0;
 rpm = 0;
 timeStamp = 0;
 newTimeStamp = true;
 count = 0;
 Serial.begin(9600);
 attachInterrupt(digitalPinToInterrupt(PININ), revCount, FALLING);        //pin 2 is our interrupt
}

void loop(){
  //have THRESH samples been taken?
 if (newTimeStamp){    
    noInterrupts();//disable interrupt
    newTimeStamp = false;//toggle newTimeStamp back
    count++;//increment count so cycles can compare so we aren't printing every cycle
    //(pulse/5) / millis/60,000
    rpm = (((float)pulse) * 2.0/(((float)(newTime-timeStamp)/MILTOMIN) * POLES));//calc rpm
    //check and print
    if(count >= CYCLESTOPRINT){
      count = 0;
      Serial.println(rpm);
    }
    //reset pulse and timestamp
    pulse = 0;
    timeStamp = millis();
    interrupts();//reattach interrupt
  }
}

void revCount() {
  //update pulse
   pulse++;
   if (pulse >= THRESH) {
       newTime = millis();
       newTimeStamp = true; // flag to tell main code to read the value of timeStamp
  }
}

Go Up