001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj; 006 007import edu.wpi.first.hal.AddressableLEDJNI; 008import edu.wpi.first.hal.FRCNetComm.tResourceType; 009import edu.wpi.first.hal.HAL; 010import edu.wpi.first.hal.PWMJNI; 011 012/** 013 * A class for driving addressable LEDs, such as WS2812Bs and NeoPixels. 014 * 015 * <p>By default, the timing supports WS2812B LEDs, but is configurable using setBitTiming() 016 * 017 * <p>Only 1 LED driver is currently supported by the roboRIO. 018 */ 019public class AddressableLED implements AutoCloseable { 020 private final int m_pwmHandle; 021 private final int m_handle; 022 023 /** 024 * Constructs a new driver for a specific port. 025 * 026 * @param port the output port to use (Must be a PWM header, not on MXP) 027 */ 028 public AddressableLED(int port) { 029 m_pwmHandle = PWMJNI.initializePWMPort(HAL.getPort((byte) port)); 030 m_handle = AddressableLEDJNI.initialize(m_pwmHandle); 031 HAL.report(tResourceType.kResourceType_AddressableLEDs, port + 1); 032 } 033 034 @Override 035 public void close() { 036 if (m_handle != 0) { 037 AddressableLEDJNI.free(m_handle); 038 } 039 if (m_pwmHandle != 0) { 040 PWMJNI.freePWMPort(m_pwmHandle); 041 } 042 } 043 044 /** 045 * Sets the length of the LED strip. 046 * 047 * <p>Calling this is an expensive call, so it's best to call it once, then just update data. 048 * 049 * <p>The max length is 5460 LEDs. 050 * 051 * @param length the strip length 052 */ 053 public void setLength(int length) { 054 AddressableLEDJNI.setLength(m_handle, length); 055 } 056 057 /** 058 * Sets the LED output data. 059 * 060 * <p>If the output is enabled, this will start writing the next data cycle. It is safe to call, 061 * even while output is enabled. 062 * 063 * @param buffer the buffer to write 064 */ 065 public void setData(AddressableLEDBuffer buffer) { 066 AddressableLEDJNI.setData(m_handle, buffer.m_buffer); 067 } 068 069 /** 070 * Sets the bit timing. 071 * 072 * <p>By default, the driver is set up to drive WS2812Bs, so nothing needs to be set for those. 073 * 074 * @param highTime0NanoSeconds high time for 0 bit (default 400ns) 075 * @param lowTime0NanoSeconds low time for 0 bit (default 900ns) 076 * @param highTime1NanoSeconds high time for 1 bit (default 900ns) 077 * @param lowTime1NanoSeconds low time for 1 bit (default 600ns) 078 */ 079 public void setBitTiming( 080 int highTime0NanoSeconds, 081 int lowTime0NanoSeconds, 082 int highTime1NanoSeconds, 083 int lowTime1NanoSeconds) { 084 AddressableLEDJNI.setBitTiming( 085 m_handle, 086 highTime0NanoSeconds, 087 lowTime0NanoSeconds, 088 highTime1NanoSeconds, 089 lowTime1NanoSeconds); 090 } 091 092 /** 093 * Sets the sync time. 094 * 095 * <p>The sync time is the time to hold output so LEDs enable. Default set for WS2812B. 096 * 097 * @param syncTimeMicroSeconds the sync time (default 280us) 098 */ 099 public void setSyncTime(int syncTimeMicroSeconds) { 100 AddressableLEDJNI.setSyncTime(m_handle, syncTimeMicroSeconds); 101 } 102 103 /** 104 * Starts the output. 105 * 106 * <p>The output writes continuously. 107 */ 108 public void start() { 109 AddressableLEDJNI.start(m_handle); 110 } 111 112 /** Stops the output. */ 113 public void stop() { 114 AddressableLEDJNI.stop(m_handle); 115 } 116}