diff --git a/arduino_examples/3_loop_digit_crossfade/3_loop_digit_crossfade.ino b/arduino_examples/3_loop_digit_crossfade/3_loop_digit_crossfade.ino index 8c3bd74..e9ce9ba 100644 --- a/arduino_examples/3_loop_digit_crossfade/3_loop_digit_crossfade.ino +++ b/arduino_examples/3_loop_digit_crossfade/3_loop_digit_crossfade.ino @@ -18,7 +18,7 @@ exixe my_tube = exixe(cs_pin); void setup() { my_tube.clear(); - my_tube.set_led(127, 0, 127); // purple + my_tube.set_led(32, 127, 127); // purple } void loop() diff --git a/arduino_library/exixe.zip b/arduino_library/exixe.zip index f1a7d51..200287d 100644 Binary files a/arduino_library/exixe.zip and b/arduino_library/exixe.zip differ diff --git a/arduino_library/exixe/examples/1_LED_test/1_LED_test.ino b/arduino_library/exixe/examples/1_LED_test/1_LED_test.ino new file mode 100644 index 0000000..04afcda --- /dev/null +++ b/arduino_library/exixe/examples/1_LED_test/1_LED_test.ino @@ -0,0 +1,25 @@ +/* + exixe modules: + https://github.com/dekuNukem/exixe + + library docs: + https://github.com/dekuNukem/exixe/tree/master/arduino_library + + Demo 1: LED test +*/ + +#include "exixe.h" + +// change this to the cs pin you're using +int cs_pin = 10; +exixe my_tube = exixe(cs_pin); + +void setup() +{ + my_tube.set_led(127, 0, 127); // purple +} + +void loop() +{ + +} \ No newline at end of file diff --git a/arduino_library/exixe/examples/2_loop_digit_simple/2_loop_digit_simple.ino b/arduino_library/exixe/examples/2_loop_digit_simple/2_loop_digit_simple.ino new file mode 100644 index 0000000..a39fce8 --- /dev/null +++ b/arduino_library/exixe/examples/2_loop_digit_simple/2_loop_digit_simple.ino @@ -0,0 +1,35 @@ +/* + exixe modules: + https://github.com/dekuNukem/exixe + + library docs: + https://github.com/dekuNukem/exixe/tree/master/arduino_library + + Demo 2: loop digits +*/ + +#include "exixe.h" + +// change this to the cs pin you're using +int cs_pin = 10; +unsigned char count; + +exixe my_tube = exixe(cs_pin); + +void setup() +{ + my_tube.clear(); + my_tube.set_led(127, 0, 127); // purple +} + +void loop() +{ + count++; + /* + 1st arg: Digit to show, 0 to 9 + 2nd arg: Digit brightness, 0 to 127 + 3rd arg: Overdrive, 0 disable 1 enable + */ + my_tube.show_digit(count, 127, 0); + delay(500); +} \ No newline at end of file diff --git a/arduino_library/exixe/examples/3_loop_digit_crossfade/3_loop_digit_crossfade.ino b/arduino_library/exixe/examples/3_loop_digit_crossfade/3_loop_digit_crossfade.ino new file mode 100644 index 0000000..8c3bd74 --- /dev/null +++ b/arduino_library/exixe/examples/3_loop_digit_crossfade/3_loop_digit_crossfade.ino @@ -0,0 +1,44 @@ +/* + exixe modules: + https://github.com/dekuNukem/exixe + + library docs: + https://github.com/dekuNukem/exixe/tree/master/arduino_library + + Demo 3: Loop digits with crossfade animation +*/ + +#include "exixe.h" + +// change this to the cs pin you're using +int cs_pin = 10; +unsigned char count; +exixe my_tube = exixe(cs_pin); + +void setup() +{ + my_tube.clear(); + my_tube.set_led(127, 0, 127); // purple +} + +void loop() +{ + count++; + /* + 1st arg: Digit to show, 0 to 9 + 2nd arg: how many frames does crossfade last, 30 frames = 1 second + 3rd arg: digit brightness, 0 to 127 + 4th arg: overdrive, 0 disable 1 enable + + This function sets up the crossfade animation + call crossfade_run() to actually start it + */ + my_tube.crossfade_init(count, 15, 127, 0); + + // crossfade_run() is non-blocking and returns right away + // call it regularly(at least every 33ms) for a smooth animation + // check its return value to see if the animation is finished + while(my_tube.crossfade_run() == EXIXE_ANIMATION_IN_PROGRESS) + ; + delay(250); +} \ No newline at end of file diff --git a/arduino_library/exixe/examples/4_multiple_tubes_simple/4_multiple_tubes_simple.ino b/arduino_library/exixe/examples/4_multiple_tubes_simple/4_multiple_tubes_simple.ino new file mode 100644 index 0000000..f45f41c --- /dev/null +++ b/arduino_library/exixe/examples/4_multiple_tubes_simple/4_multiple_tubes_simple.ino @@ -0,0 +1,36 @@ +/* + exixe modules: + https://github.com/dekuNukem/exixe + + library docs: + https://github.com/dekuNukem/exixe/tree/master/arduino_library + + Demo 4: Loop digits on two tubes +*/ + + +#include "exixe.h" + +// change those to the cs pins you're using +int cs1 = 10; +int cs2 = 9; +unsigned char count; + +exixe my_tube1 = exixe(cs1); +exixe my_tube2 = exixe(cs2); + +void setup() +{ + my_tube1.clear(); + my_tube2.clear(); + my_tube1.set_led(127, 0, 127); // purple; + my_tube2.set_led(127, 127, 0); // yellow; +} + +void loop() +{ + count = (count + 1) % 10; // keep count between 0 to 9 + my_tube1.show_digit(count, 127, 0); + my_tube2.show_digit(10 - count, 127, 0); + delay(500); +} \ No newline at end of file diff --git a/arduino_library/exixe/examples/5_multiple_tubes_crossfade/5_multiple_tubes_crossfade.ino b/arduino_library/exixe/examples/5_multiple_tubes_crossfade/5_multiple_tubes_crossfade.ino new file mode 100644 index 0000000..e474e74 --- /dev/null +++ b/arduino_library/exixe/examples/5_multiple_tubes_crossfade/5_multiple_tubes_crossfade.ino @@ -0,0 +1,53 @@ +/* + exixe modules: + https://github.com/dekuNukem/exixe + + library docs: + https://github.com/dekuNukem/exixe/tree/master/arduino_library + + Demo 5: Loop digits on two tubes with crossfade animation +*/ + + +#include "exixe.h" + +// change those to the cs pins you're using +int cs1 = 10; +int cs2 = 9; +unsigned char count; + +exixe my_tube1 = exixe(cs1); +exixe my_tube2 = exixe(cs2); + +void setup() +{ + my_tube1.clear(); + my_tube2.clear(); + my_tube1.set_led(127, 0, 127); // purple; + my_tube2.set_led(127, 127, 0); // yellow; +} + +void loop() +{ + count = (count + 1) % 10; // keep count between 0 to 9 + + my_tube1.crossfade_init(count, 15, 127, 0); + my_tube2.crossfade_init(10-count, 15, 127, 0); + + /* + again, crossfade_run() is non-blocking, that means + you can run other tasks in the loop. + just make sure to call it at least every 33ms + and check its return value to see if it's finished. + */ + while(1) + { + unsigned char result1 = my_tube1.crossfade_run(); + unsigned char result2 = my_tube2.crossfade_run(); + // exit when both animations are finished + if(result1 == EXIXE_ANIMATION_FINISHED && result2 == EXIXE_ANIMATION_FINISHED) + break; + } + + delay(250); +} \ No newline at end of file diff --git a/arduino_library/exixe/exixe.cpp b/arduino_library/exixe/exixe.cpp new file mode 100644 index 0000000..afa89e9 --- /dev/null +++ b/arduino_library/exixe/exixe.cpp @@ -0,0 +1,133 @@ +#include "exixe.h" +#include + +/* + SPI command details: + https://github.com/dekuNukem/exixe/blob/master/technical_details.md + + Project repo: + https://github.com/dekuNukem/exixe +*/ + +exixe::exixe(int my_cs) +{ + cs_pin = my_cs; + memset(spi_buf, 0, EXIXE_SPI_BUF_SIZE); + pinMode(cs_pin, OUTPUT); + digitalWrite(cs_pin, HIGH); + SPI.begin(); + SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0)); + show_digit(0, 0, 0); +} + +void exixe::spi_write() +{ + digitalWrite(cs_pin, LOW); + for (int i = 0; i < EXIXE_SPI_BUF_SIZE; ++i) + SPI.transfer(spi_buf[i]); + digitalWrite(cs_pin, HIGH); +} + +// cap digit between 1 and 10 +unsigned char exixe::cap_digit(unsigned char digit) +{ + digit = digit % 10; + if(digit == 0) + digit = 10; + return digit; +} + +// cap a float between 0 and 127 +unsigned char exixe::cap_float(float temp) +{ + if(temp > 127) + temp = 127; + if(temp < 0) + temp = 0; + return (unsigned char)temp; +} + +// Turn off all digits and LED +void exixe::clear() +{ + memset(spi_buf, 0x80, EXIXE_SPI_BUF_SIZE); + spi_buf[0] = EXIXE_SPI_HEADER; + spi_write(); +} + +void exixe::show_digit(unsigned char digit, unsigned char brightness, unsigned char overdrive) +{ + // cap brightness to 127 + brightness &= 0x7f; + digit = cap_digit(digit); + + memset(spi_buf, 0, EXIXE_SPI_BUF_SIZE); // clear SPI buffer + memset(spi_buf, 0x80, EXIXE_SPI_BUF_SIZE - 5); // set EN bit to 1 for all digits + spi_buf[0] = overdrive ? EXIXE_SPI_HEADER_OD : EXIXE_SPI_HEADER; // first byte, header + spi_buf[digit] = 0x80 | brightness; // set digit brightness + + animation_src_digit = digit; + spi_write(); +} + +void exixe::set_led(unsigned char red, unsigned char green, unsigned char blue) +{ + // cap brightness to 127 + red &= 0x7f; + green &= 0x7f; + blue &= 0x7f; + + memset(spi_buf, 0, EXIXE_SPI_BUF_SIZE - 3); // clear SPI buffer + spi_buf[0] = EXIXE_SPI_HEADER; + spi_buf[13] = 0x80 | red; // set LED colors + spi_buf[14] = 0x80 | green; + spi_buf[15] = 0x80 | blue; + + spi_write(); +} + +void exixe::set_dots(unsigned char left_brightness, unsigned char right_brightness) +{ + // cap brightness to 127 + left_brightness &= 0x7f; + right_brightness &= 0x7f; + + memset(spi_buf, 0, EXIXE_SPI_BUF_SIZE); + spi_buf[0] = EXIXE_SPI_HEADER; + spi_buf[11] = 0x80 | left_brightness; + spi_buf[12] = 0x80 | right_brightness; + + spi_write(); +} + +void exixe::crossfade_init(unsigned char digit, unsigned int duration_frames, unsigned char brightness, unsigned char overdrive) +{ + animation_dest_digit = cap_digit(digit); + animation_start_frame = millis() / EXIXE_ANIMATION_FRAME_DURATION_MS; + animation_duration = duration_frames; + animation_brightness = brightness & 0x7f; + animation_overdrive = overdrive; + animation_step = (float)animation_brightness / (float)animation_duration; +} + +unsigned char exixe::crossfade_run() +{ + unsigned long current_frame = (millis() / EXIXE_ANIMATION_FRAME_DURATION_MS) - animation_start_frame; + + if(current_frame > animation_duration) + { + animation_src_digit = animation_dest_digit; + return EXIXE_ANIMATION_FINISHED; + } + + memset(spi_buf, 0, EXIXE_SPI_BUF_SIZE); + memset(spi_buf, 0x80, EXIXE_SPI_BUF_SIZE - 5); + spi_buf[0] = animation_overdrive ? EXIXE_SPI_HEADER_OD : EXIXE_SPI_HEADER; + + unsigned char temp = cap_float(animation_step * (float)current_frame); + spi_buf[animation_src_digit] = 0x80 | (animation_brightness - temp); + spi_buf[animation_dest_digit] = 0x80 | temp; + spi_write(); + + return EXIXE_ANIMATION_IN_PROGRESS; +} \ No newline at end of file diff --git a/arduino_library/exixe/exixe.h b/arduino_library/exixe/exixe.h new file mode 100644 index 0000000..6a76b0a --- /dev/null +++ b/arduino_library/exixe/exixe.h @@ -0,0 +1,39 @@ +#ifndef exixe_h +#define exixe_h + +#define EXIXE_SPI_BUF_SIZE (16) +#define EXIXE_SPI_HEADER (0xaa) +#define EXIXE_SPI_HEADER_OD (0xab) +#define EXIXE_ANIMATION_FRAME_DURATION_MS (33) +#define EXIXE_ANIMATION_IN_PROGRESS (1) +#define EXIXE_ANIMATION_FINISHED (0) + +class exixe +{ + public: + exixe(int my_cs); + void show_digit(unsigned char digit, unsigned char brightness, unsigned char overdrive); + void set_led(unsigned char red, unsigned char green, unsigned char blue); + void set_dots(unsigned char left_brightness, unsigned char right_brightness); + void crossfade_init(unsigned char digit, unsigned int duration_frames, unsigned char brightness, unsigned char overdrive); + unsigned char crossfade_run(); + void clear(); + private: + unsigned char cs_pin; + unsigned char spi_buf[EXIXE_SPI_BUF_SIZE]; + unsigned char cap_digit(unsigned char digit); + unsigned char cap_float(float temp); + void spi_write(); + + //------- crossfade animation variables ------- + unsigned char animation_src_digit; + unsigned char animation_dest_digit; + unsigned long animation_start_frame; + unsigned long animation_duration; + unsigned char animation_brightness; + unsigned char animation_overdrive; + float animation_step; +}; + +#endif + diff --git a/arduino_library/exixe/keywords.txt b/arduino_library/exixe/keywords.txt new file mode 100644 index 0000000..a27f4dc --- /dev/null +++ b/arduino_library/exixe/keywords.txt @@ -0,0 +1,25 @@ +####################################### +# Datatypes (KEYWORD1) +####################################### + +exixe KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +show_digit KEYWORD2 +set_led KEYWORD2 +set_dots KEYWORD2 +crossfade_init KEYWORD2 +crossfade_run KEYWORD2 +clear KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### +