// Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. package org.wpilib.counter; import org.wpilib.hardware.hal.CounterJNI; import org.wpilib.hardware.hal.HAL; import org.wpilib.util.sendable.Sendable; import org.wpilib.util.sendable.SendableBuilder; import org.wpilib.util.sendable.SendableRegistry; /** * Tachometer. * *

The Tachometer class measures the time between digital pulses to determine the rotation * velocity of a mechanism. Examples of devices that could be used with the tachometer class are a * hall effect sensor, break beam sensor, or optical sensor detecting tape on a shooter wheel. * Unlike encoders, this class only needs a single digital input. */ public class Tachometer implements Sendable, AutoCloseable { private final int m_handle; private int m_edgesPerRevolution = 1; /** * Constructs a new tachometer. * * @param channel The channel of the Tachometer. * @param configuration The edge configuration */ @SuppressWarnings("this-escape") public Tachometer(int channel, EdgeConfiguration configuration) { m_handle = CounterJNI.initializeCounter(channel, configuration.rising); HAL.reportUsage("IO", channel, "Tachometer"); SendableRegistry.add(this, "Tachometer", channel); } @Override public void close() { SendableRegistry.remove(this); CounterJNI.freeCounter(m_handle); } /** * Gets the tachometer period. * * @return Current period (in seconds). */ public double getPeriod() { return CounterJNI.getCounterPeriod(m_handle); } /** * Gets the tachometer frequency. * * @return Current frequency (in hertz). */ public double getFrequency() { double period = getPeriod(); if (period == 0) { return 0; } return 1 / period; } /** * Gets the number of edges per revolution. * * @return Edges per revolution. */ public int getEdgesPerRevolution() { return m_edgesPerRevolution; } /** * Sets the number of edges per revolution. * * @param edgesPerRevolution Edges per revolution. */ public void setEdgesPerRevolution(int edgesPerRevolution) { m_edgesPerRevolution = edgesPerRevolution; } /** * Gets the current tachometer revolutions per second. * *

setEdgesPerRevolution must be set with a non 0 value for this to return valid values. * * @return Current RPS. */ public double getRevolutionsPerSecond() { double period = getPeriod(); if (period == 0) { return 0; } int edgesPerRevolution = getEdgesPerRevolution(); if (edgesPerRevolution == 0) { return 0; } return (1.0 / edgesPerRevolution) / period; } /** * Gets the current tachometer revolutions per minute. * *

setEdgesPerRevolution must be set with a non 0 value for this to return valid values. * * @return Current RPM. */ public double getRevolutionsPerMinute() { return getRevolutionsPerSecond() * 60; } /** * Gets if the tachometer is stopped. * * @return True if the tachometer is stopped. */ public boolean getStopped() { return CounterJNI.getCounterStopped(m_handle); } /** * Sets the maximum period before the tachometer is considered stopped. * * @param maxPeriod The max period (in seconds). */ public void setMaxPeriod(double maxPeriod) { CounterJNI.setCounterMaxPeriod(m_handle, maxPeriod); } @Override public void initSendable(SendableBuilder builder) { builder.setSmartDashboardType("Tachometer"); builder.addDoubleProperty("RPS", this::getRevolutionsPerSecond, null); builder.addDoubleProperty("RPM", this::getRevolutionsPerMinute, null); } }