implemented ws2812 interface (lib)
This commit is contained in:
parent
a7f8d563bd
commit
8c452ebdcf
|
@ -24,6 +24,10 @@ todo
|
|||
|
||||
## Software
|
||||
|
||||
#Librarys
|
||||
|
||||
https://github.com/marenz2569/libws2812_avr
|
||||
|
||||
todo
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ double ioController::get15VProbe() {
|
|||
}
|
||||
|
||||
void ioController::ports_init() {
|
||||
DDRD |= 1 << WS2812B;
|
||||
DDRB |= 1 << ACTIVELED;
|
||||
DDRB |= 1 << BUZZER;
|
||||
DDRB |= 1 << POWERON;
|
||||
|
@ -103,3 +102,19 @@ void ioController::setMultiplexer(bool pS2, bool pS1, bool pS0) {
|
|||
|
||||
}
|
||||
|
||||
void ioController::setWS2812(const unsigned char red, const unsigned char green,
|
||||
const unsigned char blue) {
|
||||
|
||||
WS2812 led(LED_C);
|
||||
led.set_output(&PORTD, &DDRD, DDD2);
|
||||
Color strobe;
|
||||
uint8_t i;
|
||||
|
||||
strobe.r = red;
|
||||
strobe.g = green;
|
||||
strobe.b = blue;
|
||||
for (i = 0; i < LED_C; i++)
|
||||
led.set_rgb_at(i, strobe);
|
||||
led.sync();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ class ioController {
|
|||
|
||||
private:
|
||||
|
||||
|
||||
public:
|
||||
ioController();
|
||||
~ioController();
|
||||
|
@ -26,6 +25,9 @@ public:
|
|||
void adc_init(void);
|
||||
int readAdc(char chan);
|
||||
void setMultiplexer(bool pS2, bool pS1, bool pS0);
|
||||
void setWS2812(const unsigned char red, const unsigned char green,
|
||||
const unsigned char blue);
|
||||
|
||||
};
|
||||
|
||||
#endif /* SRC_IOCONTROLLER_H_ */
|
||||
|
|
|
@ -30,6 +30,8 @@ int main(void) {
|
|||
|
||||
createChargers();
|
||||
|
||||
io.setWS2812(0, 255, 255);
|
||||
|
||||
//loop till power off
|
||||
while (true) {
|
||||
checkForBattery();
|
||||
|
@ -131,13 +133,10 @@ void printStatus() {
|
|||
for (int i = 0; i < CHARGER_SIZE; i++) {
|
||||
if (chargers[i].getStatus()) {
|
||||
//chargers[i].getInfo(); //print values
|
||||
char charVal[10];
|
||||
|
||||
//char charVal[10];
|
||||
//dtostrf(chargers[i].getCurrent(), 4, 0, charVal);
|
||||
|
||||
sprintf(charVal, "%i µAh\r\n", chargers[i].getCapacity());
|
||||
|
||||
serialSend(charVal);
|
||||
//sprintf(charVal, "%i µAh\r\n", chargers[i].getCapacity());
|
||||
//serialSend(charVal);
|
||||
//serialSend(" mA\r\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,15 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
/* project header */
|
||||
#include "ws2812/ws2812.h"
|
||||
#include "ioController.h"
|
||||
#include "multiplexer.h"
|
||||
#include "clock.h"
|
||||
#include "charger.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* Pins */
|
||||
#define WS2812B PD2
|
||||
#define ACTIVELED PB5
|
||||
|
@ -57,5 +60,6 @@ void serialSend(const char* sendString);
|
|||
#define CH3_U 3
|
||||
#define CH3_I 7
|
||||
|
||||
|
||||
/* ws2812 */
|
||||
#define LED_C 1
|
||||
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COLOR_H__
|
||||
#define COLOR_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/**
|
||||
* A class used to save and convert hsi and rgb values
|
||||
*/
|
||||
class Color
|
||||
{
|
||||
/**
|
||||
* check if the rgb values of 2 Color objects are the same
|
||||
* @param a first Color object
|
||||
* @param b second Color object
|
||||
*/
|
||||
friend bool operator ==(Color a, Color b)
|
||||
{
|
||||
if (a.r != b.r)
|
||||
return false;
|
||||
if (a.g != b.g)
|
||||
return false;
|
||||
if (a.b != b.b)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the rgb values of 2 Color objecs are not the same
|
||||
* @param a first Color object
|
||||
* @param b second Color object
|
||||
*/
|
||||
friend bool operator !=(Color a, Color b)
|
||||
{
|
||||
if (a.r != b.r)
|
||||
return true;
|
||||
if (a.g != b.g)
|
||||
return true;
|
||||
if (a.b != b.b)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* red value
|
||||
*/
|
||||
uint8_t r;
|
||||
/**
|
||||
* green value
|
||||
*/
|
||||
uint8_t g;
|
||||
/**
|
||||
* blue value
|
||||
*/
|
||||
uint8_t b;
|
||||
/**
|
||||
* hue value
|
||||
*/
|
||||
float h;
|
||||
/**
|
||||
* saturation value
|
||||
*/
|
||||
float s;
|
||||
/**
|
||||
* intensity value
|
||||
*/
|
||||
float i;
|
||||
|
||||
/**
|
||||
* convert hsi to rgb
|
||||
* @param h_ hue value
|
||||
* @param s_ saturation value
|
||||
* @param i_ intensity value
|
||||
*/
|
||||
void hsi2rgb(float h_, float s_, float i_);
|
||||
/**
|
||||
* convert rgb to hsi
|
||||
* @param r_ red value
|
||||
* @param g_ green value
|
||||
* @param b_ blue value
|
||||
*/
|
||||
void rgb2hsi(uint8_t r_, uint8_t g_, uint8_t b_);
|
||||
};
|
||||
|
||||
/**
|
||||
* A type to define the fadeing direction
|
||||
*/
|
||||
enum color_fade_dir_t
|
||||
{
|
||||
shortest,
|
||||
longest,
|
||||
clockwise,
|
||||
counter_clockwise
|
||||
};
|
||||
|
||||
/**
|
||||
* A class used to fade linear between two points in hsi color space
|
||||
*/
|
||||
class FadeLinear
|
||||
{
|
||||
private:
|
||||
uint16_t step_count;
|
||||
|
||||
uint16_t cur_step;
|
||||
|
||||
float h_step, s_step, i_step;
|
||||
|
||||
Color cCur;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @param cFrom Color object as fade origin
|
||||
* @param cTo Color oject as fade result
|
||||
* @param stepCount number of fadeing steps
|
||||
* @param fadeDir fade direction in hsi color space
|
||||
*/
|
||||
FadeLinear(Color &cFrom, Color &cTo, uint16_t stepCount, color_fade_dir_t fadeDir);
|
||||
/**
|
||||
* calls constructor {@link #FadeLinear(Color &cFrom, Color &cTo, uint16_t stepCount, color_fade_dir_t fadeDir)}
|
||||
* with fadeDir = shortest
|
||||
*/
|
||||
FadeLinear(Color &cFrom, Color &cTo, uint16_t stepCount);
|
||||
|
||||
/**
|
||||
* updates Color object in this class, that saves current fade color
|
||||
* @return 1 if successful, 0 if not
|
||||
*/
|
||||
uint8_t next(void);
|
||||
|
||||
/**
|
||||
* @return Color object
|
||||
*/
|
||||
Color get_cur_color(void);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A class is used to fade from the color to a grayscale with i = deltaI / 2 to the second color
|
||||
*/
|
||||
class FadeThroughIAxis {
|
||||
private:
|
||||
uint16_t step_count;
|
||||
|
||||
uint16_t cur_step;
|
||||
|
||||
float from_step_count, to_step_count;
|
||||
|
||||
float h_from_step, s_from_step, i_from_step;
|
||||
|
||||
float h_to_step, s_to_step, i_to_step;
|
||||
|
||||
Color cCur;
|
||||
public:
|
||||
FadeThroughIAxis(Color& cFrom, Color& cTo, uint16_t stepCount);
|
||||
|
||||
uint8_t next(void);
|
||||
|
||||
Color get_cur_color(void);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "ws2812_avr_macros.h"
|
||||
|
||||
/* derived from http://fourier.eng.hmc.edu/e161/lectures/ColorProcessing/node3.html */
|
||||
void Color::hsi2rgb(float h_, float s_, float i_)
|
||||
{
|
||||
h = h_;
|
||||
s = s_;
|
||||
i = i_;
|
||||
|
||||
h_ = fmod(h_, 360);
|
||||
/* convert h to radiants */
|
||||
h_ = M_PI * h_ / 180.0;
|
||||
/* clamp s and i to interval [0:1] */
|
||||
s_ = clamp_to_0_1(s_);
|
||||
i_ = clamp_to_0_1(i_);
|
||||
|
||||
if (s_ == 0.0) {
|
||||
r = g = b = i_ * 255;
|
||||
} else {
|
||||
float r_, g_, b_;
|
||||
#define hsi2rgb_color1 ((1 - s_) / 3)
|
||||
#define hsi2rgb_color2 ((1 + s_ * cos(h_) / cos((M_PI / 3.0) - h_)) / 3)
|
||||
if ((h_ >= 0.0) && (h_ < 2.0 * M_PI / 3.0)) {
|
||||
b_ = hsi2rgb_color1;
|
||||
r_ = hsi2rgb_color2;
|
||||
g_ = 1 - b_ - r_;
|
||||
} else if ((h_ >= 2.0 * M_PI / 3.0) && (h_ < 4.0 * M_PI / 3.0)) {
|
||||
h_ -= 2.0 * M_PI / 3.0;
|
||||
r_ = hsi2rgb_color1;
|
||||
g_ = hsi2rgb_color2;
|
||||
b_ = 1 - r_ - g_;
|
||||
} else {
|
||||
h_ -= 4.0 * M_PI / 3.0;
|
||||
g_ = hsi2rgb_color1;
|
||||
b_ = hsi2rgb_color2;
|
||||
r_ = 1 - g_ - b_;
|
||||
}
|
||||
|
||||
r_ = i_ * r_ * 255;
|
||||
g_ = i_ * g_ * 255;
|
||||
b_ = i_ * b_ * 255;
|
||||
|
||||
/* clamp r, g and b to interval [0:255] */
|
||||
r = clamp_to_0_255(r_);
|
||||
g = clamp_to_0_255(g_);
|
||||
b = clamp_to_0_255(b_);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "color.h"
|
||||
|
||||
/* derived form http://www.cse.usf.edu/~mshreve/rgb-to-hsi */
|
||||
void Color::rgb2hsi(uint8_t r_, uint8_t g_, uint8_t b_)
|
||||
{
|
||||
r = r_;
|
||||
g = g_;
|
||||
b = b_;
|
||||
|
||||
float h_, s_, i_, sum;
|
||||
sum = (float) (r_ + g_ + b_);
|
||||
i_ = sum / 255.0;
|
||||
|
||||
/* normalize rgb values */
|
||||
float n_r = (float) r_ / sum;
|
||||
float n_g = (float) g_ / sum;
|
||||
float n_b = (float) b_ / sum;
|
||||
|
||||
h_ = acos(0.5 * ((n_r - n_g) + (n_r - n_b)) / sqrt(pow((n_r - n_g), 2.0) + ((n_r - n_b) * (n_g - n_b))));
|
||||
|
||||
if (n_b > n_g)
|
||||
h_ = 2 * M_PI - h_;
|
||||
|
||||
s_ = 1 - 3 * fmin(n_r, fmin(n_g, n_b));
|
||||
|
||||
h = h_ * 180.0 / M_PI;
|
||||
s = s_;
|
||||
i = i_;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "ws2812_avr_macros.h"
|
||||
|
||||
FadeLinear::FadeLinear(Color &cFrom, Color &cTo, uint16_t stepCount, color_fade_dir_t fadeDir) : step_count(stepCount), cCur(cFrom), cur_step(0)
|
||||
{
|
||||
float h_step_;
|
||||
h_step_ = cTo.h - cFrom.h;
|
||||
|
||||
switch (fadeDir) {
|
||||
case shortest:
|
||||
if (fabs(h_step_) > 180.0)
|
||||
h_step_ = _change_pos_neg(h_step_) * _360_min_fabs(h_step_);
|
||||
break;
|
||||
case longest:
|
||||
if (fabs(h_step_) < 180.0)
|
||||
h_step_ = _change_pos_neg(h_step_) * _360_min_fabs(h_step_);
|
||||
break;
|
||||
case clockwise:
|
||||
if (h_step_ < 0.0)
|
||||
h_step_ = _360_min_fabs(h_step_);
|
||||
break;
|
||||
case counter_clockwise:
|
||||
if (h_step_ > 0.0)
|
||||
h_step_ = -1.0 * _360_min_fabs(h_step_);
|
||||
break;
|
||||
}
|
||||
h_step = h_step_ / (float)step_count;
|
||||
s_step = (cTo.s - cFrom.s) / (float)step_count;
|
||||
i_step = (cTo.i - cFrom.i) / (float)step_count;
|
||||
}
|
||||
|
||||
FadeLinear::FadeLinear(Color &cFrom, Color &cTo, uint16_t stepCount) : FadeLinear(cFrom, cTo, stepCount, shortest)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint8_t FadeLinear::next(void)
|
||||
{
|
||||
if (cur_step++ < step_count) {
|
||||
cCur.hsi2rgb(cCur.h + h_step, cCur.s + s_step, cCur.i + i_step);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Color FadeLinear::get_cur_color(void)
|
||||
{
|
||||
return cCur;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "ws2812_avr_macros.h"
|
||||
|
||||
FadeThroughIAxis::FadeThroughIAxis(Color& cFrom, Color& cTo, uint16_t stepCount) : step_count(stepCount), cur_step(0), cCur(cFrom)
|
||||
{
|
||||
Color center;
|
||||
float deltaI, tri_i_s_from;
|
||||
|
||||
deltaI = fabs(cFrom.i - cTo.i);
|
||||
tri_i_s_from = sqrt(pow(deltaI, 2) / 4 + pow(cFrom.s, 2));
|
||||
from_step_count = tri_i_s_from / (tri_i_s_from + sqrt(pow(deltaI, 2) / 4 + pow(cTo.s, 2))) * step_count;
|
||||
to_step_count = step_count - from_step_count;
|
||||
|
||||
center.i = fmin(cFrom.i, cTo.i) + deltaI / 2;
|
||||
center.h = 0.0;
|
||||
center.s = 0.0;
|
||||
|
||||
float h_from_step_;
|
||||
/* shortest */
|
||||
h_from_step_ = center.h - cFrom.h;
|
||||
if (fabs(h_from_step_) > 180.0)
|
||||
h_from_step_ = _change_pos_neg(h_from_step_) * _360_min_fabs(h_from_step_);
|
||||
h_from_step = h_from_step_ / (float)from_step_count;
|
||||
s_from_step = (center.s - cFrom.s) / (float)from_step_count;
|
||||
i_from_step = (center.i - cFrom.i) / (float)from_step_count;
|
||||
|
||||
float h_to_step_;
|
||||
/* shortest */
|
||||
h_to_step_ = cTo.h - center.h;
|
||||
if (fabs(h_to_step_) > 180.0)
|
||||
h_to_step_ = _change_pos_neg(h_to_step_) * _360_min_fabs(h_to_step_);
|
||||
h_to_step = h_to_step_;
|
||||
s_to_step = (cTo.s - center.s) / (float)to_step_count;
|
||||
i_to_step = (cTo.i - center.i) / (float)to_step_count;
|
||||
}
|
||||
|
||||
uint8_t FadeThroughIAxis::next(void)
|
||||
{
|
||||
if (cur_step++ < from_step_count) {
|
||||
cCur.hsi2rgb(cCur.h + h_from_step, cCur.s + s_from_step, cCur.i + i_from_step);
|
||||
return 1;
|
||||
} else if (cur_step++ < step_count) {
|
||||
cCur.hsi2rgb(cCur.h + h_to_step, cCur.s + s_to_step, cCur.i + i_to_step);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Color FadeThroughIAxis::get_cur_color(void)
|
||||
{
|
||||
return cCur;
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* light weight WS2812 lib V2.1 - Arduino support
|
||||
*
|
||||
* Controls WS2811/WS2812/WS2812B RGB-LEDs
|
||||
* Author: Tim (cpldcpu@gmail.com)
|
||||
*
|
||||
* Jan 18th, 2014 v2.0b Initial Version
|
||||
* March 7th, 2014 v2.1 Added option to retarget the port register during runtime
|
||||
* Removes inlining to allow compiling with c++
|
||||
*
|
||||
* License: GNU GPL v2 (see LICENSE)
|
||||
*/
|
||||
|
||||
#include "ws2812.h"
|
||||
|
||||
/*
|
||||
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 3
|
||||
#define w_fixedhigh 6
|
||||
#define w_fixedtotal 10
|
||||
|
||||
// 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 WS2812::ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi,uint8_t *port, uint8_t *portreg)
|
||||
{
|
||||
uint8_t curbyte,ctr,masklo;
|
||||
uint8_t sreg_prev;
|
||||
|
||||
masklo = ~maskhi & *port;
|
||||
maskhi |= *port;
|
||||
sreg_prev=SREG;
|
||||
cli();
|
||||
|
||||
while (datlen--) {
|
||||
curbyte=*data++;
|
||||
|
||||
asm volatile(
|
||||
" ldi %0,8 \n\t"
|
||||
"loop%=: \n\t"
|
||||
" st X,%3 \n\t" // '1' [02] '0' [02] - 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' [04] '0' [03]
|
||||
" st X,%4 \n\t" // '1' [--] '0' [05] - fe-low
|
||||
" lsl %1 \n\t" // '1' [05] '0' [06]
|
||||
#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
|
||||
" brcc skipone%= \n\t" // '1' [+1] '0' [+2] -
|
||||
" st X,%4 \n\t" // '1' [+3] '0' [--] - fe-high
|
||||
"skipone%=: " // '1' [+3] '0' [+2] -
|
||||
|
||||
#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' [+4] '0' [+3]
|
||||
" brne loop%=\n\t" // '1' [+5] '0' [+4]
|
||||
: "=&d" (ctr)
|
||||
// : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo)
|
||||
: "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo)
|
||||
);
|
||||
}
|
||||
|
||||
SREG=sreg_prev;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ws2812.h"
|
||||
|
||||
WS2812::WS2812(int ledCount) {
|
||||
count_led = ledCount;
|
||||
pixels = (uint8_t*) malloc(count_led * 3);
|
||||
}
|
||||
|
||||
void WS2812::sync(void) {
|
||||
*ws2812_port_reg |= pinMask;
|
||||
ws2812_sendarray_mask(pixels, 3 * count_led, pinMask,
|
||||
(uint8_t*) ws2812_port, (uint8_t*) ws2812_port_reg);
|
||||
}
|
||||
|
||||
/* &PORTB, &DDRB, DDB2 */
|
||||
void WS2812::set_output(const volatile uint8_t* port, volatile uint8_t* reg,
|
||||
uint8_t pin) {
|
||||
pinMask = (1 << pin);
|
||||
ws2812_port = port;
|
||||
ws2812_port_reg = reg;
|
||||
}
|
||||
|
||||
uint8_t WS2812::set_rgb_at(uint16_t index, Color &pixel) {
|
||||
if (index < count_led) {
|
||||
uint16_t tmp;
|
||||
tmp = index * 3;
|
||||
|
||||
pixels[OFFSET_R(tmp)] = pixel.r;
|
||||
pixels[OFFSET_G(tmp)] = pixel.g;
|
||||
pixels[OFFSET_B(tmp)] = pixel.b;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef WS2812_H__
|
||||
#define WS2812_H__
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "color.h"
|
||||
|
||||
#define OFFSET_R(r) r+1
|
||||
#define OFFSET_G(g) g
|
||||
#define OFFSET_B(b) b+2
|
||||
|
||||
class WS2812
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param num_led number of WS2812 leds
|
||||
*/
|
||||
WS2812(int ledCount);
|
||||
~WS2812(void);
|
||||
|
||||
/**
|
||||
* sets a pin as signal output
|
||||
* @param port PORTx
|
||||
* @param reg DDRx
|
||||
* @param pin DDBy
|
||||
*/
|
||||
void set_output(const volatile uint8_t* port, volatile uint8_t* reg, uint8_t pin);
|
||||
|
||||
/**
|
||||
* get number of leds
|
||||
* @return number of leds
|
||||
*/
|
||||
uint16_t get_led_count(void);
|
||||
|
||||
/**
|
||||
* get rgb values of a led
|
||||
* @param index number of the led
|
||||
* @return Color object with rgb values
|
||||
*/
|
||||
Color get_rgb_at(uint16_t index);
|
||||
/**
|
||||
* set rgb values of a led
|
||||
* @param index number of the led
|
||||
* @param pixel Color object with rgb values
|
||||
* @return 1 if successful, 0 if not
|
||||
*/
|
||||
uint8_t set_rgb_at(uint16_t index, Color &pixel);
|
||||
|
||||
/**
|
||||
* synchronize the leds with the set color values
|
||||
*/
|
||||
void sync(void);
|
||||
|
||||
private:
|
||||
uint16_t count_led;
|
||||
uint8_t *pixels;
|
||||
|
||||
void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask, uint8_t *port, uint8_t *portreg);
|
||||
|
||||
const volatile uint8_t *ws2812_port;
|
||||
volatile uint8_t *ws2812_port_reg;
|
||||
uint8_t pinMask;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* clamps x to interval [0,1]
|
||||
*/
|
||||
#define clamp_to_0_1(x) (x>0?(x<1?x:1):0)
|
||||
/**
|
||||
* clamps x to interval [0,255]
|
||||
*/
|
||||
#define clamp_to_0_255(x) (x>0?(x<255?x:255):0)
|
||||
/**
|
||||
* function
|
||||
*
|
||||
* 360 - |x|
|
||||
*/
|
||||
#define _360_min_fabs(x) (360.0 - fabs(x))
|
||||
/**
|
||||
* function
|
||||
*
|
||||
* x
|
||||
* - -----
|
||||
* |x|
|
||||
*/
|
||||
#define _change_pos_neg(x) (-1.0 * x / fabs(x))
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ws2812.h"
|
||||
|
||||
WS2812::~WS2812(void)
|
||||
{
|
||||
free(pixels);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ws2812.h"
|
||||
|
||||
uint16_t WS2812::get_led_count(void)
|
||||
{
|
||||
return count_led;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* A library for avr microcontrollers to control WS2812 leds
|
||||
*
|
||||
* Copyright (C) 2016 Markus Schmidl
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ws2812.h"
|
||||
|
||||
Color WS2812::get_rgb_at(uint16_t index)
|
||||
{
|
||||
Color pixel;
|
||||
|
||||
if (index < count_led) {
|
||||
uint16_t tmp;
|
||||
tmp = index * 3;
|
||||
|
||||
pixel.r = pixels[OFFSET_R(tmp)];
|
||||
pixel.g = pixels[OFFSET_G(tmp)];
|
||||
pixel.b = pixels[OFFSET_B(tmp)];
|
||||
}
|
||||
|
||||
return pixel;
|
||||
}
|
Loading…
Reference in New Issue