implemented most of the leds
parent
a1315e1e50
commit
9aa8af017f
|
@ -0,0 +1,131 @@
|
||||||
|
#ifndef _potion_leds_h
|
||||||
|
#define _potion_leds_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "rom/ets_sys.h"
|
||||||
|
#include "shared.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
// pack the struct to match exactly 8 * 4 = 32bits
|
||||||
|
struct __attribute__((__packed__)) led_components_t {
|
||||||
|
uint8_t global; // global baseline brightness, highest 3 bits should always be ones
|
||||||
|
// RGB component values
|
||||||
|
uint8_t red;
|
||||||
|
uint8_t green;
|
||||||
|
uint8_t blue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// union of components and their representation as a u32
|
||||||
|
// allows for easier sending of data over serial
|
||||||
|
union led_t {
|
||||||
|
struct led_components_t components;
|
||||||
|
uint32_t bits;
|
||||||
|
};
|
||||||
|
|
||||||
|
// point on a gradient
|
||||||
|
struct gradient_point_t {
|
||||||
|
union led_t led; // value of the led at this point
|
||||||
|
size_t offset; // offset (measured in leds) from the beginning
|
||||||
|
};
|
||||||
|
|
||||||
|
// buffer that will be written out to the led strip over serial
|
||||||
|
// for leds to work, the
|
||||||
|
uint32_t g_serial_out_buffer[62];
|
||||||
|
// 60-long slice of the out buffer that represents the first few leds
|
||||||
|
union led_t* g_leds = (uint32_t*)(g_serial_out_buffer + 1);
|
||||||
|
|
||||||
|
#define CLOCK 4
|
||||||
|
#define DATA 5
|
||||||
|
|
||||||
|
static
|
||||||
|
void send_leds() {
|
||||||
|
LOGLN("Writing to leds");
|
||||||
|
// index of the bit being written
|
||||||
|
// the first 5 bits represent the bit of the byte represented by the rest of the int
|
||||||
|
int write_bit = 0;
|
||||||
|
int write_next = 0;
|
||||||
|
|
||||||
|
gpio_set_level(CLOCK, 0);
|
||||||
|
|
||||||
|
while(write_bit < sizeof(g_serial_out_buffer) * 8) {
|
||||||
|
// fetch the bit being adressed
|
||||||
|
write_next = 0x1 & (g_serial_out_buffer[write_bit >> 5] >> (write_bit & 0x1F));
|
||||||
|
// set clock out to high, triggering a rising edge
|
||||||
|
gpio_set_level(CLOCK, 1);
|
||||||
|
// write bit to data out
|
||||||
|
gpio_set_level(DATA, write_next);
|
||||||
|
|
||||||
|
os_delay_us(10);
|
||||||
|
// set clock to low, triggering a falling edge
|
||||||
|
gpio_set_level(CLOCK, 0);
|
||||||
|
os_delay_us(10);
|
||||||
|
|
||||||
|
write_bit++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void leds_init() {
|
||||||
|
g_serial_out_buffer[0] = 0;
|
||||||
|
g_serial_out_buffer[61] = 0xFFFFFFFF;
|
||||||
|
for(int i = 0; i < 60; ++i) {
|
||||||
|
g_leds[i].components = (struct led_components_t) {
|
||||||
|
.red = 255,
|
||||||
|
.green = 10,
|
||||||
|
.blue = 255,
|
||||||
|
.global = 0xE0 | 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_config_t config = {
|
||||||
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = 0x18030,
|
||||||
|
.pull_up_en = 0,
|
||||||
|
.pull_down_en = 0,
|
||||||
|
};
|
||||||
|
gpio_config(&config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
uint8_t lerp_uint8(uint8_t a, uint8_t b, float t) {
|
||||||
|
int dir = b - a;
|
||||||
|
return a + t * dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void lerp_led(union led_t* out, const union led_t* from, const union led_t* to, float t) {
|
||||||
|
out->components.red = lerp_uint8(from->components.red, to->components.red, t);
|
||||||
|
out->components.green = lerp_uint8(from->components.green, to->components.green, t);
|
||||||
|
out->components.blue = lerp_uint8(from->components.blue, to->components.blue, t);
|
||||||
|
uint8_t glob_from = from->components.global & 0x1F;
|
||||||
|
uint8_t glob_to = to->components.global & 0x1F;
|
||||||
|
out->components.global = 0xE0 | lerp_uint8(glob_from, glob_to, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void lerp_points_between(const struct gradient_point_t from, const struct gradient_point_t to) {
|
||||||
|
const int dif = to.offset - from.offset;
|
||||||
|
float t = 0.f;
|
||||||
|
for(int led = from.offset; led < to.offset; ++led) {
|
||||||
|
t = (float)(led - from.offset) / (float)dif;
|
||||||
|
lerp_led(g_leds + led, &from.led, &to.led, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void leds_set_gradient(struct gradient_point_t* points, size_t points_len) {
|
||||||
|
struct gradient_point_t from = points[0];
|
||||||
|
struct gradient_point_t to;
|
||||||
|
for(int i = 1; i < points_len; ++i) {
|
||||||
|
to = points[i];
|
||||||
|
lerp_points_between(from, to);
|
||||||
|
from = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_leds();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !_leds_h
|
|
@ -33,7 +33,6 @@ void wifi_init() {
|
||||||
LOGLN("Configuring WIFI");
|
LOGLN("Configuring WIFI");
|
||||||
// init tcp/ip stack
|
// init tcp/ip stack
|
||||||
tcpip_adapter_init();
|
tcpip_adapter_init();
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
||||||
// initialize wifi
|
// initialize wifi
|
||||||
wifi_init_config_t wifi_startup = WIFI_INIT_CONFIG_DEFAULT();
|
wifi_init_config_t wifi_startup = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
ESP_ERROR_CHECK(esp_wifi_init(&wifi_startup));
|
ESP_ERROR_CHECK(esp_wifi_init(&wifi_startup));
|
||||||
|
|
|
@ -1,18 +1,31 @@
|
||||||
|
#include "leds.h"
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
#include "server.h"
|
||||||
#include "rom/ets_sys.h"
|
#include "rom/ets_sys.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <esp_http_server.h>
|
static
|
||||||
|
void init_esp(void) {
|
||||||
void app_main() {
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
LOGLN("starting {");
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
}
|
||||||
wifi_init();
|
|
||||||
softap_init();
|
void app_main(void) {
|
||||||
|
LOGLN("---- starting");
|
||||||
LOGLN("}");
|
|
||||||
|
init_esp();
|
||||||
|
leds_init();
|
||||||
|
send_leds();
|
||||||
|
wifi_init();
|
||||||
|
softap_init();
|
||||||
|
server_init();
|
||||||
|
|
||||||
|
os_delay_us(10000);
|
||||||
|
send_leds();
|
||||||
|
|
||||||
|
LOGLN("---- finished setting up");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
115
main/server.h
115
main/server.h
|
@ -1,7 +1,114 @@
|
||||||
#ifndef _server_h
|
#ifndef _potion_party_server_h
|
||||||
#define _server_h
|
#define _potion_party_server_h
|
||||||
|
|
||||||
void server_init() {
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "shared.h"
|
||||||
|
#include "leds.h"
|
||||||
|
#include "esp_http_server.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_netif.h"
|
||||||
|
|
||||||
|
static
|
||||||
|
httpd_handle_t g_http_server = NULL;
|
||||||
|
|
||||||
|
static
|
||||||
|
void parse_leds_query(char* query_string, size_t query_size) {
|
||||||
|
char query_value[16];
|
||||||
|
char query_key[3];
|
||||||
|
size_t gradient_point_count = 0;
|
||||||
|
|
||||||
|
if(httpd_query_key_value(query_string, "l", query_value, sizeof(query_value)) == ESP_OK) {
|
||||||
|
gradient_point_count = atoi(query_value);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !_server_h
|
struct gradient_point_t* points = malloc(gradient_point_count * sizeof(union led_t));
|
||||||
|
|
||||||
|
for(int point = 0; point < gradient_point_count; ++point) {
|
||||||
|
sprintf(query_key, "r%d", point);
|
||||||
|
if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_size)) == ESP_OK) {
|
||||||
|
points[point].led.components.red = atoi(query_value);
|
||||||
|
}
|
||||||
|
sprintf(query_key, "g%d", point);
|
||||||
|
if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_size)) == ESP_OK) {
|
||||||
|
points[point].led.components.green = atoi(query_value);
|
||||||
|
}
|
||||||
|
sprintf(query_key, "b%d", point);
|
||||||
|
if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_value)) == ESP_OK) {
|
||||||
|
points[point].led.components.blue = atoi(query_value);
|
||||||
|
}
|
||||||
|
sprintf(query_key, "a%d", point);
|
||||||
|
if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_value)) == ESP_OK) {
|
||||||
|
points[point].led.components.global = atoi(query_value) | 0xE0;
|
||||||
|
}
|
||||||
|
sprintf(query_key, "t%d", point);
|
||||||
|
if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_value)) == ESP_OK) {
|
||||||
|
points[point].offset = atoi(query_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGLN("led %d:", point);
|
||||||
|
LOGLN(" r %d", points[point].led.components.red);
|
||||||
|
LOGLN(" g %d", points[point].led.components.green);
|
||||||
|
LOGLN(" b %d", points[point].led.components.blue);
|
||||||
|
LOGLN(" global %d", points[point].led.components.global);
|
||||||
|
LOGLN(" t %d", (int)points[point].offset);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
leds_set_gradient(points, gradient_point_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
esp_err_t on_http_post(httpd_req_t* request) {
|
||||||
|
LOGLN("POST received on '/'.");
|
||||||
|
|
||||||
|
char* buffer;
|
||||||
|
size_t buffer_len;
|
||||||
|
|
||||||
|
buffer_len = httpd_req_get_url_query_len(request) + 1;
|
||||||
|
|
||||||
|
if(buffer_len > 1) {
|
||||||
|
buffer = malloc(buffer_len * sizeof(char));
|
||||||
|
if(httpd_req_get_url_query_str(request, buffer, buffer_len) == ESP_OK) {
|
||||||
|
LOGLN("Received query.");
|
||||||
|
parse_leds_query(buffer, buffer_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* response = "OK!";
|
||||||
|
httpd_resp_send(request, response, strlen(response));
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
httpd_uri_t post = {
|
||||||
|
.uri="/",
|
||||||
|
.method=HTTP_POST,
|
||||||
|
.handler=&on_http_post,
|
||||||
|
.user_ctx = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
httpd_handle_t start_webserver(void) {
|
||||||
|
httpd_handle_t server = NULL;
|
||||||
|
httpd_config_t server_config = HTTPD_DEFAULT_CONFIG();
|
||||||
|
|
||||||
|
LOGLN("Starting HTTPd server ':%d'.", server_config.server_port);
|
||||||
|
if(httpd_start(&server, &server_config) == ESP_OK) {
|
||||||
|
httpd_register_uri_handler(server, &post);
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGLN("Failed to start HTTPd server.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void server_init(void) {
|
||||||
|
g_http_server = start_webserver();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !_potion_party_server_h
|
||||||
|
|
Loading…
Reference in New Issue