2024-09-18 13:05:17 -04:00

898 lines
30 KiB
C++

/**
* \file pros/adi.hpp
*
* Contains prototypes for interfacing with the ADI.
*
* Visit https://pros.cs.purdue.edu/v5/tutorials/topical/adi.html to learn more.
*
* This file should not be modified by users, since it gets replaced whenever
* a kernel upgrade occurs.
*
* \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef _PROS_ADI_HPP_
#define _PROS_ADI_HPP_
#include <cstdint>
#include <tuple>
#include <utility>
#include <vector>
#include "pros/adi.h"
namespace pros {
/** type definition for the pair of smart port and adi port for the basic adi devices */
using ext_adi_port_pair_t = std::pair<std::uint8_t, std::uint8_t>;
/** type definition for the triplet of smart port and two adi ports for the two wire adi devices*/
using ext_adi_port_tuple_t = std::tuple<std::uint8_t, std::uint8_t, std::uint8_t>;
class ADIPort {
public:
/**
* Configures an ADI port to act as a given sensor type.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param type
* The configuration type for the port
*/
explicit ADIPort(std::uint8_t adi_port, adi_port_config_e_t type = E_ADI_TYPE_UNDEFINED);
/**
* Configures an ADI port on an adi expander to act as a given sensor type.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_pair
* The pair of the smart port number (from 1-22) and the ADI port number
* (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param type
* The configuration type for the port
*/
ADIPort(ext_adi_port_pair_t port_pair, adi_port_config_e_t type = E_ADI_TYPE_UNDEFINED);
/**
* Gets the configuration for the given ADI port.
*
* \return The ADI configuration for the given port
*/
std::int32_t get_config() const;
/**
* Gets the value for the given ADI port.
*
* \return The value stored for the given port
*/
std::int32_t get_value() const;
/**
* Configures an ADI port to act as a given sensor type.
*
* \param type
* The configuration type for the port
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
std::int32_t set_config(adi_port_config_e_t type) const;
/**
* Sets the value for the given ADI port.
*
* This only works on ports configured as outputs, and the behavior will
* change depending on the configuration of the port.
*
* \param value
* The value to set the ADI port to
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
std::int32_t set_value(std::int32_t value) const;
protected:
std::uint8_t _smart_port;
std::uint8_t _adi_port;
};
class ADIAnalogIn : protected ADIPort {
public:
/**
* Configures an ADI port to act as an Analog Input.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
explicit ADIAnalogIn(std::uint8_t adi_port);
/**
* Configures an ADI port on an adi expander to act as an Analog Input.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_pair
* The pair of the smart port number (from 1-22) and the
* ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
ADIAnalogIn(ext_adi_port_pair_t port_pair);
/**
* Calibrates the analog sensor on the specified port and returns the new
* calibration value.
*
* This method assumes that the true sensor value is not actively changing at
* this time and computes an average from approximately 500 samples, 1 ms
* apart, for a 0.5 s period of calibration. The average value thus calculated
* is returned and stored for later calls to the
* pros::ADIAnalogIn::get_value_calibrated() and
* pros::ADIAnalogIn::get_value_calibrated_HR() functions. These functions
* will return the difference between this value and the current sensor value
* when called.
*
* Do not use this function when the sensor value might be unstable (gyro
* rotation, accelerometer movement).
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as an analog input
*
* \return The average sensor value computed by this function
*/
std::int32_t calibrate() const;
/**
* Gets the 12 bit calibrated value of an analog input port.
*
* The pros::ADIAnalogIn::calibrate() function must be run first. This
* function is inappropriate for sensor values intended for integration, as
* round-off error can accumulate causing drift over time. Use
* pros::ADIAnalogIn::get_value_calibrated_HR() instead.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as an analog input
*
* \return The difference of the sensor value from its calibrated default from
* -4095 to 4095
*/
std::int32_t get_value_calibrated() const;
/**
* Gets the 16 bit calibrated value of an analog input port.
*
* The pros::ADIAnalogIn::calibrate() function must be run first. This is
* intended for integrated sensor values such as gyros and accelerometers to
* reduce drift due to round-off, and should not be used on a sensor such as a
* line tracker or potentiometer.
*
* The value returned actually has 16 bits of "precision", even though the ADC
* only reads 12 bits, so that error induced by the average value being
* between two values when integrated over time is trivial. Think of the value
* as the true value times 16.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as an analog input
*
* \return The difference of the sensor value from its calibrated default from
* -16384 to 16384
*/
std::int32_t get_value_calibrated_HR() const;
/**
* Gets the 12-bit value of the specified port.
*
* The value returned is undefined if the analog pin has been switched to a
* different mode.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as an analog input
*
* \return The analog sensor value, where a value of 0 reflects an input
* voltage of nearly 0 V and a value of 4095 reflects an input voltage of
* nearly 5 V
*/
using ADIPort::get_value;
};
// using ADIPotentiometer = ADIAnalogIn;
using ADILineSensor = ADIAnalogIn;
using ADILightSensor = ADIAnalogIn;
using ADIAccelerometer = ADIAnalogIn;
class ADIAnalogOut : private ADIPort {
public:
/**
* Configures an ADI port to act as an Analog Output.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
*/
explicit ADIAnalogOut(std::uint8_t adi_port);
/**
* Configures an ADI port on an adi_expander to act as an Analog Output.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_pair
* The pair of the smart port number (from 1-22) and the
* ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
*
*/
ADIAnalogOut(ext_adi_port_pair_t port_pair);
/**
* Sets the value for the given ADI port.
*
* This only works on ports configured as outputs, and the behavior will
* change depending on the configuration of the port.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as an analog output
*
* \param value
* The value to set the ADI port to
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
using ADIPort::set_value;
};
class ADIDigitalOut : private ADIPort {
public:
/**
* Configures an ADI port to act as a Digital Output.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param init_state
* The initial state for the port
*/
explicit ADIDigitalOut(std::uint8_t adi_port, bool init_state = LOW);
/**
* Configures an ADI port on an adi_expander to act as a Digital Output.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_pair
* The pair of the smart port number (from 1-22) and the
* ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param init_state
* The initial state for the port
*/
ADIDigitalOut(ext_adi_port_pair_t port_pair, bool init_state = LOW);
/**
* Sets the value for the given ADI port.
*
* This only works on ports configured as outputs, and the behavior will
* change depending on the configuration of the port.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a digital output
*
* \param value
* The value to set the ADI port to
*
* \return if the operation was successful or PROS_ERR if the operation failed, setting errno.
*/
using ADIPort::set_value;
};
class ADIDigitalIn : private ADIPort {
public:
/**
* Configures an ADI port to act as a Digital Input.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
*/
explicit ADIDigitalIn(std::uint8_t adi_port);
/**
* Configures an ADI port on an adi_expander to act as a Digital Input.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_pair
* The pair of the smart port number (from 1-22) and the
* ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
*/
ADIDigitalIn(ext_adi_port_pair_t port_pair);
/**
* Gets a rising-edge case for a digital button press.
*
* This function is not thread-safe.
* Multiple tasks polling a single button may return different results under
* the same circumstances, so only one task should call this function for any
* given button. E.g., Task A calls this function for buttons 1 and 2. Task B
* may call this function for button 3, but should not for buttons 1 or 2. A
* typical use-case for this function is to call inside opcontrol to detect
* new button presses, and not in any other tasks.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a digital input
*
* \return 1 if the button is pressed and had not been pressed the last time
* this function was called, 0 otherwise.
*/
std::int32_t get_new_press() const;
/**
* Gets the value for the given ADI port.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a digital input
*
* \return The value stored for the given port
*/
using ADIPort::get_value;
};
using ADIButton = ADIDigitalIn;
class ADIMotor : private ADIPort {
public:
/**
* Configures an ADI port to act as a Motor.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
*/
explicit ADIMotor(std::uint8_t adi_port);
/**
* Configures an ADI port on an adi_expander to act as a Motor.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_pair
* The pair of the smart port number (from 1-22) and the
* ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
*/
ADIMotor(ext_adi_port_pair_t port_pair);
/**
* Stops the motor on the given port.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a motor
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
std::int32_t stop() const;
/**
* Sets the speed of the motor on the given port.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a motor
*
* \param value
* The new signed speed; -127 is full reverse and 127 is full forward,
* with 0 being off
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
using ADIPort::set_value;
/**
* Gets the last set speed of the motor on the given port.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a motor
*
* \return The last set speed of the motor on the given port
*/
using ADIPort::get_value;
};
class ADIEncoder : private ADIPort {
public:
/**
* Configures a set of ADI ports to act as an Encoder.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port_top
* The "top" wire from the encoder sensor with the removable cover side up
* \param adi_port_bottom
* The "bottom" wire from the encoder sensor
* \param reverse
* If "true", the sensor will count in the opposite direction
*/
ADIEncoder(std::uint8_t adi_port_top, std::uint8_t adi_port_bottom, bool reversed = false);
/**
* Configures a set of ADI ports on an adi_expander to act as an Encoder.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_tuple
* The tuple of the smart port number, the "top" wire from the encoder
* sensor with the removable cover side up, and the "bottom" wire from
* the encoder sensor
* \param reverse
* If "true", the sensor will count in the opposite direction
*/
ADIEncoder(ext_adi_port_tuple_t port_tuple, bool reversed = false);
// Delete copy constructor to prevent a compilation error from the constructor above.
ADIEncoder(ADIEncoder &) = delete;
/**
* Sets the encoder value to zero.
*
* It is safe to use this method while an encoder is enabled. It is not
* necessary to call this method before stopping or starting an encoder.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a motor
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
std::int32_t reset() const;
/**
* Gets the number of ticks recorded by the encoder.
*
* There are 360 ticks in one revolution.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a motor
*
* \return The signed and cumulative number of counts since the last start or
* reset
*/
std::int32_t get_value() const;
};
class ADIUltrasonic : private ADIPort {
public:
/**
* Configures a set of ADI ports to act as an Ultrasonic sensor.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_ping
* The port connected to the orange OUTPUT cable. This should be in port
* 1, 3, 5, or 7 ('A', 'C', 'E', 'G').
* \param port_echo
* The port connected to the yellow INPUT cable. This should be in the
* next highest port following port_ping.
*/
ADIUltrasonic(std::uint8_t adi_port_ping, std::uint8_t adi_port_echo);
/**
* Configures a set of ADI ports on an adi_expander to act as an Ultrasonic sensor.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_tuple
* The tuple of the smart port number, the port connected to the orange
* OUTPUT cable (1, 3, 5, 7 or 'A', 'C', 'E', 'G'), and the port
* connected to the yellow INPUT cable (the next) highest port
* following port_ping).
*/
ADIUltrasonic(ext_adi_port_tuple_t port_tuple);
/**
* Gets the current ultrasonic sensor value in centimeters.
*
* If no object was found, zero is returned. If the ultrasonic sensor was
* never started, the return value is undefined. Round and fluffy objects can
* cause inaccurate values to be returned.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as an ultrasonic
*
* \return The distance to the nearest object in m^-4 (10000 indicates 1
* meter), measured from the sensor's mounting points.
*/
std::int32_t get_value() const;
};
class ADIGyro : private ADIPort {
public:
/**
* Initializes a gyroscope on the given port. If the given port has not
* previously been configured as a gyro, then this function starts a 1300ms
* calibration period.
*
* It is highly recommended that an ADIGyro object be created in initialize()
* when the robot is stationary to ensure proper calibration. If an ADIGyro
* object is declared at the global scope, a hardcoded 1300ms delay at the
* beginning of initialize will be necessary to ensure that the gyro's
* returned values are correct at the beginning of autonomous/opcontrol.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H')
* \param multiplier
* A scalar value that will be multiplied by the gyro heading value
* supplied by the ADI
*/
explicit ADIGyro(std::uint8_t adi_port, double multiplier = 1);
/**
* Initializes a gyroscope on the given port of an adi expander. If the given
* port has not previously been configured as a gyro, then this function starts
* a 1300ms calibration period.
*
* It is highly recommended that an ADIGyro object be created in initialize()
* when the robot is stationary to ensure proper calibration. If an ADIGyro
* object is declared at the global scope, a hardcoded 1300ms delay at the
* beginning of initialize will be necessary to ensure that the gyro's
* returned values are correct at the beginning of autonomous/opcontrol.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_pair
* The pair of the smart port number (from 1-22) and the
* ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param multiplier
* A scalar value that will be multiplied by the gyro heading value
* supplied by the ADI
*/
ADIGyro(ext_adi_port_pair_t port_pair, double multiplier = 1);
/**
* Gets the current gyro angle in tenths of a degree. Unless a multiplier is
* applied to the gyro, the return value will be a whole number representing
* the number of degrees of rotation times 10.
*
* There are 360 degrees in a circle, thus the gyro will return 3600 for one
* whole rotation.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a gyro
*
* \return The gyro angle in degrees.
*/
double get_value() const;
/**
* Resets the gyroscope value to zero.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a gyro
*
* \return 1 if the operation was successful or PROS_ERR if the operation
* failed, setting errno.
*/
std::int32_t reset() const;
};
class ADIPotentiometer : public ADIAnalogIn {
public:
/**
* Configures an ADI port to act as a Potentiometer.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param potentiometer_type
* An adi_potentiometer_type_e_t enum value specifying the potentiometer version type
*/
ADIPotentiometer(std::uint8_t adi_port, adi_potentiometer_type_e_t potentiometer_type = E_ADI_POT_EDR);
/**
* Configures an ADI port on an adi_expander to act as a Potentiometer.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The pair of the smart port number (from 1-22) and the
* ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param potentiometer_type
* An adi_potentiometer_type_e_t enum value specifying the potentiometer version type
*/
ADIPotentiometer(ext_adi_port_pair_t port_pair, adi_potentiometer_type_e_t potentiometer_type = E_ADI_POT_EDR);
/**
* Gets the current potentiometer angle in tenths of a degree.
*
* The original potentiometer rotates 250 degrees thus returning an angle between 0-250 degrees.
* Potentiometer V2 rotates 330 degrees thus returning an angle between 0-330 degrees.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - The given value is not within the range of ADI Ports
* EADDRINUSE - The port is not configured as a potentiometer
* \return The potentiometer angle in degrees.
*/
double get_angle() const;
/**
* Gets the 12-bit value of the specified port.
*
* The value returned is undefined if the analog pin has been switched to a
* different mode.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a potentiometer
*
* \return The analog sensor value, where a value of 0 reflects an input
* voltage of nearly 0 V and a value of 4095 reflects an input voltage of
* nearly 5 V
*/
using ADIAnalogIn::get_value;
/**
* Calibrates the potentiometer on the specified port and returns the new
* calibration value.
*
* This method assumes that the potentiometer value is not actively changing at
* this time and computes an average from approximately 500 samples, 1 ms
* apart, for a 0.5 s period of calibration. The average value thus calculated
* is returned and stored for later calls to the
* pros::ADIPotentiometer::get_value_calibrated() function. This function
* will return the difference between this value and the current sensor value
* when called.
*
* Do not use this function when the potentiometer value might be unstable (rotating the potentiometer)
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a potentiometer
*
* \return The average potentiometer value computed by this function
*/
using ADIAnalogIn::calibrate;
/**
* Gets the 12 bit calibrated value of a potentiometer port.
*
* The pros::ADIPotentiometer::calibrate() function must be run first.
*
* This function uses the following values of errno when an error state is
* reached:
* ENODEV - The port is not configured as a potentiometer
*
* \return The difference of the potentiometer value from its calibrated default from
* -4095 to 4095
*/
using ADIAnalogIn::get_value_calibrated;
};
class ADILed : protected ADIPort {
public:
/**
* @brief Configures an ADI port to act as a LED.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param adi_port
* The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param length
* The number of LEDs in the chain
*/
ADILed(std::uint8_t adi_port, std::uint32_t length);
/**
* @brief Configures an ADI port on a adi_expander to act as a LED.
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - Either the ADI port value or the smart port value is not within its
* valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21).
*
* \param port_pair
* The pair of the smart port number (from 1-22) and the
* ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure
* \param length
* The number of LEDs in the chain
*/
ADILed(ext_adi_port_pair_t port_pair, std::uint32_t length);
/**
* @brief Operator overload to access the buffer in the ADILed class, it is
* recommended that you call .update(); after doing any operations with this.
*
* @param i 0 indexed pixel of the lED
* @return uint32_t& the address of the buffer at i to modify
*/
std::uint32_t& operator[] (size_t i);
/**
* @brief Clear the entire led strip of color
*
* This function uses the following values of errno when an error state is
* reached:
* ENXIO - The given value is not within the range of ADI Ports
* EINVAL - A parameter is out of bounds/incorrect
* EADDRINUSE - The port is not configured for ADI output
*
* @return PROS_SUCCESS if successful, PROS_ERR if not
*/
std::int32_t clear_all();
std::int32_t clear();
/**
* @brief Force the LED strip to update with the current buffered values, this
* should be called after any changes to the buffer using the [] operator.
*
* This function uses the following values of errno when an error state is
* reached:
* EINVAL - A parameter is out of bounds/incorrect
* EADDRINUSE - The port is not configured for ADI output
*
* @return PROS_SUCCESS if successful, PROS_ERR if not
*/
std::int32_t update() const;
/**
* @brief Set the entire led strip to one color
*
* This function uses the following values of errno when an error state is
* reached:
* EINVAL - A parameter is out of bounds/incorrect
* EADDRINUSE - The port is not configured for ADI output
*
* @param color color to set all the led strip value to
* @return PROS_SUCCESS if successful, PROS_ERR if not
*/
std::int32_t set_all(uint32_t color);
/**
* @brief Set one pixel on the led strip
*
* This function uses the following values of errno when an error state is
* reached:
* EINVAL - A parameter is out of bounds/incorrect
* EADDRINUSE - The port is not configured for ADI output
*
* @param color color to clear all the led strip to
* @param pixel_position position of the pixel to clear
* @return PROS_SUCCESS if successful, PROS_ERR if not
*/
std::int32_t set_pixel(uint32_t color, uint32_t pixel_position);
/**
* @brief Clear one pixel on the led strip
*
* This function uses the following values of errno when an error state is
* reached:
* EINVAL - A parameter is out of bounds/incorrect
* EADDRINUSE - The port is not configured for ADI output
*
* @param pixel_position position of the pixel to clear
* @return PROS_SUCCESS if successful, PROS_ERR if not
*/
std::int32_t clear_pixel(uint32_t pixel_position);
/**
* @brief Get the length of the led strip
*
* This function uses the following values of errno when an error state is
* reached:
* EINVAL - A parameter is out of bounds/incorrect
* EADDRINUSE - The port is not configured for ADI output
*
* @return The length (in pixels) of the LED strip
*/
std::int32_t length();
protected:
std::vector<uint32_t> _buffer;
};
// Alias for ADILed
using ADILED = ADILed;
} // namespace pros
#endif // _PROS_ADI_HPP_