Counters

IO Diagram showing the up/down pulses the counter is counting.

The Counter class (Java, C++) is a versatile class that allows the counting of pulse edges on a digital input. Counter is used as a component in several more-complicated WPILib classes (such as Encoder and Ultrasonic), but is also quite useful on its own.

Nota

Hay un total de 8 unidades de contador en la FPGA roboRIO, lo que significa que no más de 8 objetos Counter pueden instanciar en cualquier momento, incluidos aquellos contenidos como recursos en otros objetos WPILib. Para obtener información detallada sobre cuándo un Counter puede ser utilizado por otro objeto, consulte la documentación oficial de la API.

Configurar un counter

La clase Counter se puede configurar de varias formas para proporcionar diferentes funcionalidades.

Modos del counter

El objeto Counter puede configurarse para operar en uno de cuatro modos diferentes:

  1. Two-pulse mode: cuenta hacia arriba y hacia abajo según los bordes de dos canales diferentes.

  2. Semi-period mode:Mide la duración de un pulso en un solo canal.

  3. Pulse-length mode: cuenta hacia arriba y hacia abajo según los bordes de un canal, con la dirección determinada por la duración del pulso en ese canal.

  4. External direction mode: cuenta hacia arriba y hacia abajo según los bordes de un canal, con un canal separado que especifica la dirección.

Nota

In all modes except semi-period mode, the counter can be configured to increment either once per edge (2X decoding), or once per pulse (1X decoding). By default, counters are set to two-pulse mode, though if only one channel is specified the counter will only count up.

Modo de dos pulsos

En el modo de dos pulsos, el Counter contará hacia arriba por cada flanco / pulso en el «canal ascendente» especificado, y hacia abajo por cada flanco / pulso en el «canal descendente» especificado. Un contador se puede inicializar en dos pulsos con el siguiente código:

// Create a new Counter object in two-pulse mode
Counter counter = new Counter(Counter.Mode.k2Pulse);

@Override
public void robotInit() {
    // Set up the input channels for the counter
    counter.setUpSource(1);
    counter.setDownSource(2);

    // Set the decoding type to 2X
    counter.setUpSourceEdge(true, true);
    counter.setDownSourceEdge(true, true);
}
// Create a new Counter object in two-pulse mode
frc::Counter counter{frc::Counter::Mode::k2Pulse};

void Robot::RobotInit() {
    // Set up the input channels for the counter
    counter.SetUpSource(1);
    counter.SetDownSource(2);

    // Set the decoding type to 2X
    counter.SetUpSourceEdge(true, true);
    counter.SetDownSourceEdge(true, true);

Modo de semiperíodo

En el modo de semiperíodo, el Counter contará la duración de los pulsos en un canal, ya sea desde un borde ascendente hasta el siguiente borde descendente, o desde un borde descendente hasta el siguiente borde ascendente. Un contador se puede inicializar en modo semiperíodo con el siguiente código:

// Create a new Counter object in two-pulse mode
Counter counter = new Counter(Counter.Mode.kSemiperiod);

@Override
public void robotInit() {
    // Set up the input channel for the counter
    counter.setUpSource(1);

    // Set the encoder to count pulse duration from rising edge to falling edge
    counter.setSemiPeriodMode(true);
}
// Create a new Counter object in two-pulse mode
frc::Counter counter{frc::Counter::Mode::kSemiperiod};

void Robot() {
    // Set up the input channel for the counter
    counter.SetUpSource(1);

    // Set the encoder to count pulse duration from rising edge to falling edge
    counter.SetSemiPeriodMode(true);

Para obtener el ancho de pulso, llame al método getPeriod().

// Return the measured pulse width in seconds
counter.getPeriod();
// Return the measured pulse width in seconds
counter.GetPeriod();

Modo de duración de pulso

En el modo de longitud de pulso, el contador contará hacia arriba o hacia abajo según la longitud del pulso. Un pulso por debajo del umbral de tiempo especificado se interpretará como un conteo hacia adelante y un pulso por encima del umbral es un conteo hacia atrás. Esto es útil para algunos sensores de dientes de engranajes que codifican la dirección de esta manera. Un contador se puede inicializar en este modo de la siguiente manera:

// Create a new Counter object in two-pulse mode
Counter counter = new Counter(Counter.Mode.kPulseLength);

@Override
public void robotInit() {
    // Set up the input channel for the counter
    counter.setUpSource(1);

    // Set the decoding type to 2X
    counter.setUpSourceEdge(true, true);

    // Set the counter to count down if the pulses are longer than .05 seconds
    counter.setPulseLengthMode(.05)
}
// Create a new Counter object in two-pulse mode
frc::Counter counter{frc::Counter::Mode::kPulseLength};

void Robot::RobotInit() {
    // Set up the input channel for the counter
    counter.SetUpSource(1);

    // Set the decoding type to 2X
    counter.SetUpSourceEdge(true, true);

    // Set the counter to count down if the pulses are longer than .05 seconds
    counter.SetPulseLengthMode(.05)

Modo de dirección externa

In external direction mode, the counter counts either up or down depending on the level on the second channel. If the direction source is low, the counter will increase; if the direction source is high, the counter will decrease (to reverse this, see the next section). A counter can be initialized in this mode as follows:

// Create a new Counter object in two-pulse mode
Counter counter = new Counter(Counter.Mode.kExternalDirection);

@Override
public void robotInit() {
    // Set up the input channels for the counter
    counter.setUpSource(1);
    counter.setDownSource(2);

    // Set the decoding type to 2X
    counter.setUpSourceEdge(true, true);
}
// Create a new Counter object in two-pulse mode
frc::Counter counter{frc::Counter::Mode::kExternalDirection};

void RobotInit() {
    // Set up the input channels for the counter
    counter.SetUpSource(1);
    counter.SetDownSource(2);

    // Set the decoding type to 2X
    counter.SetUpSourceEdge(true, true);

Configurar los parámetros del contador

Nota

La clase Counter no hace ninguna suposición sobre las unidades de distancia; devolverá valores en las unidades que se hayan utilizado para calcular el valor de distancia por pulso. De este modo, los usuarios tienen un control completo sobre las unidades de distancia utilizadas. Sin embargo, las unidades de tiempo son siempre en segundos.

Nota

El número de pulsos utilizados en el cálculo de la distancia por pulso no depende del tipo de decodificación; cada «pulso» siempre debe considerarse como un ciclo completo (ascendente y descendente).

Aparte de las configuraciones específicas del modo, la clase Counter ofrece varios métodos de configuración adicionales:

// Configures the counter to return a distance of 4 for every 256 pulses
// Also changes the units of getRate
counter.setDistancePerPulse(4./256.);

// Configures the counter to consider itself stopped after .1 seconds
counter.setMaxPeriod(.1);

// Configures the counter to consider itself stopped when its rate is below 10
counter.setMinRate(10);

// Reverses the direction of the counter
counter.setReverseDirection(true);

// Configures an counter to average its period measurement over 5 samples
// Can be between 1 and 127 samples
counter.setSamplesToAverage(5);
// Configures the counter to return a distance of 4 for every 256 pulses
// Also changes the units of getRate
counter.SetDistancePerPulse(4./256.);

// Configures the counter to consider itself stopped after .1 seconds
counter.SetMaxPeriod(.1);

// Configures the counter to consider itself stopped when its rate is below 10
counter.SetMinRate(10);

// Reverses the direction of the counter
counter.SetReverseDirection(true);

// Configures an counter to average its period measurement over 5 samples
// Can be between 1 and 127 samples
counter.SetSamplesToAverage(5);

Leer información de contadores

Independientemente del modo, hay cierta información que la clase Counter siempre expone a los usuarios:

Count

Los usuarios pueden obtener el recuento actual con el método get().

// returns the current count
counter.get();
// returns the current count
counter.Get();

Distancia

Nota

Counters measure relative distance, not absolute; the distance value returned will depend on the position of the encoder when the robot was turned on or the encoder value was last reset.

If the distance per pulse has been configured, users can obtain the total distance traveled by the counted sensor with the getDistance() method:

// returns the current distance
counter.getDistance();
// returns the current distance
counter.GetDistance();

Velocidad

Nota

Las unidades de tiempo para la clase Counter son siempre en segundos.

Los usuarios pueden obtener la tasa de cambio actual del contador con el método getRate():

// Gets the current rate of the counter
counter.getRate();
// Gets the current rate of the counter
counter.GetRate();

Detenido

Los usuarios pueden obtener si el contador está parado con el método: code:getStopped():

// Gets whether the counter is stopped
counter.getStopped();
// Gets whether the counter is stopped
counter.GetStopped();

Dirección

Los usuarios pueden obtener la dirección en la que el contador se movió por última vez con el método getDirection() :

// Gets the last direction in which the counter moved
counter.getDirection();
// Gets the last direction in which the counter moved
counter.GetDirection();

Período

Nota

In semi-period mode, this method returns the duration of the pulse, not of the period.

Los usuarios pueden obtener la duración (en segundos) del período más reciente con el método getPeriod() :

// returns the current period in seconds
counter.getPeriod();
// returns the current period in seconds
counter.GetPeriod();

Reiniciar un counter

Para restablecer un contador a una lectura de distancia de cero, llame al método reset(). Esto es útil para asegurar que la distancia medida corresponde a la medida física deseada real.

// Resets the encoder to read a distance of zero
counter.reset();
// Resets the encoder to read a distance of zero
counter.Reset();

Usando conters en código

Counters are useful for a wide variety of robot applications - but since the Counter class is so varied, it is difficult to provide a good summary of them here. Many of these applications overlap with the Encoder class - a simple counter is often a cheaper alternative to a quadrature encoder. For a summary of potential uses for encoders in code, see Codificadores - Software.