diff --git a/lib/ws2812b.c b/lib/ws2812b.c
new file mode 100644
index 0000000..34c3d18
--- /dev/null
+++ b/lib/ws2812b.c
@@ -0,0 +1,214 @@
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+/* This library allows to control WS2812B LEDs
+ * it uses timer 0 with interruts
+ */
+
+#include // Standard Integer Types
+#include // Standard IO facilities
+#include // General utilities
+#include // boolean type
+
+#include // AVR device-specific IO definitions
+#include // Interrupts
+
+#include "ws2812b.h" // WS2812B header
+
+/* has the WS2812B been initialized correctly */
+bool initialized = false;
+/* the green, red, and blue (8 bits each) bit values for each LEDs */
+uint8_t color_bits[3*8*WS2812B_NB_LEDS] = {0};
+/* how much to shift for which channel */
+uint8_t channel_shifts[WS2812B_NB_CHANNELS] = {0};
+/* have the 50 us reset code timeout passed */
+volatile bool reset_code = true;
+
+/* initialize */
+bool ws2812b_init()
+{
+ initialized = false;
+ /* verify we are running with 16 MHz */
+ if (F_CPU != 16000000) {
+ return initialized; // the code has been designed for 16 MHz
+ }
+ /* verify there are LEDs to use */
+ if (WS2812B_NB_LEDS==0) {
+ return initialized; // there in no data to send
+ }
+ /* generate the channel shift depending on mask*/
+ uint8_t channel = 0;
+ for (uint8_t shift=0; shift<8; shift++) {
+ if ( (WS2812B_MASK>>shift)&0x01 ) {
+ channel_shifts[channel++] = shift;
+ }
+ }
+ /* verify the number of channels corresponds to the mask */
+ if (WS2812B_NB_CHANNELS!=channel) {
+ return initialized; // the number of channels does not match the mask
+ }
+
+ WS2812B_DDR |= WS2812B_MASK; // set pins as output
+
+ /* user timer 0 to time the reset code of 50 us */
+ TCCR0B |= (0<=WS2812B_NB_CHANNELS) {
+ return false;
+ }
+ if (led>=WS2812B_NB_LEDS) {
+ return false;
+ }
+
+ /* set color values
+ * composition of 24bit data: G7..G0,R7..R0,B7..B0
+ * high bit is sent first
+ * LEDs keep the first values and forward the next
+ */
+ for (uint8_t i=0; i<8; i++) {
+ uint8_t color_bit = 1<<(7-i);
+ if (green&color_bit) {
+ color_bits[8*3*led+i] |= (1<.
+ *
+ */
+/* This library allows to control WS2812B LEDs
+ * it uses timer 0 with interruts
+ */
+
+/* the port on which the WS2812B LEDs are attached */
+#define WS2812B_PORT PORTD
+#define WS2812B_DDR DDRD
+#define WS2812B_PIN PIND
+/* the pin on the previous port on which the WS2812B LEDs are attached
+ * use as many strips in parallel on the available pins to save time and memory */
+#define WS2812B_MASK 0xfc
+#define WS2812B_NB_CHANNELS 6
+/* the maximum number of chained WS2812B LEDs attached on a pin
+ * use as few in series and prefer putting them in parrallel to save time and memory */
+#define WS2812B_NB_LEDS 11
+
+/* initialize port */
+bool ws2812b_init(void);
+/* set the color of the LED on a channel LED chain, but do not show yet */
+bool ws2812b_set_led_color(uint8_t channel, uint8_t led, uint8_t red, uint8_t green, uint8_t blue);
+/* switch off all LEDs, but do not show yet */
+void ws2812b_off(void);
+/* send the RGB values to the LEDs */
+void ws2812b_show(void);