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.HAL; 009 010/** 011 * A class for driving addressable LEDs, such as WS2812B, WS2815, and NeoPixels. 012 * 013 * <p>Some LEDs use a different color order than the default GRB. The color order is configurable 014 * using {@link #setColorOrder(ColorOrder)}. 015 * 016 * <p>Up to 1024 LEDs may be controlled in total across all AddressableLED instances. A single 017 * global buffer is used for all instances. The start position used for LED data for the output is 018 * set via SetStart() and the length of the strip is set via SetLength(). Both of these default to 019 * zero, so multiple instances will access the same pixel data unless SetStart() is called to adjust 020 * the starting point. 021 */ 022public class AddressableLED implements AutoCloseable { 023 /** Order that color data is sent over the wire. */ 024 public enum ColorOrder { 025 /** RGB order. */ 026 kRGB(AddressableLEDJNI.COLOR_ORDER_RGB), 027 /** RBG order. */ 028 kRBG(AddressableLEDJNI.COLOR_ORDER_RBG), 029 /** BGR order. */ 030 kBGR(AddressableLEDJNI.COLOR_ORDER_BGR), 031 /** BRG order. */ 032 kBRG(AddressableLEDJNI.COLOR_ORDER_BRG), 033 /** GBR order. */ 034 kGBR(AddressableLEDJNI.COLOR_ORDER_GBR), 035 /** GRB order. This is the default order. */ 036 kGRB(AddressableLEDJNI.COLOR_ORDER_GRB); 037 038 /** The native value for this ColorOrder. */ 039 public final int value; 040 041 ColorOrder(int value) { 042 this.value = value; 043 } 044 045 /** 046 * Gets a color order from an int value. 047 * 048 * @param value int value 049 * @return color order 050 */ 051 public ColorOrder fromValue(int value) { 052 return switch (value) { 053 case AddressableLEDJNI.COLOR_ORDER_RBG -> kRBG; 054 case AddressableLEDJNI.COLOR_ORDER_BGR -> kBGR; 055 case AddressableLEDJNI.COLOR_ORDER_BRG -> kBRG; 056 case AddressableLEDJNI.COLOR_ORDER_GRB -> kGRB; 057 case AddressableLEDJNI.COLOR_ORDER_GBR -> kGBR; 058 case AddressableLEDJNI.COLOR_ORDER_RGB -> kRGB; 059 default -> kGRB; 060 }; 061 } 062 } 063 064 private final int m_channel; 065 private final int m_handle; 066 private int m_start; 067 private int m_length; 068 private ColorOrder m_colorOrder = ColorOrder.kGRB; 069 070 /** 071 * Constructs a new driver for a specific channel. 072 * 073 * @param channel the output channel to use 074 */ 075 public AddressableLED(int channel) { 076 m_channel = channel; 077 m_handle = AddressableLEDJNI.initialize(channel); 078 HAL.reportUsage("IO", channel, "AddressableLED"); 079 } 080 081 @Override 082 public void close() { 083 if (m_handle != 0) { 084 AddressableLEDJNI.free(m_handle); 085 } 086 } 087 088 /** 089 * Gets the output channel. 090 * 091 * @return the output channel 092 */ 093 public int getChannel() { 094 return m_channel; 095 } 096 097 /** 098 * Sets the color order for this AddressableLED. The default order is GRB. 099 * 100 * <p>This will take effect on the next call to {@link #setData(AddressableLEDBuffer)}. 101 * 102 * @param order the color order 103 */ 104 public void setColorOrder(ColorOrder order) { 105 m_colorOrder = order; 106 } 107 108 /** 109 * Sets the display start of the LED strip in the global buffer. 110 * 111 * @param start the strip start, in LEDs 112 */ 113 public void setStart(int start) { 114 m_start = start; 115 AddressableLEDJNI.setStart(m_handle, start); 116 } 117 118 /** 119 * Gets the display start of the LED strip in the global buffer. 120 * 121 * @return the strip start, in LEDs 122 */ 123 public int getStart() { 124 return m_start; 125 } 126 127 /** 128 * Sets the length of the LED strip. 129 * 130 * @param length the strip length, in LEDs 131 */ 132 public void setLength(int length) { 133 m_length = length; 134 AddressableLEDJNI.setLength(m_handle, length); 135 } 136 137 /** 138 * Sets the LED output data. 139 * 140 * <p>This will write to the global buffer starting at the location set by setStart() and up to 141 * the length set by setLength(). 142 * 143 * @param buffer the buffer to write 144 */ 145 public void setData(AddressableLEDBuffer buffer) { 146 AddressableLEDJNI.setData( 147 m_start, 148 m_colorOrder.value, 149 buffer.m_buffer, 150 0, 151 3 * Math.min(m_length, buffer.getLength())); 152 } 153 154 /** 155 * Sets the LED output data at an arbitrary location in the global buffer. 156 * 157 * @param start the start location, in LEDs 158 * @param colorOrder the color order 159 * @param buffer the buffer to write 160 */ 161 public static void setGlobalData(int start, ColorOrder colorOrder, AddressableLEDBuffer buffer) { 162 AddressableLEDJNI.setData(start, colorOrder.value, buffer.m_buffer); 163 } 164}