2021-11-23 20:33:36 -08:00
|
|
|
// 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.
|
|
|
|
|
|
2025-11-07 19:55:43 -05:00
|
|
|
package org.wpilib.counter;
|
2021-11-23 20:33:36 -08:00
|
|
|
|
2025-11-07 19:55:43 -05:00
|
|
|
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;
|
2021-11-23 20:33:36 -08:00
|
|
|
|
2021-12-18 21:40:03 -08:00
|
|
|
/**
|
|
|
|
|
* Tachometer.
|
|
|
|
|
*
|
2026-03-06 14:19:15 -08:00
|
|
|
* <p>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.
|
2021-12-18 21:40:03 -08:00
|
|
|
*/
|
2021-11-23 20:33:36 -08:00
|
|
|
public class Tachometer implements Sendable, AutoCloseable {
|
|
|
|
|
private final int m_handle;
|
|
|
|
|
private int m_edgesPerRevolution = 1;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructs a new tachometer.
|
|
|
|
|
*
|
2025-01-28 08:58:34 -08:00
|
|
|
* @param channel The channel of the Tachometer.
|
|
|
|
|
* @param configuration The edge configuration
|
2021-11-23 20:33:36 -08:00
|
|
|
*/
|
2023-12-09 21:45:02 -08:00
|
|
|
@SuppressWarnings("this-escape")
|
2025-01-28 08:58:34 -08:00
|
|
|
public Tachometer(int channel, EdgeConfiguration configuration) {
|
|
|
|
|
m_handle = CounterJNI.initializeCounter(channel, configuration.rising);
|
2021-11-23 20:33:36 -08:00
|
|
|
|
2025-02-07 12:37:23 -08:00
|
|
|
HAL.reportUsage("IO", channel, "Tachometer");
|
2025-01-28 08:58:34 -08:00
|
|
|
SendableRegistry.add(this, "Tachometer", channel);
|
2021-11-23 20:33:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2022-06-14 20:26:53 -07:00
|
|
|
public void close() {
|
2021-11-23 20:33:36 -08:00
|
|
|
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;
|
|
|
|
|
}
|
2022-06-01 10:13:19 -07:00
|
|
|
return 1 / period;
|
2021-11-23 20:33:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2021-12-26 18:52:18 -05:00
|
|
|
* Gets the current tachometer revolutions per second.
|
2021-11-23 20:33:36 -08:00
|
|
|
*
|
|
|
|
|
* <p>setEdgesPerRevolution must be set with a non 0 value for this to return valid values.
|
|
|
|
|
*
|
2021-12-26 18:52:18 -05:00
|
|
|
* @return Current RPS.
|
2021-11-23 20:33:36 -08:00
|
|
|
*/
|
2021-12-26 18:52:18 -05:00
|
|
|
public double getRevolutionsPerSecond() {
|
2021-11-23 20:33:36 -08:00
|
|
|
double period = getPeriod();
|
|
|
|
|
if (period == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int edgesPerRevolution = getEdgesPerRevolution();
|
|
|
|
|
if (edgesPerRevolution == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2021-12-26 18:52:18 -05:00
|
|
|
return (1.0 / edgesPerRevolution) / period;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the current tachometer revolutions per minute.
|
|
|
|
|
*
|
|
|
|
|
* <p>setEdgesPerRevolution must be set with a non 0 value for this to return valid values.
|
|
|
|
|
*
|
|
|
|
|
* @return Current RPM.
|
|
|
|
|
*/
|
|
|
|
|
public double getRevolutionsPerMinute() {
|
|
|
|
|
return getRevolutionsPerSecond() * 60;
|
2021-11-23 20:33:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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");
|
2021-12-26 18:52:18 -05:00
|
|
|
builder.addDoubleProperty("RPS", this::getRevolutionsPerSecond, null);
|
2021-11-23 20:33:36 -08:00
|
|
|
builder.addDoubleProperty("RPM", this::getRevolutionsPerMinute, null);
|
|
|
|
|
}
|
|
|
|
|
}
|