8000 2016-11-27 · Smeedy/esp32-snippets@ac57831 · GitHub
[go: up one dir, main page]

Skip to content

Commit ac57831

Browse files
author
kolban
committed
2016-11-27
1 parent ecc89d9 commit ac57831

File tree

3 files changed

+172
-0
lines changed

3 files changed

+172
-0
lines changed

hardware/neopixels/WS2812.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* WS2812.cpp
3+
*
4+
* Created on: Nov 27, 2016
5+
* Author: kolban
6+
*/
7+
8+
#include "WS2812.h"
9+
#include <esp_log.h>
10+
#include <driver/gpio.h>
11+
#include <stdint.h>
12+
#include <driver/rmt.h>
13+
#include "sdkconfig.h"
14+
15+
static char tag[] = "WS2812";
16+
17+
/**
18+
* A NeoPixel is defined by 3 bytes ... red, green and blue.
19+
* Each byte is composed of 8 bits ... therefore a NeoPixel is 24 bits of data.
20+
* At the underlying level, 1 bit of NeoPixel data is one item (two levels)
21+
* This means that the number of items we need is:
22+
*
23+
* #pixels * 24
24+
*
25+
*/
26+
27+
static void setItem1(rmt_item32_t *pItem) {
28+
pItem->level0 = 1;
29+
pItem->duration0 = 7;
30+
pItem->level1 = 0;
31+
pItem->duration1 = 6;
32+
} // setItem1
33+
34+
35+
static void setItem0(rmt_item32_t *pItem) {
36+
pItem->level0 = 1;
37+
pItem->duration0 = 4;
38+
pItem->level1 = 0;
39+
pItem->duration1 = 8;
40+
} // setItem0
41+
42+
43+
WS2812::WS2812(rmt_channel_t channel, gpio_num_t gpioNum, uint16_t pixelCount) {
44+
this->pixelCount = pixelCount;
45+
this->channel = channel;
46+
this->items = (rmt_item32_t *)malloc(sizeof(rmt_item32_t) * (pixelCount * 24));
47+
this->pixels = (pixel_t *)malloc(sizeof(pixel_t) * pixelCount);
48+
49+
rmt_config_t config;
50+
config.rmt_mode = RMT_MODE_TX;
51+
config.channel = channel;
52+
config.gpio_num = gpioNum;
53+
config.mem_block_num = 1;
54+
config.tx_config.loop_en = 0;
55+
config.tx_config.carrier_en = 0;
56+
config.tx_config.idle_output_en = 1;
57+
config.tx_config.idle_level = (rmt_idle_level_t)0;
58+
config.tx_config.carrier_duty_percent = 50;
59+
config.tx_config.carrier_freq_hz = 10000;
60+
config.tx_config.carrier_level = (rmt_carrier_level_t)1;
61+
config.clk_div = 8;
62+
63+
ESP_ERROR_CHECK(rmt_config(&config));
64+
ESP_ERROR_CHECK(rmt_driver_install(this->channel, 0, 19));
65+
} // WS2812
66+
67+
68+
void WS2812::show() {
69+
uint32_t i,j;
70+
rmt_item32_t *pCurrentItem = this->items;
71+
for (i=0; i<this->pixelCount; i++) {
72+
uint32_t currentPixel = this->pixels[i].red | (this->pixels[i].green << 8) | (this->pixels[i].blue << 16);
73+
for (j=0; j<24; j++) {
74+
if (currentPixel & 1<<j) {
75+
setItem1(pCurrentItem);
76+
} else {
77+
setItem0(pCurrentItem);
78+
}
79+
pCurrentItem++;
80+
}
81+
}
82+
// Show the pixels.
83+
rmt_write_items(this->channel, this->items, this->pixelCount*24,
84+
1 /* wait till done */);
85+
} // show
86+
87+
88+
void WS2812::setPixel(uint16_t index, uint8_t red, uint8_t green,
89+
uint8_t blue) {
90+
if (index >= this->pixelCount) {
91+
ESP_LOGE(tag, "setPixel: index out of range: %d", index);
92+
return;
93+
}
94+
this->pixels[index].red = red;
95+
this->pixels[index].green = green;
96+
this->pixels[index].blue = blue;
97+
} // setPixel
98+
99+
100+
void WS2812::setPixel(uint16_t index, pixel_t pixel) {
101+
if (index >= this->pixelCount) {
102+
ESP_LOGE(tag, "setPixel: index out of range: %d", index);
103+
return;
104+
}
105+
this->pixels[index] = pixel;
106+
} // setPixel
107+
108+
void WS2812::setPixel(uint16_t index, uint32_t pixel) {
109+
if (index >= this->pixelCount) {
110+
ESP_LOGE(tag, "setPixel: index out of range: %d", index);
111+
return;
112+
}
113+
this->pixels[index].red = pixel & 0xff;
114+
this->pixels[index].green = (pixel & 0xff00) >> 8;
115+
this->pixels[index].blue = (pixel & 0xff0000) >> 16;
116+
} // setPixel
117+
118+
void WS2812::clear() {
119+
uint16_t i;
120+
for (i=0; i<this->pixelCount; i++) {
121+
this->pixels[i].red = 0;
122+
this->pixels[i].green = 0;
123+
this->pixels[i].blue = 0;
124+
}
125+
} // clear
126+
127+
WS2812::~WS2812() {
128+
free(this->items);
129+
free(this->pixels);
130+
} // ~WS2812()

hardware/neopixels/WS2812.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* WS2812.h
3+
*
4+
* Created on: Nov 27, 2016
5+
* Author: kolban
6+
*/
7+
8+
#ifndef MAIN_WS2812_H_
9+
#define MAIN_WS2812_H_
10+
#include <stdint.h>
11+
#include <driver/rmt.h>
12+
typedef struct {
13+
uint8_t red;
14+
uint8_t green;
15+
uint8_t blue;
16+
} pixel_t;
17+
18+
class WS2812 {
19+
public:
20+
WS2812(rmt_channel_t channel, gpio_num_t gpioNum, uint16_t pixelCount);
21+
void show();
22+
void setPixel(uint16_t index, uint8_t red, uint8_t green, uint8_t blue);
23+
void setPixel(uint16_t index, pixel_t pixel);
24+
void setPixel(uint16_t index, uint32_t pixel);
25+
void clear();
26+
virtual ~WS2812();
27+
private:
28+
uint16_t pixelCount;
29+
rmt_channel_t channel;
30+
rmt_item32_t *items;
31+
pixel_t *pixels;
32+
};
33+
34+
#endif /* MAIN_WS2812_H_ */

hardware/neopixels/component.mk

6ADD Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#
2+
# Main component makefile.
3+
#
4+
# This Makefile can be left empty. By default, it will take the sources in the
5+
# src/ directory, compile them and link them into lib(subdirectory_name).a
6+
# in the build directory. This behaviour is entirely configurable,
7+
# please read the ESP-IDF documents if you need to do this.
8+
#

0 commit comments

Comments
 (0)
0