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