CANdle Implementation?

Our team is using a CANdle to communicate with our human player(s) without any LED strips.

I can find how to declare the CANdle using the CTRE website and some old code from team 2168, however, I cannot find where to declare it (robotcontainer, robotinit, etc…) or where to put the .setLEDS command.

Anyone know where everything goes?

2 Likes

Where you put it is going to depend on how your code is structured. Can you share your code? Ideally as a github (or similar) link

Hi, i am also using a CANdle without any led strips and have only been able setLeds once, anything after that doesnt seem to work, i have even tried making seperate intances of each and still no luck.

Currently I have the following code which is not the best since it is creating multiple instances but i would apreaciate any help. As it will only change the color once.

  
 import com.ctre.phoenix.led.CANdle; 
  
 import edu.wpi.first.wpilibj2.command.CommandBase; 
 import frc.robot.Constants; 
 import frc.robot.subsystems.Arm; 
 import frc.robot.subsystems.DriveTrain; 
  
 public class OutputRollers extends CommandBase { 
   
   public double speed; 
   public boolean isDone = false; 
   public String gamePiece; 
  
   public OutputRollers(double speed, String gamePiece) { 
     this.speed = speed; 
     this.gamePiece = gamePiece; 
   } 
  
    
   @Override 
   public void initialize() { 
   } 
  
    
   @Override 
   public void execute() {
        
       System.out.println(Arm.getRollersVoltage()); 
       if(gamePiece == "Cube" || gamePiece == "cube"){ 
         CANdle led = new CANdle(Constants.ROBOT.CANDLE_ID, "can"); 
         led.setLEDs(125, 35, 250); 
         Arm.setRoller(speed); 
       }  
    
       if(gamePiece == "Cone" || gamePiece == "cone"){ 
         CANdle led = new CANdle(Constants.ROBOT.CANDLE_ID, "can"); 
         led.setLEDs(125, 35, 250); 
         Arm.setRoller(-speed); 
       } 
     // } 
   } 
  
    
   @Override 
    
   public void end(boolean interrupted) { 
     //Stops the motors 
     Arm.setRoller(0); 
   } 
  
    
   @Override 
   public boolean isFinished() { 
     return isDone; 
   } 
 }

Your problem is likely because you are attempting to construct multiple CANdle’s with the same CAN id.

Depending on how you have your code structured teams will construct and define sensors/motors/etc like the CANDle in their corresponding subsystem then access that instance of it inside of the command via the command constructor or similar. Or some teams will statically define stuff inside of robot container.

import com.ctre.phoenix.led.CANdle; 
  
import edu.wpi.first.wpilibj2.command.CommandBase; 
import frc.robot.Constants; 
import frc.robot.subsystems.Arm; 
import frc.robot.subsystems.DriveTrain; 
 
public class OutputRollers extends CommandBase { 
  
  public double speed; 
  public boolean isDone = false; 
  public String gamePiece; 
  private CANdle led;
  public OutputRollers(double speed, String gamePiece, CANdle led) { 
    this.speed = speed; 
    this.gamePiece = gamePiece;
    this.led = led;
  } 
 
   
  @Override 
  public void initialize() { 
  } 
 
   
  @Override 
  public void execute() {
       
      System.out.println(Arm.getRollersVoltage()); 
      if(gamePiece == "Cube" || gamePiece == "cube"){ 
        led.setLEDs(125, 35, 250); 
        Arm.setRoller(speed); 
      }  
   
      if(gamePiece == "Cone" || gamePiece == "cone"){ 
        led.setLEDs(125, 35, 250); 
        Arm.setRoller(-speed); 
      } 
    // } 
  } 
 
   
  @Override 
   
  public void end(boolean interrupted) { 
    //Stops the motors 
    Arm.setRoller(0); 
  } 
 
   
  @Override 
  public boolean isFinished() { 
    return isDone; 
  } 
}

Edit:
Not sure If I misunderstood your problem. It also appears like are setting the leds to be the same color regardless if there is a cone or cube. Also the string comparisons with == will only return true if you pass the same instance of the string. To check if two strings are equal you would want to use the .equals method. Or in this case .equalsIgnoreCase("otherString")
Info on java String comparisons String Comparison in Java - javatpoint

1 Like

Code for our “other” subsystem, I am trying to define the candle, and set brightness, as well as a rainbow animation, but have yet to make a command to change the led color.

edit: changed my code around a bit, added commands, but still wondering if i’ve missed anything else.

edit2: also wondering if you can set individual LEDs, like having 0-3 being red while 4-7 being blue

package frc.robot.subsystems;
import frc.robot.commands.*;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import edu.wpi.first.wpilibj.PowerDistribution.ModuleType;
import com.ctre.phoenix.led.CANdle;
import com.ctre.phoenix.led.RainbowAnimation;
import edu.wpi.first.wpilibj.PowerDistribution;


public class Other extends SubsystemBase {
        //CANdle stuff
        //purple = 80, 45, 127
        //gold = 255, 200, 46
        //define candle
        CANdle candle1 = new CANdle(20);
        //create a rainbow anim.
        RainbowAnimation rainbowAnimation = new RainbowAnimation(1, 1, 0);





private PowerDistribution pDH;

   
    public Other() {
pDH = new PowerDistribution();
 addChild("PDH",pDH);
 


    }

    @Override
    public void periodic() {
        // This method will be called once per scheduler run

    }

    @Override
    public void simulationPeriodic() {
        // This method will be called once per scheduler run when in simulation

    }

    // Put methods for controlling this subsystem
    // here. Call these from Commands.

    //CANdle
    //purple = 80, 45, 127
    //gold = 255, 200, 46

    public void candlePurple(){
        //set brightness
        candle1.configBrightnessScalar(1);
        //set color
        candle1.setLEDs(80, 45, 127);

    }

    public void candleGold(){
        //set brightness
        candle1.configBrightnessScalar(1);
        //set color
        candle1.setLEDs(255, 200, 46);

    }
}


Here is our lights subsystem for this year. There are some custom behaviors and sections commented out, but overall it works pretty well for us.

That is a lot, I also see that your using some stuff like .disableWhenLOS and .vBatOutputMode
whats the purpose of these?

It’s likely you won’t need to bother with that configuration, but it can be helpful depending on your preferences. I’d recommend ctrl+clicking on these options in vscode or reading the docs to see all of the options available and their implications, and if they are important for your use case.

okay, thank you.

What version of Phoenix are you on? This is a known issue, the fix is here: Release Phoenix 5 (v5.30.3) & Phoenix Pro (v23.0.2) · CrossTheRoadElec/Phoenix-Releases · GitHub

I recently made sure the CANdle was correct with phoenix tuner, and the candle now works as intended (ended up being a mix of the code and settings from phoenix tuner)

My response was specifically intended for the problem @mohd was having, but glad you figured it out.

oh sorry, was blind to the reply picture

Our CANdle appears correctly on Tuner, and can be run successfully on our extremely simple practice bot, however when connected to the main can bus our code cannot control it and it causes all Sparkmax motors on the bot to begin a sort of spasm motion? We have reflashed the firmware multiple times, and did fix a CAN id issue but no luck. Has anyone else experienced this? The practice bot does contain Sparkmax controllers on the same bus.
LightClass.txt (987 Bytes)

What firmware version are you running? There was a bug in the kickoff CANdle firmware that could cause that issue. We fixed the issue in version 22.3.1.0 (changelog), so make sure you update to that firmware version. You can get the firmware version by running the latest Phoenix Framework installer or by manually downloading the firmware file from our Phoenix-Releases repo.

It definitely was