2023-05-02 13:46:25 +02:00
|
|
|
//********************************//
|
2023-05-01 15:55:42 +02:00
|
|
|
|
2023-04-24 20:26:49 +02:00
|
|
|
#include <ESP8266WiFi.h>
|
|
|
|
#include <ESP8266mDNS.h>
|
|
|
|
#include <ESP8266HTTPUpdateServer.h>
|
|
|
|
#include <ESP8266WebServer.h>
|
|
|
|
#include <WiFiManager.h>
|
|
|
|
#include <ArduinoJson.h>
|
|
|
|
#include <EEPROM.h>
|
2023-05-02 13:46:25 +02:00
|
|
|
#include <FS.h>
|
2023-04-24 20:26:49 +02:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2023-05-03 11:51:37 +02:00
|
|
|
//********* preprocessor block *********//
|
|
|
|
|
|
|
|
#ifdef DEVELOPMENT
|
2023-05-19 10:21:36 +02:00
|
|
|
#define LIGHT_NAME "Lumini/Lominie Pixie30/P30 light control (DEV)"
|
2023-05-03 11:51:37 +02:00
|
|
|
#else
|
|
|
|
#define LIGHT_NAME LIGHT_NAME_STR
|
|
|
|
#endif
|
|
|
|
|
2023-04-24 20:26:49 +02:00
|
|
|
//********* Config block *********//
|
2023-05-03 11:51:37 +02:00
|
|
|
|
2023-04-29 20:30:42 +02:00
|
|
|
// blue, warmwhite, purple, white&red&green
|
|
|
|
// blau, schwarz, rot, weiß
|
2023-04-29 12:05:13 +02:00
|
|
|
// ch1, ch2, ch3, ch4
|
2023-04-29 20:30:42 +02:00
|
|
|
// D1, D2, D7, D5
|
|
|
|
uint8_t pins[LIGHTS_COUNT] = { 5, 4, 13, 14 };
|
2023-04-24 20:26:49 +02:00
|
|
|
|
2023-05-01 19:39:55 +02:00
|
|
|
#ifndef DEVELOPMENT
|
2023-04-30 19:54:16 +02:00
|
|
|
IPAddress strip_ip (192, 168, 0, 26); // choose an unique IP Adress
|
2023-05-01 19:39:55 +02:00
|
|
|
#endif
|
|
|
|
#ifdef DEVELOPMENT
|
|
|
|
IPAddress strip_ip (192, 168, 0, 27); // choose an unique IP Adress
|
|
|
|
#endif
|
2023-04-30 19:54:16 +02:00
|
|
|
IPAddress gateway_ip (192, 168, 0, 1); // Router IP
|
|
|
|
IPAddress subnet_mask(255, 255, 255, 0);
|
|
|
|
IPAddress dns (192, 168, 0, 1);
|
2023-04-24 20:26:49 +02:00
|
|
|
|
|
|
|
//********************************//
|
|
|
|
|
|
|
|
#define LIGHT_VERSION 2.1
|
|
|
|
|
|
|
|
#define LAST_STATE_STARTUP_LIGHT_LAST_STATE 0
|
2023-04-29 12:05:13 +02:00
|
|
|
#define LAST_STATE_STARTUP_LIGHT_ON_STATE 1
|
|
|
|
#define LAST_STATE_STARTUP_LIGHT_OFF_STATE 2
|
2023-04-24 20:26:49 +02:00
|
|
|
|
2023-04-29 12:05:13 +02:00
|
|
|
#define LIGHT_STATE_ON 1
|
2023-04-24 20:26:49 +02:00
|
|
|
#define LIGHT_STATE_OFF 0
|
|
|
|
|
2023-04-29 12:05:13 +02:00
|
|
|
#define TIMING_CONTROL_ENABLED 1
|
2023-04-24 20:26:49 +02:00
|
|
|
#define TIMING_CONTROL_DISABLED 0
|
|
|
|
|
2023-04-29 12:05:13 +02:00
|
|
|
#define SCENE_RELEAX 0
|
|
|
|
#define SCENE_BRIGHT 1
|
2023-04-24 20:26:49 +02:00
|
|
|
#define SCENE_NIGHTLY 2
|
|
|
|
|
2023-04-25 08:18:36 +02:00
|
|
|
//********************************//
|
|
|
|
|
2023-04-24 20:26:49 +02:00
|
|
|
uint8_t scene;
|
|
|
|
uint8_t tc_enabled;
|
2023-05-11 16:48:59 +02:00
|
|
|
uint8_t tc_enabled_old;
|
|
|
|
|
2023-04-24 20:26:49 +02:00
|
|
|
bool light_state[LIGHTS_COUNT];
|
|
|
|
bool in_transition;
|
|
|
|
|
2023-05-11 19:37:17 +02:00
|
|
|
int default_transitiontime = 4; // 4 = 4 seconds
|
2023-04-29 12:40:14 +02:00
|
|
|
|
2023-05-11 19:37:17 +02:00
|
|
|
uint16_t transitiontime[LIGHTS_COUNT];
|
|
|
|
uint16_t bri[LIGHTS_COUNT];
|
2023-04-28 12:01:50 +02:00
|
|
|
uint16_t current_pwm[LIGHTS_COUNT];
|
2023-04-24 20:26:49 +02:00
|
|
|
|
|
|
|
float step_level[LIGHTS_COUNT];
|
|
|
|
float current_bri[LIGHTS_COUNT];
|
|
|
|
byte mac[6];
|
|
|
|
|
|
|
|
ESP8266WebServer server(80);
|
|
|
|
ESP8266HTTPUpdateServer httpUpdateServer;
|
|
|
|
|
2023-04-25 20:06:04 +02:00
|
|
|
uint32_t last_lightengine_activity = 0;
|
|
|
|
|
2023-04-25 08:18:36 +02:00
|
|
|
//********************************//
|
2023-04-24 20:26:49 +02:00
|
|
|
|
2023-04-28 10:56:26 +02:00
|
|
|
void setup()
|
|
|
|
{
|
2023-04-25 15:35:04 +02:00
|
|
|
EEPROM.begin(256);
|
2023-04-25 08:18:36 +02:00
|
|
|
|
2023-05-02 13:46:25 +02:00
|
|
|
SPIFFS.begin();
|
|
|
|
|
2023-04-25 08:18:36 +02:00
|
|
|
Serial.begin(SERIAL_BAUD_RATE);
|
|
|
|
|
2023-05-02 13:46:25 +02:00
|
|
|
Serial.flush();
|
|
|
|
delay(1000);
|
|
|
|
|
2023-05-03 16:40:39 +02:00
|
|
|
//Serial.println("Flash size: " + (String)ESP.getFlashChipSize());
|
2023-05-03 16:21:45 +02:00
|
|
|
|
2023-05-02 13:46:25 +02:00
|
|
|
Dir dir = SPIFFS.openDir("/");
|
|
|
|
Serial.println("\n\nSPIFFS directory content:");
|
|
|
|
while (dir.next())
|
|
|
|
{
|
|
|
|
String fileName = dir.fileName();
|
|
|
|
size_t fileSize = dir.fileSize();
|
|
|
|
Serial.printf("Datei Name: %s, Größe: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
|
|
|
|
}
|
|
|
|
|
2023-05-19 10:21:36 +02:00
|
|
|
read_eeprom_config();
|
|
|
|
|
2023-04-29 12:05:13 +02:00
|
|
|
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 0)
|
2023-05-19 10:21:36 +02:00
|
|
|
{ // static ip is used
|
2023-04-25 15:35:04 +02:00
|
|
|
WiFi.config(strip_ip, gateway_ip, subnet_mask, dns);
|
2023-04-25 08:18:36 +02:00
|
|
|
}
|
|
|
|
|
2023-04-29 12:05:13 +02:00
|
|
|
for (int j = 0; j < 200; j++)
|
|
|
|
{
|
2023-04-24 20:26:49 +02:00
|
|
|
lightEngine();
|
|
|
|
}
|
|
|
|
|
|
|
|
WiFi.mode(WIFI_STA);
|
|
|
|
WiFiManager wifiManager;
|
|
|
|
wifiManager.setConfigPortalTimeout(120);
|
2023-05-03 11:51:37 +02:00
|
|
|
wifiManager.autoConnect(LIGHT_NAME);
|
2023-04-24 20:26:49 +02:00
|
|
|
|
|
|
|
IPAddress myIP = WiFi.localIP();
|
|
|
|
Serial.print("IP: ");
|
|
|
|
Serial.println(myIP);
|
|
|
|
|
2023-04-30 19:54:16 +02:00
|
|
|
analogWriteFreq(PWM_FREQ);
|
|
|
|
|
2023-04-29 12:05:13 +02:00
|
|
|
if (!light_state[0])
|
|
|
|
{
|
2023-04-24 20:26:49 +02:00
|
|
|
// Show that we are connected
|
|
|
|
analogWrite(pins[0], 100);
|
|
|
|
delay(500);
|
|
|
|
analogWrite(pins[0], 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
WiFi.macAddress(mac);
|
|
|
|
|
|
|
|
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
|
|
|
|
digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
|
|
|
|
|
2023-04-27 16:40:27 +02:00
|
|
|
httpUpdateServer.setup(&server); // start http server
|
2023-04-24 20:26:49 +02:00
|
|
|
|
2023-04-25 08:18:36 +02:00
|
|
|
init_webserver();
|
|
|
|
|
2023-05-02 13:46:25 +02:00
|
|
|
Serial.println("Init timinc control");
|
2023-04-25 08:18:36 +02:00
|
|
|
tc_init();
|
|
|
|
|
2023-05-02 13:46:25 +02:00
|
|
|
Serial.println("Starting webserver");
|
2023-04-25 08:18:36 +02:00
|
|
|
server.begin();
|
2023-04-27 16:40:27 +02:00
|
|
|
} // end of setup
|
2023-04-25 08:18:36 +02:00
|
|
|
|
2023-04-25 14:32:42 +02:00
|
|
|
//********************************//
|
|
|
|
|
2023-04-28 10:56:26 +02:00
|
|
|
void loop()
|
|
|
|
{
|
2023-05-13 23:01:27 +02:00
|
|
|
static uint8_t state = 0;
|
2023-05-11 16:48:59 +02:00
|
|
|
|
2023-05-13 23:01:27 +02:00
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
server.handleClient();
|
|
|
|
state = 1;
|
|
|
|
ESP.wdtFeed();
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
lightEngine();
|
|
|
|
state = 2;
|
|
|
|
ESP.wdtFeed();
|
|
|
|
case 2:
|
|
|
|
tc_update_loop();
|
|
|
|
state = 3;
|
|
|
|
ESP.wdtFeed();
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
test_pwm_main();
|
|
|
|
state = 0;
|
|
|
|
ESP.wdtFeed();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
state = 0;
|
|
|
|
}
|
2023-05-11 16:48:59 +02:00
|
|
|
|
2023-05-13 23:01:27 +02:00
|
|
|
delay(10);
|
2023-04-25 08:18:36 +02:00
|
|
|
}
|
|
|
|
|
2023-04-25 14:32:42 +02:00
|
|
|
//********************************//
|
|
|
|
|
2023-05-12 22:19:31 +02:00
|
|
|
void read_eeprom_config()
|
2023-04-28 12:01:50 +02:00
|
|
|
{
|
2023-04-25 14:32:42 +02:00
|
|
|
|
2023-05-13 23:01:27 +02:00
|
|
|
// -------------------- //
|
2023-05-12 22:19:31 +02:00
|
|
|
uint8_t tmp = EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS);
|
|
|
|
if (tmp == TIMING_CONTROL_DISABLED)
|
2023-05-11 16:48:59 +02:00
|
|
|
{
|
2023-05-11 18:17:08 +02:00
|
|
|
tc_enabled = TIMING_CONTROL_DISABLED;
|
2023-05-11 16:48:59 +02:00
|
|
|
|
2023-05-12 22:19:31 +02:00
|
|
|
} else if (tmp == TIMING_CONTROL_ENABLED)
|
2023-05-02 09:04:21 +02:00
|
|
|
{
|
2023-05-12 22:19:31 +02:00
|
|
|
tc_enabled = TIMING_CONTROL_ENABLED;
|
2023-05-01 19:23:31 +02:00
|
|
|
|
2023-05-02 09:04:21 +02:00
|
|
|
} else {
|
2023-05-12 22:19:31 +02:00
|
|
|
// Write default value
|
|
|
|
EEPROM.write(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS, TIMING_CONTROL_DISABLED);
|
|
|
|
EEPROM.commit();
|
|
|
|
tc_enabled = TIMING_CONTROL_DISABLED;
|
|
|
|
Serial.println("Written default timing control config to EEPROM (disabled)");
|
2023-05-02 09:04:21 +02:00
|
|
|
}
|
2023-05-12 22:19:31 +02:00
|
|
|
Serial.println("Timing Control status: " + (String)tc_enabled);
|
2023-05-01 19:23:31 +02:00
|
|
|
|
2023-05-13 23:01:27 +02:00
|
|
|
// -------------------- //
|
2023-05-12 22:19:31 +02:00
|
|
|
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) > 2)
|
2023-05-02 09:04:21 +02:00
|
|
|
{
|
2023-05-12 22:19:31 +02:00
|
|
|
// set the default value on uninitialized EEPROM
|
|
|
|
EEPROM.write(EEPROM_LAST_STATE_STARTUP_ADDRESS, 0);
|
|
|
|
EEPROM.commit();
|
|
|
|
Serial.println("Written default 'last state' config to EEPROM");
|
2023-05-02 09:04:21 +02:00
|
|
|
}
|
2023-05-12 22:19:31 +02:00
|
|
|
Serial.println("Last state startup setting: " + (String)EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS));
|
2023-05-01 19:23:31 +02:00
|
|
|
|
2023-05-12 22:19:31 +02:00
|
|
|
if (EEPROM.read(EEPROM_SCENE_ADDRESS) > 2)
|
2023-05-02 09:04:21 +02:00
|
|
|
{
|
2023-05-12 22:19:31 +02:00
|
|
|
// set the default value on uninitialized EEPROM
|
|
|
|
EEPROM.write(EEPROM_SCENE_ADDRESS, 0);
|
|
|
|
EEPROM.commit();
|
|
|
|
Serial.println("Written default scene config to EEPROM");
|
2023-05-02 09:04:21 +02:00
|
|
|
}
|
2023-05-12 22:19:31 +02:00
|
|
|
Serial.println("Scene setting: " + (String)EEPROM.read(EEPROM_SCENE_ADDRESS));
|
2023-05-01 19:23:31 +02:00
|
|
|
|
2023-05-13 23:01:27 +02:00
|
|
|
// -------------------- //
|
2023-05-12 22:19:31 +02:00
|
|
|
#ifdef USE_STATIC_IP
|
|
|
|
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) > 1)
|
2023-05-02 09:04:21 +02:00
|
|
|
{
|
2023-05-12 22:19:31 +02:00
|
|
|
EEPROM.write(EEPROM_DYNAMIC_IP_ADDRESS, 0);
|
|
|
|
EEPROM.commit();
|
|
|
|
Serial.println("Written default dynamic IP setting (disabled) to EEPROM");
|
2023-05-02 09:04:21 +02:00
|
|
|
}
|
2023-05-12 22:19:31 +02:00
|
|
|
#else
|
|
|
|
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) > 1)
|
2023-05-02 09:04:21 +02:00
|
|
|
{
|
2023-05-12 22:19:31 +02:00
|
|
|
EEPROM.write(EEPROM_DYNAMIC_IP_ADDRESS, 1);
|
|
|
|
EEPROM.commit();
|
|
|
|
Serial.println("Written default dynamic IP setting (enabled) to EEPROM");
|
2023-05-02 09:04:21 +02:00
|
|
|
}
|
2023-05-12 22:19:31 +02:00
|
|
|
#endif
|
|
|
|
Serial.println("Dynamic IP setting: " + (String)EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS));
|
2023-04-24 20:26:49 +02:00
|
|
|
|
2023-05-13 23:01:27 +02:00
|
|
|
// -------------------- //
|
2023-05-12 22:19:31 +02:00
|
|
|
for (uint8_t light = 0; light < LIGHTS_COUNT; light++)
|
2023-05-02 09:04:21 +02:00
|
|
|
{
|
2023-05-12 22:19:31 +02:00
|
|
|
apply_scene(EEPROM.read(EEPROM_SCENE_ADDRESS), light);
|
|
|
|
step_level[light] = bri[light] / 150.0;
|
2023-05-02 13:46:25 +02:00
|
|
|
|
2023-05-12 22:19:31 +02:00
|
|
|
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) == LAST_STATE_STARTUP_LIGHT_LAST_STATE ||
|
|
|
|
(EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) == LAST_STATE_STARTUP_LIGHT_ON_STATE &&
|
|
|
|
EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == LIGHT_STATE_ON))
|
|
|
|
{
|
|
|
|
light_state[light] = true; // set the light state to on
|
|
|
|
}
|
|
|
|
Serial.println("light[" + (String)light + "] = " + (String)light_state[light]);
|
2023-05-02 13:46:25 +02:00
|
|
|
}
|
|
|
|
|
2023-05-19 10:21:36 +02:00
|
|
|
// read IP, NetMask, GateWay and DNS from EEPROM or store default value
|
|
|
|
// only IPv4 is supported
|
|
|
|
if (EEPROM.read(EEPROM_IP_ADDRESS) == 255)
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
EEPROM.write(EEPROM_IP_ADDRESS + i, strip_ip[i]);
|
|
|
|
EEPROM.write(EEPROM_GW_ADDRESS + i, gateway_ip[i]);
|
|
|
|
EEPROM.write(EEPROM_NM_ADDRESS + i, subnet_mask[i]);
|
|
|
|
EEPROM.write(EEPROM_DNS_ADDRESS + i, dns[i]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 0)
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
strip_ip[i] = EEPROM.read(EEPROM_IP_ADDRESS + i);
|
|
|
|
gateway_ip[i] = EEPROM.read(EEPROM_GW_ADDRESS + i);
|
|
|
|
subnet_mask[i] = EEPROM.read(EEPROM_NM_ADDRESS + i);
|
|
|
|
dns[i] = EEPROM.read(EEPROM_DNS_ADDRESS + i);
|
|
|
|
}
|
|
|
|
Serial.println("IP from EEPROM: " +
|
|
|
|
(String)strip_ip[0] + "." +
|
|
|
|
(String)strip_ip[1] + "." +
|
|
|
|
(String)strip_ip[2] + "." +
|
|
|
|
(String)strip_ip[3]);
|
|
|
|
Serial.println("GW from EEPROM: " +
|
|
|
|
(String)gateway_ip[0] + "." +
|
|
|
|
(String)gateway_ip[1] + "." +
|
|
|
|
(String)gateway_ip[2] + "." +
|
|
|
|
(String)gateway_ip[3]);
|
|
|
|
Serial.println("NetMask from EEPROM: " +
|
|
|
|
(String)subnet_mask[0] + "." +
|
|
|
|
(String)subnet_mask[1] + "." +
|
|
|
|
(String)subnet_mask[2] + "." +
|
|
|
|
(String)subnet_mask[3]);
|
|
|
|
Serial.println("DNS from EEPROM: " +
|
|
|
|
(String)dns[0] + "." +
|
|
|
|
(String)dns[1] + "." +
|
|
|
|
(String)dns[2] + "." +
|
|
|
|
(String)dns[3]);
|
|
|
|
}
|
|
|
|
}
|
2023-05-02 13:46:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//********************************//
|
|
|
|
|
|
|
|
String formatBytes(size_t bytes)
|
|
|
|
{
|
|
|
|
if (bytes < 1024)
|
|
|
|
{
|
|
|
|
return String(bytes) + " B";
|
|
|
|
} else if (bytes < (1024 * 1024))
|
|
|
|
{
|
|
|
|
return String(bytes / 1024.0) + " KB";
|
|
|
|
} else if (bytes < (1024 * 1024 * 1024))
|
|
|
|
{
|
|
|
|
return String(bytes / 1024.0 / 1024.0) + " MB";
|
|
|
|
} else {
|
|
|
|
return String(bytes / 1024.0 / 1024.0 / 1024.0) + " GB";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//********************************//
|