Dzisiaj przyszła do mnie żarówka jak w temacie. Pobawiłem się trochę korzystając z zasobów internetu i efekt poniżej.
Skorzystałem z Arduino IDE i biblioteki SuplaDevice (kod w załączniku).
Nie jest doskonały i wymaga poprawek i optymalizacji ale dla dzisiejszego efektu wystarczy
Code: Select all
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define SUPLADEVICE_CPP
#include <SuplaDevice.h>
WiFiClient client;
// Setup Supla connection
const char* ssid = "XXXX";
const char* password = "XXXX";
unsigned char _red = 0;
unsigned char _green = 0;
unsigned char _blue = 0;
unsigned char _color_brightness = 0;
unsigned char _brightness = 0;
uint8_t light_pdi_pin;
uint8_t light_pdcki_pin;
float light_hue = 0.0;
float light_saturation = 0.0;
typedef struct {
double h;
double s;
double v;
} hsv;
extern "C" {
void os_delay_us(unsigned int);
}
hsv rgb2hsv(int rgb)
{
hsv out;
double min, max, delta;
unsigned char r = (unsigned char)((rgb & 0x00FF0000) >> 16);
unsigned char g = (unsigned char)((rgb & 0x0000FF00) >> 8);
unsigned char b = (unsigned char)(rgb & 0x000000FF);
min = r < g ? r : g;
min = min < b ? min : b;
max = r > g ? r : g;
max = max > b ? max : b;
out.v = max;
delta = max - min;
if (delta < 0.00001)
{
out.s = 0;
out.h = 0;
return out;
}
if( max > 0.0 ) {
out.s = (delta / max);
} else {
out.s = 0.0;
out.h = -1;
return out;
}
if( r >= max )
out.h = ( g - b ) / delta;
else
if( g >= max )
out.h = 2.0 + ( b - r ) / delta;
else
out.h = 4.0 + ( r - g ) / delta;
out.h *= 60.0;
if( out.h < 0.0 )
out.h += 360.0;
return out;
}
int hsv2rgb(hsv in)
{
double hh, p, q, t, ff;
long i;
unsigned char r,g,b;
int rgb = 0;
if(in.s <= 0.0) { // < is bogus, just shuts up warnings
r = in.v;
g = in.v;
b = in.v;
rgb = r & 0xFF; rgb<<=8;
rgb |= g & 0xFF; rgb<<=8;
rgb |= b & 0xFF;
return rgb;
}
hh = in.h;
if(hh >= 360.0) hh = 0.0;
hh /= 60.0;
i = (long)hh;
ff = hh - i;
p = in.v * (1.0 - in.s);
q = in.v * (1.0 - (in.s * ff));
t = in.v * (1.0 - (in.s * (1.0 - ff)));
switch(i) {
case 0:
r = in.v; g = t; b = p;
break;
case 1:
r = q; g = in.v; b = p;
break;
case 2:
r = p; g = in.v; b = t;
break;
case 3:
r = p; g = q; b = in.v;
break;
case 4:
r = t; g = p; b = in.v;
break;
case 5:
default:
r = in.v; g = p; b = q;
break;
}
rgb = r & 0xFF; rgb<<=8;
rgb |= g & 0xFF; rgb<<=8;
rgb |= b & 0xFF;
return rgb;
}
void LightMy92x1Write(uint8_t data)
{
for (uint8_t i = 0; i < 4; i++) { // Send 8bit Data
digitalWrite(light_pdcki_pin, LOW);
digitalWrite(light_pdi_pin, (data & 0x80));
digitalWrite(light_pdcki_pin, HIGH);
data = data << 1;
digitalWrite(light_pdi_pin, (data & 0x80));
digitalWrite(light_pdcki_pin, LOW);
digitalWrite(light_pdi_pin, LOW);
data = data << 1;
}
}
void get_rgbw_value(int channelNumber, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *color_brightness, unsigned char *brightness) {
*brightness = _brightness;
*color_brightness= _color_brightness;
*red = _red;
*green = _green;
*blue = _blue;
}
void set_rgbw() {
hsv _hsv;
int rgb = _red & 0xFF; rgb<<=8;
rgb |= _green & 0xFF; rgb<<=8;
rgb |= _blue & 0xFF;
_hsv = rgb2hsv(rgb);
_hsv.v = 255 * _color_brightness / 100;
rgb = hsv2rgb(_hsv);
unsigned char r = (unsigned char)((rgb & 0x00FF0000) >> 16);
unsigned char g = (unsigned char)((rgb & 0x0000FF00) >> 8);
unsigned char b = (unsigned char)(rgb & 0x000000FF);
uint8_t duty[6] = {(_brightness * 255) / 100, (_brightness * 255) / 100, 0, g, r, b }; // Definition for RGBWC channels
os_delay_us(12); // TStop > 12us.
for (uint8_t channel = 0; channel < 6; channel++) {
LightMy92x1Write(duty[channel]); // Send 8bit Data
}
os_delay_us(12); // TStart > 12us. Ready for send DI pulse.
LightDiPulse(8); // Send 8 DI pulse. After 8 pulse falling edge, store old data.
os_delay_us(12); // TStop > 12us.
}
void set_rgbw_value(int channelNumber, unsigned char red, unsigned char green, unsigned char blue, unsigned char color_brightness, unsigned char brightness) {
_brightness = brightness;
_color_brightness= color_brightness;
_red = red;
_green = green;
_blue = blue;
set_rgbw();
}
void LightDiPulse(uint8_t times)
{
for (uint8_t i = 0; i < times; i++) {
digitalWrite(light_pdi_pin, HIGH);
digitalWrite(light_pdi_pin, LOW);
}
}
void LightDckiPulse(uint8_t times)
{
for (uint8_t i = 0; i < times; i++) {
digitalWrite(light_pdcki_pin, HIGH);
digitalWrite(light_pdcki_pin, LOW);
}
}
void LightMy92x1Init(void)
{
uint8_t chips = 2; // 1 (AiLight)
LightDckiPulse(chips * 32); // Clear all duty register
os_delay_us(12); // TStop > 12us.
// Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12
// pulse's rising edge convert to command mode.
LightDiPulse(12);
os_delay_us(12); // Delay >12us, begin send CMD data
for (uint8_t n = 0; n < chips; n++) { // Send CMD data
LightMy92x1Write(0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM
}
os_delay_us(12); // TStart > 12us. Delay 12 us.
// Send 16 DI pulse, at 14 pulse's falling edge store CMD data, and
// at 16 pulse's falling edge convert to duty mode.
LightDiPulse(16);
os_delay_us(12); // TStop > 12us.
}
void setup() {
Serial.begin(9600);
delay(10);
Serial.write("test");
// Replace the falowing GUID
char GUID[SUPLA_GUID_SIZE] = {0x20,0x09,0xFA,0xF8,0x1D,0x00,0x58,0x3C,0x76,0x2D,0x0B,0x86,0x7D,0x63,0xB0,0xF9};
// with GUID that you can retrieve from https://www.supla.org/arduino/get-guid
// Ethernet MAC address
uint8_t mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
light_pdi_pin = 12;
light_pdcki_pin = 14;
pinMode(light_pdi_pin, OUTPUT);
pinMode(light_pdcki_pin, OUTPUT);
digitalWrite(light_pdi_pin, LOW);
digitalWrite(light_pdcki_pin, LOW);
LightMy92x1Init();
/*
* Having your device already registered at cloud.supla.org,
* you want to change CHANNEL sequence or remove any of them,
* then you must also remove the device itself from cloud.supla.org.
* Otherwise you will get "Channel conflict!" error.
*/
SuplaDevice.setRGBWCallbacks(&get_rgbw_value, &set_rgbw_value);
SuplaDevice.addRgbControllerAndDimmer();
SuplaDevice.begin(GUID, // Global Unique Identifier
mac, // Ethernet MAC address
"srv", // SUPLA server address
0, // Location ID
"XXXX"); // Location Password
}
void loop() {
if (WiFi.status() != WL_CONNECTED) // Jeżeli sieć WiFi nie jest podłączona, wywołaj procedurę łączenia
{
WiFi_up();
}
SuplaDevice.iterate();
}
// Supla.org ethernet layer
int supla_arduino_tcp_read(void *buf, int count) {
_supla_int_t size = client.available();
if ( size > 0 ) {
if ( size > count ) size = count;
return client.read((uint8_t *)buf, size);
};
return -1;
};
int supla_arduino_tcp_write(void *buf, int count) {
return client.write((const uint8_t *)buf, count);
};
bool supla_arduino_svr_connect(const char *server, int port) {
return client.connect(server, 2015);
}
bool supla_arduino_svr_connected(void) {
return client.connected();
}
void supla_arduino_svr_disconnect(void) {
client.stop();
}
void supla_arduino_eth_setup(uint8_t mac[6], IPAddress *ip) {
WiFi_up();
}
SuplaDeviceCallbacks supla_arduino_get_callbacks(void) {
SuplaDeviceCallbacks cb;
cb.tcp_read = &supla_arduino_tcp_read;
cb.tcp_write = &supla_arduino_tcp_write;
cb.eth_setup = &supla_arduino_eth_setup;
cb.svr_connected = &supla_arduino_svr_connected;
cb.svr_connect = &supla_arduino_svr_connect;
cb.svr_disconnect = &supla_arduino_svr_disconnect;
cb.get_temperature = NULL;
cb.get_temperature_and_humidity = NULL;
cb.get_rgbw_value = NULL;
cb.set_rgbw_value = NULL;
return cb;
}
void WiFi_up() // Procedura podłączenia do sieci WiFi
{
Serial.print("Proba podlaczenia do sieci ");
Serial.println(ssid);
WiFi.begin(ssid, password); // Próba podłączenia do sieci
for (int x = 60; x > 0; x--) // Powtarzaj pętlę maksymanie maksymalnie 30 sekund (ponieważ przy każdym elsie jest 0,5 sekundy zwłoki)
{
if (WiFi.status() == WL_CONNECTED) // Jezeli WiFi jest podłączone
{
break; // to zatrzymaj pętlę
}
else // w przeciwnym wypadku
{
Serial.print("."); // wystaw na serial .
delay(500); // i czekaj 0,5 sekundy
}
}
if (WiFi.status() == WL_CONNECTED) // Jeżeli połączenie z siecią zostało nawiązane, wyślij na serial jego parametry
{
Serial.println("");
Serial.println("Polaczenie nawiazane");
Serial.println("Adres IP: ");
Serial.print(WiFi.localIP());
Serial.print(" / ");
Serial.println(WiFi.subnetMask());
Serial.print("Brama: ");
Serial.println(WiFi.gatewayIP());
long rssi = WiFi.RSSI();
Serial.print("Sila sygnalu (RSSI): ");
Serial.print(rssi);
Serial.println(" dBm");
}
else // w przeciwnym wypadku poinformuj przez serial o nieudanej próbie
{
Serial.println("");
Serial.println("Polaczenia nie udalo sie nawiazac");
}
}
https://youtu.be/9-9kH-GmFoI