Read RPM with interrupt; adjust motor speed.

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Read RPM with interrupt; adjust motor speed.

Postby shi-nee » Tue May 01, 2012 5:57 pm

RPM code I've been using, which is great for reading RPM. Every time I attempt to switch an output based on the variable 'rpm' I get no activity on 'motorPin'. But if I manually apply voltage to the motor I get a perfect rpm reading. If I digitalWrite motorPin HIGH in loop it will turn on the pin and still give correct rpm.

Code: Select all
   int rpmcount = 0;
   int rpm = 0;
   int timeold = 0;
   int motorPin = 8;
   int ledPin = 13;

void setup()
{
   pinMode(motorPin, OUTPUT);
   pinMode(ledPin, OUTPUT);
   digitalWrite(motorPin, HIGH);
   digitalWrite(ledPin, HIGH);
   
   Serial.begin(57600);
   attachInterrupt(0, rpm_fun, RISING);
}

void loop()
{
   if (rpmcount >= 20) {
     //Update RPM every 20 counts, increase this for better RPM resolution,
     //decrease for faster update
     rpm = 30*1000/(millis() - timeold)*rpmcount;
     timeold = millis();
     rpmcount = 0;
     Serial.println(rpm,DEC);
     if (rpm < 3400){
     digitalWrite(motorPin, HIGH);
     digitalWrite(ledPin, HIGH);
     } else {
     digitalWrite(motorPin, LOW);
     digitalWrite(ledPin, LOW);
     }
   }
}

void rpm_fun()
{
   rpmcount++;
   //Each rotation, this interrupt function is run twice
}
shi-nee
 
Posts: 5
Joined: Tue May 01, 2012 1:28 pm

Re: Read RPM with interrupt; adjust motor speed.

Postby pylon » Wed May 02, 2012 3:47 am

Given the code you posted I estimate you get an interrupt about every 5-10ms. The code inside your "if" is called once in about 150ms (if the motor is running). I don't know your motor and application but don't you think it is possible that the motor stops completely before that code is called again? If this is the case, it never gets to the point again where it would start your motor.
pylon
 
Posts: 14
Joined: Tue Apr 24, 2012 10:27 am

Re: Read RPM with interrupt; adjust motor speed.

Postby adafruit_support_bill » Wed May 02, 2012 4:40 am

I think Pylon is right there. The control will not execute if the motor is not turning. Better to execute the control based on time instead of revolutions.
User avatar
adafruit_support_bill
 
Posts: 16055
Joined: Sat Feb 07, 2009 9:11 am

Re: Read RPM with interrupt; adjust motor speed.

Postby shi-nee » Wed May 02, 2012 9:34 am

Interrupts suck.

I think I'm going to end up with either a real time clock or monostable 555 w/ schottky to change RPM into a varying voltage. So yes, time is the answer, but not in code.

Thanks for your help.
shi-nee
 
Posts: 5
Joined: Tue May 01, 2012 1:28 pm

Re: Read RPM with interrupt; adjust motor speed.

Postby pylon » Wed May 02, 2012 11:53 am

You seem to be the hardware guy :-)

Me being the software guy I would not give up that quickly. It's solved very simple: Just let the RPMs be calculated every time you get an interrupt. Don't take the millis() but the micros() and you get enough sensibility (I guess, depends on your setup). Your interrupt handler does not count the number of times it's called but the time difference between these calls.

BTW: in your sketch rpmcount is not declared volatile although it's changed in a interrupt handler. You should only change global variables in an interrupt service routine declared "volatile".

Snippet:

Code: Select all
volatile unsigned long last_irq_time = 0;
volatile unsigned int rpm = 0;

void rpm_fun() {
  rpm = 30000000L / (micros() - last_irq_time);
  last_irq_time = micros();
}


So you have always an accurate RPM value (given you get two rising edges on pin 2 for every round of your motor) and you can decide in every run of loop() if you wanna stop or start your motor. No additional electronics needed :-).
pylon
 
Posts: 14
Joined: Tue Apr 24, 2012 10:27 am

Re: Read RPM with interrupt; adjust motor speed.

Postby shi-nee » Wed May 02, 2012 2:56 pm

Ideally I want to do it both ways for the education. I just got a couple L293 to replace those I burned in my motorShield so I'll rewrite for AFmotor and try millis() tonight.

Thanks Pylon.. Ada
shi-nee
 
Posts: 5
Joined: Tue May 01, 2012 1:28 pm


Return to Arduino

Who is online

Users browsing this forum: Exabot [Bot] and 6 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [103]

Raspberry Pi[80]
 
FLORA[23]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[11]
Arduino[60]
 
NETduino[14]
 
BeagleBone[24]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[33]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[8]


 
Breakout Boards[33]
LCDs & Displays[48]
Components & Parts[69]
Batteries & Power[49]
EL Wire/Tape/Panel[52]
LEDs[109]
 
Wireless[14]
Cables[61]
 
Lasers[6]
Sensors/Parts[145]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[39]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[24]


 
Stickers[41]
 
Skill badges[55]
 
Books[25]
 
Circuit Playground[7]
 
Gift Certificates[4]