Skip to content

Instantly share code, notes, and snippets.

@PascalKu
Created July 15, 2023 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PascalKu/106db4797f7f1caacf01c11143749590 to your computer and use it in GitHub Desktop.
Save PascalKu/106db4797f7f1caacf01c11143749590 to your computer and use it in GitHub Desktop.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <FastLED.h>
#include <arduino_homekit_server.h>
#define FASTLED_ESP32_SPI_BUS HSPI
#define DATA_PIN 13
#define LED_RGB_SCALE 255 // this is the scaling factor used for color conversion
#define NUM_LEDS 5
CRGB leds[NUM_LEDS];
const char *ssid = "****";
const char *password = "***";
void setup() {
Serial.begin(115200);
Serial.setRxBufferSize(32);
Serial.setDebugOutput(false);
WiFi.mode(WIFI_STA);
WiFi.persistent(false);
WiFi.disconnect(false);
WiFi.setAutoReconnect(true);
WiFi.begin(ssid, password);
printf("\n");
printf("SketchSize: %d B\n", ESP.getSketchSize());
printf("FreeSketchSpace: %d B\n", ESP.getFreeSketchSpace());
printf("FlashChipSize: %d B\n", ESP.getFlashChipSize());
printf("FlashChipRealSize: %d B\n", ESP.getFlashChipRealSize());
printf("FlashChipSpeed: %d\n", ESP.getFlashChipSpeed());
printf("SdkVersion: %s\n", ESP.getSdkVersion());
printf("FullVersion: %s\n", ESP.getFullVersion().c_str());
printf("CpuFreq: %dMHz\n", ESP.getCpuFreqMHz());
printf("FreeHeap: %d B\n", ESP.getFreeHeap());
printf("ResetInfo: %s\n", ESP.getResetInfo().c_str());
printf("ResetReason: %s\n", ESP.getResetReason().c_str());
DEBUG_HEAP();
homekit_setup();
DEBUG_HEAP();
setup_led();
}
void loop() {
homekit_loop();
delay(5);
}
//==============================
// Homekit setup and loop
//==============================
extern "C" homekit_server_config_t config;
extern "C" homekit_characteristic_t name;
extern "C" void led_toggle();
extern "C" void accessory_init();
uint32_t next_heap_millis = 0;
void homekit_setup() {
accessory_init();
uint8_t mac[WL_MAC_ADDR_LENGTH];
WiFi.macAddress(mac);
int name_len = snprintf(NULL, 0, "%s_%02X%02X%02X", name.value.string_value, mac[3], mac[4], mac[5]);
char *name_value = (char*)malloc(name_len + 1);
snprintf(name_value, name_len + 1, "%s_%02X%02X%02X", name.value.string_value, mac[3], mac[4], mac[5]);
name.value = HOMEKIT_STRING_CPP(name_value);
arduino_homekit_setup(&config);
}
void homekit_loop() {
arduino_homekit_loop();
uint32_t time = millis();
if (time > next_heap_millis) {
INFO("heap: %d, sockets: %d", ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
next_heap_millis = time + 5000;
}
loop_led();
}
void setup_led() {
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(100);
}
void loop_led() {
FastLED.show();
}
extern "C" void update_led(bool led_on, byte red, byte green, byte blue) {
if (led_on) {
Serial.println(red);
Serial.println(green);
Serial.println(blue);
printf("r=%d,g=%d,b=%d", green, red, blue);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(120, 75, 120);
}
} else {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
}
}
}
/*
* ledstrip_accessory.c
* Define the accessory in pure C language using the Macro in characteristics.h
*
* Created on: 2023-07-14
* Author: PascallKu (Pascal Kutscha)
*/
#include <Arduino.h>
#include <homekit/types.h>
#include <homekit/homekit.h>
#include <homekit/characteristics.h>
#include <stdio.h>
#include <port.h>
#define LED_RGB_SCALE 255 // this is the scaling factor used for color conversion
// Global variables
float led_hue = 0;
float led_saturation = 59; // saturation is scaled 0 to 100
float led_brightness = 100; // brightness is scaled 0 to 100
bool led_on = true; // on is boolean on or off
static void hsi2rgb(float h, float s, float i, byte* red, byte* green, byte* blue) {
int r, g, b;
while (h < 0) { h += 360.0F; }; // cycle h around to 0-360 degrees
while (h >= 360) { h -= 360.0F; };
h = 3.14159F*h / 180.0F; // convert to radians.
s /= 100.0F; // from percentage to ratio
i /= 100.0F; // from percentage to ratio
s = s > 0 ? (s < 1 ? s : 1) : 0; // clamp s and i to interval [0,1]
i = i > 0 ? (i < 1 ? i : 1) : 0; // clamp s and i to interval [0,1]
i = i * sqrt(i); // shape intensity to have finer granularity near 0
if (h < 2.09439) {
r = LED_RGB_SCALE * i / 3 * (1 + s * cos(h) / cos(1.047196667 - h));
g = LED_RGB_SCALE * i / 3 * (1 + s * (1 - cos(h) / cos(1.047196667 - h)));
b = LED_RGB_SCALE * i / 3 * (1 - s);
}
else if (h < 4.188787) {
h = h - 2.09439;
g = LED_RGB_SCALE * i / 3 * (1 + s * cos(h) / cos(1.047196667 - h));
b = LED_RGB_SCALE * i / 3 * (1 + s * (1 - cos(h) / cos(1.047196667 - h)));
r = LED_RGB_SCALE * i / 3 * (1 - s);
}
else {
h = h - 4.188787;
b = LED_RGB_SCALE * i / 3 * (1 + s * cos(h) / cos(1.047196667 - h));
r = LED_RGB_SCALE * i / 3 * (1 + s * (1 - cos(h) / cos(1.047196667 - h)));
g = LED_RGB_SCALE * i / 3 * (1 - s);
}
*red = (uint8_t) r;
*green = (uint8_t) g;
*blue = (uint8_t) b;
}
void updateLed() {
byte r, g, b;
hsi2rgb(led_hue, led_saturation, led_brightness, r, g, b);
update_led(led_on, r, g, b);
}
homekit_value_t led_on_get() {
return HOMEKIT_BOOL(led_on);
}
void led_on_set(homekit_value_t value) {
if (value.format != homekit_format_bool) {
// printf("Invalid on-value format: %d\n", value.format);
return;
}
led_on = value.bool_value;
updateLed();
}
homekit_value_t led_brightness_get() {
return HOMEKIT_INT(led_brightness);
}
void led_brightness_set(homekit_value_t value) {
if (value.format != homekit_format_int) {
// printf("Invalid brightness-value format: %d\n", value.format);
return;
}
led_brightness = value.int_value;
updateLed();
}
homekit_value_t led_hue_get() {
return HOMEKIT_FLOAT(led_hue);
}
void led_hue_set(homekit_value_t value) {
if (value.format != homekit_format_float) {
// printf("Invalid hue-value format: %d\n", value.format);
return;
}
led_hue = value.float_value;
updateLed();
}
homekit_value_t led_saturation_get() {
return HOMEKIT_FLOAT(led_saturation);
}
void led_saturation_set(homekit_value_t value) {
if (value.format != homekit_format_float) {
// printf("Invalid sat-value format: %d\n", value.format);
return;
}
led_saturation = value.float_value;
updateLed();
}
void led_identify(homekit_value_t _value) {
printf("accessory identify\n");
}
homekit_characteristic_t name = HOMEKIT_CHARACTERISTIC_(NAME, "LED Plant");
homekit_accessory_t *accessories[] = {
HOMEKIT_ACCESSORY(.id = 1, .category = homekit_accessory_category_lightbulb, .services = (homekit_service_t*[]) {
HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics = (homekit_characteristic_t*[]) {
&name,
HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Pascal Kutscha"),
HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "037A2BABF19D"),
HOMEKIT_CHARACTERISTIC(MODEL, "LED Plant"),
HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1"),
HOMEKIT_CHARACTERISTIC(IDENTIFY, led_identify),
NULL
}),
HOMEKIT_SERVICE(LIGHTBULB, .primary = true, .characteristics = (homekit_characteristic_t*[]) {
HOMEKIT_CHARACTERISTIC(NAME, "Ledstrip"),
HOMEKIT_CHARACTERISTIC(
ON, true,
.getter = led_on_get,
.setter = led_on_set
),
HOMEKIT_CHARACTERISTIC(
BRIGHTNESS, 100,
.getter = led_brightness_get,
.setter = led_brightness_set
),
HOMEKIT_CHARACTERISTIC(
HUE, 0,
.getter = led_hue_get,
.setter = led_hue_set
),
HOMEKIT_CHARACTERISTIC(
SATURATION, 0,
.getter = led_saturation_get,
.setter = led_saturation_set
),
NULL
}),
NULL
}),
NULL
};
homekit_server_config_t config = {
.accessories = accessories,
.password = "111-11-111",
.setupId = "ABCD"
};
void accessory_init() {
updateLed();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment