First almost completely working timing controller.
This commit is contained in:
parent
7a96c055d7
commit
211b06ed62
3 changed files with 193 additions and 71 deletions
|
@ -14,8 +14,10 @@
|
|||
#define EEPROM_LAST_STATE_ADDRESS 4 // the first "last state" information for the first light
|
||||
#define EEPROM_TIMING_DATA_ADDRESS (EEPROM_LAST_STATE_ADDRESS + LIGHTS_COUNT) // Stored data date per light ELE_USED; HH; MM; CH1; CH2; CH3; CH4;
|
||||
|
||||
#define BRI_MOD_STEPS_PER_SEC 5.0
|
||||
|
||||
#define TIME_CHECK_INTERVAL_MS (60000UL) // 60 second interval
|
||||
#define TIME_LIGHTENGINE_INTERVAL_MS (100UL)
|
||||
#define TIME_LIGHTENGINE_INTERVAL_MS (1000UL / BRI_MOD_STEPS_PER_SEC) // BRI_MOD_STEPS_PER_SEC steps per second to in-/decrease the brightness
|
||||
|
||||
#define MY_NTP_SERVER "de.pool.ntp.org"
|
||||
|
||||
|
|
|
@ -82,14 +82,14 @@ void apply_scene(uint8_t new_scene, uint8_t light)
|
|||
|
||||
//********************************//
|
||||
|
||||
void process_lightdata(uint8_t light, float transitiontime)
|
||||
void process_lightdata(uint8_t light, float tt)
|
||||
{
|
||||
transitiontime *= 16;
|
||||
if (light_state[light])
|
||||
{
|
||||
step_level[light] = (bri[light] - current_bri[light]) / transitiontime;
|
||||
step_level[light] = (bri[light] - current_bri[light]) / tt;
|
||||
|
||||
} else {
|
||||
step_level[light] = current_bri[light] / transitiontime;
|
||||
step_level[light] = current_bri[light] / tt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,20 +108,22 @@ void lightEngine()
|
|||
|
||||
for (int i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
|
||||
if (light_state[i])
|
||||
{
|
||||
if (bri[i] != current_bri[i])
|
||||
{
|
||||
in_transition = true;
|
||||
current_bri[i] += step_level[i] / 10.0;
|
||||
current_bri[i] += step_level[i] / BRI_MOD_STEPS_PER_SEC;
|
||||
if ((step_level[i] > 0.0 && current_bri[i] > bri[i]) ||
|
||||
(step_level[i] < 0.0 && current_bri[i] < bri[i]))
|
||||
{
|
||||
current_bri[i] = bri[i];
|
||||
//Serial.println("Reached target bri[" + (String)i + "] = " + (String)bri[i]);
|
||||
}
|
||||
|
||||
uint16_t tmp_pwm = calcPWM(current_bri[i]);
|
||||
//Serial.println("pin" + (String)i + " = PWM(" + (String)tmp_pwm + ")");
|
||||
//Serial.println("lon: pin" + (String)i + " = PWM(" + (String)tmp_pwm + ")");
|
||||
analogWrite(pins[i], tmp_pwm);
|
||||
}
|
||||
} else {
|
||||
|
@ -129,18 +131,20 @@ void lightEngine()
|
|||
if (current_bri[i] != 0)
|
||||
{
|
||||
in_transition = true;
|
||||
current_bri[i] -= step_level[i] / 10.0;
|
||||
current_bri[i] -= step_level[i] / BRI_MOD_STEPS_PER_SEC;
|
||||
if (current_bri[i] < 0)
|
||||
{
|
||||
current_bri[i] = 0;
|
||||
//Serial.println("Reached target bri[" + (String)i + "] = " + (String)bri[i]);
|
||||
}
|
||||
|
||||
uint16_t tmp_pwm = calcPWM(current_bri[i]);
|
||||
//Serial.println("pin" + (String)i + " = PWM(" + (String)tmp_pwm + ")");
|
||||
//Serial.println("loff: pin" + (String)i + " = PWM(" + (String)tmp_pwm + ")");
|
||||
analogWrite(pins[i], tmp_pwm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // for loop end
|
||||
|
||||
if (in_transition)
|
||||
{
|
||||
|
@ -281,7 +285,7 @@ void loop()
|
|||
|
||||
if (tc_enabled == TIMING_CONTROL_ENABLED)
|
||||
{
|
||||
tc_update();
|
||||
tc_update_loop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,14 +549,13 @@ void init_webserver()
|
|||
}
|
||||
|
||||
// set the light step level
|
||||
if (light_state[light])
|
||||
if (server.hasArg("transition") && light_state[light])
|
||||
{
|
||||
Serial.println("Webinterface transitiontime = " + (String)transitiontime);
|
||||
transitiontime = server.arg("transition").toFloat();
|
||||
step_level[light] = ((float)bri[light] - current_bri[light]) / transitiontime;
|
||||
|
||||
} else {
|
||||
step_level[light] = current_bri[light] / transitiontime;
|
||||
}
|
||||
}
|
||||
} // process all lights
|
||||
|
||||
#endif // DISABLE_WEB_CONTROL
|
||||
|
||||
|
|
|
@ -6,33 +6,30 @@
|
|||
|
||||
//***********************************//
|
||||
|
||||
// 7 byte
|
||||
#define TIMER_DATA_ENSTATE 0
|
||||
#define TIMER_DATA_HH 1
|
||||
#define TIMER_DATA_MM 2
|
||||
#define TIMER_DATA_CH1 3 // the brightness of the channel
|
||||
#define TIMER_DATA_CH2 4 // the brightness of the channel
|
||||
#define TIMER_DATA_CH3 5 // the brightness of the channel
|
||||
#define TIMER_DATA_CH4 6 // the brightness of the channel
|
||||
// 6 byte
|
||||
#define TIMER_DATA_HH 0
|
||||
#define TIMER_DATA_MM 1
|
||||
#define TIMER_DATA_CH1 2 // the brightness of the channel
|
||||
#define TIMER_DATA_CH2 3 // the brightness of the channel
|
||||
#define TIMER_DATA_CH3 4 // the brightness of the channel
|
||||
#define TIMER_DATA_CH4 5 // the brightness of the channel
|
||||
|
||||
#define LENGTH_OF_TIMER_DATA_BLOCK (TIMER_DATA_CH4 + 1)
|
||||
#define NUMBER_OF_TIMER_DATA_BLOCKS 10
|
||||
|
||||
#define ENSTATE_ENABLED 1
|
||||
#define ENSTATE_DISABLED 0
|
||||
|
||||
//***********************************//
|
||||
/* Globals */
|
||||
|
||||
bool tc_testOngoing = true;
|
||||
|
||||
uint32_t tc_last_check = 60000;
|
||||
|
||||
const long utcOffsetInSeconds = 3600;
|
||||
long utcOffsetInSeconds = 3600;
|
||||
|
||||
WiFiUDP ntpUDP;
|
||||
NTPClient timeClient(ntpUDP, MY_NTP_SERVER, utcOffsetInSeconds);
|
||||
|
||||
struct tc_data_st {
|
||||
uint8_t enstate;
|
||||
uint8_t hh;
|
||||
uint8_t mm;
|
||||
uint8_t ch1;
|
||||
|
@ -44,17 +41,31 @@ struct tc_data_st {
|
|||
struct tc_data_st tc_data[10];
|
||||
|
||||
uint8_t example_timer_data_block[] = {
|
||||
// hour min ch1 ch2 ch3 ch3
|
||||
8, 0, 0, 0, 0, 0, // 0: off
|
||||
8, 30, 25, 0, 0, 0, // 1: 10% ch1 blues
|
||||
9, 0, 25, 0, 25, 0, // 2: 10% all blues
|
||||
13, 0, 205, 205, 205, 205, // 3: 80% all
|
||||
18, 0, 205, 205, 205, 205, // 4: 80% all for 5 hours
|
||||
19, 0, 50, 50, 50, 50, // 5: 20% all
|
||||
19, 30, 50, 0, 50, 0, // 6: 20% all blues
|
||||
20, 30, 25, 0, 0, 0, // 7: 10% ch1 blues
|
||||
21, 0, 0, 0, 0, 0, // 8: 0% all
|
||||
20, 0, 0, 0, 0, 0, // 9: disabled
|
||||
};
|
||||
|
||||
uint8_t test_timer_data_block[] = {
|
||||
// state hour min ch1 ch2 ch3 ch3
|
||||
ENSTATE_ENABLED, 8, 0, 0, 0, 0, 0, // off
|
||||
ENSTATE_ENABLED, 8, 30, 25, 0, 0, 0, // 10% ch1 blues
|
||||
ENSTATE_ENABLED, 9, 0, 25, 0, 25, 0, // 10% all blues
|
||||
ENSTATE_ENABLED, 13, 0, 205, 205, 205, 205, // 80% all
|
||||
ENSTATE_ENABLED, 18, 0, 50, 50, 50, 50, // 20% blue
|
||||
ENSTATE_ENABLED, 20, 0, 50, 0, 50, 0, // 20% all blues
|
||||
ENSTATE_ENABLED, 20, 0, 25, 0, 0, 0, // 10% ch1 blues
|
||||
ENSTATE_ENABLED, 21, 0, 0, 0, 0, 0, // 0% all
|
||||
ENSTATE_DISABLED, 20, 0, 0, 0, 0, 0, // disabled
|
||||
ENSTATE_DISABLED, 20, 0, 0, 0, 0, 0, // disabled
|
||||
9, 20, 0, 0, 0, 0, // 0: off
|
||||
9, 30, 25, 0, 0, 0, // 1: 10% ch1 blues
|
||||
9, 40, 25, 0, 25, 0, // 2: 10% all blues
|
||||
9, 50, 205, 205, 205, 205, // 3: 80% all
|
||||
10, 0, 100, 100, 100, 100, // 4: 80% all for 5 hours
|
||||
10, 10, 50, 50, 50, 50, // 5: 20% all
|
||||
10, 20, 50, 0, 50, 0, // 6: 20% all blues
|
||||
10, 30, 25, 0, 0, 0, // 7: 10% ch1 blues
|
||||
10, 40, 0, 0, 0, 0, // 8: all off
|
||||
11, 0, 0, 0, 0, 0, // 9: all off
|
||||
};
|
||||
|
||||
//***********************************//
|
||||
|
@ -81,83 +92,176 @@ void tc_init()
|
|||
Serial.println("TC: Read data block from eeprom");
|
||||
tc_readConfig();
|
||||
|
||||
if (tc_testOngoing == true)
|
||||
{
|
||||
Serial.println("TC: Test ongoing, reading test data");
|
||||
for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS * LENGTH_OF_TIMER_DATA_BLOCK; i += LENGTH_OF_TIMER_DATA_BLOCK)
|
||||
{
|
||||
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].hh = test_timer_data_block[i];
|
||||
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].mm = test_timer_data_block[i+1];
|
||||
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch1 = test_timer_data_block[i+2];
|
||||
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch2 = test_timer_data_block[i+3];
|
||||
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch3 = test_timer_data_block[i+4];
|
||||
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch4 = test_timer_data_block[i+5];
|
||||
|
||||
Serial.print("data block: "); Serial.println(i / LENGTH_OF_TIMER_DATA_BLOCK);
|
||||
Serial.print(" hh: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].hh);
|
||||
Serial.print(" mm: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].mm);
|
||||
Serial.print(" ch1: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch1);
|
||||
Serial.print(" ch2: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch2);
|
||||
Serial.print(" ch3: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch3);
|
||||
Serial.print(" ch4: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch4);
|
||||
}
|
||||
}
|
||||
|
||||
tc_update_main();
|
||||
|
||||
}
|
||||
|
||||
//********************************//
|
||||
|
||||
void tc_update()
|
||||
void tc_update_loop()
|
||||
{
|
||||
static uint8_t last_min_check = 255;
|
||||
|
||||
if ((timeClient.getMinutes() % 10) != 0 || last_min_check == timeClient.getMinutes()) // && tc_testOngoing == false
|
||||
{
|
||||
last_min_check = timeClient.getMinutes();
|
||||
return; // only run every 10 minutes
|
||||
}
|
||||
|
||||
tc_update_main();
|
||||
}
|
||||
|
||||
void tc_update_main()
|
||||
{
|
||||
static uint8_t current_target_data_block = 255;
|
||||
uint8_t target_data_block = 255;
|
||||
|
||||
tc_updateTime();
|
||||
|
||||
if ((timeClient.getMinutes() % 10) != 0)
|
||||
// search for the current active time slot
|
||||
for (int i = NUMBER_OF_TIMER_DATA_BLOCKS-1; i >= 0 && target_data_block == 255; i--)
|
||||
{
|
||||
return; // only run every 10 minutes
|
||||
}
|
||||
//Serial.println((String)tc_data[i].hh + ":" + (String)tc_data[i].mm);
|
||||
|
||||
// 2. find current active time slot
|
||||
for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS-1; i++)
|
||||
if (tc_data[i].hh <= timeClient.getHours() &&
|
||||
tc_data[i].mm <= timeClient.getMinutes())
|
||||
{
|
||||
if (tc_data[i].hh == timeClient.getHours() &&
|
||||
tc_data[i].mm == timeClient.getMinutes() &&
|
||||
tc_data[i].enstate == ENSTATE_ENABLED)
|
||||
{
|
||||
// we have a new time data slot reached
|
||||
for (uint8_t j = i+1; j < NUMBER_OF_TIMER_DATA_BLOCKS; j++)
|
||||
{ // search for the next enabled successor
|
||||
if (tc_data[j].enstate == ENSTATE_ENABLED)
|
||||
{
|
||||
target_data_block = j; // get the next block to activate
|
||||
}
|
||||
}
|
||||
target_data_block = i+1; // found the next block to load
|
||||
}
|
||||
//Serial.println((String)i + " => " + target_data_block);
|
||||
}
|
||||
|
||||
if (target_data_block == 255)
|
||||
{
|
||||
// no new successor found
|
||||
// no new predecessor or successor found, start over
|
||||
current_target_data_block = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. set the channels brightness
|
||||
if (current_target_data_block != target_data_block)
|
||||
{
|
||||
// new target block should be reached
|
||||
current_target_data_block = target_data_block;
|
||||
|
||||
} else {
|
||||
// drop the found target block, we are already going on to reach it
|
||||
return;
|
||||
}
|
||||
|
||||
if (target_data_block >= NUMBER_OF_TIMER_DATA_BLOCKS)
|
||||
{
|
||||
target_data_block = 255;
|
||||
current_target_data_block = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
// print out the current light state
|
||||
Serial.println("-----\nCurrent values");
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
Serial.println("current_bri[" + (String)i + "] = " + (String)current_bri[i]);
|
||||
}
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
Serial.println("bri[" + (String)i + "] = " + (String)bri[i]);
|
||||
}
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
Serial.println("step_level[" + (String)i + "] = " + (String)step_level[i]);
|
||||
}
|
||||
|
||||
Serial.println("-----\ntdb = " + (String)target_data_block);
|
||||
Serial.print("target time: "); Serial.print(tc_data[target_data_block].hh); Serial.print(":"); Serial.print(tc_data[target_data_block].mm); Serial.println();
|
||||
|
||||
// set the channels current and target brightness
|
||||
bri[0] = tc_data[target_data_block].ch1;
|
||||
bri[1] = tc_data[target_data_block].ch2;
|
||||
bri[2] = tc_data[target_data_block].ch3;
|
||||
bri[3] = tc_data[target_data_block].ch4;
|
||||
if (tc_data[target_data_block-1].ch1 != current_bri[0])
|
||||
{
|
||||
current_bri[0] = tc_data[target_data_block-1].ch1;
|
||||
}
|
||||
if (tc_data[target_data_block-1].ch2 != current_bri[1])
|
||||
{
|
||||
current_bri[1] = tc_data[target_data_block-1].ch2;
|
||||
}
|
||||
if (tc_data[target_data_block-1].ch3 != current_bri[2])
|
||||
{
|
||||
current_bri[2] = tc_data[target_data_block-1].ch3;
|
||||
}
|
||||
if (tc_data[target_data_block-1].ch4 != current_bri[3])
|
||||
{
|
||||
current_bri[3] = tc_data[target_data_block-1].ch4;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
Serial.println("current_bri[" + (String)i + "] = " + (String)current_bri[i]);
|
||||
}
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
Serial.println("bri[" + (String)i + "] = " + (String)bri[i]);
|
||||
}
|
||||
|
||||
// 4. enable/disable the lights
|
||||
light_state[0] = tc_data[target_data_block].ch1 > 0 ? true : false;
|
||||
light_state[1] = tc_data[target_data_block].ch2 > 0 ? true : false;
|
||||
light_state[2] = tc_data[target_data_block].ch3 > 0 ? true : false;
|
||||
light_state[3] = tc_data[target_data_block].ch4 > 0 ? true : false;
|
||||
// enable the lights
|
||||
light_state[0] = true;
|
||||
light_state[1] = true;
|
||||
light_state[2] = true;
|
||||
light_state[3] = true;
|
||||
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
Serial.println("light_state[" + (String)i + "] = " + (String)light_state[i]);
|
||||
}
|
||||
|
||||
// 5. set the transition time
|
||||
// set the transition time
|
||||
int t_time = 0;
|
||||
if (target_data_block > 0)
|
||||
{
|
||||
t_time = ((uint16_t)tc_data[target_data_block].hh * 60 * 30) - ((uint16_t)tc_data[target_data_block-1].hh * 60 * 30); // hours as seconds from now on to the next enabled block
|
||||
t_time += ((uint16_t)tc_data[target_data_block].mm * 60) - ((uint16_t)tc_data[target_data_block-1].mm * 60); // add the left over seconds to the next enabled block
|
||||
// hours as seconds from now on to the next enabled block
|
||||
t_time = ((uint16_t)tc_data[target_data_block].hh * 60 * 60) - ((uint16_t)timeClient.getHours() * 60 * 60);
|
||||
// add the left over seconds to the next enabled block
|
||||
t_time += ((uint16_t)tc_data[target_data_block].mm * 60) - ((uint16_t)timeClient.getMinutes() * 60);
|
||||
|
||||
}
|
||||
transitiontime[0] = t_time;
|
||||
transitiontime[1] = t_time;
|
||||
transitiontime[2] = t_time;
|
||||
transitiontime[3] = t_time;
|
||||
|
||||
// calculate the step level
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
process_lightdata(i, transitiontime[i]);
|
||||
Serial.println("transitiontime[" + (String)i + "] = " + (String)transitiontime[i]);
|
||||
}
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
Serial.println("step_level[" + (String)i + "] = " + (String)step_level[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -172,7 +276,21 @@ void tc_updateTime()
|
|||
//Serial.println("TC: Read time from server...");
|
||||
//Serial.println(timeClient.getFormattedTime());
|
||||
|
||||
Serial.print("Local time: ");
|
||||
/*
|
||||
if (dow == 7 && mo == 10 && d >= 25 && h == 3 && DST==1)
|
||||
{
|
||||
// DST=0;
|
||||
timeClient.setTimeOffset(utcOffsetInSeconds);
|
||||
timeClient.forceUpdate();
|
||||
} else if (dow == 7 && mo == 3 && d >= 25 && h ==2 && DST==0)
|
||||
{
|
||||
// DST = 1
|
||||
timeClient.setTimeOffset(utcOffsetInSeconds * 2);
|
||||
timeClient.forceUpdate();
|
||||
}
|
||||
*/
|
||||
|
||||
Serial.print("=====\nLocal time: ");
|
||||
Serial.print(timeClient.getHours());
|
||||
Serial.print(":");
|
||||
Serial.println(timeClient.getMinutes());
|
||||
|
@ -194,7 +312,6 @@ void tc_readConfig()
|
|||
Serial.print(") + ");
|
||||
Serial.println(TIMER_DATA_ENSTATE);*/
|
||||
|
||||
tc_data[i].enstate = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_ENSTATE);
|
||||
tc_data[i].hh = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_HH);
|
||||
tc_data[i].mm = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_MM);
|
||||
tc_data[i].ch1 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH1);
|
||||
|
|
Loading…
Reference in a new issue