2025-11-18 15:39:59 -08:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
|
|
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
|
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
|
|
|
/* the project. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
package frc4388.robot.subsystems;
|
|
|
|
|
|
2026-02-12 14:36:26 -07:00
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
2025-11-18 15:39:59 -08:00
|
|
|
import org.littletonrobotics.junction.AutoLogOutput;
|
|
|
|
|
|
|
|
|
|
import edu.wpi.first.wpilibj.DriverStation;
|
2026-01-29 18:02:04 -07:00
|
|
|
import edu.wpi.first.wpilibj.PWM;
|
2025-11-18 15:39:59 -08:00
|
|
|
import edu.wpi.first.wpilibj2.command.SubsystemBase;
|
|
|
|
|
import frc4388.robot.constants.Constants.LEDConstants;
|
|
|
|
|
import frc4388.utility.status.Status;
|
|
|
|
|
import frc4388.utility.status.FaultReporter;
|
|
|
|
|
import frc4388.utility.status.Queryable;
|
|
|
|
|
import frc4388.utility.status.Status.ReportLevel;
|
|
|
|
|
import frc4388.utility.structs.LEDPatterns;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Allows for the control of a 5v LED Strip using a Rev Robotics Blinkin LED
|
|
|
|
|
* Driver
|
|
|
|
|
*/
|
|
|
|
|
public class LED extends SubsystemBase implements Queryable {
|
2026-01-29 18:02:04 -07:00
|
|
|
private PWM m_pwm;
|
|
|
|
|
|
|
|
|
|
public LED(int PWMport) {
|
2025-11-18 15:39:59 -08:00
|
|
|
FaultReporter.register(this);
|
2026-01-29 18:02:04 -07:00
|
|
|
m_pwm = new PWM(PWMport);
|
|
|
|
|
|
|
|
|
|
m_pwm.setBoundsMicroseconds(2003, 1550, 1500, 1460, 999);
|
|
|
|
|
m_pwm.setPeriodMultiplier(PWM.PeriodMultiplier.k1X);
|
|
|
|
|
m_pwm.setSpeed(0.0);
|
|
|
|
|
m_pwm.setZeroLatch();
|
|
|
|
|
|
2025-11-18 15:39:59 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private LEDPatterns mode = LEDConstants.DEFAULT_PATTERN;
|
|
|
|
|
|
|
|
|
|
public void setMode(LEDPatterns pattern){
|
2026-02-12 10:18:12 -07:00
|
|
|
// Don't stall the main thread every time the setMode function is called
|
|
|
|
|
if(this.mode != pattern) {
|
2026-02-12 14:36:26 -07:00
|
|
|
this.mode = pattern;
|
2026-02-12 10:18:12 -07:00
|
|
|
setTo5V();
|
|
|
|
|
}
|
2025-11-18 15:39:59 -08:00
|
|
|
}
|
|
|
|
|
|
2026-02-14 14:03:32 -08:00
|
|
|
@AutoLogOutput
|
2026-01-29 19:30:50 -07:00
|
|
|
public String getMode(){
|
|
|
|
|
return mode.name();
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-18 15:39:59 -08:00
|
|
|
public void update() {
|
|
|
|
|
if(DriverStation.isDisabled()){
|
2026-01-29 18:02:04 -07:00
|
|
|
m_pwm.setSpeed(LEDConstants.DEFAULT_PATTERN.getValue());
|
2025-11-18 15:39:59 -08:00
|
|
|
}else
|
2026-01-29 18:02:04 -07:00
|
|
|
m_pwm.setSpeed(mode.getValue());
|
2025-11-18 15:39:59 -08:00
|
|
|
}
|
|
|
|
|
|
2026-01-29 18:02:04 -07:00
|
|
|
// I freaking hate unmaintained code so much
|
|
|
|
|
// https://github.com/REVrobotics/Blinkin-Firmware/pull/12
|
|
|
|
|
// Turns out the REV Blinkin firmware has an undocumented 'feature'
|
|
|
|
|
// that means that whenever a specific pulse length is randomly generated,
|
|
|
|
|
// the pulse has a chance of changing the selected strip of the Blinkin
|
|
|
|
|
// 2125 μs for 5v, 2145 μs for 12v
|
|
|
|
|
// Also check out: https://www.chiefdelphi.com/t/rev-blinkin-resetting-strip-mode-randomly/432510/12
|
|
|
|
|
public void setTo5V() {
|
|
|
|
|
try {
|
|
|
|
|
m_pwm.setPulseTimeMicroseconds(2125);
|
2026-02-12 14:36:26 -07:00
|
|
|
TimeUnit.MICROSECONDS.sleep(2125*2);// Wait long enough for one pulse to go through
|
2026-01-29 18:02:04 -07:00
|
|
|
update();
|
|
|
|
|
} catch (InterruptedException e) {}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-18 15:39:59 -08:00
|
|
|
@AutoLogOutput
|
|
|
|
|
public String state() {
|
|
|
|
|
return mode.getClass().toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getName() {
|
|
|
|
|
return "LEDs";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Status diagnosticStatus() {
|
|
|
|
|
Status status = new Status();
|
|
|
|
|
|
2026-01-29 18:02:04 -07:00
|
|
|
// if(!LEDController.isAlive())
|
|
|
|
|
// status.addReport(ReportLevel.ERROR, "LED is DISCONNECTED");
|
2025-11-18 15:39:59 -08:00
|
|
|
|
|
|
|
|
status.addReport(ReportLevel.INFO, "LED Mode: " + mode.name());
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|