Arduino Zero, i.e. ATSAMD21? That's a Cortex-M0+, and darnit, that one does not have a cycle counter in the DWT. On Cortex-M4's and others, DWT_CYCCNT is a monotonic cycle counter one can read and use to accurately measure intervals of up to 2**32 cycles (minute and a half at 48 MHz, minute at 72 MHz, and so on); all one needs to do is ensure the DWT is enabled.
The core Arduino support for SAMD21 is
here, with linker scripts
here, pin definitions
here, and the Arduino main library stuff
here.
If we look at
SAMD core delay.c, we'll find a note that indicates
millis() is not safe in an interrupt context, but
micros() is.
(
micros() calculates microseconds, and uses the same systick counter. It uses the counter value in addition to the number of cycles of the counter, thus getting somewhat better resolution. Since a 32-bit microsecond counter rolls over every 4294 seconds or so, it suffices for intervals of up to about an hour and eleven minutes.)
My very first suggestion would be to replace every instance of
millis() with
(micros()/1000), and see if anything changes. Better yet,
void lcdSpeedPrint() {
uint32_t tempvarTime = micros();
uint32_t tempvarCounts = vTachoSpeedCounts;
vTachoSpeedCounts = 0;
uint32_t tvTimeDifference = (tempvarTime - varLastSpeedTime);
varLastSpeedTime = tempvarTime;
uint32_t vtSpeed = (vTachoSpeedCounts * tachoStep * 6) / (tvTimeDifference * 10); // *600/1000 = *6/10
lcd.clear();
lcd.print((int)tvTimeDifference, DEC);
lcd.setCursor(0, 1);
lcd.print((int)vtSpeed, DEC);
lcd.setCursor(0, 2);
lcd.print((int)vTachoSpeedCounts, DEC);
lcd.setCursor(0, 3);
lcd.print((int)tempvarTime, DEC);
}
With this, looking at the LCD output will tell us crucial information. I assume it has four lines, with at least 10 digits visible on each line.
The first lcd.print prints the tachometer counting duration in microseconds: 1000 is one millisecond, 1000000 one second.
The second lcd.print prints the calculated (RPM?) value. I didn't check the math, just copied it and adjusted to microseconds from the initial post.
(If you asked me, I'd say the correct formula is
(pulses * 60000) / (interval_in_microseconds * pulses_per_revolution / 1000), but you can move the zeros from the multiplier to the divisor or vice versa to ensure both subexpressions can be properly represented as a 32-bit unsigned integer. As it stands, at less than second intervals, it works for up to 71582 pulses per second and 4294 pulses per revolution, before it craps out.)
The third lcd.print prints, I assume, the number of tachometer pulses. If this stays zero, it means either that the variable is not being updated, or that it is updated in an interrupt but vTachoSpeedCounts is not marked volatile, and thus the compiler assumes it does not change (unlikely, though).
The fourth lcd.print prints the microsecond timer value. If it does not change at all, it means the systick counter (hardware) is disabled. If only the three or four lowest/rightmost digits change, it means the systick interrupt is not firing correctly (perhaps because interrupts are disabled).
This should be a relatively simple test, but provide much needed additional information (by observing what the LCD shows).