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. However, multiple LED strips can be 018 * connected in series and controlled from the single driver. 019 */ 020public class AddressableLED implements AutoCloseable { 021 private final int m_pwmHandle; 022 private final int m_handle; 023 024 /** 025 * Constructs a new driver for a specific port. 026 * 027 * @param port the output port to use (Must be a PWM header, not on MXP) 028 */ 029 public AddressableLED(int port) { 030 m_pwmHandle = PWMJNI.initializePWMPort(HAL.getPort((byte) port)); 031 m_handle = AddressableLEDJNI.initialize(m_pwmHandle); 032 HAL.report(tResourceType.kResourceType_AddressableLEDs, port + 1); 033 } 034 035 @Override 036 public void close() { 037 if (m_handle != 0) { 038 AddressableLEDJNI.free(m_handle); 039 } 040 if (m_pwmHandle != 0) { 041 PWMJNI.freePWMPort(m_pwmHandle); 042 } 043 } 044 045 /** 046 * Sets the length of the LED strip. 047 * 048 * <p>Calling this is an expensive call, so it's best to call it once, then just update data. 049 * 050 * <p>The max length is 5460 LEDs. 051 * 052 * @param length the strip length 053 */ 054 public void setLength(int length) { 055 AddressableLEDJNI.setLength(m_handle, length); 056 } 057 058 /** 059 * Sets the LED output data. 060 * 061 * <p>If the output is enabled, this will start writing the next data cycle. It is safe to call, 062 * even while output is enabled. 063 * 064 * @param buffer the buffer to write 065 */ 066 public void setData(AddressableLEDBuffer buffer) { 067 AddressableLEDJNI.setData(m_handle, buffer.m_buffer); 068 } 069 070 /** 071 * Sets the bit timing. 072 * 073 * <p>By default, the driver is set up to drive WS2812Bs, so nothing needs to be set for those. 074 * 075 * @param highTime0NanoSeconds high time for 0 bit (default 400ns) 076 * @param lowTime0NanoSeconds low time for 0 bit (default 900ns) 077 * @param highTime1NanoSeconds high time for 1 bit (default 900ns) 078 * @param lowTime1NanoSeconds low time for 1 bit (default 600ns) 079 */ 080 public void setBitTiming( 081 int highTime0NanoSeconds, 082 int lowTime0NanoSeconds, 083 int highTime1NanoSeconds, 084 int lowTime1NanoSeconds) { 085 AddressableLEDJNI.setBitTiming( 086 m_handle, 087 highTime0NanoSeconds, 088 lowTime0NanoSeconds, 089 highTime1NanoSeconds, 090 lowTime1NanoSeconds); 091 } 092 093 /** 094 * Sets the sync time. 095 * 096 * <p>The sync time is the time to hold output so LEDs enable. Default set for WS2812B. 097 * 098 * @param syncTimeMicroSeconds the sync time (default 280us) 099 */ 100 public void setSyncTime(int syncTimeMicroSeconds) { 101 AddressableLEDJNI.setSyncTime(m_handle, syncTimeMicroSeconds); 102 } 103 104 /** 105 * Starts the output. 106 * 107 * <p>The output writes continuously. 108 */ 109 public void start() { 110 AddressableLEDJNI.start(m_handle); 111 } 112 113 /** Stops the output. */ 114 public void stop() { 115 AddressableLEDJNI.stop(m_handle); 116 } 117}