connornishijima před 6 roky
rodič
revize
375ab09627

+ 2 - 0
.gitattributes

@@ -0,0 +1,2 @@
+# Auto detect text files and perform LF normalization
+* text=auto

+ 78 - 0
examples/animation/animation.ino

@@ -0,0 +1,78 @@
+/*
+ * Edgelit "animation" example
+ * Counts from 0 to 4,294,967,295 with transitions and theming
+ */
+
+#include "Edgelit.h"
+
+#define DATA_PIN 5            // Pin "D1" using Wemos D1 mini's stupid labels
+#define DISPLAY_COUNT 6       // Number of displays in chain
+#define DISPLAY_TYPE LIXIE_1  // Type of display (LIXIE_1, NIXIE_PIPE, etc.)
+Edgelit lit(DATA_PIN, DISPLAY_COUNT, DISPLAY_TYPE);
+
+uint32_t count = 123456;
+uint8_t hue = 0;
+uint8_t pos = 0;
+uint8_t animation_type = 0;
+
+void setup(){
+  lit.begin();                        // Initialize the interrupts for animation
+  lit.transition_type(FADE_TO_BLACK); // Can be INSTANT, CROSSFADE, or FADE_TO_BLACK
+  lit.transition_time(250);           // Transition time in milliseconds. (Does nothing for INSTANT transitions)
+  lit.animation_callback(animator);    // User function called at 100FPS when displays are updated
+  lit.empty_displays(true);           // Allows showing background color on displays not currently showing a numeral
+}
+
+void loop() {
+  lit.write(count);
+  count++;
+  delay(500);
+
+  if(millis() >= 20000 && animation_type == 0){
+    animation_type = 1;
+  }
+}
+
+// All of this happens in the background while loop() is running your own code!
+void animator(){
+  hue++;
+  
+  // Rainbow with twinkling colors
+  if(animation_type == 0){    
+    if(random(1,10) == 1){ // 10% chance
+      uint8_t sparkle_pos = random(0,lit.led_count()); // pick a random location in the string
+      lit.color_pixel(sparkle_pos,CHSV(random(0,256),255,96), BACK); // set this random location to a random color
+    }
+    
+    for(uint16_t i = 0; i < lit.led_count(); i++){
+      CRGB col = lit.color_pixel(i, BACK); // get pixel color
+      // Fade all "BACK" pixels to black over time
+      col.r = col.r*0.95;
+      col.g = col.g*0.95;
+      col.b = col.b*0.95;
+      lit.color_pixel(i, col, BACK); // set pixel color
+      
+      lit.color_pixel(i,CHSV(hue+i,255,255), FRONT); // Creates cycling rainbow for foreground colors
+    }
+  }
+
+  // White with color scanning in background
+  else if(animation_type == 1){
+    pos++; // "pos" is where in the chain we're currently turning pixels on
+    if(pos >= lit.led_count()){ // If we reach the end of the chain, start over
+      pos = 0;
+    }
+
+    lit.color(CRGB(255,255,255),FRONT);           // Foreground color to white
+    lit.color_pixel(pos, CHSV(hue,255,127),BACK); // Set one background pixel @ "pos" to "hue"
+
+    // Fade all background pixels to black over time
+    for(uint16_t i = 0; i < lit.led_count(); i++){
+      CRGB col = lit.color_pixel(i, BACK); // get pixel color
+      col.r = col.r*0.95;
+      col.g = col.g*0.95;
+      col.b = col.b*0.95;
+      lit.color_pixel(i, col, BACK); // set pixel color
+    }
+  }
+}

+ 34 - 0
examples/counter/counter.ino

@@ -0,0 +1,34 @@
+/*
+ * Edgelit "counter" example
+ * Counts from 0 to 4,294,967,295 with transitions and theming
+ */
+
+#include "Edgelit.h"
+
+#define DATA_PIN 5            // Pin "D1" using Wemos D1 mini's stupid labels
+#define DISPLAY_COUNT 6       // Number of displays in chain
+#define DISPLAY_TYPE LIXIE_1  // Type of display (LIXIE_1, NIXIE_PIPE, etc.)
+Edgelit lit(DATA_PIN, DISPLAY_COUNT, DISPLAY_TYPE);
+
+uint32_t count = 0;
+
+void setup(){
+  lit.begin();                        // Initialize the interrupts for animation
+  lit.transition_type(FADE_TO_BLACK); // Can be INSTANT, CROSSFADE, or FADE_TO_BLACK
+  lit.transition_time(250);           // Transition time in milliseconds. (Does nothing for INSTANT transitions)
+  lit.nixie(1);                       // Sets the color scheme to match the ionized neon/argon mix in an average Nixie tube.
+                                      // The 1 is "Argon intensity", the subtle blue hue some Nixie tubes have. (0-255)
+// Some other display presets to try:
+// lit.vfd_green();
+// lit.vfd_blue();
+
+// Or a theme of your own:
+// lit.color(CRGB(255,255,255), FRONT); // "FRONT" is coloring for numerals shown
+// lit.color(CRGB(0,8,2), BACK);        // "BACK" is coloring for numerals not shown. (Background)
+}
+
+void loop() {
+  lit.write(count);
+  count++;
+  delay(500);
+}

+ 46 - 0
keywords.txt

@@ -0,0 +1,46 @@
+###################################
+# Syntax Coloring Map for Edgelit
+###################################
+
+###################################
+# Datatypes (KEYWORD1)
+###################################
+
+Edgelit	KEYWORD1
+
+###################################
+# Methods and Functions (KEYWORD2)
+###################################
+
+begin	KEYWORD2
+write	KEYWORD2
+push_digit	KEYWORD2
+clear	KEYWORD2
+max_power	KEYWORD2
+nixie	KEYWORD2
+vfd_green	KEYWORD2
+vfd_blue	KEYWORD2
+progress	KEYWORD2
+animation_callback	KEYWORD2
+led_count	KEYWORD2
+empty_displays	KEYWORD2
+brightness	KEYWORD2
+transition_type	KEYWORD2
+transition_time	KEYWORD2
+color	KEYWORD2
+color_pixel	KEYWORD2
+color_display	KEYWORD2
+
+###################################
+# Constants (LITERAL1)
+###################################
+
+LIXIE_1	LITERAL1
+NIXIE_PIPE	LITERAL1
+
+FRONT	LITERAL1
+BACK	LITERAL1
+
+INSTANT	LITERAL1
+CROSSFADE	LITERAL1
+FADE_TO_BLACK	LITERAL1

+ 22 - 0
library.json

@@ -0,0 +1,22 @@
+{
+  "name": "Edgelit",
+  "description": "Library for controlling any WS2812B-based edgelit numeric display, such as the Lixie or NixiePipe!",
+  "keywords": "fastled, lixie, magic, pwm, edgelit, clock",
+  "authors":
+  {
+    "name": "Connor Nishijima",
+    "email": "connornishijima@gmail.com"
+  },
+  "repository":
+  {
+    "type": "git",
+    "url": "https://github.com/connornishijima/Edgelit.git"
+  },
+  "version": "1.0.0",
+  "examples": "examples/*.ino",
+  "frameworks": "arduino",
+  "platforms":
+  [
+    "esp8266"
+  ]
+}

+ 9 - 0
library.properties

@@ -0,0 +1,9 @@
+name=Lixie II
+version=1.0.0
+author=Connor Nishijima
+maintainer=Connor Nishijima <connornishijima@gmail.com>
+sentence=ESP32 Library for controlling the Lixie II!
+paragraph=ESP32 Library for controlling the Lixie II!
+category=Signal Input/Output
+url=https://github.com/connornishijima/Lixie_II-arduino
+architectures=esp32

+ 484 - 0
src/Lixie_II.cpp

@@ -0,0 +1,484 @@
+/*
+	Lixie_II.cpp - Library for controlling the Lixie 2!
+	
+	Created by Connor Nishijma July 6th, 2019
+	Released under the GPLv3 License
+*/
+
+#include "Lixie_II.h"
+
+uint8_t get_size(uint32_t input);
+
+// FastLED info for the LEDs
+#define LED_TYPE WS2812B
+#define COLOR_ORDER GRB
+
+const uint8_t leds_per_digit = 22;
+uint8_t n_digits;      // Keeps the number of displays
+uint16_t n_LEDs;       // Keeps the number of LEDs based on display quantity.
+CLEDController *lix_controller; // FastLED 
+CRGB *lix_leds;
+
+const uint8_t led_assignments[leds_per_digit] = {	1, 9, 4, 6, 255, 7, 3, 0, 2, 8, 5, 5, 8, 2, 0, 3, 7, 255, 6, 4, 9, 1	}; // 255 is extra pane
+const uint8_t x_offsets[leds_per_digit] 	  = {	0, 0, 0, 0, 1,   1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4,   5, 5, 5, 5	};
+uint8_t max_x_pos = 0;
+
+CRGB *color_on;
+CRGB *color_off;
+
+uint8_t *led_mask_0;
+uint8_t *led_mask_1;
+
+uint8_t current_mask = 0;
+float mask_fader = 0.0;
+float mask_push = 1.0;
+bool mask_fade_finished = false;
+
+uint8_t transition_type = CROSSFADE;
+bool transition_mid_point = true;
+
+Ticker lixie_animation;
+
+uint16_t led_to_x_pos(uint16_t led){
+	uint8_t led_digit_pos = x_offsets[led%22];
+	
+	uint8_t complete_digits = 0;
+	while(led >= leds_per_digit){
+		led -= leds_per_digit;
+		complete_digits += 1;
+	}
+	
+	return max_x_pos - (led_digit_pos + (complete_digits*6));
+}
+
+void animate(){
+	if(mask_fader < 1.0){
+		mask_fader += mask_push;
+	}
+	
+	if(mask_fader >= 1.0){
+		mask_fader = 1.0;
+		if(!mask_fade_finished){
+			mask_fade_finished = true;
+			
+		}
+	}
+	else if(mask_fader >= 0.5){
+		transition_mid_point = true;
+	}
+	
+	for(uint16_t i = 0; i < n_LEDs; i++){
+		float mask_float;
+		CRGB new_col;
+		uint8_t mask_input_0 = led_mask_0[i];
+		uint8_t mask_input_1 = led_mask_1[i];
+
+		if(transition_type == INSTANT || transition_type == CROSSFADE){
+			if(current_mask == 0){	
+				mask_float = ((mask_input_0*(1-mask_fader)) + (mask_input_1*(mask_fader)))/255.0;
+			}
+			else if(current_mask == 1){
+				mask_float = ((mask_input_1*(1-mask_fader)) + (mask_input_0*(mask_fader)))/255.0;
+			}
+		}
+		
+		new_col.r = (color_on[i].r*mask_float) + (color_off[i].r*(1-mask_float));
+		new_col.g = (color_on[i].g*mask_float) + (color_off[i].g*(1-mask_float));
+		new_col.b = (color_on[i].b*mask_float) + (color_off[i].b*(1-mask_float));
+		
+		lix_leds[i] = new_col;	
+		
+		//Serial.print(led_to_x_pos(i));
+		//Serial.print('\t');
+		//Serial.println(max_x_pos);
+	}
+			
+	lix_controller->showLeds();	
+}
+
+void Lixie_II::start_animation(){
+	lixie_animation.attach_ms(20, animate);
+}
+
+void Lixie_II::stop_animation(){
+	lixie_animation.detach();
+}
+
+Lixie_II::Lixie_II(const uint8_t pin, uint8_t number_of_digits){
+	n_LEDs = number_of_digits * leds_per_digit;
+	n_digits = number_of_digits;
+	max_x_pos = (number_of_digits * 6)-1;
+	
+	lix_leds = new CRGB[n_LEDs];	
+	led_mask_0 = new uint8_t[n_LEDs];
+	led_mask_1 = new uint8_t[n_LEDs];
+		
+	color_on = new CRGB[n_LEDs];
+	color_off = new CRGB[n_LEDs];
+	
+	for(uint16_t i = 0; i < n_LEDs; i++){
+		led_mask_0[i] = 0;
+		led_mask_1[i] = 0;
+		
+		color_on[i] = CRGB(255,255,255);
+		color_off[i] = CRGB(0,0,0);
+	}
+	
+	build_controller(pin);
+}
+
+void Lixie_II::build_controller(const uint8_t pin){
+	//FastLED control pin has to be defined as a constant, (not just const, it's weird) this is a hacky workaround.
+	// Also, this stops you from defining non existent pins with your current board architecture
+	if (pin == 0)
+		lix_controller = &FastLED.addLeds<LED_TYPE, 0, COLOR_ORDER>(lix_leds, n_LEDs);
+	else if (pin == 2)
+		lix_controller = &FastLED.addLeds<LED_TYPE, 2, COLOR_ORDER>(lix_leds, n_LEDs);
+	else if (pin == 4)
+		lix_controller = &FastLED.addLeds<LED_TYPE, 4, COLOR_ORDER>(lix_leds, n_LEDs);
+	else if (pin == 5)
+		lix_controller = &FastLED.addLeds<LED_TYPE, 5, COLOR_ORDER>(lix_leds, n_LEDs);
+	else if (pin == 12)
+		lix_controller = &FastLED.addLeds<LED_TYPE, 12, COLOR_ORDER>(lix_leds, n_LEDs);
+	else if (pin == 13)
+		lix_controller = &FastLED.addLeds<LED_TYPE, 13, COLOR_ORDER>(lix_leds, n_LEDs);
+		//FastLED.addLeds<LED_TYPE, 13, COLOR_ORDER>(lix_leds, n_LEDs);
+}
+
+void Lixie_II::begin(){
+	max_power(5,500); // Default for the safety of your PC USB
+	start_animation();
+}
+
+void Lixie_II::max_power(uint8_t V, uint16_t mA){
+	FastLED.setMaxPowerInVoltsAndMilliamps(V, mA);
+}
+
+void Lixie_II::clear_all(){
+	if(current_mask == 0){
+		for(uint16_t i = 0; i < n_LEDs; i++){
+			led_mask_0[i] = 0;
+		}
+	}
+	else if(current_mask == 1){
+		for(uint16_t i = 0; i < n_LEDs; i++){
+			led_mask_1[i] = 0;
+		}
+	}
+}
+
+void Lixie_II::write(uint32_t input){
+	//if(get_size(input) <= n_digits){
+		clear_all();
+		
+		uint32_t n_place = 1;
+		// Powers of 10 while avoiding floating point math
+		for(uint8_t i = 1; i < get_size(input); i++){
+			n_place *= 10;
+		}
+
+		for(n_place; n_place > 0; n_place /= 10){
+			push_digit(input / n_place);
+			if(n_place > 1) input = (input % n_place);
+		}
+			
+	//}
+	
+	if(current_mask == 0){
+		current_mask = 1;
+	}
+	else if(current_mask == 1){
+		current_mask = 0;
+	}
+	
+	mask_update();
+}
+
+void Lixie_II::write_float(float input_raw, uint8_t dec_places){
+	uint16_t dec_places_10s = 1;
+	float input_mult = input_raw;
+	
+	for(uint8_t i = 0; i < dec_places; i++){
+		input_mult*=10;
+		dec_places_10s*=10;
+	}
+	
+	uint16_t input = input_mult;
+	
+	clear_all();
+		
+	uint32_t n_place = 1;
+	// Powers of 10 while avoiding floating point math
+	for(uint8_t i = 1; i < get_size(input); i++){
+		n_place *= 10;
+	}
+
+	for(n_place; n_place > 0; n_place /= 10){
+		if(n_place == (dec_places_10s/10)){
+			push_digit(255);
+		}
+		
+		push_digit(input / n_place);
+		
+		
+		
+		if(n_place > 1) input = (input % n_place);
+	}
+	
+	if(current_mask == 0){
+		current_mask = 1;
+	}
+	else if(current_mask == 1){
+		current_mask = 0;
+	}
+	
+	mask_update();
+}
+
+void Lixie_II::push_digit(uint8_t number) {
+	// If multiple displays, move all LED states forward one
+	if (n_digits > 1) {
+		for (uint16_t i = n_LEDs - 1; i >= leds_per_digit; i--) {
+			if(current_mask == 0){
+				led_mask_0[i] = led_mask_0[i - leds_per_digit];
+			}
+			else{
+				led_mask_1[i] = led_mask_1[i - leds_per_digit];
+			}
+		}
+	}
+	
+	// Clear the LED states for the first display
+	for (uint16_t i = 0; i < leds_per_digit; i++) {
+		if(current_mask == 0){
+			led_mask_0[i] = led_mask_0[i - leds_per_digit];
+		}
+		else{
+			led_mask_1[i] = led_mask_1[i - leds_per_digit];
+		}
+	}
+	
+	for(uint8_t i = 0; i < leds_per_digit; i++){
+		if(led_assignments[i] == number){
+			if(current_mask == 0){
+				led_mask_0[i] = 255;
+			}
+			else{
+				led_mask_1[i] = 255;
+			}
+		}
+		else{
+			if(current_mask == 0){
+				led_mask_0[i] = 0;
+			}
+			else{
+				led_mask_1[i] = 0;
+			}
+		}
+	}	
+}
+
+void Lixie_II::write_digit(uint8_t digit, uint8_t num){
+	uint16_t start_index = leds_per_digit*digit;
+	
+	if(num < 10){
+		clear_digit(digit,num);
+		for(uint8_t i = 0; i < leds_per_digit; i++){			
+			if(led_assignments[i] == num){
+				
+				if(current_mask == 0){
+					led_mask_1[start_index+i] = 255;
+				}
+				else if(current_mask == 1){
+					led_mask_0[start_index+i] = 255;
+				}				
+			}
+		}
+		
+		mask_update();
+	}
+}
+
+void Lixie_II::clear_digit(uint8_t digit, uint8_t num){
+	uint16_t start_index = leds_per_digit*digit;
+	for(uint8_t i = 0; i < 22; i++){
+		if(current_mask == 0){
+			led_mask_1[start_index+i] = 0;//CRGB(0*0.06,100*0.06,255*0.06);		
+		}
+		if(current_mask == 1){
+			led_mask_0[start_index+i] = 0;//CRGB(0*0.06,100*0.06,255*0.06);		
+		}
+	}
+	
+	mask_update();
+}
+
+void Lixie_II::mask_update(){
+	mask_fader = 0.0;
+	
+	if(transition_type == INSTANT){
+		mask_push = 1.0;
+	}
+	else{
+		mask_push = 0.1;
+	}
+	mask_fade_finished = false;
+	transition_mid_point = false;
+}
+
+void Lixie_II::color_all(uint8_t layer, CRGB col){
+	for(uint16_t i = 0; i < n_LEDs; i++){
+		if(layer == ON){
+			color_on[i] = col;
+		}
+		else if(layer == OFF){
+			color_off[i] = col;
+		}
+	}
+}
+
+void Lixie_II::color_all_dual(uint8_t layer, CRGB col_left, CRGB col_right){
+	bool side = 1;
+	for(uint16_t i = 0; i < n_LEDs; i++){
+		if(i % (leds_per_digit/2) == 0){
+			side = !side;
+		}
+		
+		if(layer == ON){
+			if(side){
+				color_on[i] = col_left;
+			}
+			else{
+				color_on[i] = col_right;
+			}
+		}
+		else if(layer == OFF){
+			if(side){
+				color_off[i] = col_left;
+			}
+			else{
+				color_off[i] = col_right;
+			}
+		}
+	}
+}
+
+void Lixie_II::color_display(uint8_t display, uint8_t layer, CRGB col){
+	uint16_t start_index = leds_per_digit*display;
+	for(uint16_t i = 0; i < leds_per_digit; i++){
+		if(layer == ON){
+			color_on[start_index+i] = col;
+		}
+		else if(layer == OFF){
+			color_off[start_index+i] = col;
+		}
+	}
+}
+
+void Lixie_II::gradient_rgb(uint8_t layer, CRGB col_left, CRGB col_right){
+	for(uint16_t i = 0; i < n_LEDs; i++){
+		float progress = 1-(led_to_x_pos(i)/float(max_x_pos));
+
+		CRGB col_out = CRGB(0,0,0);
+		col_out.r = (col_right.r*(1-progress)) + (col_left.r*(progress));
+		col_out.g = (col_right.g*(1-progress)) + (col_left.g*(progress));
+		col_out.b = (col_right.b*(1-progress)) + (col_left.b*(progress));
+		
+		if(layer == ON){
+			color_on[i] = col_out;
+		}
+		else if(layer == OFF){
+			color_off[i] = col_out;
+		}
+	}
+}
+
+void Lixie_II::streak(CRGB col, int16_t pos, uint8_t blur){
+	for(uint16_t i = 0; i < n_LEDs; i++){
+		
+		uint16_t pos_delta = abs(led_to_x_pos(i) - pos);
+		if(pos_delta > blur){
+			pos_delta = blur;
+		}
+		float pos_level = 1-(pos_delta/float(blur));
+		
+		pos_level*=pos_level;
+		
+		if(i == 0){
+			//Serial.println(pos_level);
+		}
+		lix_leds[i] = CRGB(col.r * pos_level, col.g * pos_level, col.b * pos_level);
+
+	}
+	lix_controller->showLeds();
+}
+
+void Lixie_II::sweep_color(CRGB col, uint16_t speed, uint8_t blur, bool reverse){
+	stop_animation();
+	sweep_gradient(col, col, speed, blur, reverse);
+	start_animation();
+}
+
+void Lixie_II::sweep_gradient(CRGB col_left, CRGB col_right, uint16_t speed, uint8_t blur, bool reverse){
+	stop_animation();
+	
+	if(!reverse){
+		for(int16_t sweep_pos = (blur*-1); sweep_pos <= max_x_pos+(blur); sweep_pos++){
+			int16_t sweep_pos_fixed = sweep_pos;
+			if(sweep_pos < 0){
+				sweep_pos_fixed = 0;
+			}
+			if(sweep_pos > max_x_pos){
+				sweep_pos_fixed = max_x_pos;
+			}
+			float progress = 1-(sweep_pos_fixed/float(max_x_pos));
+
+			CRGB col_out = CRGB(0,0,0);
+			col_out.r = (col_right.r*(1-progress)) + (col_left.r*(progress));
+			col_out.g = (col_right.g*(1-progress)) + (col_left.g*(progress));
+			col_out.b = (col_right.b*(1-progress)) + (col_left.b*(progress));
+			
+			streak(col_out, sweep_pos, blur);
+			FastLED.delay(speed);
+		}
+	}
+	else{
+		for(int16_t sweep_pos = max_x_pos+(blur); sweep_pos >= (blur*-1); sweep_pos--){
+			int16_t sweep_pos_fixed = sweep_pos;
+			if(sweep_pos < 0){
+				sweep_pos_fixed = 0;
+			}
+			if(sweep_pos > max_x_pos){
+				sweep_pos_fixed = max_x_pos;
+			}
+			float progress = 1-(sweep_pos_fixed/float(max_x_pos));
+
+			CRGB col_out = CRGB(0,0,0);
+			col_out.r = (col_right.r*(1-progress)) + (col_left.r*(progress));
+			col_out.g = (col_right.g*(1-progress)) + (col_left.g*(progress));
+			col_out.b = (col_right.b*(1-progress)) + (col_left.b*(progress));
+			
+			streak(col_out, sweep_pos, blur);
+			FastLED.delay(speed);
+		}
+	}
+	start_animation();
+}
+
+uint8_t Lixie_II::get_size(uint32_t input){
+  uint8_t places = 1;
+  while(input > 9){
+    places++;
+    input /= 10;
+  }
+  return places;
+}
+
+/*
+void fill_all(CRGB col){
+  for(uint16_t i = 0; i < n_LEDs; i++){
+    led_mask[i] = 255;
+	color_on[i] = col;
+  }
+}
+*/

+ 59 - 0
src/Lixie_II.h

@@ -0,0 +1,59 @@
+/*
+	Lixie_II.h - Library for controlling the Lixie II!
+	
+	Created by Connor Nishijma July 6th, 2019
+	Released under the GPLv3 License
+*/
+
+#ifndef lixie_II_h
+#define lixie_II_h
+
+#include "Arduino.h"
+#include <Ticker.h>	// ESP ONLY
+
+// FastLED has issues with the ESP8266, especially
+// when used with networking, so we fix that here.
+#define FASTLED_ESP8266_RAW_PIN_ORDER
+#define FASTLED_ALLOW_INTERRUPTS 		0
+#define FASTLED_INTERRUPT_RETRY_COUNT	0
+
+// Aside from those issues, it's my tool of choice for WS2812B
+#include "FastLED.h"
+
+#define ON  1
+#define OFF 0
+
+#define INSTANT   		0
+#define CROSSFADE 		1
+#define FADE_TO_BLACK	2
+
+// Functions
+class Lixie_II
+{
+	public:
+		Lixie_II(const uint8_t pin, uint8_t n_digits);
+		void build_controller(const uint8_t pin);
+		void begin();
+		void max_power(uint8_t V, uint16_t mA);
+		void color_all(uint8_t layer, CRGB col);
+		void color_all_dual(uint8_t layer, CRGB col_left, CRGB col_right);
+		void color_display(uint8_t display, uint8_t layer, CRGB col);
+		void gradient_rgb(uint8_t layer, CRGB col_left, CRGB col_right);
+		void streak(CRGB col, int16_t pos, uint8_t blur);
+		void sweep_color(CRGB col, uint16_t speed, uint8_t blur, bool reverse = false);
+		void sweep_gradient(CRGB col_left, CRGB col_right, uint16_t speed, uint8_t blur, bool reverse);
+		void start_animation();
+		void stop_animation();
+		void write(uint32_t input);
+		void write_float(float input, uint8_t dec_places = 1);
+		void clear_all();
+		void write_digit(uint8_t digit, uint8_t num);
+		void push_digit(uint8_t number);
+		void clear_digit(uint8_t digit, uint8_t num);
+		void mask_update();
+		
+	private:
+		uint8_t get_size(uint32_t input);
+};
+
+#endif