I copied some tachometer code from https://www.homemade-circuits.com/tachometer-using-arduino/ which had an attachInterrupt() before setting the pinMode() and discovered that on the Teensy 3.2, different from the Uno, setting the pinMode after the attachInterrupt seems to detach the interrupt.
After spending too long debugging my way to the difference and into some much improved different tachometer code, I found some discussion at https://github.com/arduino/ArduinoCore-sam/issues/26 and tried this code:
The github thread indicated a use-case for keeping interrupts while changing pinmode, but that wasn't what I needed. I would expect the Teensy behavior to be the same as the Uno, and to not have to pay attention to the order of calls on different architectures.
My kluged working tachometer code is below. It worked well enough to test the 5-650RPM range of speeds on a DIY wood lathe with a 12" plywood pulley driven by a treadmill motor.
After spending too long debugging my way to the difference and into some much improved different tachometer code, I found some discussion at https://github.com/arduino/ArduinoCore-sam/issues/26 and tried this code:
Code:
// Interrupt comparison between Uno & Teensy 3.2
// Based on https://github.com/arduino/ArduinoCore-sam/issues/26 code
// Expected output (obtained on Uno)
// Pin high, count=0
// Pin low, count=1
// Pin high, count=1
// Pin low, count=2
// BUT...
// On due (Teensy 3.2), count remains 0
int pin = 3; // INT 1 on UNO
volatile int i = 0;
void test() { i++; }
void setup() {
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(pin), test, FALLING); // Uno: Counts up, Teensy: does not count
pinMode(pin, OUTPUT);
//attachInterrupt(digitalPinToInterrupt(pin), test, FALLING); // Both Uno and Teensy count
}
void loop() {
digitalWrite(pin, HIGH);
Serial.print("Pin high, count="); Serial.println(i);
delay(500);
digitalWrite(pin, LOW);
Serial.print("Pin low, count="); Serial.println(i);
delay(500);
}
The github thread indicated a use-case for keeping interrupts while changing pinmode, but that wasn't what I needed. I would expect the Teensy behavior to be the same as the Uno, and to not have to pay attention to the order of calls on different architectures.
My kluged working tachometer code is below. It worked well enough to test the 5-650RPM range of speeds on a DIY wood lathe with a 12" plywood pulley driven by a treadmill motor.
Code:
// Tachometer from https://www.homemade-circuits.com/tachometer-using-arduino/
// But its interrupts were odd.
// This measures dT between pulses, debounced
// and reports when RPM changes
const byte millis_not_micros = 0;
const byte debug = 1; // should optimize out stuff
const int debounce = (2 * millis_not_micros?1:1000); // ms for settling.
const int sensorPin = 14; // reed sensor
const int sensor_ground = 15 ; // Ground for pulling sensor low
volatile int countsD = 0;
const float alpha = 0.5; // EWMA smoother
float rpm;
unsigned long tnow = 0UL;
unsigned long prev = 0UL;
volatile unsigned long dt = 1;
void count_function()
{ /*The ISR function
Called on Interrupt */
tnow=millis_not_micros? millis() : micros();
if ((tnow - prev) >= debounce){
dt = tnow - prev;
prev = tnow;
countsD++;
}
}
void setup()
{
Serial.begin(9600);
pinMode(sensorPin, INPUT_PULLUP); //Sets sensor as input
pinMode(sensor_ground, OUTPUT); //Sets sensor as input
attachInterrupt(digitalPinToInterrupt(sensorPin), count_function, FALLING); //Interrupts are called on Rise of Input
digitalWrite(sensor_ground,0);
rpm = 0;
count_function(); // initialize
}
void loop()
{
static int lastcount;
if (countsD != lastcount ) {
lastcount = countsD;
rpm = (1-alpha)* rpm+ alpha * 60.0 * (millis_not_micros?1000.0:1e6) /(dt);
Serial.print("RPM=");
Serial.print(rpm); //Calculated values are displayed
if(debug){
Serial.print(" Sensor: ");Serial.print(digitalRead(sensorPin));
Serial.print(" tnow: ");Serial.print(tnow);
Serial.print(" prev: ");Serial.print(prev);
}
Serial.print(" countsD: ");Serial.print(countsD);
Serial.print(" dt: ");Serial.print(dt);;
Serial.println();
}
}