Broken timing stuff

This commit is contained in:
Kai Lauterbach 2023-04-25 14:32:42 +02:00
parent 4f0a191d0b
commit 510f6756b0
3 changed files with 194 additions and 133 deletions

View file

@ -5,14 +5,17 @@
#define light_name "Dimmable Hue Light" //default light name
#define LIGHTS_COUNT 4 // do not modify because luminie p30 only ha 4 channel
#define LIGHTS_COUNT 4 // do not modify because luminie p30 only has 4 channel, never set above 80
#define EEPROM_LAST_STATE_STARTUP_ADDRESS 0 // startup behavior is used for all lights
#define EEPROM_SCENE_ADDRESS 1 // scene is used for all of the lights
#define EEPROM_LAST_STATE_ADDRESS 2 // the first "last state" information for the first light
#define EEPROM_TIMING_CONTROL_ENABLED_ADDRESS 3 // the first "last state" information for the first light
#define EEPROM_DYNAMIC_IP_ADDRESS 4
#define EEPROM_LAST_DEFAULT_BLOCK_ADDRESS 20
#define EEPROM_TIMING_DATA_ADDRESS (EEPROM_TIMING_CONTROL_ENABLED_ADDRESS + LIGHTS_COUNT) // Stored data date per light ELE_USED; HH; MM; CH1; CH2; CH3; CH4;
#define EEPROM_TIMING_CONTROL_ENABLED_ADDRESS 2
#define EEPROM_DYNAMIC_IP_ADDRESS 3
#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 TC_TIME_CHECK_INTERVAL_MS 600000
#define TIME_CHECK_INTERVAL_MS (10000UL) // 600000
#define MY_NTP_SERVER "de.pool.ntp.org"
#define DISABLE_WEB_CONTROL

View file

@ -39,6 +39,7 @@ IPAddress subnet_mask( 255, 255, 255, 0);
#define PWM_MIN 640 // 15V - minimum light amount (~1%)
#define PWM_MAX 1023 // 24V - maximum light amount (100%)
#define PWM_INC 4 // 24V-15V = 9V range; 9V ≙ 1024/640 = 383 counts; 383/100% = 3,83 counts (1%) / % => round up 4 counts / % (~1%)
#define BRI_TO_PWM_FACTOR 4 // 0-255 uint8_t brightness data x4 is 0 to 1024
//********************************//
@ -127,7 +128,6 @@ void lightEngine()
{
delay(6);
in_transition = false;
}
}
@ -232,13 +232,13 @@ void setup()
init_webserver();
tc_init();
server.begin();
} // end of setup
//********************************//
void loop()
{
server.handleClient();
@ -250,6 +250,8 @@ void loop()
}
}
//********************************//
void handleNotFound()
{
String message = "File Not Found\n\n";
@ -268,8 +270,12 @@ void handleNotFound()
server.send(404, "text/plain", message);
}
//********************************//
void init_webserver()
{
#ifndef DISABLE_WEB_CONTROL
server.on("/state", HTTP_PUT, []()
{ // HTTP PUT request used to set a new light state
DynamicJsonDocument root(1024);
@ -360,8 +366,12 @@ void init_webserver()
server.send(200, "text/plain", output);
});
#endif // DISABLE_WEB_CONTROL
server.on("/", []()
{
#ifndef DISABLE_WEB_CONTROL
static float transitiontime = 4.0;
if (server.hasArg("transition"))
@ -376,10 +386,21 @@ void init_webserver()
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) != startup)
{
EEPROM.write(EEPROM_LAST_STATE_STARTUP_ADDRESS, startup);
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
uint8_t tmp = (light_state[i] == true ? LIGHT_STATE_ON : LIGHT_STATE_OFF);
if (EEPROM.read(EEPROM_LAST_STATE_ADDRESS + i) != tmp)
{
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + i, tmp);
}
}
EEPROM.commit();
Serial.print("Startup behavior set to "); Serial.println(EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS));
}
}
#endif // DISABLE_WEB_CONTROL
// timing controller switch handling
if (server.hasArg("tc"))
@ -412,6 +433,8 @@ void init_webserver()
}
}
#ifndef DISABLE_WEB_CONTROL
// scene switch handling
if (server.hasArg("scene"))
{
@ -425,6 +448,18 @@ void init_webserver()
}
if (server.hasArg("dip"))
{
uint8_t tmp = EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS);
uint8_t tmp2 = (server.arg("dip") == "true" ? 1 : 0);
if (tmp != tmp2)
{
EEPROM.write(EEPROM_DYNAMIC_IP_ADDRESS, tmp2);
EEPROM.commit();
Serial.print("Set dynamic IP to "); Serial.println(EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS));
}
}
// process the received data for every light
for (int light = 0; light < LIGHTS_COUNT; light++)
{
@ -439,23 +474,24 @@ void init_webserver()
if (server.hasArg("on" + (String)light))
{
uint8_t tmp = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
if (server.arg("on" + (String)light) == "true")
if (server.arg("on" + (String)light) == "true" && light_state[light] == false)
{
light_state[light] = true;
if (tmp == 0 && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == 0)
{
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_ON);
}
Serial.print("Light "); Serial.print(light); Serial.print(" state set to "); Serial.println(light_state[light]);
} else {
} else if (server.arg("on" + (String)light) == "false" && light_state[light] == true)
{
light_state[light] = false;
if (tmp == 0 && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == 1)
{
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_OFF);
}
}
Serial.print("Light "); Serial.print(light); Serial.print(" state set to "); Serial.println(light_state[light]);
}
EEPROM.commit();
@ -464,7 +500,6 @@ void init_webserver()
// start alerting for every light
if (server.hasArg("alert"))
{
if (light_state[light])
{
current_bri[light] = 0;
@ -474,7 +509,7 @@ void init_webserver()
}
// switch the light
// set the light step level
if (light_state[light])
{
step_level[light] = ((float)bri[light] - current_bri[light]) / transitiontime;
@ -484,6 +519,8 @@ void init_webserver()
}
}
#endif // DISABLE_WEB_CONTROL
if (server.hasArg("resettc"))
{ // reqrite the tc config and reboot
tc_write_default();
@ -507,57 +544,28 @@ void init_webserver()
http_content += "</head>";
http_content += "<body>";
http_content += "<fieldset>";
http_content += "<h3>Setup of " + (String)LIGHTS_COUNT + " light"; if (LIGHTS_COUNT > 1) http_content += "'s"; http_content += "</h3>";
http_content += "<h3>" + (String)light_name + "</h3>";
http_content += "<div class=\"pure-controls\">";
http_content += "<span class=\"pure-form-message\"><a href=\"/?alert=1\">alert</a> &nbsp; <a href=\"/?reset=1\">reset</a> &nbsp; <a href=\"/?resettc\">reset timing control data</a> &nbsp; <a href=\"/update\">update</a></span>";
http_content += "<label for=\"cb\" class=\"pure-checkbox\">";
http_content += "</label>";
http_content += "</div>";
http_content += "<form class=\"pure-form pure-form-aligned\" action=\"/\" method=\"post\">";
// timer data processing, startup state and scene for all of the lights
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"startup\">Startup</label>";
http_content += "<select onchange=\"this.form.submit()\" id=\"startup\" name=\"startup\">";
int ls_val = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_LAST_STATE) http_content += "selected=\"selected\""; http_content += " value=\"0\">Last state</option>";
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_ON_STATE) http_content += "selected=\"selected\""; http_content += " value=\"1\">On</option>";
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_OFF_STATE) http_content += "selected=\"selected\""; http_content += " value=\"2\">Off</option>";
http_content += "</select>";
http_content += "</div>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"scene\">Scene</label>";
http_content += "<select onchange = \"this.form.submit()\" id=\"scene\" name=\"scene\">";
int sc_val = EEPROM.read(EEPROM_SCENE_ADDRESS);
http_content += "<option "; if (sc_val == SCENE_RELEAX) http_content += "selected=\"selected\""; http_content += " value=\"0\">Relax</option>";
http_content += "<option "; if (sc_val == SCENE_BRIGHT) http_content += "selected=\"selected\""; http_content += " value=\"1\">Bright</option>";
http_content += "<option "; if (sc_val == SCENE_NIGHTLY) http_content += "selected=\"selected\""; http_content += " value=\"2\">Night</option>";
http_content += "</select>";
http_content += "</div>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"power\"><strong>Enable timing control</strong></label>";
int tc_val = EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS);
http_content += "<a class=\"pure-button"; if (tc_val == TIMING_CONTROL_ENABLED) http_content += " pure-button-primary"; http_content += "\" href=\"/?tc=true\">ON</a>";
http_content += "<a class=\"pure-button"; if (tc_val == TIMING_CONTROL_DISABLED) http_content += " pure-button-primary"; http_content += "\" href=\"/?tc=false\">OFF</a>";
http_content += "</div>";
#ifndef DISABLE_WEB_CONTROL
http_content += "<br>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"transition\">Transition time (s)</label>";
http_content += "<input id=\"transition\" name=\"transition\" type=\"text\" placeholder=\"10\" value\"" + (String)transitiontime + "\">";
http_content += "</div>";
// Light control
for (uint8 light_num = 0; light_num < LIGHTS_COUNT; light_num++)
{
http_content += "<h3>Light " + (String)(light_num+1) + "</h3>";
http_content += "<h4>Light " + (String)(light_num+1) + "</h4>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"power\"><strong>Power</strong></label>";
http_content += "<a class=\"pure-button"; if ( light_state[light_num]) http_content += " pure-button-primary"; http_content += "\" href=\"/?on" + (String)light_num + "=true\">ON</a>";
http_content += "<a class=\"pure-button"; if (!light_state[light_num]) http_content += " pure-button-primary"; http_content += "\" href=\"/?on" + (String)light_num + "=false\">OFF</a>";
http_content += "</div>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"state\"><strong>State</strong></label>";
http_content += "</div>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"bri\"" + (String)light_num + ">Bri</label>";
http_content += "<input id=\"bri" + (String)light_num + "\" name=\"bri" + (String)light_num + "\" type=\"range\" min=\"0\" max=\"100\" value=\"" + (String)bri[light_num] + "\">";
@ -573,6 +581,42 @@ void init_webserver()
http_content += "</div>";
}
// timer data processing, startup state and scene for all of the lights
http_content += "<br>";
http_content += "<h3>Config</h3>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"startup\"><strong>Startup</strong></label>";
http_content += "<select onchange=\"this.form.submit()\" id=\"startup\" name=\"startup\">";
int ls_val = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_LAST_STATE) http_content += "selected=\"selected\""; http_content += " value=\"0\">Last state</option>";
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_ON_STATE) http_content += "selected=\"selected\""; http_content += " value=\"1\">On</option>";
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_OFF_STATE) http_content += "selected=\"selected\""; http_content += " value=\"2\">Off</option>";
http_content += "</select>";
http_content += "</div>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"scene\"><strong>Scene</strong></label>";
http_content += "<select onchange = \"this.form.submit()\" id=\"scene\" name=\"scene\">";
int sc_val = EEPROM.read(EEPROM_SCENE_ADDRESS);
http_content += "<option "; if (sc_val == SCENE_RELEAX) http_content += "selected=\"selected\""; http_content += " value=\"0\">Relax</option>";
http_content += "<option "; if (sc_val == SCENE_BRIGHT) http_content += "selected=\"selected\""; http_content += " value=\"1\">Bright</option>";
http_content += "<option "; if (sc_val == SCENE_NIGHTLY) http_content += "selected=\"selected\""; http_content += " value=\"2\">Night</option>";
http_content += "</select>";
http_content += "</div>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"power\"><strong>Timing control</strong></label>";
int tc_val = EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS);
http_content += "<a class=\"pure-button"; if (tc_val == TIMING_CONTROL_ENABLED) http_content += " pure-button-primary"; http_content += "\" href=\"/?tc=true\">ON</a>";
http_content += "<a class=\"pure-button"; if (tc_val == TIMING_CONTROL_DISABLED) http_content += " pure-button-primary"; http_content += "\" href=\"/?tc=false\">OFF</a>";
http_content += "</div>";
http_content += "<br>";
http_content += "<div class=\"pure-control-group\">";
http_content += "<label for=\"transition\">Transition time (s)</label>";
http_content += "<input id=\"transition\" name=\"transition\" type=\"text\" placeholder=\"10\" value=\"" + (String)transitiontime + "\">";
http_content += "</div>";
// Wifi settings
http_content += "<br>";
http_content += "<h3>Wifi</h3>";
@ -612,12 +656,11 @@ void init_webserver()
}
http_content += "<div class=\"pure-controls\">";
http_content += "<span class=\"pure-form-message\"><a href=\"/?alert=1\">alert</a> &nbsp; <a href=\"/?reset=1\">reset</a> &nbsp; <a href=\"/?resettc\">reset timing control data</a> &nbsp; <a href=\"/update\">update</a></span>";
http_content += "<label for=\"cb\" class=\"pure-checkbox\">";
http_content += "</label>";
http_content += "<button type=\"submit\" class=\"pure-button pure-button-primary\">Save</button>";
http_content += "</div>";
#endif // DISABLE_WEB_CONTROL
http_content += "</fieldset>";
http_content += "</form>";
http_content += "</body>";

View file

@ -1,6 +1,6 @@
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include "config.h"
@ -22,14 +22,15 @@
#define ENSTATE_DISABLED 0
//***********************************//
/* Globals */
const long utcOffsetInSeconds = 3600; // Europe/Berlin (not summer time)
uint32_t tc_last_check = 0;
const long updateInterval = 60000;
const long utcOffsetInSeconds = 3600;
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
static uint32_t tc_last_time_check;
NTPClient timeClient(ntpUDP, MY_NTP_SERVER, utcOffsetInSeconds, updateInterval);
struct tc_data_st {
uint8_t enstate;
@ -61,13 +62,6 @@ uint8_t example_timer_data_block[] = {
void tc_init()
{
while ( WiFi.status() != WL_CONNECTED )
{
delay ( 500 );
Serial.print ( "." );
}
timeClient.begin();
if (tc_check_no_data_block() == true)
{
@ -75,79 +69,42 @@ void tc_init()
tc_write_default();
}
//Serial.println("TC: Read data block from eeprom");
while ( WiFi.status() != WL_CONNECTED )
{
delay (500);
Serial.print ( "." );
}
tc_last_check = millis();
timeClient.begin();
Serial.println("TC: Read data block from eeprom");
tc_readConfig();
tc_last_time_check = millis();
}
void tc_readConfig()
{
for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS; i++)
{
/*Serial.print("Reading from address: "); Serial.print(EEPROM_TIMING_DATA_ADDRESS);
Serial.print(" + (");
Serial.print(i);
Serial.print(" * ");
Serial.print(LENGTH_OF_TIMER_DATA_BLOCK);
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);
tc_data[i].ch2 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH2);
tc_data[i].ch3 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH3);
tc_data[i].ch4 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH4);
/*Serial.print("data block: "); Serial.print(i);
Serial.print(" @ ");
Serial.println((EEPROM_TIMING_DATA_ADDRESS + (i * LENGTH_OF_TIMER_DATA_BLOCK) + TIMER_DATA_ENSTATE));
Serial.print(" es: "); Serial.println(tc_data[i].enstate);
Serial.print(" hh: "); Serial.println(tc_data[i].hh);
Serial.print(" mm: "); Serial.println(tc_data[i].mm);
Serial.print(" ch1: "); Serial.println(tc_data[i].ch1);
Serial.print(" ch2: "); Serial.println(tc_data[i].ch2);
Serial.print(" ch3: "); Serial.println(tc_data[i].ch3);
Serial.print(" ch4: "); Serial.println(tc_data[i].ch4);*/
}
}
void tc_updateTime()
{
timeClient.update();
Serial.print("Local time: ");
Serial.print(timeClient.getHours());
Serial.print(":");
Serial.println(timeClient.getMinutes());
}
//********************************//
void tc_update()
{
uint8_t target_data_block = 255;
if (millis() > tc_last_time_check + TC_TIME_CHECK_INTERVAL_MS)
{
tc_last_time_check = millis();
tc_updateTime();
}
if ((timeClient.getMinutes() % 10) != 0)
{
return; // only run every 10 minutes
}
//tc_updateTime();
// 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() && tc_data[i].enstate == ENSTATE_ENABLED)
{ // we have a new time data slot reached
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)
@ -190,6 +147,60 @@ void tc_update()
}
//********************************//
void tc_updateTime()
{
if (timeClient.update())
{
Serial.println("TC: Reading time from server...");
Serial.println(timeClient.getFormattedTime());
Serial.print("Local time: ");
Serial.print(timeClient.getHours());
Serial.print(":");
Serial.println(timeClient.getMinutes());
}
}
//********************************//
void tc_readConfig()
{
for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS; i++)
{
/*Serial.print("Reading from address: "); Serial.print(EEPROM_TIMING_DATA_ADDRESS);
Serial.print(" + (");
Serial.print(i);
Serial.print(" * ");
Serial.print(LENGTH_OF_TIMER_DATA_BLOCK);
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);
tc_data[i].ch2 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH2);
tc_data[i].ch3 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH3);
tc_data[i].ch4 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH4);
/*Serial.print("data block: "); Serial.print(i);
Serial.print(" @ ");
Serial.println((EEPROM_TIMING_DATA_ADDRESS + (i * LENGTH_OF_TIMER_DATA_BLOCK) + TIMER_DATA_ENSTATE));
Serial.print(" es: "); Serial.println(tc_data[i].enstate);
Serial.print(" hh: "); Serial.println(tc_data[i].hh);
Serial.print(" mm: "); Serial.println(tc_data[i].mm);
Serial.print(" ch1: "); Serial.println(tc_data[i].ch1);
Serial.print(" ch2: "); Serial.println(tc_data[i].ch2);
Serial.print(" ch3: "); Serial.println(tc_data[i].ch3);
Serial.print(" ch4: "); Serial.println(tc_data[i].ch4);*/
}
}
//********************************//
void tc_write_default()
{
//Serial.print("-----\nWrite data block starting from address EEPROM_TIMING_DATA_ADDRESS = "); Serial.println(EEPROM_TIMING_DATA_ADDRESS);
@ -205,6 +216,8 @@ void tc_write_default()
//Serial.println("-----");
}
//********************************//
bool tc_check_no_data_block()
{
//Serial.print("Check data block address EEPROM_TIMING_DATA_ADDRESS = "); Serial.println(EEPROM_TIMING_DATA_ADDRESS);
@ -217,3 +230,5 @@ bool tc_check_no_data_block()
}
return false;
}
//********************************//