Hi All
I am trying to get an RPM tachometer working for my lathe using FreqMeasure.h
the RPM range will be 1RPM-2000RPM
The encoder is a generic Chinese ( OMRON style ) 1000ppr with A,B & Z. The Z outputs 1 pulse per Rev with 5v output
The enc output on pin Z is high until the index mark is reach then drops low, briefly
I am feeding pin 22 via a voltage divider into the Teensy, voltage is about 3.15-3.2v. I have also feed the pin via a BC547 which also inverts the logic Thinking this might help with an inverted signal that just gives a single pulse every revolution
at 0 rpm it displays ( via serial ) a value of between 1-4...as the speed increases it will pick up the pulse and display RPM. Above 800rpm it displays the RPM accurately, but under 800 rpm it starts to display the rpm AND the 0 rpm value, as the rpm decrease the 0 rpm value is show a lot more between the RPM value
I have tried pullup/down resistors, adding a filter cap.....but nothing seems to change the results
The spindle encoding using the same enc works perfectly
The relevant code is after // RPM measure
Outputs - NOTE freq =RPM....I just havent changed the code..
Full Code
I am trying to get an RPM tachometer working for my lathe using FreqMeasure.h
the RPM range will be 1RPM-2000RPM
The encoder is a generic Chinese ( OMRON style ) 1000ppr with A,B & Z. The Z outputs 1 pulse per Rev with 5v output
The enc output on pin Z is high until the index mark is reach then drops low, briefly
I am feeding pin 22 via a voltage divider into the Teensy, voltage is about 3.15-3.2v. I have also feed the pin via a BC547 which also inverts the logic Thinking this might help with an inverted signal that just gives a single pulse every revolution
at 0 rpm it displays ( via serial ) a value of between 1-4...as the speed increases it will pick up the pulse and display RPM. Above 800rpm it displays the RPM accurately, but under 800 rpm it starts to display the rpm AND the 0 rpm value, as the rpm decrease the 0 rpm value is show a lot more between the RPM value
I have tried pullup/down resistors, adding a filter cap.....but nothing seems to change the results
The spindle encoding using the same enc works perfectly
The relevant code is after // RPM measure
Code:
void loop() {
newSpindle = spindleEnc.read();
if (newSpindle != oldPosition) {
//Serial.print("Spindle = ");
//Serial.print(newSpindle);
//Serial.println();
oldPosition = newSpindle;
}
{
// RPM measure
sum = sum + FreqMeasure.read();
count = count + 1;
if (count > 1) {
float frequency = FreqMeasure.countToFrequency(sum / count);
RPM = frequency/0.0166;
if (RPM >0) {
Serial.print("freq ");
Serial.println(RPM);
display1.clear();
display1.showNumberDec(RPM, false, 4, 4);
}
sum = 0;
count = 0;
}
}
Outputs - NOTE freq =RPM....I just havent changed the code..
Code:
freq 4.19
freq 4.19
freq 588.49
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 588.75
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 588.69
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 588.64
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 588.46
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 588.65
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 588.60
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 588.65
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 4.19
freq 588.91
freq 4.19
Code:
freq 992.98
freq 992.56
freq 992.72
freq 992.59
freq 993.34
freq 992.79
freq 993.47
freq 993.20
freq 993.09
freq 993.26
freq 993.38
freq 4.20
freq 993.19
freq 993.24
freq 993.23
freq 993.21
freq 993.17
freq 993.33
freq 993.44
freq 993.42
freq 993.20
freq 993.32
freq 993.32
freq 993.47
freq 993.22
freq 993.34
freq 993.35
freq 993.07
freq 993.19
freq 993.31
freq 993.33
freq 993.52
freq 993.39
freq 993.43
freq 992.99
freq 993.61
freq 993.34
freq 993.29
freq 993.52
freq 993.46
freq 993.34
freq 993.23
freq 4.20
freq 993.38
freq 993.23
freq 993.30
freq 993.34
freq 993.04
Code:
freq 992.98
freq 992.56
freq 992.72
freq 992.59
freq 993.34
freq 992.79
freq 993.47
freq 993.20
freq 993.09
freq 993.26
freq 993.38
freq 4.20
freq 993.19
freq 993.24
freq 993.23
freq 993.21
freq 993.17
freq 993.33
freq 993.44
freq 993.42
freq 993.20
freq 993.32
freq 993.32
freq 993.47
freq 993.22
freq 993.34
freq 993.35
freq 993.07
freq 993.19
freq 993.31
freq 993.33
freq 993.52
freq 993.39
freq 993.43
freq 992.99
freq 993.61
freq 993.34
freq 993.29
freq 993.52
freq 993.46
freq 993.34
freq 993.23
freq 4.20
freq 993.38
freq 993.23
freq 993.30
freq 993.34
freq 993.04
Code:
freq 1659.76
freq 1659.56
freq 1659.33
freq 1659.93
freq 1659.31
freq 1659.36
freq 1659.55
freq 1659.46
freq 1658.83
freq 1659.54
freq 1659.41
freq 1659.77
freq 1658.81
freq 1658.86
freq 1659.27
freq 1659.12
freq 1659.18
freq 1659.19
freq 1658.67
freq 1658.65
freq 1659.37
freq 1658.81
freq 1658.06
freq 1658.97
freq 1658.68
freq 1658.97
freq 1658.47
freq 1658.13
freq 1658.87
Code:
freq 951.88
freq 951.92
freq 951.73
freq 952.52
freq 951.94
freq 951.84
freq 4.20
freq 951.95
freq 947.11
freq 932.62
freq 926.38
freq 902.29
freq 4.20
freq 862.85
freq 851.86
freq 4.20
freq 842.86
freq 842.22
freq 4.20
freq 842.00
freq 841.83
freq 4.20
freq 842.22
freq 842.54
freq 4.20
freq 842.21
freq 841.53
freq 4.20
freq 841.85
freq 842.81
freq 4.20
freq 842.51
freq 841.65
Full Code
Code:
/*
MM Pin0 = MMButt
Pin1 = MMLed
TPI Pin2 = TPIButt
Pin3 = TPILed
Feed Pin4 = FeedButt
Pin5 = FeedLED
STOP Pin6 = STOPButt
Pin7 = STOPLed
FWD Pin8 = FWDButt
Pin9 = FWDLED
REV Pin10 = REVButt
Pin11 = REVLED
DISP1 Pin16 = DISP1Clk
Pin17 = DISP1Dat
DISP2 Pin18 = DISP2Clk
Pin19 = DISP2Dat
ENC Pin20 = ENCClk
PIN21 = ENCDat
PIN22 = RPM - <FreqMeasure.h> derived from Encoder pin 31 as shared input from spindleEnc . Hardware set pin
SPINDLE Pin31 = SPINDLE_A <QuadEncoder.h> Uses hardware quad encoder pins
Pin33 = SPINDLE_b
*/
#include <RotaryEncoder.h> //Rotary_Encoder_KY-040_Fixed-main/RotaryEncoder.h https://github.com/ownprox/Rotary_Encoder_KY-040_Fixed.....NOTE. this installs as RotaryEncoder.h, so make sure to remove any existing library
#include <Bounce2.h>
#include <SPI.h>
#include <Wire.h>
#include <TM1637Display.h>
#include <QuadEncoder.h>
#include <Encoder.h>
#include <FreqMeasure.h>
#define MMButt_PIN 0 // WE WILL attach() THE BUTTON TO THE FOLLOWING PIN IN setup()
#define MMLed_PIN 1 // DEFINE THE PIN FOR THE LED :
#define TPIButt_PIN 2
#define TPILed_PIN 3
#define FEEDButt_PIN 4
#define FEEDLed_PIN 5
#define STOPButt_PIN 6
#define STOPLed_PIN 7
#define FWDButt_PIN 8
#define FWDLed_PIN 9
#define REVButt_PIN 10
#define REVLed_PIN 11
#define CLK1 16 //Display 1 Clk
#define DIO1 17 // Display 1 data
#define CLK2 18 // Display 2 Clk
#define DIO2 19 // Display 2 data
//define pin 22 for freqmeasure.h - pin is assigned in the library and is a FIXED HARDWARE PIN
TM1637Display display1(CLK1, DIO1);
TM1637Display display2(CLK2, DIO2);
QuadEncoder spindleEnc(1, 31, 33, 1); // Encoder on channel 1 of 4 available // Channel (1), Phase A (pin0), PhaseB(pin1), Pullups Req(1=intPullup). FIXED HARWARE PINS
Bounce MMdebouncer = Bounce();
Bounce TPIdebouncer = Bounce();
Bounce FEEDdebouncer = Bounce();
Bounce STOPdebouncer = Bounce();
Bounce FWDdebouncer = Bounce();
Bounce REVdebouncer = Bounce();
int ledState = LOW; // SET A VARIABLE TO STORE THE LED STATE
int Counter = 100, LastCount = 0;
float Countermm = Counter;
float Countertpi = 0;
float Counterfeed = 0;
float RPM = 0;
long newSpindle = 0;
long oldPosition = -999; // for spindle
float Pitchmm; // used for metric leadscrew calculation and stepper config
float Pitchtpi;
double sum = 0;
int count = 0;
enum MODE // available modes
{
MM,
TPI,
FEED,
};
MODE mode = MM;
void RotaryChanged();
RotaryEncoder Rotary(&RotaryChanged, 20, 21, 28); // Pins 20 (DT), 21 (CLK), 28 (SW) - 28 is just a null number as the (SW) is not used
void RotaryChanged() {
const unsigned int state = Rotary.GetState();
if (state & DIR_CW)
Counter++;
if (state & DIR_CCW)
Counter--;
}
void setup() {
Serial.begin(19200);
pinMode(22,INPUT_PULLUP);
FreqMeasure.begin();
Serial.println("T.I.S.M"); // Death to ART tour, featuring Great Trucking Songs of The Renaissance
display1.setBrightness(0x0f);
display2.setBrightness(0x0f);
delay(500);
display1.clear();
display2.clear();
display1.showNumberDecEx(8888, 0b01000000, false, 4, 4); //Displays 10.11
display2.showNumberDec(1234, false, 4, 0); // shows 10 on far left
MMdebouncer.attach(MMButt_PIN, INPUT_PULLUP); // Attach the debouncer to a pin with INPUT_PULLUP mode
MMdebouncer.interval(25); // Use a debounce interval of 25 milliseconds
pinMode(MMLed_PIN, OUTPUT); // Setup the LED
digitalWrite(MMLed_PIN, ledState);
TPIdebouncer.attach(TPIButt_PIN, INPUT_PULLUP);
TPIdebouncer.interval(25);
pinMode(TPILed_PIN, OUTPUT);
digitalWrite(TPILed_PIN, ledState);
FEEDdebouncer.attach(FEEDButt_PIN, INPUT_PULLUP);
FEEDdebouncer.interval(25);
pinMode(FEEDLed_PIN, OUTPUT);
digitalWrite(FEEDLed_PIN, ledState);
STOPdebouncer.attach(STOPButt_PIN, INPUT_PULLUP);
STOPdebouncer.interval(25);
pinMode(STOPLed_PIN, OUTPUT);
digitalWrite(STOPLed_PIN, ledState);
FWDdebouncer.attach(FWDButt_PIN, INPUT_PULLUP);
FWDdebouncer.interval(25);
pinMode(FWDLed_PIN, OUTPUT);
digitalWrite(FWDLed_PIN, ledState);
REVdebouncer.attach(REVButt_PIN, INPUT_PULLUP);
REVdebouncer.interval(25);
pinMode(REVLed_PIN, OUTPUT);
digitalWrite(REVLed_PIN, ledState);
spindleEnc.setInitConfig(); //Loads default configuration for the encoder channel
spindleEnc.init(); //Initializers the encoder for the channel selected
}
void loop() {
newSpindle = spindleEnc.read();
if (newSpindle != oldPosition) {
//Serial.print("Spindle = ");
//Serial.print(newSpindle);
//Serial.println();
oldPosition = newSpindle;
}
{
// average several readings together - gives slower output and averages out readings
sum = sum + FreqMeasure.read();
count = count + 1;
if (count > 1) {
float frequency = FreqMeasure.countToFrequency(sum / count);
RPM = frequency/0.0166;
if (RPM >0) {
Serial.print("freq ");
Serial.println(RPM);
display1.clear();
display1.showNumberDec(RPM, false, 4, 4);
}
sum = 0;
count = 0;
}
}
readButton(); // read button and update mode
switch (mode) {
case MM:
mm();
break;
case TPI:
tpi();
break;
case FEED:
feed();
break;
}
}
// read button and update mode
void readButton() {
MMdebouncer.update(); // Update the Bounce instance
if (MMdebouncer.fell()) { // Call code if button transitions from HIGH to LOW
ledState = !ledState; // Toggle LED state
digitalWrite(MMLed_PIN, ledState);
switch (mode)
case MM:
default:
break;
} else
TPIdebouncer.update();
if (TPIdebouncer.fell()) {
ledState = !ledState;
digitalWrite(TPILed_PIN, ledState);
switch (mode)
case TPI:
default:
break;
} else
FEEDdebouncer.update();
if (FEEDdebouncer.fell()) {
ledState = !ledState;
digitalWrite(FEEDLed_PIN, ledState);
switch (mode)
case FEED:
default:
break;
}
}
void mm() {
//Serial.println("void mm");
if (LastCount != Counter) {
//Serial.println(Counter);
Pitchmm = Counter / 100.00; //Metric threads have dec point values. i.e 1.25mm
display2.clear();
display2.showNumberDecEx(Counter, 0b10000000, true, 3, 1); // Use Counter value for deciml point placement on LED disp
//Serial.println(Pitchmm);
}
}
void tpi() {
Serial.println("void tpi");
if (LastCount != Counter) {
Serial.println(Counter);
Pitchtpi = Counter; // value in TPI
display2.clear();
display2.showNumberDec(Pitchtpi, false, 2, 1);
}
}
void feed() {
Serial.println("feed tpi");
if (LastCount != Counter) {
Serial.println(Counter);
Pitchtpi = Counter; // value in TPI
display2.clear();
display2.showNumberDec(Pitchtpi, false, 2, 1);
}
}