Version 1
This commit is contained in:
commit
9bce215a08
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,80 @@
|
||||||
|
# ATtiny 13 WS2812B-LED Fire-Effect Garden Lamp
|
||||||
|
This is how you can build a Garden Lamp based on an ATtiny13 and some WS2812B (Neopixel) LEDs.
|
||||||
|
The LEDs are Simulating a nice-looking Fire-Effect. This effect is generated using a random number generator.
|
||||||
|
It also features a LDR Light-Sensor to turn on the Lamp in the Darkness automatically.
|
||||||
|
In the code you can set a time after which the lamp automatically turns off, even if it is still dark.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Software
|
||||||
|
The software is based on several different code snippets. You can find links to them in the Sources-Tab.
|
||||||
|
There are a view different configuration options (like on-time, color, ...), which can be done in the `config.h` file. They are well described in this file.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
1. Fire-Effect turns on when LDR-value gets under `on_val` as defined
|
||||||
|
2. Second state is entered after the timeout `max_on_time` is reached. The LEDs light in the color, defined as `timeout_...`.
|
||||||
|
3. If it gets light again the LEDs light in the color, defined as `day_...`. If you want it to be off, set all values to 0.
|
||||||
|
|
||||||
|
## Program the ATtiny
|
||||||
|
### 1. Upload `ArduinoISP` sketch to the Arduino
|
||||||
|
You can find it in the Examples folder of the Arduino-IDE
|
||||||
|
|
||||||
|
### 2. wiring
|
||||||
|
I use a Arduino Nano to program the ATtiny, but also a Arduino UNO will do fine. Hook up the ATtiny like it is shown in the schematic:
|
||||||
|
<img src="pictures/Program_ATtiny_Steckplatine.png" width="50%">
|
||||||
|
The capacitor is important because it prevents the Arduino from resetting itself while programming the ATtiny.
|
||||||
|
|
||||||
|
### 3. Download ATtiny13 support for the IDE
|
||||||
|
Add the URL `http://drazzy.com/package_drazzy.com_index.json` to the Additional Boards Manager URLs in the IDE Preferences. After that open the Boards-Manager, search for "DIY Attiny" and install it. Now you should find the Attiny13 and some other Attiny Boards in the Board menu.
|
||||||
|
|
||||||
|
### 4. Uploading
|
||||||
|
Open the code in the Arduino IDE and select the Attiny13 as the Board.
|
||||||
|
Select the following settings:
|
||||||
|
<img src="pictures/ide_settings.png" width="40%">
|
||||||
|
|
||||||
|
These settings are important:
|
||||||
|
- Processor-Speed to 9.6 Mhz
|
||||||
|
- Millis, Tone Support to "No Millis, No Tone"
|
||||||
|
|
||||||
|
**After that Press `Burn Bootloader` to make sure that these Settings are applied.**
|
||||||
|
|
||||||
|
Now you can upload the code by simply pressing **Upload**.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Hardware
|
||||||
|
## Schematic
|
||||||
|
<img src="pictures/ATtiny_WS2812_garden_lamp_Schaltplan.png" width="80%">
|
||||||
|
|
||||||
|
## PCB Layout
|
||||||
|
<img src="pictures/ATtiny_WS2812_garden_lamp_Leiterplatte.png" width="40%">
|
||||||
|
|
||||||
|
## ATtiny-Pinout
|
||||||
|
<img src="pictures/attiny-pinout.png" width="40%">
|
||||||
|
<br>(Source: https://cdn.sparkfun.com/assets/f/8/f/d/9/52713d5b757b7fc0658b4567.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Sources / Useful Links
|
||||||
|
You can find more detailed information here:
|
||||||
|
- Arduino ISP: https://www.instructables.com/Updated-Guide-on-How-to-Program-an-Attiny13-or-13a/
|
||||||
|
- Light sensor: https://www.elec-cafe.com/attiny85-light-sensor-switch/
|
||||||
|
- Timer Interrupt: https://arduinodiy.wordpress.com/2015/06/22/flashing-an-led-with-attiny13/
|
||||||
|
- WS2812B Lib:
|
||||||
|
- https://blog.podkalicki.com/attiny13-controlling-leds-ws2811ws2812/
|
||||||
|
- https://www.instructables.com/Updated-Guide-on-How-to-Program-an-Attiny13-or-13a/
|
||||||
|
- Random number gernerator lib:
|
||||||
|
- https://blog.podkalicki.com/attiny13-pseudo-random-numbers/
|
||||||
|
- https://github.com/lpodkalicki/blog/tree/master/avr/attiny13/009_lightweigth_prng_based_on_lfsr
|
||||||
|
- Fire Effect:
|
||||||
|
- https://codebender.cc/sketch:271084#Neopixel%20Flames.ino
|
||||||
|
- WS2812FX-Lib, "Fire-Flicker" Effect: https://github.com/kitesurfer1404/WS2812FX
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### I hope you like this project!
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<p xmlns:dct="http://purl.org/dc/terms/" xmlns:cc="http://creativecommons.org/ns#" class="license-text">This work by <span property="cc:attributionName">Dustin Brunner</span> is licensed under <a rel="license" href="https://creativecommons.org/licenses/by/4.0">CC BY 4.0<img style="height:15px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" /><img style="height:15px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" /></a></p>
|
||||||
|
|
||||||
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons Lizenzvertrag" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />Dieses Werk von <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">Dustin Brunner</span> ist lizenziert unter einer <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Namensnennung 4.0 International Lizenz</a>.
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
ATtiny 13 WS2812B-LED Fire-Effect Garden Lamp
|
||||||
|
Author: dustinbrun
|
||||||
|
licensed under CC BY 4.0
|
||||||
|
|
||||||
|
Version 03.2021
|
||||||
|
|
||||||
|
|
||||||
|
Make sure to Set in the Board Settings:
|
||||||
|
Processor-Speed to 9.6 Mhz
|
||||||
|
Millis, Tone Support to "No Millis, No Tone"
|
||||||
|
After that Press "Burn Bootloader" to make sure that these Settings are applied
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------- !!!! Configuration can be done in the "config.h file !!!! -----------------------------------------
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "light_ws2812.c"
|
||||||
|
#include "light_ws2812.h"
|
||||||
|
#include "random_avr.h"
|
||||||
|
#include "random_avr.c"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool on = true;
|
||||||
|
bool was_on = true;
|
||||||
|
volatile unsigned long counter = 0;// interrupt needs volatile variable
|
||||||
|
|
||||||
|
struct pix
|
||||||
|
{
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t b;
|
||||||
|
};
|
||||||
|
pix pixel[PIXEL_NUM];
|
||||||
|
|
||||||
|
|
||||||
|
ISR(TIMER0_OVF_vect) {
|
||||||
|
/*
|
||||||
|
Timer Configuration:
|
||||||
|
Prescaler 1024, CPU-Speed 9,6MHz = 9600000 Hz
|
||||||
|
|
||||||
|
Interrupt is called with a Frequency of: 9600000Hz/1024/256 = 36,6Hz
|
||||||
|
so every --> 0,027s <---
|
||||||
|
|
||||||
|
*/
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
random_init(0xabcd); // initialize 16 bit seed
|
||||||
|
pinMode(LDR_pin, INPUT);
|
||||||
|
pinMode(2, OUTPUT);
|
||||||
|
|
||||||
|
//Interrupt Setup
|
||||||
|
cli(); // Clear interrupts, just to make sure
|
||||||
|
TCCR0B |= (1 << CS02) | (1 << CS00); // set prescale timer to 1/1024th, set CS02 and CS00 bit in TCCR0B
|
||||||
|
TIMSK0 |= 1 << TOIE0; // enable timer overflow interrupt, left shift 1 to TOIE0 and OR with TIMSK
|
||||||
|
sei(); //start timer
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (analogRead(LDR_pin) < on_val && !was_on)
|
||||||
|
{
|
||||||
|
on = true;
|
||||||
|
was_on = true;
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (analogRead(LDR_pin) > off_val && was_on)
|
||||||
|
{
|
||||||
|
on = false;
|
||||||
|
was_on = false;
|
||||||
|
counter = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < PIXEL_NUM; i++)
|
||||||
|
{
|
||||||
|
pixel[i].r = day_red;
|
||||||
|
pixel[i].g = day_green;
|
||||||
|
pixel[i].b = day_blue;
|
||||||
|
}
|
||||||
|
ws2812_setleds((struct cRGB *)pixel, PIXEL_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter > max_on_time && on)
|
||||||
|
{
|
||||||
|
on = false;
|
||||||
|
counter = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < PIXEL_NUM; i++)
|
||||||
|
{
|
||||||
|
pixel[i].r = timeout_red;
|
||||||
|
pixel[i].g = timeout_green;
|
||||||
|
pixel[i].b = timeout_blue;
|
||||||
|
}
|
||||||
|
ws2812_setleds((struct cRGB *)pixel, PIXEL_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (on)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Flicker, based on our initial RGB values
|
||||||
|
int flicker = random_avr() % indensity;
|
||||||
|
int f_red = red - flicker;
|
||||||
|
int f_green = green - flicker;
|
||||||
|
int f_blue = blue - flicker;
|
||||||
|
if (f_red < 0) f_red = 0;
|
||||||
|
if (f_green < 0) f_green = 0;
|
||||||
|
if (f_blue < 0) f_blue = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < PIXEL_NUM; i++)
|
||||||
|
{
|
||||||
|
pixel[i].r = f_red;
|
||||||
|
pixel[i].g = f_green;
|
||||||
|
pixel[i].b = f_blue;
|
||||||
|
}
|
||||||
|
ws2812_setleds((struct cRGB *)pixel, PIXEL_NUM);
|
||||||
|
|
||||||
|
delay(400 - random_avr() % d_delay);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* ----------------------------------------
|
||||||
|
* ------ Configuration Options -----------
|
||||||
|
* ----------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int on_val = 400; //LDR Value below that to switch the Light on
|
||||||
|
int off_val = 500; //LDR Value above that to switch the Light off
|
||||||
|
unsigned long max_on_time = 666666; // Calculation: ('on_time_in_minutes' * 60) / 0.027
|
||||||
|
//Example: 5h (=300min) ON-time: max_on_time = (300 * 60) / 0.027 = 666666
|
||||||
|
#define PIXEL_NUM 3 //Ammount of WS2812 LEDs
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------
|
||||||
|
* ---------- Colour Settings -------------
|
||||||
|
* ----------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
//----------- Flickering Effect -----------
|
||||||
|
//Default Colours
|
||||||
|
int red = 255;
|
||||||
|
int green = 70;
|
||||||
|
int blue = 20;
|
||||||
|
|
||||||
|
// Purple flame:
|
||||||
|
// int red = 158, green = 8, blue = 148;
|
||||||
|
// Green flame:
|
||||||
|
//int red = 74, green = 150, blue = 12;
|
||||||
|
|
||||||
|
int indensity = 40; // Maximum Flickering offset
|
||||||
|
int d_delay = 300; // Maximum Delay offset
|
||||||
|
|
||||||
|
|
||||||
|
// ----- colour after timeout ----
|
||||||
|
// This is the Colour with which the leds light up, after the timeout (max_on_time) is reached until it gets light again
|
||||||
|
// If you want it to be off, set all values to 0
|
||||||
|
int timeout_red = 0;
|
||||||
|
int timeout_green = 0;
|
||||||
|
int timeout_blue = 5;
|
||||||
|
|
||||||
|
|
||||||
|
// ------ color throughout the day -------
|
||||||
|
// This is the Colour with which the leds light up, when the LDR detects daylight
|
||||||
|
int day_red = 0;
|
||||||
|
int day_green = 0;
|
||||||
|
int day_blue = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------
|
||||||
|
* ---------------- Pins ------------------
|
||||||
|
* ----------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LDR_pin A3
|
||||||
|
// Pin Defintion for LEDs in the light_ws2812.h File as "ws2812_pin" variable
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------
|
||||||
|
* ---------- End of config ---------------
|
||||||
|
* ----------------------------------------
|
||||||
|
*/
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* light weight WS2812 lib V2.0b
|
||||||
|
*
|
||||||
|
* Controls WS2811/WS2812/WS2812B RGB-LEDs
|
||||||
|
* Author: Tim (cpldcpu@gmail.com)
|
||||||
|
*
|
||||||
|
* Jan 18th, 2014 v2.0b Initial Version
|
||||||
|
* Nov 29th, 2015 v2.3 Added SK6812RGBW support
|
||||||
|
*
|
||||||
|
* License: GNU GPL v2+ (see License.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "light_ws2812.h"
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
// Setleds for standard RGB
|
||||||
|
void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds)
|
||||||
|
{
|
||||||
|
ws2812_setleds_pin(ledarray, leds, _BV(ws2812_pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask)
|
||||||
|
{
|
||||||
|
ws2812_sendarray_mask((uint8_t *)ledarray, leds + leds + leds, pinmask);
|
||||||
|
_delay_us(ws2812_resettime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setleds for SK6812RGBW
|
||||||
|
void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds)
|
||||||
|
{
|
||||||
|
ws2812_sendarray_mask((uint8_t *)ledarray, leds << 2, _BV(ws2812_pin));
|
||||||
|
_delay_us(ws2812_resettime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws2812_sendarray(uint8_t *data, uint16_t datlen)
|
||||||
|
{
|
||||||
|
ws2812_sendarray_mask(data, datlen, _BV(ws2812_pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This routine writes an array of bytes with RGB values to the Dataout pin
|
||||||
|
using the fast 800kHz clockless WS2811/2812 protocol.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Timing in ns
|
||||||
|
#define w_zeropulse 350
|
||||||
|
#define w_onepulse 900
|
||||||
|
#define w_totalperiod 1250
|
||||||
|
|
||||||
|
// Fixed cycles used by the inner loop
|
||||||
|
#define w_fixedlow 2
|
||||||
|
#define w_fixedhigh 4
|
||||||
|
#define w_fixedtotal 8
|
||||||
|
|
||||||
|
// Insert NOPs to match the timing, if possible
|
||||||
|
#define w_zerocycles (((F_CPU / 1000) * w_zeropulse) / 1000000)
|
||||||
|
#define w_onecycles (((F_CPU / 1000) * w_onepulse + 500000) / 1000000)
|
||||||
|
#define w_totalcycles (((F_CPU / 1000) * w_totalperiod + 500000) / 1000000)
|
||||||
|
|
||||||
|
// w1 - nops between rising edge and falling edge - low
|
||||||
|
#define w1 (w_zerocycles - w_fixedlow)
|
||||||
|
// w2 nops between fe low and fe high
|
||||||
|
#define w2 (w_onecycles - w_fixedhigh - w1)
|
||||||
|
// w3 nops to complete loop
|
||||||
|
#define w3 (w_totalcycles - w_fixedtotal - w1 - w2)
|
||||||
|
|
||||||
|
#if w1 > 0
|
||||||
|
#define w1_nops w1
|
||||||
|
#else
|
||||||
|
#define w1_nops 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The only critical timing parameter is the minimum pulse length of the "0"
|
||||||
|
// Warn or throw error if this timing can not be met with current F_CPU settings.
|
||||||
|
#define w_lowtime ((w1_nops + w_fixedlow) * 1000000) / (F_CPU / 1000)
|
||||||
|
#if w_lowtime > 550
|
||||||
|
#error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?"
|
||||||
|
#elif w_lowtime > 450
|
||||||
|
#warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)."
|
||||||
|
#warning "Please consider a higher clockspeed, if possible"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if w2 > 0
|
||||||
|
#define w2_nops w2
|
||||||
|
#else
|
||||||
|
#define w2_nops 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if w3 > 0
|
||||||
|
#define w3_nops w3
|
||||||
|
#else
|
||||||
|
#define w3_nops 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define w_nop1 "nop \n\t"
|
||||||
|
#define w_nop2 "rjmp .+0 \n\t"
|
||||||
|
#define w_nop4 w_nop2 w_nop2
|
||||||
|
#define w_nop8 w_nop4 w_nop4
|
||||||
|
#define w_nop16 w_nop8 w_nop8
|
||||||
|
|
||||||
|
void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi)
|
||||||
|
{
|
||||||
|
uint8_t curbyte, ctr, masklo;
|
||||||
|
uint8_t sreg_prev;
|
||||||
|
|
||||||
|
ws2812_DDRREG |= maskhi; // Enable output
|
||||||
|
|
||||||
|
masklo = ~maskhi & ws2812_PORTREG;
|
||||||
|
maskhi |= ws2812_PORTREG;
|
||||||
|
|
||||||
|
sreg_prev = SREG;
|
||||||
|
cli();
|
||||||
|
|
||||||
|
while (datlen--)
|
||||||
|
{
|
||||||
|
curbyte = *data++;
|
||||||
|
|
||||||
|
__asm volatile(
|
||||||
|
" ldi %0,8 \n\t"
|
||||||
|
"loop%=: \n\t"
|
||||||
|
" out %2,%3 \n\t" // '1' [01] '0' [01] - re
|
||||||
|
#if (w1_nops & 1)
|
||||||
|
w_nop1
|
||||||
|
#endif
|
||||||
|
#if (w1_nops & 2)
|
||||||
|
w_nop2
|
||||||
|
#endif
|
||||||
|
#if (w1_nops & 4)
|
||||||
|
w_nop4
|
||||||
|
#endif
|
||||||
|
#if (w1_nops & 8)
|
||||||
|
w_nop8
|
||||||
|
#endif
|
||||||
|
#if (w1_nops & 16)
|
||||||
|
w_nop16
|
||||||
|
#endif
|
||||||
|
" sbrs %1,7 \n\t" // '1' [03] '0' [02]
|
||||||
|
" out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low
|
||||||
|
" lsl %1 \n\t" // '1' [04] '0' [04]
|
||||||
|
#if (w2_nops & 1)
|
||||||
|
w_nop1
|
||||||
|
#endif
|
||||||
|
#if (w2_nops & 2)
|
||||||
|
w_nop2
|
||||||
|
#endif
|
||||||
|
#if (w2_nops & 4)
|
||||||
|
w_nop4
|
||||||
|
#endif
|
||||||
|
#if (w2_nops & 8)
|
||||||
|
w_nop8
|
||||||
|
#endif
|
||||||
|
#if (w2_nops & 16)
|
||||||
|
w_nop16
|
||||||
|
#endif
|
||||||
|
" out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high
|
||||||
|
#if (w3_nops & 1)
|
||||||
|
w_nop1
|
||||||
|
#endif
|
||||||
|
#if (w3_nops & 2)
|
||||||
|
w_nop2
|
||||||
|
#endif
|
||||||
|
#if (w3_nops & 4)
|
||||||
|
w_nop4
|
||||||
|
#endif
|
||||||
|
#if (w3_nops & 8)
|
||||||
|
w_nop8
|
||||||
|
#endif
|
||||||
|
#if (w3_nops & 16)
|
||||||
|
w_nop16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
" dec %0 \n\t" // '1' [+2] '0' [+2]
|
||||||
|
" brne loop%=\n\t" // '1' [+3] '0' [+4]
|
||||||
|
: "=&d"(ctr)
|
||||||
|
: "r"(curbyte), "I"(_SFR_IO_ADDR(ws2812_PORTREG)), "r"(maskhi), "r"(masklo));
|
||||||
|
}
|
||||||
|
|
||||||
|
SREG = sreg_prev;
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
light_ws2812_config.h
|
||||||
|
|
||||||
|
v2.4 - Nov 27, 2016
|
||||||
|
|
||||||
|
User Configuration file for the light_ws2812_lib
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Define I/O pin
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define ws2812_port B // Data port
|
||||||
|
#define ws2812_pin 0 // Data out pin
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Define Reset time in µs.
|
||||||
|
//
|
||||||
|
// This is the time the library spends waiting after writing the data.
|
||||||
|
//
|
||||||
|
// WS2813 needs 300 µs reset time
|
||||||
|
// WS2812 and clones only need 50 µs <<<-----
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define ws2812_resettime 50
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* WS2812_CONFIG_H_
|
||||||
|
* light weight WS2812 lib include
|
||||||
|
*
|
||||||
|
* Version 2.3 - Nev 29th 2015
|
||||||
|
* Author: Tim (cpldcpu@gmail.com)
|
||||||
|
*
|
||||||
|
* Please do not change this file!"
|
||||||
|
*
|
||||||
|
* License: GNU GPL v2+ (see License.txt)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIGHT_WS2812_H_
|
||||||
|
#define LIGHT_WS2812_H_
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure of the LED array
|
||||||
|
*
|
||||||
|
* cRGB: RGB for WS2812S/B/C/D, SK6812, SK6812Mini, SK6812WWA, APA104, APA106
|
||||||
|
* cRGBW: RGBW for SK6812RGBW
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct cRGB { uint8_t g; uint8_t r; uint8_t b; };
|
||||||
|
struct cRGBW { uint8_t g; uint8_t r; uint8_t b; uint8_t w;};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* User Interface
|
||||||
|
*
|
||||||
|
* Input:
|
||||||
|
* ledarray: An array of GRB data describing the LED colors
|
||||||
|
* number_of_leds: The number of LEDs to write
|
||||||
|
* pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0)
|
||||||
|
*
|
||||||
|
* The functions will perform the following actions:
|
||||||
|
* - Set the data-out pin as output
|
||||||
|
* - Send out the LED data
|
||||||
|
* - Wait 50µs to reset the LEDs
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ws2812_setleds (struct cRGB *ledarray, uint16_t number_of_leds);
|
||||||
|
void ws2812_setleds_pin (struct cRGB *ledarray, uint16_t number_of_leds,uint8_t pinmask);
|
||||||
|
void ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t number_of_leds);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Old interface / Internal functions
|
||||||
|
*
|
||||||
|
* The functions take a byte-array and send to the data output as WS2812 bitstream.
|
||||||
|
* The length is the number of bytes to send - three per LED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ws2812_sendarray (uint8_t *array,uint16_t length);
|
||||||
|
void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal defines
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CONCAT(a, b) a ## b
|
||||||
|
#define CONCAT_EXP(a, b) CONCAT(a, b)
|
||||||
|
|
||||||
|
#define ws2812_PORTREG CONCAT_EXP(PORT,ws2812_port)
|
||||||
|
#define ws2812_DDRREG CONCAT_EXP(DDR,ws2812_port)
|
||||||
|
|
||||||
|
#endif /* LIGHT_WS2812_H_ */
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
Copyright (c) 2017, Łukasz Marcin Podkalicki <lpodkalicki@gmail.com>
|
||||||
|
Lightweight library of 16 bit random number generator based on LFSR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
#include "random_avr.h"
|
||||||
|
|
||||||
|
static uint16_t random_number = 0;
|
||||||
|
|
||||||
|
static uint16_t
|
||||||
|
lfsr16_next(uint16_t n)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (n >> 0x01U) ^ (-(n & 0x01U) & 0xB400U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void random_init(uint16_t seed)
|
||||||
|
{
|
||||||
|
#ifdef USE_RANDOM_SEED
|
||||||
|
random_number = lfsr16_next(eeprom_read_word((uint16_t *)RANDOM_SEED_ADDRESS) ^ seed);
|
||||||
|
eeprom_write_word((uint16_t *)0, random_number);
|
||||||
|
#else
|
||||||
|
random_number = seed;
|
||||||
|
#endif /* !USE_RANDOM_SEED */
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
random_avr(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (random_number = lfsr16_next(random_number));
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2017, Łukasz Marcin Podkalicki <lpodkalicki@gmail.com>
|
||||||
|
Lightweight library of 16 bit random number generator based on LFSR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RANDOM_H_
|
||||||
|
#define _RANDOM_H_
|
||||||
|
|
||||||
|
#ifdef USE_RANDOM_SEED
|
||||||
|
#define RANDOM_SEED_ADDRESS 0x00
|
||||||
|
#endif /* !USE_RANDOM_SEED */
|
||||||
|
|
||||||
|
void random_init(uint16_t seed);
|
||||||
|
uint16_t random_avr(void);
|
||||||
|
|
||||||
|
#endif /* !_RANDOM_H_ */
|
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
Binary file not shown.
After Width: | Height: | Size: 159 KiB |
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
Loading…
Reference in New Issue