Finding RPM of 5VDC Motor (attached encoder) - shaft is manually being rotated

Hello all,

I am constructing a small wind turbine that utilizes a small 5V motor with an encoder attached (TT Motor with Encoder (6V 160RPM 120:1)-DFRobot). To lower the gear ratio, I removed the gears from the link above to leave us with just the motor attached to the encoder, making it easier for the attached fan blades to rotate.

I need my code to use the "interrupt" function as well as print the angular displacement over time.

The code I have below works but for only one 360-degree rotation. I need this code to work for more than 1 rotation since I need the shaft to consistently rotate (1-3 minutes of rotating due to the movement of the attached fan blades to the shaft) so that from the angular displacement, I can calculate the angular velocity (via Matlab most likely). From here, I'm using Matlab to plot the angular displacement and velocity and determine the energy produced. But I'm still are struggling to adjust the code below to run for more than 1 shaft rotation and print the angular displacement using the encoder attached.

The encoder has a resolution of 16 pulse single per round giving a maximum output of 1920 within one round.

Any suggestions on how to adjust the code below to work for more than 1 manual rotation of the motor/encoder shaft while still utilizing the encoder and the "interrupt" function? Thank you in advance!

/*********************************************
INITIALIZATION
**********************************************/
// Use pinX for PWM output to control the motion of the motor
const int pinX = 10; // for PWM output
// Use pinA as the interrupt pin dictated by Encoder Channel A
const int pinA = 2; // Yellow(Channel A) in oscilloscope graph
// Use pinB as the interrupt pin dictated by Encoder Channel B
const int pinB = 3; // Blue(Channel B) in oscilloscope graph
// Variables to record the number of interrupts
volatile long counter = 0;
volatile long lastcount = 0;
volatile unsigned long InrptTimeA = 0;
volatile unsigned long InrptTimeB = 0;
int duty = 127; // duty cycle between 0 and 255
/***********************************************
SETUP
************************************************/
void setup() {
// Select the baud rate for the serial monitor
Serial.begin(115200);
// Set up pinX to provide PWM output to move the motor
pinMode(pinX, OUTPUT);
// Set up pinA and pinB to read the A, B pulses from the encoder
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
// Attach the interrupt service routines
attachInterrupt(digitalPinToInterrupt(pinA),isrA,RISING);
attachInterrupt(digitalPinToInterrupt(pinB),isrB,RISING);
Serial.println("Start"); 

}
/*************************************************
Interrupt Service Routine A
**************************************************/
void isrA (){
// isrA is activated if pinA changes from LOW to HIGH
// Check pinB to determine the rfotation direction
if(digitalRead(pinB)==LOW) {
counter++;
} else {
counter--;
}
InrptTimeA = millis();
}
/*************************************************
Interrupt Service Routine B
**************************************************/
void isrB (){
// isrB is activated if pinB changes from LOW to HIGH
// Check pinA to determine the rfotation direction
if(digitalRead(pinA)==LOW) {
counter--;
} else {
counter++;
}
InrptTimeB = millis();
}
/***********************************************
Main Loop
************************************************/
int yes=1;
void loop() {
while(yes)
{
// Generate PWM on pinX to control motor speed
duty = 0; // keep the motor at rest
analogWrite(pinX, duty);
// Serial print interrupt times and encoder counts
if( counter != lastcount ) {
Serial.print(InrptTimeA);
Serial.print("\t"); // prints a tab
Serial.print(counter);
Serial.print("\t"); // prints a tab
Serial.println(InrptTimeB);
lastcount = counter;
} 

// Terminate the loop and stop motor motion after 180 seconds
if (InrptTimeB >= 180000) { // allow 3 minutes to manually turn the
// motor shaft
yes=0;
duty = 0;
analogWrite(pinX, duty);
}
}
noInterrupts(); // stop interrupts
}

Please edit your post to add code tags, after reading and following the instructions in the "How to use the forum" post at the head of every forum topic.

I need my code to use the "interrupt" function

No, you don't, and use of interrupts often introduces more problems than it solves.

To measure RPM you don't need to read both channels of the encoder.

What scheme do you have to ensure your unit will always be facing the wind? Even if you had a BIG tail to rotate the mechanism, there will be times when a breeze from the back will make your blades rotate the opposite way. Don't write your code so that you cannot allow for reverse rotation.

Paul

I apologize for not adding the code tag.

I have just verified that the proof of concept of this project no longer requires the use of an interrupt, so I apologize for this confusion. We would still like to keep the encoder.

This small-scale wind turbine project is a proof of concept that we can use microprocessing system control techniques/programs (ie Arduino) to measure the angular displacement and/or velocity of the blades that are directly attached to the motor-encoder shaft, to calculate how much energy is being produced in the end. The hardware is fairly bare-boned.

The system has few external variables; the "wind" is just a small fan directly facing the turbine blades, so as a minimum, we need only to account for the wind coming in in 1 direction.