Hi Everyone,
This is my first post to the Forum, so please bear with me. I am trying to increase the accuracy of my rpm reading from 2 IR sensors that are measuring the rpm of a 8.5" diameter rotating shaft. I have placed an encoder strip on each shaft with 100 "tick" marks on it and I am using the attachInterrupt function to record the data. In order to be able to compare the to rotating shafts, I am recording the rpm every 100 ms. I am using time to be abel to compare the 2 shafts so that my data arrays are the same length.
The problem I am having is that if I reduce the accuracy number (recording data more often), I get erratic rpm readings. I do not know if this is because I am trying to take data too often or if it is an alignment issue. Any help or suggestions on this matter would be greatly appreciated.
IR Sensors: SEN-00246 - Optical Detector / Phototransistor - QRD1114
#include <SdFat.h>
#include <String.h>
const int chipSelect = 8;
//Change these variables
int accuracy = 100; //This is the number of ms between data points
int targetRPM = 900;
int num = 1; // of our file.
//Naming our Files
String frontFile = "Fron"; //Create an array that contains this name
String rearFile = "Rear"; //Crears an arrya that contains the name of the rear rpm
String timeFile = "Time";
String text = ".txt";
char fFile[10];
char rFile[10];
char tFile[10];
char contents[100];
//SD Card Setup
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile test;
SdFile file;
int i = 0;
//MOTOR
int motorPin = 10;
//Solenoid
int solenoidPin = 9;
//BUTTON
int switchPin = 5;
boolean lastButton = LOW;
boolean ledOn = false;
boolean currentButton = LOW;
//Front RPM Variables
int fRpmPin = 0; //Digital pin 2
unsigned long rpmFront = 0;
volatile byte frontCount = 0;
unsigned long deltaT = 0;
unsigned long lastRpm_F = 0;
SdFile front;
//Rear RPM Variables
int rRpmPin = 1; //Digital pin 3
unsigned long rpmRear = 0;
volatile byte rearCount = 0;
unsigned long deltaT_Rear = 0;
SdFile rear;
//Other Variables
unsigned long rpmFactor = 60000; // millisec*sec = 1000*60
boolean motorOff = false;
boolean changeMotor = false;
unsigned long lastTime = 0;
//Time Variables
unsigned long plotTime = 0;
SdFile time;
void setup() {
Serial.begin(9600);
//SD CARD SETUP
pinMode(10, OUTPUT);
card.init(SPI_FULL_SPEED, 8);
volume.init(card);
root.openRoot(volume);
//Switch SETUP
pinMode(switchPin, INPUT);
pinMode(solenoidPin, OUTPUT);
pinMode(motorPin, OUTPUT);
//IR Sensors
attachInterrupt(fRpmPin, frontISR, CHANGE);
attachInterrupt(rRpmPin, rearISR, CHANGE);
NAME_FILE();
}
void loop() {
currentButton = debounce(lastButton);
if (lastButton == LOW && currentButton == HIGH) {
changeMotor = !changeMotor;
digitalWrite(motorPin, changeMotor);
}
NEXT_FILE();
RPM();
lastButton = currentButton;
}
void RPM() {
deltaT = millis() - lastTime;
if (deltaT >=accuracy) {
lastRpm_F = rpmFront;
rpmFront = rpmFactor*frontCount/(99*deltaT);
rpmRear = rpmFactor*rearCount/(102*deltaT); //3 more ticks on this rotor thus the 102 vs 99
frontCount = 0;
rearCount = 0;
Serial.println(rpmFront);
lastTime = millis();
if (rpmFront >= targetRPM | rpmRear >= targetRPM | motorOff == true) {
//Serial.println("writing data");
front.open(root, fFile, O_CREAT | O_APPEND | O_WRITE);
sprintf(contents, "%d\n", rpmFront);
front.print(contents);
front.close();
// Serial.println(rpmFront);
rear.open(root, rFile, O_CREAT | O_APPEND | O_WRITE);
sprintf(contents, "%d\n", rpmRear);
rear.print(contents);
rear.close();
//Records time for ploting later
plotTime = plotTime + accuracy;
time.open(root, tFile, O_CREAT | O_APPEND | O_WRITE);
sprintf(contents,"%d\n", plotTime);
time.print(contents);
time.close();
if (lastRpm_F >= targetRPM |motorOff == true) {
//Turns motor off at target RPM
motorOff = true;
digitalWrite(motorPin, LOW);
digitalWrite(solenoidPin, HIGH);
}
}
}
}
//This code read whether the switch is on or off
boolean debounce(boolean last)
{
boolean current = digitalRead(switchPin);
if (last != current)
{
delay(5);
current = digitalRead(switchPin);
}
return current;
}
//creates a new file and restarts the cycle
void NEXT_FILE() {
if (rpmFront <=40 && motorOff == true) {
num++;
rpmFront = 0;
rpmRear = 0;
digitalWrite(solenoidPin, LOW);
delay(7000);
digitalWrite(motorPin, HIGH);
motorOff = false;
frontCount = 0;
rearCount = 0;
plotTime = 0;
frontFile = "Fron"; //Create an array that contains this name
rearFile = "Rear"; //Crears an arrya that contains the name of the rear rpm
timeFile = "Time";
NAME_FILE();
}
}
void NAME_FILE() {
frontFile = frontFile + num;
frontFile.concat(text);
frontFile.toCharArray(fFile, 14);
Serial.println(fFile);
rearFile = rearFile + num;
rearFile.concat(text);
rearFile.toCharArray(rFile,14);
Serial.println(rFile);
timeFile = timeFile + num;
timeFile.concat(text);
timeFile.toCharArray(tFile,14);
Serial.println(tFile);
}
//Front interrupt Servie routine
void frontISR() {
frontCount++;
}
//Rear interrupt service routine
void rearISR() {
rearCount++;
}