소스 검색

New Sing. Test NTP client. Test TM1650.

Vladimir N. Shilov 2 년 전
부모
커밋
4a32729d55
18개의 변경된 파일482개의 추가작업 그리고 1096개의 파일을 삭제
  1. 0 155
      .cproject
  2. 1 0
      .gitignore
  3. 0 28
      .project
  4. 4 0
      Changelog.txt
  5. 3 18
      Makefile
  6. 0 39
      Makefile-user.mk
  7. 79 258
      app/application.cpp
  8. 37 59
      app/configuration.cpp
  9. 0 83
      app/max7219.cpp
  10. 137 0
      app/tm1650.cpp
  11. 141 193
      app/webserver.cpp
  12. 3 0
      component.mk
  13. 0 1
      dump.bat
  14. 31 45
      include/configuration.h
  15. 0 167
      include/max7219.h
  16. 45 0
      include/tm1650.h
  17. 0 46
      include/user_config.h
  18. 1 4
      include/webserver.h

+ 0 - 155
.cproject

@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-	<storageModule moduleId="org.eclipse.cdt.core.settings">
-		<cconfiguration id="cdt.managedbuild.toolchain.gnu.mingw.base.1135534147">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.mingw.base.1135534147" moduleId="org.eclipse.cdt.core.settings" name="Sming">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.mingw.base.1135534147" name="Sming" parent="org.eclipse.cdt.build.core.emptycfg">
-					<folderInfo id="cdt.managedbuild.toolchain.gnu.mingw.base.1135534147.86962463" name="/" resourcePath="">
-						<toolChain id="cdt.managedbuild.toolchain.gnu.cross.base.1164554300" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.base">
-							<option id="cdt.managedbuild.option.gnu.cross.prefix.521205673" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix"/>
-							<option id="cdt.managedbuild.option.gnu.cross.path.393887888" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path"/>
-							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.712123812" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
-							<builder id="cdt.managedbuild.builder.gnu.cross.2110485170" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
-							<tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1168221903" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
-								<option id="gnu.c.compiler.option.include.paths.357494572" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}/system/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}/Libraries&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${ESP_HOME}/sdk/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/MyProj-WallClock/include}&quot;"/>
-								</option>
-								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.313321806" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1999763015" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
-								<option id="gnu.cpp.compiler.option.include.paths.611746109" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}/system/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}/Libraries&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${ESP_HOME}/sdk/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/MyProj-WallClock/include}&quot;"/>
-								</option>
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1330530366" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.65193859" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
-							<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1795850540" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.364843833" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.cross.archiver.525412186" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
-							<tool id="cdt.managedbuild.tool.gnu.cross.assembler.587940548" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
-								<option id="gnu.both.asm.option.include.paths.1067006329" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}/system/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${SMING_HOME}/Libraries&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${ESP_HOME}/sdk/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/MyProj-WallClock/include}&quot;"/>
-								</option>
-								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.651581712" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-							</tool>
-						</toolChain>
-					</folderInfo>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-			<storageModule moduleId="ilg.gnuarmeclipse.managedbuild.packs"/>
-		</cconfiguration>
-	</storageModule>
-	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-		<project id="MyProj-Test.null.1347473968" name="MyProj-Test"/>
-	</storageModule>
-	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-	<storageModule moduleId="refreshScope" versionNumber="2">
-		<configuration configurationName="Sming">
-			<resource resourceType="PROJECT" workspacePath="/MyProj-Test"/>
-		</configuration>
-	</storageModule>
-	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
-		<buildTargets>
-			<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
-				<buildCommand>make</buildCommand>
-				<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
-				<buildTarget>all</buildTarget>
-				<stopOnError>true</stopOnError>
-				<useDefaultCommand>true</useDefaultCommand>
-				<runAllBuilders>true</runAllBuilders>
-			</target>
-			<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
-				<buildCommand>make</buildCommand>
-				<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
-				<buildTarget>clean</buildTarget>
-				<stopOnError>true</stopOnError>
-				<useDefaultCommand>true</useDefaultCommand>
-				<runAllBuilders>true</runAllBuilders>
-			</target>
-			<target name="flash" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
-				<buildCommand>make</buildCommand>
-				<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
-				<buildTarget>flash</buildTarget>
-				<stopOnError>true</stopOnError>
-				<useDefaultCommand>true</useDefaultCommand>
-				<runAllBuilders>true</runAllBuilders>
-			</target>
-			<target name="flashonefile" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
-				<buildCommand>make</buildCommand>
-				<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
-				<buildTarget>flashonefile</buildTarget>
-				<stopOnError>true</stopOnError>
-				<useDefaultCommand>true</useDefaultCommand>
-				<runAllBuilders>true</runAllBuilders>
-			</target>
-			<target name="flashinit" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
-				<buildCommand>make</buildCommand>
-				<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
-				<buildTarget>flashinit</buildTarget>
-				<stopOnError>true</stopOnError>
-				<useDefaultCommand>true</useDefaultCommand>
-				<runAllBuilders>true</runAllBuilders>
-			</target>
-			<target name="flashboot" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
-				<buildCommand>make</buildCommand>
-				<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
-				<buildTarget>flashboot</buildTarget>
-				<stopOnError>true</stopOnError>
-				<useDefaultCommand>true</useDefaultCommand>
-				<runAllBuilders>true</runAllBuilders>
-			</target>
-			<target name="rebuild" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
-				<buildCommand>make</buildCommand>
-				<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
-				<buildTarget>rebuild</buildTarget>
-				<stopOnError>true</stopOnError>
-				<useDefaultCommand>true</useDefaultCommand>
-				<runAllBuilders>true</runAllBuilders>
-			</target>
-		</buildTargets>
-	</storageModule>
-	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
-	<storageModule moduleId="scannerConfiguration">
-		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1135534147;cdt.managedbuild.toolchain.gnu.mingw.base.1135534147.86962463;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.2032390008;cdt.managedbuild.tool.gnu.c.compiler.input.1700912488">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1135534147;cdt.managedbuild.toolchain.gnu.mingw.base.1135534147.86962463;cdt.managedbuild.tool.gnu.cross.c.compiler.1168221903;cdt.managedbuild.tool.gnu.c.compiler.input.313321806">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1135534147;cdt.managedbuild.toolchain.gnu.mingw.base.1135534147.86962463;cdt.managedbuild.tool.gnu.cross.cpp.compiler.1999763015;cdt.managedbuild.tool.gnu.cpp.compiler.input.1330530366">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1135534147;cdt.managedbuild.toolchain.gnu.mingw.base.1135534147.86962463;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.454898447;cdt.managedbuild.tool.gnu.cpp.compiler.input.501261625">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-		</scannerConfigBuildInfo>
-	</storageModule>
-</cproject>

+ 1 - 0
.gitignore

@@ -4,3 +4,4 @@ language.settings.xml
 nbproject
 ~*.*
 *.*~
+.vscode/BROWSE.*

+ 0 - 28
.project

@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>MyProj-WallClock</name>
-	<comment></comment>
-	<projects>
-		<project>SmingFramework</project>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<triggers>clean,full,incremental,</triggers>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-			<triggers>full,incremental,</triggers>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.cdt.core.cnature</nature>
-		<nature>org.eclipse.cdt.core.ccnature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-	</natures>
-</projectDescription>

+ 4 - 0
Changelog.txt

@@ -82,3 +82,7 @@ UPD: развести можно, только я попутал индикат
 
 Приступаю к коду.
 Пытаюсь заставить компилиться Sming...
+---
+2022.10.03
+
+Переход на Sming 4.6, переписывание всего.

+ 3 - 18
Makefile

@@ -1,24 +1,9 @@
 #####################################################################
-#### Please don't change this file. Use Makefile-user.mk instead ####
+#### Please don't change this file. Use component.mk instead ####
 #####################################################################
-# Including user Makefile.
-# Should be used to set project-specific parameters
-include ./Makefile-user.mk
 
-# Important parameters check.
-# We need to make sure SMING_HOME and ESP_HOME variables are set.
-# You can use Makefile-user.mk in each project or use enviromental variables to set it globally.
- 
 ifndef SMING_HOME
-$(error SMING_HOME is not set. Please configure it in Makefile-user.mk)
-endif
-ifndef ESP_HOME
-$(error ESP_HOME is not set. Please configure it in Makefile-user.mk)
+$(error SMING_HOME is not set: please configure it as an environment variable)
 endif
 
-# Include main Sming Makefile
-ifeq ($(RBOOT_ENABLED), 1)
-include $(SMING_HOME)/Makefile-rboot.mk
-else
-include $(SMING_HOME)/Makefile-project.mk
-endif
+include $(SMING_HOME)/project.mk

+ 0 - 39
Makefile-user.mk

@@ -1,39 +0,0 @@
-## Local build configuration
-## Parameters configured here will override default and ENV values.
-## Uncomment and change examples:
-
-## Add your source directories here separated by space
-# MODULES = app
-# EXTRA_INCDIR = include
-
-## ESP_HOME sets the path where ESP tools and SDK are located.
-## Windows:
-# ESP_HOME = c:/Espressif
-
-## MacOS / Linux:
-# ESP_HOME = /opt/esp-open-sdk
-
-## SMING_HOME sets the path where Sming framework is located.
-## Windows:
-# SMING_HOME = c:/tools/sming/Sming 
-
-## MacOS / Linux
-# SMING_HOME = /opt/sming/Sming
-
-## COM port parameter is reqruied to flash firmware correctly.
-## Windows: 
-# COM_PORT = COM3
-
-## MacOS / Linux:
-# COM_PORT = /dev/tty.usbserial
-
-## Com port speed
-# COM_SPEED	= 115200
-
-## Configure flash parameters (for ESP12-E and other new boards):
-# SPI_MODE = dio
-
-## SPIFFS options
-# DISABLE_SPIFFS = 1
-SPIFF_FILES = web
-

+ 79 - 258
app/application.cpp

@@ -1,23 +1,18 @@
-#include <user_config.h>
-#include <SmingCore/SmingCore.h>
-#include <Libraries/DHT/DHT.h>
+#include <SmingCore.h>
 
 ///////////////////////////////////////////////////////////////////
 // Set your SSID & Pass for initial configuration
-#include "../include/configuration.h" // application configuration
+#include "configuration.h" // application configuration
 ///////////////////////////////////////////////////////////////////
 
-#include "max7219.h"
 #include "webserver.h"
-
-DHT dht(DHT_PIN, DHT22);
+#include "tm1650.h"
 
 Timer procTimer, procRTimer;
 Timer displayTimer, tmpTimer;
 Timer showHighTimer, showLowTimer;
 Timer brightTimer;
-
-// Sensors values
+// Sensors string values
 float SensorT, SensorH, SensorHI, SensorCR;
 String StrCF;
 // Time values
@@ -25,8 +20,10 @@ time_t Time, NTPLastUpdate;
 DateTime dt;
 
 void process(void);
-void connectOk(void);
-void connectFail(void);
+void connectOk(const String& SSID, MacAddress bssid, uint8_t channel);
+void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason);
+void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway);
+
 void showWatch(void);
 void showTime(void);
 void showTemperature(void);
@@ -34,15 +31,14 @@ void showHumidity(void);
 void setBright(void);
 
 // NTP Client
-void
-onNtpReceive(NtpClient& client, time_t timestamp);
-NtpClient ntpClient("ntps1-0.cs.tu-berlin.de", 300, onNtpReceive);
+void onNtpReceive(NtpClient& client, time_t timestamp);
+NtpClient ntpClient("ntp.time.in.ua", 1500, onNtpReceive); // every 15 min
 
 void init()
 {
 	spiffs_mount(); // Mount file system, in order to work with files
 
-	Serial.begin(SERIAL_BAUD_RATE); // 115200 by default
+	Serial.begin(SERIAL_BAUD_RATE);  // 115200 by default
 	Serial.systemDebugOutput(false); // Debug output to serial
 	Serial.println("Wall Segment Clock");
 
@@ -55,27 +51,26 @@ void init()
 	WifiStation.enable(true);
 	WifiAccessPoint.enable(false);
 
-	WifiStation.waitConnection(connectOk, 20, connectFail); // We recommend 20+ seconds for connection timeout at start
+	WifiEvents.onStationConnect(connectOk);
+	WifiEvents.onStationDisconnect(connectFail);
+	WifiEvents.onStationGotIP(gotIP);
 
-	// DHT sensor start
-	dht.begin();
+	// Sensors start
+	//dht.begin();
 
-	// опрос датчиков -- раз в минуту?
+	// polling sensors - once a minute?
 	procTimer.initializeMs(60000, process).start();
 	process();
 
-	// 7-segment output
-	MAX7219_Init();
-	tmpTimer.initializeMs(10, MAX7219_FillMinus).startOnce();
+	// Low LED output
+	TM1650_Init();
 	brightTimer.initializeMs(1000, setBright).start();
 
 	// обновление экрана два раза в секунду
 	displayTimer.initializeMs(500, showWatch).start();
 }
 
-void showWatch()
-{
-	static uint8_t old_si = 0xFF;
+void showWatch(void) {
 	static time_t oldTime;
 
 	Time = SystemClock.now();
@@ -94,292 +89,118 @@ void showWatch()
 	 * 	int16_t Year;  // Full Year numer
 	 */
 
-	uint8_t si = dt.Second / 5;
-	/*
-	 * 0 - Temp
-	 * 1 - Humidity
-	 * 2 - Temp
-	 * 3 - Humidity
-	 * 4 - Temp
-	 * 5 - Humidity
-	 * 6 - Temp
-	 * 7 - Humidity
-	 * 8 - Temp
-	 * 9 - Humidity
-	 * 10 - Temp
-	 * 11 - Humidity
-	 */
-
-	if (oldTime == Time)
-	{
-	// Старая секунда
-		// time the same, output blank for [HH MM]
-		MAX7219_writeData(MAX7219_DIGIT2, SYM_BLANK);
-		/*
-		if (si != 5 || si != 11)
-		{
-			MAX7219_writeData(MAX7219_DIGIT2, SYM_BLANK);
-		}
-		*/
-	}
-	else
-	{
-	// Новая секунда
+	if (oldTime == Time) {
+		// Старая секунда - нужно гасить точки
+		TM1650_DotRes(Dig_2);
+	}	else {
+		// Новая секунда
 		oldTime = Time;
-
-		// Запланируем обновление индикаторов
-		showHighTimer.initializeMs(10, showTime).startOnce();
-
-		switch(dt.Second / 15)
-		{
-			case 0:
-				MAX7219_writeData(MAX7219_DIGIT2, SYM_Minus);
-				break;
-			case 1:
-				MAX7219_writeData(MAX7219_DIGIT2, SYM_Minus2L);
-				break;
-			case 2:
-				MAX7219_writeData(MAX7219_DIGIT2, SYM_Minus2H);
-				break;
-			case 3:
-				MAX7219_writeData(MAX7219_DIGIT2, SYM_Minus3);
-				break;
-		}
-
-		if (old_si != si)
-		{
-			old_si = si;
-
-			switch (si)
-			{
-			case 0:
-				showLowTimer.initializeMs(20, showTemperature).startOnce();
-				break;
-			case 1:
-				showLowTimer.initializeMs(20, showHumidity).startOnce();
-				break;
-			case 2:
-				showLowTimer.initializeMs(20, showTemperature).startOnce();
-				break;
-			case 3:
-				showLowTimer.initializeMs(20, showHumidity).startOnce();
-				break;
-			case 4:
-				showLowTimer.initializeMs(20, showTemperature).startOnce();
-				break;
-			case 5:
-				showLowTimer.initializeMs(20, showHumidity).startOnce();
-				break;
-			case 6:
-				showLowTimer.initializeMs(20, showTemperature).startOnce();
-				break;
-			case 7:
-				showLowTimer.initializeMs(20, showHumidity).startOnce();
-				break;
-			case 8:
-				showLowTimer.initializeMs(20, showTemperature).startOnce();
-				break;
-			case 9:
-				showLowTimer.initializeMs(20, showHumidity).startOnce();
-				break;
-			case 10:
-				showLowTimer.initializeMs(20, showTemperature).startOnce();
-				break;
-			case 11:
-				showLowTimer.initializeMs(20, showHumidity).startOnce();
-				break;
-			}
-		}
+		TM1650_Out(dt.Hour >> 4, dt.Hour & 0xf, dt.Minute >>4, dt.Minute & 0xf);
+		TM1650_DotSet(Dig_2);
 	}
 }
 
 /*
  * Выводим текущее время [HH MM] на верхние индикаторы
  */
-void showTime(void)
-{
+void showTime(void) {
 	static uint8_t oldHour = 0xFF, oldMinute = 0xFF;
 
-	if (oldMinute != dt.Minute)
-	{
+	if (oldMinute != dt.Minute) {
 		oldMinute = dt.Minute;
 
-		MAX7219_writeData(MAX7219_DIGIT3, dt.Minute / 10);
-		MAX7219_writeData(MAX7219_DIGIT4, dt.Minute % 10);
-
-		if (oldHour != dt.Hour)
-		{
+		// ...
+		
+		if (oldHour != dt.Hour) {
 			oldHour = dt.Hour;
 
-			// уберём ведущий ноль у часов
-			if (dt.Hour < 10)
-			{
-				MAX7219_writeData(MAX7219_DIGIT0, MAX7219_CHAR_BLANK);
-			}
-			else
-			{
-				MAX7219_writeData(MAX7219_DIGIT0, dt.Hour / 10);
-			}
-			MAX7219_writeData(MAX7219_DIGIT1, dt.Hour % 10);
-
-		}
-	}
-
+			// ...
+		} // new hour
+	} // new minute
 }
 
 /*
  * Выводим температуру на нижние индикаторы
  */
-void showTemperature(void)
-{
-	MAX7219_writeData(MAX7219_DIGIT5, SYM_Temp);
-	MAX7219_writeData(MAX7219_DIGIT6, (int) (SensorT) / 10);
-	MAX7219_writeData(MAX7219_DIGIT7, (int) (SensorT) % 10);
+void showTemperature(void) {
+		// ...
 }
 
 /*
  * Выводим влажность на нижние индикаторы
  */
-void showHumidity(void)
-{
-	MAX7219_writeData(MAX7219_DIGIT5, SYM_H_SM);
-	MAX7219_writeData(MAX7219_DIGIT6, (int) (SensorH) / 10);
-	MAX7219_writeData(MAX7219_DIGIT7, (int) (SensorH) % 10);
+void showHumidity(void) {
+		// ...
 }
 
 /*
  * Выводим дату на верхние индикаторы [DD MM]
  */
-/*
- void showDate(void)
- {
- MAX7219_writeData(MAX7219_DIGIT0, dt.Day/10);
- MAX7219_writeData(MAX7219_DIGIT1, dt.Day%10);
- MAX7219_writeData(MAX7219_DIGIT2, SYM_Minus);
- MAX7219_writeData(MAX7219_DIGIT3, dt.Month/10);
- MAX7219_writeData(MAX7219_DIGIT4, dt.Month%10);
-
- MAX7219_writeData(MAX7219_DIGIT6, (uint8_t)(dt.DayofWeek / 10));
- MAX7219_writeData(MAX7219_DIGIT7, (uint8_t)(dt.DayofWeek % 10));
- }
- */
+ void showDate(void) {
+ 		// ...
+}
 
 /*
  * Автоматическая регулировка яркости индикаторов
+ * GY-49
  */
-void setBright(void)
-{
-	// приведём к диапазону 0-16
-	uint8_t bright = (1024 - system_adc_read()) >> 6;
-
-	// переведём диапазон значений 9-16/1 в 1-15/2
-	if (bright > 8)
-	{
-		bright = ( (bright - 9) * 2 ) + 1;
-	}
-	else
-	{
-		bright = 1;
-	}
-
-	MAX7219_writeData(MAX7219_MODE_INTENSITY, bright);
+void setBright(void) {
+		// ...
 }
 
-/*
- * Читаем данные с DHT22, в случае неудачи -- данные остануться старыми.
- * меня это полностью устраивает.
+/**
+ * @brief Get data from Temperature/Humidity Sensor
+ * Currently planed AHT10. Пока заглушка.
  */
-void process()
-{
-	TempAndHumidity th;
-	ComfortState cf;
-	static int8_t status;
-
-	if (dht.readTempAndHumidity(th))
-	{
-		status = 0;
-		SensorT = th.temp;
-		SensorH = th.humid;
-		SensorHI = dht.getHeatIndex();
-		SensorCR = dht.getComfortRatio(cf);
-
-		switch (cf)
-		{
-		case Comfort_OK:
-			StrCF = "OK";
-			break;
-		case Comfort_TooHot:
-			StrCF = "Too Hot";
-			break;
-		case Comfort_TooCold:
-			StrCF = "Too Cold";
-			break;
-		case Comfort_TooDry:
-			StrCF = "Too Dry";
-			break;
-		case Comfort_TooHumid:
-			StrCF = "Too Humid";
-			break;
-		case Comfort_HotAndHumid:
-			StrCF = "Hot And Humid";
-			break;
-		case Comfort_HotAndDry:
-			StrCF = "Hot And Dry";
-			break;
-		case Comfort_ColdAndHumid:
-			StrCF = "Cold And Humid";
-			break;
-		case Comfort_ColdAndDry:
-			StrCF = "Cold And Dry";
-			break;
-		default:
-			StrCF = "Unknown";
-			break;
-		}
-	}
-	else
-	{
-		/*
-		 * В случае, если от датчика ничего не получили, запустим повторный опрос через
-		 * 10 секунд, но не более 5 раз подряд.
-		 */
-		if (status < 6)
-		{
-			status++;
-			procRTimer.initializeMs(10000, process).startOnce();
-		}
-	}
+void process() {
+	float t = 25.0;
+	float h = 60.5;
+
+	Serial.print("Humidity: ");
+	Serial.print(h);
+	Serial.print("%. Temperature: ");
+	Serial.print(t);
+	Serial.println("*C");
 }
 
-void connectOk()
+void connectOk(const String& SSID, MacAddress bssid, uint8_t channel)
 {
+	debugf("connected");
 	WifiAccessPoint.enable(false);
-	Serial.print("I'm connecteed. IP: ");
-	Serial.println(WifiStation.getIP().toString());
+}
+
+void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway)
+{
+	Serial.print("Got IP address: ");
+	Serial.println(ip);
+	// Restart main screen output
+	procTimer.restart();
+	displayTimer.restart();
+
+	// start NTP Client there?
 
 	startWebServer();
 }
 
-/*
- * в случае неудачи подключения поднимаем точку доступа без авторизации
- */
-void connectFail()
+void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason)
 {
-	WifiAccessPoint.config("MeteoConfig", "", AUTH_OPEN);
+	debugf("connection FAILED: %s", WifiEvents.getDisconnectReasonDesc(reason).c_str());
+	WifiAccessPoint.config("ClockConfig", "", AUTH_OPEN);
 	WifiAccessPoint.enable(true);
-// Stop main screen output
+	// Stop main screen output
 	procTimer.stop();
 	displayTimer.stop();
 
-	Serial.println("WiFi MeteoConfig");
+	Serial.println("WiFi ClockConfig");
 	Serial.println(WifiAccessPoint.getIP());
 
 	startWebServer();
-	WifiStation.waitConnection(connectOk); // Wait connection
+	WifiStation.disconnect();
+	WifiStation.connect();
 }
 
-/*
- * NTP Client
+/**
+ * @brief NTP Client
  */
 void onNtpReceive(NtpClient& client, time_t timestamp)
 {

+ 37 - 59
app/configuration.cpp

@@ -1,77 +1,55 @@
-#include "../include/configuration.h"
-
-#include <SmingCore/SmingCore.h>
+#include "configuration.h"
+#include <SmingCore.h>
 
 ClockConfig ActiveConfig;
 
-ClockConfig
-loadConfig ()
+ClockConfig loadConfig(void)
 {
-  DynamicJsonBuffer jsonBuffer;
-  ClockConfig cfg;
-  if (fileExist (CLOCK_CONFIG_FILE))
-    {
-      int size = fileGetSize (CLOCK_CONFIG_FILE);
-      char* jsonString = new char[size + 1];
-      fileGetContent (CLOCK_CONFIG_FILE, jsonString, size + 1);
-      JsonObject& root = jsonBuffer.parseObject (jsonString);
-
-      JsonObject& network = root["network"];
-      cfg.NetworkSSID = String ((const char*) network["ssid"]);
-      cfg.NetworkPassword = String ((const char*) network["password"]);
-
-      JsonObject& correction = root["correction"];
-      cfg.AddTZ = correction["TZ"];
-
-      JsonObject& light = root["light"];
-      cfg.LightTrhLow = light["low"];
-      cfg.LightTrhHigh = light["high"];
-
-      JsonObject& bright = root["bright"];
-      cfg.BrightnessLow = bright["low"];
-      cfg.BrightnessMiddle = bright["mid"];
-      cfg.BrightnessHigh = bright["high"];
-
-      delete[] jsonString;
-    }
-  else
-    {
-      cfg.NetworkSSID = WIFI_SSID;
-      cfg.NetworkPassword = WIFI_PWD;
-    }
-  return cfg;
+	DynamicJsonDocument doc(1024);
+	ClockConfig cfg;
+	if(Json::loadFromFile(doc, CLOCK_CONFIG_FILE)) {
+		JsonObject network = doc["network"];
+		cfg.NetworkSSID = network["ssid"].as<const char*>();
+		cfg.NetworkPassword = network["password"].as<const char*>();
+
+		JsonObject correction = doc["correction"];
+		cfg.AddTZ = correction["TZ"];
+
+		JsonObject light = doc["light"];
+		cfg.LightTrhLow = light["low"];
+		cfg.LightTrhHigh = light["high"];
+
+		JsonObject bright = doc["bright"];
+		cfg.BrightnessLow = bright["low"];
+		cfg.BrightnessMiddle = bright["mid"];
+		cfg.BrightnessHigh = bright["high"];
+	} else {
+		cfg.NetworkSSID = WIFI_SSID;
+		cfg.NetworkPassword = WIFI_PWD;
+	}
+	return cfg;
 }
 
-void
-saveConfig (ClockConfig& cfg)
+void saveConfig(ClockConfig& cfg)
 {
-  ActiveConfig = cfg;
+	ActiveConfig = cfg;
 
-  DynamicJsonBuffer jsonBuffer;
-  JsonObject& root = jsonBuffer.createObject ();
+	DynamicJsonDocument doc(1024);
+	auto network = doc.createNestedObject("network");
+	network["ssid"] = cfg.NetworkSSID;
+	network["password"] = cfg.NetworkPassword;
 
-  JsonObject& network = jsonBuffer.createObject ();
-  root["network"] = network;
-  network["ssid"] = cfg.NetworkSSID.c_str ();
-  network["password"] = cfg.NetworkPassword.c_str ();
+	auto correction = doc.createNestedObject("correction");
+	correction["TZ"] = cfg.AddTZ;
 
-  JsonObject& correction = jsonBuffer.createObject ();
-  root["correction"] = correction;
-  correction["TZ"] = cfg.AddTZ;
-
-  JsonObject& light = jsonBuffer.createObject ();
-  root["light"] = light;
+	auto light = doc.createNestedObject("light");
   light["low"] = cfg.LightTrhLow;
   light["high"] = cfg.LightTrhHigh;
 
-  JsonObject& bright = jsonBuffer.createObject ();
-  root["bright"] = bright;
+	auto bright = doc.createNestedObject("bright");
   bright["low"] = cfg.BrightnessLow;
   bright["mid"] = cfg.BrightnessMiddle;
   bright["high"] = cfg.BrightnessHigh;
 
-  char buf[3048];
-  root.prettyPrintTo (buf, sizeof(buf));
-  fileSetContent (CLOCK_CONFIG_FILE, buf);
+	Json::saveToFile(doc, CLOCK_CONFIG_FILE, Json::Pretty);
 }
-

+ 0 - 83
app/max7219.cpp

@@ -1,83 +0,0 @@
-/* max7219.cpp
- * MAX7219 Interaction Code
- * ---------------------------
- * For more information see
- * http://www.adnbr.co.uk/articles/max7219-and-7-segment-displays
- *
- *  Created on: 29 січ. 2016
- *      Author: shilov
- */
-
-#include <user_config.h>
-#include <SmingCore/SmingCore.h>
-#include "configuration.h"
-#include "max7219.h"
-
-// перевод числа 0-7 в номер индикатора
-//const uint8_t max7219_dig[8] = {
-//	0x05,0x01,0x07,0x03,0x04,0x08,0x06,0x02
-//};
-
-void
-MAX7219_writeData (uint8_t reg, uint8_t data)
-{
-	PinRes(PIN_LOAD); // опустили защёлку
-
-	// software spi
-	uint8_t i; // счетчик бит
-	uint16_t sdata = ((reg & 0x000F) << 8) | (data & 0x00FF);
-	for (i = 16; i != 0; i--)
-		{
-			PinRes(PIN_CLK); // выдали строб
-			if (sdata >= 0x8000)
-				{ // если старший бит == 1
-					PinSet(PIN_DIN); // MOSI = 1
-				}
-			else
-				{ // если старший бит == 0
-					PinRes(PIN_DIN); // MOSI = 0
-				}
-			PinSet(PIN_CLK); // защёлкнули строб
-
-			sdata <<= 1; // сдвиг влево на 1 бит
-		}
-
-	PinSet(PIN_LOAD); // подняли защёлку
-
-	PinSet(PIN_DIN);
-}
-
-void MAX7219_Init (void)
-{
-	// настройка пинов SPI
-	pinMode (PIN_LOAD, OUTPUT);
-	pinMode (PIN_DIN, OUTPUT);
-	pinMode (PIN_CLK, OUTPUT);
-	PinSet(PIN_LOAD);
-	PinSet(PIN_DIN);
-	PinSet(PIN_CLK);
-
-	// Настройка MAX71219
-	MAX7219_writeData (MAX7219_MODE_DECODE, MAX7219_DIG_MASK);
-	MAX7219_writeData (MAX7219_MODE_SCAN_LIMIT, MAX7219_DIGITS - 1); // Scan limit runs from 0.
-	MAX7219_writeData (MAX7219_MODE_INTENSITY, MAX7219_BRIGHT); // яркость
-	MAX7219_writeData (MAX7219_MODE_POWER, MAX7219_ON); // включили питание
-}
-
-void MAX7219_FillMinus(void)
-{
-	uint8_t i, m = MAX7219_DIG_MASK;
-
-	for (i = 8; i > 0; i--)
-		{
-			if (m >= 0x80)
-				{
-					MAX7219_writeData (i, MAX7219_CHAR_MINUS);
-				}
-			else
-				{
-					MAX7219_writeData (i, SYM_Minus);
-				}
-			m <<= 1;
-		}
-}

+ 137 - 0
app/tm1650.cpp

@@ -0,0 +1,137 @@
+#include <SmingCore.h>
+#include "configuration.h"
+#include "tm1650.h"
+#include "Wire.h"
+
+/* Private Defines */
+#define TM1650_ADDR_SYS  0x48
+#define TM1650_ADDR_BTN  0x4F
+#define TM1650_ADDR_DIG1 0x68
+#define TM1650_ADDR_DIG2 0x6A
+#define TM1650_ADDR_DIG3 0x6C
+#define TM1650_ADDR_DIG4 0x6E
+
+/* Private Variables */
+static const uint8_t Digits[16] = {
+  Sym_0, Sym_1, Sym_2, Sym_3, Sym_4, Sym_5, Sym_6, Sym_7,
+  Sym_8, Sym_9, Sym_A, Sym_B, Sym_C, Sym_D, Sym_E, Sym_F
+};
+static const uint8_t Addr[LED_NUM] = {
+  TM1650_ADDR_DIG1, TM1650_ADDR_DIG2, TM1650_ADDR_DIG3, TM1650_ADDR_DIG4
+};
+static uint8 Buffer[LED_NUM] = {0};
+
+/* Private Fuctions */ 
+bool I2CWriteTo(uint8_t addr, uint8_t data);
+
+/**
+ * @brief Initialization
+ */
+void TM1650_Init(void) {
+  I2CWriteTo(TM1650_ADDR_SYS, 0x79);
+  TM1650_Out(Sym_Minus, Sym_Minus, Sym_Minus, Sym_Minus);
+}
+
+/**
+ * @brief Output digit to all indicators
+ * 
+ * @param i1 Value in range 0..F
+ * @param i2 Value in range 0..F
+ * @param i3 Value in range 0..F
+ * @param i4 Value in range 0..F
+ */
+void TM1650_Out(uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4) {
+  Buffer[0] = Digits[i1];
+  Buffer[1] = Digits[i2];
+  Buffer[2] = Digits[i3];
+  Buffer[3] = Digits[i4];
+
+  I2CWriteTo(TM1650_ADDR_DIG1, Buffer[0]);
+  I2CWriteTo(TM1650_ADDR_DIG2, Buffer[1]);
+  I2CWriteTo(TM1650_ADDR_DIG3, Buffer[2]);
+  I2CWriteTo(TM1650_ADDR_DIG4, Buffer[3]);
+}
+
+/**
+ * @brief Output symbol to indicator 1.
+ * 
+ * @param value Segment code.
+ */
+void TM1650_Out1(tm1650_sym_t value) {
+  Buffer[0] = value;
+  I2CWriteTo(TM1650_ADDR_DIG1, value);
+}
+
+/**
+ * @brief Output symbol to indicator 2.
+ * 
+ * @param value Segment code.
+ */
+void TM1650_Out2(tm1650_sym_t value) {
+  Buffer[1] = value;
+  I2CWriteTo(TM1650_ADDR_DIG2, value);
+}
+
+/**
+ * @brief Output symbol to indicator 3.
+ * 
+ * @param value Segment code.
+ */
+void TM1650_Out3(tm1650_sym_t value) {
+  Buffer[2] = value;
+  I2CWriteTo(TM1650_ADDR_DIG3, value);
+}
+
+/**
+ * @brief Output symbol to indicator 4.
+ * 
+ * @param value Segment code.
+ */
+void TM1650_Out4(tm1650_sym_t value) {
+  Buffer[3] = value;
+  I2CWriteTo(TM1650_ADDR_DIG4, value);
+}
+
+/**
+ * @brief Set dot for selected led
+ * 
+ * @param pos Led 0..3
+ */
+void TM1650_DotSet(tm1650_pos_t pos) {
+  if (pos > LED_NUM-1) {
+    return;
+  }
+  I2CWriteTo(Addr[pos], (Buffer[pos] | Sym_Dot));
+}
+
+/**
+ * @brief Reset dot for selected led
+ * 
+ * @param pos Led 0..3
+ */
+void TM1650_DotRes(tm1650_pos_t pos) {
+  if (pos > LED_NUM-1) {
+    return;
+  }
+  I2CWriteTo(Addr[pos], (Buffer[pos] & ~(Sym_Dot)));
+}
+
+/**
+ * @brief Set LED bright
+ * 
+ * @param bright Brgiht level 0..7
+ */
+void TM1650_Bright(uint8_t bright) {
+  if (bright > LedBrightMax) {
+    bright = LedBrightMax;
+  }
+  bright <<= 4;
+  bright |= 1; // Display On
+  I2CWriteTo(TM1650_ADDR_SYS, bright);
+}
+
+bool I2CWriteTo(uint8_t addr, uint8_t data) {
+	Wire.beginTransmission(addr);
+	Wire.write(data);
+	return Wire.endTransmission();
+}

+ 141 - 193
app/webserver.cpp

@@ -1,8 +1,5 @@
-#include <user_config.h>
-#include <SmingCore/SmingCore.h>
-
-#include "../include/configuration.h"
-#include "webserver.h"
+#include <SmingCore.h>
+#include "configuration.h"
 
 bool serverStarted = false;
 HttpServer server;
@@ -11,214 +8,165 @@ extern float SensorT, SensorH, SensorHI, SensorCR;
 extern String StrCF;
 extern time_t NTPLastUpdate;
 
-/*
- * Index page.
- * Show dht22 data as integer.
- */
-void
-onIndex (HttpRequest &request, HttpResponse &response)
+void onIndex(HttpRequest& request, HttpResponse& response)
 {
-  TemplateFileStream *tmpl = new TemplateFileStream ("index.html");
-  auto &vars = tmpl->variables ();
-  vars["T"] = String (SensorT, 0);
-  vars["RH"] = String (SensorH, 0);
-  vars["HI"] = String (SensorHI, 0);
-  vars["CR"] = String (SensorCR, 0);
+	TemplateFileStream* tmpl = new TemplateFileStream("index.html");
+	auto& vars = tmpl->variables();
+
+  vars["T"] = String(SensorT, 0);
+  vars["RH"] = String(SensorH, 0);
+  vars["HI"] = String(SensorHI, 0);
+  vars["CR"] = String(SensorCR, 0);
   vars["CF"] = StrCF; // это первое место, где оно используется
-  vars["ADC"] = String (system_adc_read ());
-  vars["VDD"] = String (system_get_vdd33 ());
+  vars["ADC"] = String(system_adc_read ());
+  vars["VDD"] = String(system_get_vdd33 ());
   vars["LASTNTP"] = String (SystemClock.now () - NTPLastUpdate);
-  response.sendTemplate (tmpl);
+
+	response.sendNamedStream(tmpl);
 }
 
-/*
- * Configuration page.
- */
-void
-onConfiguration (HttpRequest &request, HttpResponse &response)
+void onConfiguration(HttpRequest& request, HttpResponse& response)
 {
-  ClockConfig cfg = loadConfig ();
-  if (request.getRequestMethod () == RequestMethod::POST)
-    {
-      // Update config
-      if (request.getPostParameter ("SSID").length () > 0) // Network
-        {
-          cfg.NetworkSSID = request.getPostParameter ("SSID");
-          cfg.NetworkPassword = request.getPostParameter ("Password");
-        }
-
-      if (request.getPostParameter ("TZ").length () > 0) // Correction
-        {
-          float tz = request.getPostParameter ("TZ").toFloat ();
-          if (cfg.AddTZ != tz)
-            {
-              cfg.AddTZ = tz;
-              SystemClock.setTimeZone (cfg.AddTZ);
-              if (cfg.AddTZ < 0 || cfg.AddTZ > 23)
-                {
-                  cfg.AddTZ = 0;
-                }
-            }
-        }
-
-      if (request.getPostParameter ("BLow").length () > 0) // Low brightness level.
-        {
-          cfg.BrightnessLow = request.getPostParameter ("BLow").toInt ();
-          if (cfg.BrightnessLow < 0 || cfg.BrightnessLow > 15)
-            {
-              cfg.BrightnessLow = 0;
-            }
-        }
-      if (request.getPostParameter ("BMid").length () > 0) // Middle brightness level.
-        {
-          cfg.BrightnessMiddle = request.getPostParameter ("BMid").toInt ();
-          if (cfg.BrightnessMiddle < 0 || cfg.BrightnessMiddle > 15)
-            {
-              cfg.BrightnessMiddle = 7;
-            }
-        }
-      if (request.getPostParameter ("BHigh").length () > 0) // High brightness level.
-        {
-          cfg.BrightnessHigh = request.getPostParameter ("BHigh").toInt ();
-          if (cfg.BrightnessHigh < 0 || cfg.BrightnessHigh > 15)
-            {
-              cfg.BrightnessHigh = 15;
-            }
-        }
-
-      if (request.getPostParameter ("LLow").length () > 0) // Low light level trh.
-        {
-          cfg.LightTrhLow = request.getPostParameter ("LLow").toInt ();
-          if (cfg.LightTrhLow < 0 || cfg.LightTrhLow > 1023)
-            {
-              cfg.LightTrhLow = 0;
-            }
-        }
-      if (request.getPostParameter ("LHigh").length () > 0) // High light level trh.
-        {
-          cfg.LightTrhHigh = request.getPostParameter ("LHigh").toInt ();
-          if (cfg.LightTrhHigh < 0 || cfg.LightTrhHigh > 1023)
-            {
-              cfg.LightTrhHigh = 1023;
-            }
-        }
-      saveConfig (cfg);
-      response.redirect ();
-    }
-
-  TemplateFileStream *tmpl = new TemplateFileStream ("config.html");
-  auto &vars = tmpl->variables ();
-  vars["SSID"] = cfg.NetworkSSID;
-  vars["TZ"] = String (cfg.AddTZ, 2);
-  vars["LLow"] = String (cfg.LightTrhLow);
-  vars["LHigh"] = String (cfg.LightTrhHigh);
-  vars["BLow"] = String (cfg.BrightnessLow);
-  vars["BMid"] = String (cfg.BrightnessMiddle);
-  vars["BHigh"] = String (cfg.BrightnessHigh);
-  response.sendTemplate (tmpl);
+	ClockConfig cfg = loadConfig();
+	if(request.method == HTTP_POST) {
+		debugf("Update config");
+		// Update config
+
+		// Network
+		if(request.getPostParameter("SSID").length() > 0) 
+		{
+			cfg.NetworkSSID = request.getPostParameter("SSID");
+			cfg.NetworkPassword = request.getPostParameter("Password");
+		}
+		// Correction
+		if(request.getPostParameter("TZ").length() > 0) {
+			float tz = request.getPostParameter("TZ").toFloat();
+			if (cfg.AddTZ != tz) {
+				cfg.AddTZ = tz;
+				if (cfg.AddTZ < 0 || cfg.AddTZ > 23) {
+					cfg.AddTZ = 0;
+				}
+				SystemClock.setTimeZone(cfg.AddTZ);
+			}
+		}
+		// Low brightness level.
+		if (request.getPostParameter ("BLow").length () > 0) {
+			cfg.BrightnessLow = request.getPostParameter ("BLow").toInt ();
+			if (cfg.BrightnessLow < LedBrightMin || cfg.BrightnessLow > LedBrightMax) {
+				cfg.BrightnessLow = LedBrightMin;
+			}
+		}
+		// Middle brightness level.
+		if (request.getPostParameter ("BMid").length () > 0) {
+			cfg.BrightnessMiddle = request.getPostParameter ("BMid").toInt ();
+			if (cfg.BrightnessMiddle < LedBrightMin || cfg.BrightnessMiddle > LedBrightMax) {
+				cfg.BrightnessMiddle = LedBrightMiddl;
+			}
+		}
+		// High brightness level.
+		if (request.getPostParameter ("BHigh").length () > 0) {
+			cfg.BrightnessHigh = request.getPostParameter ("BHigh").toInt ();
+			if (cfg.BrightnessHigh < LedBrightMin || cfg.BrightnessHigh > LedBrightMax) {
+				cfg.BrightnessHigh = LedBrightMax;
+			}
+		}
+		// Low light level trh.
+		if (request.getPostParameter ("LLow").length () > 0) {
+			cfg.LightTrhLow = request.getPostParameter ("LLow").toInt ();
+			if (cfg.LightTrhLow < MinLightThreshold || cfg.LightTrhLow > MaxLightThreshold) {
+				cfg.LightTrhLow = MinLightThreshold;
+			}
+		}
+		// High light level trh.
+		if (request.getPostParameter ("LHigh").length () > 0) {
+			cfg.LightTrhHigh = request.getPostParameter ("LHigh").toInt ();
+			if (cfg.LightTrhHigh < MinLightThreshold || cfg.LightTrhHigh > MaxLightThreshold) {
+				cfg.LightTrhHigh = MaxLightThreshold;
+			}
+		}
+
+		saveConfig(cfg);
+		response.headers[HTTP_HEADER_LOCATION] = "/";
+	}
+
+	debugf("Send template");
+	TemplateFileStream* tmpl = new TemplateFileStream("config.html");
+	auto& vars = tmpl->variables();
+	vars["SSID"] = cfg.NetworkSSID;
+  vars["TZ"] = String(cfg.AddTZ, 2);
+  vars["LLow"] = String(cfg.LightTrhLow);
+  vars["LHigh"] = String(cfg.LightTrhHigh);
+  vars["BLow"] = String(cfg.BrightnessLow);
+  vars["BMid"] = String(cfg.BrightnessMiddle);
+  vars["BHigh"] = String(cfg.BrightnessHigh);
+	response.sendNamedStream(tmpl);
 }
 
-/*
- * роутер
+/**
+ * @brief Router
  */
-void
-onFile (HttpRequest &request, HttpResponse &response)
+void onFile(HttpRequest& request, HttpResponse& response)
 {
-  String file = request.getPath ();
-  if (file[0] == '/')
-    file = file.substring (1);
-
-  if (file[0] == '.')
-    response.forbidden ();
-  else
-    {
-      response.setCache (86400, true); // It's important to use cache for better performance.
-      response.sendFile (file);
-    }
+	String file = request.uri.getRelativePath();
+
+	if(file[0] == '.')
+		response.code = HTTP_STATUS_FORBIDDEN;
+	else {
+		response.setCache(86400, true); // It's important to use cache for better performance.
+		response.sendFile(file);
+	}
 }
 
 /// API ///
-/*
- * API page.
- */
-void
-onApiDoc (HttpRequest &request, HttpResponse &response)
-{
-  TemplateFileStream *tmpl = new TemplateFileStream ("api.html");
-  auto &vars = tmpl->variables ();
-  vars["IP"] = (
-      WifiStation.isConnected () ?
-          WifiStation.getIP () : WifiAccessPoint.getIP ()).toString ();
-  response.sendTemplate (tmpl);
-}
 
-/*
- * Get json data
- * данные с датчиков выдаём с максимальным разрешением.
- */
-void
-onApiSensors (HttpRequest &request, HttpResponse &response)
+void onApiDoc(HttpRequest& request, HttpResponse& response)
 {
-  JsonObjectStream* stream = new JsonObjectStream ();
-  JsonObject& json = stream->getRoot ();
-  json["status"] = (bool) true;
-  JsonObject& sensors = json.createNestedObject ("sensors");
-  sensors["temperature"] = String (SensorT, 2);
-  sensors["humidity"] = String (SensorH, 2);
-  sensors["heatindex"] = String (SensorHI, 2);
-  sensors["comfortp"] = String (SensorCR, 2);
-  sensors["comforts"] = StrCF.c_str (); // второе место
-  sensors["adcvalue"] = String (system_adc_read ());
-  sensors["vddvalue"] = String (system_get_vdd33 ());
-  time_t now = SystemClock.now ();
-  sensors["datetime"] = String (now);
-  sensors["lastntp"] = String (now - NTPLastUpdate);
-  response.sendJsonObject (stream);
+	TemplateFileStream* tmpl = new TemplateFileStream("api.html");
+	auto& vars = tmpl->variables();
+	vars["IP"] = (WifiStation.isConnected() ? WifiStation.getIP() : WifiAccessPoint.getIP()).toString();
+	response.sendNamedStream(tmpl);
 }
 
-/*
- * Управление выводом. кандидат на удаление.
+/**
+ * @brief Get json data
+ * данные с датчиков выдаём с максимальным разрешением.
  */
-#include "max7219.h"
-void
-onApiControl (HttpRequest &request, HttpResponse &response)
+void onApiSensors(HttpRequest& request, HttpResponse& response)
 {
-  int val = request.getQueryParameter ("bright", "-1").toInt ();
-  if (val < 1)
-    {
-      val = 1;
-    }
-  if (val > 15)
-    {
-      val = 15;
-    }
-
-  MAX7219_writeData (MAX7219_MODE_INTENSITY, val);
-
-  JsonObjectStream* stream = new JsonObjectStream ();
-  JsonObject& json = stream->getRoot ();
-  json["status"] = val;
-  response.sendJsonObject (stream);
+	JsonObjectStream* stream = new JsonObjectStream();
+	JsonObject json = stream->getRoot();
+	json["status"] = (bool)true;
+	JsonObject sensors = json.createNestedObject("sensors");
+
+  sensors["temperature"] = String(SensorT, 2);
+  sensors["humidity"] = String(SensorH, 2);
+  sensors["heatindex"] = String(SensorHI, 2);
+  sensors["comfortp"] = String(SensorCR, 2);
+  sensors["comforts"] = StrCF.c_str (); //??? второе место
+  sensors["adcvalue"] = String(system_adc_read ());
+  sensors["vddvalue"] = String(system_get_vdd33 ());
+  time_t now = SystemClock.now();
+  sensors["datetime"] = String(now);
+  sensors["lastntp"] = String(now - NTPLastUpdate);
+
+	response.sendDataStream(stream, MIME_JSON);
 }
 
-void
-startWebServer ()
+void startWebServer()
 {
-  if (serverStarted)
-    return;
-
-  server.listen (80);
-  server.addPath ("/", onIndex);
-  server.addPath ("/api", onApiDoc);
-  server.addPath ("/api/sensors", onApiSensors);
-  server.addPath ("/api/control", onApiControl);
-  server.addPath ("/config", onConfiguration);
-  server.setDefaultHandler (onFile);
-  serverStarted = true;
-  /*
-   if (WifiStation.isEnabled())
-   debugf("STA: %s", WifiStation.getIP().toString().c_str());
-   if (WifiAccessPoint.isEnabled())
-   debugf("AP: %s", WifiAccessPoint.getIP().toString().c_str());
-   */
+	if(serverStarted)
+		return;
+
+	server.listen(80);
+	server.paths.set("/", onIndex);
+	server.paths.set("/api", onApiDoc);
+	server.paths.set("/api/sensors", onApiSensors);
+	server.paths.set("/config", onConfiguration);
+	server.paths.setDefault(onFile);
+	serverStarted = true;
+
+	if(WifiStation.isEnabled())
+		debugf("STA: %s", WifiStation.getIP().toString().c_str());
+	if(WifiAccessPoint.isEnabled())
+		debugf("AP: %s", WifiAccessPoint.getIP().toString().c_str());
 }

+ 3 - 0
component.mk

@@ -0,0 +1,3 @@
+ARDUINO_LIBRARIES := LiquidCrystal DHTesp ArduinoJson6
+HWCONFIG := spiffs-2m
+SPIFF_FILES = web

+ 0 - 1
dump.bat

@@ -1 +0,0 @@
-C:\Espressif\xtensa-lx106-elf\bin\xtensa-lx106-elf-objdump -S .\out\build\app.out > .\out\app.asm

+ 31 - 45
include/configuration.h

@@ -1,62 +1,48 @@
 #ifndef INCLUDE_CONFIGURATION_H_
 #define INCLUDE_CONFIGURATION_H_
 
-#include <user_config.h>
-#include <SmingCore/SmingCore.h>
+#include <SmingCore.h>
+#include <JsonObjectStream.h>
 
 // If you want, you can define WiFi settings globally in Eclipse Environment Variables
 #ifndef WIFI_SSID
-#define WIFI_SSID "Heaven-WiFi" // Put you SSID and Password here
-#define WIFI_PWD "Heaven-32847"
+#define WIFI_SSID "PleaseEnterSSID" // Put your SSID and password here
+#define WIFI_PWD "PleaseEnterPass"
 #endif
 
-#define PinSet(pin)		GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, ((uint16_t)1<<(pin)))
-#define PinRes(pin)		GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, ((uint16_t)1<<(pin)))
-#define PinOut(pin, val)	GPIO_REG_WRITE((((val != LOW) ? GPIO_OUT_W1TS_ADDRESS : GPIO_OUT_W1TC_ADDRESS)), (1<<pin));
-#define Pin16Set		WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xffffffff))
-#define Pin16Res		WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xfffffffe))
-#define Pin16Out(pin, val)	WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xfffffffe) | (uint32)(val & 1));
+#define MinLightThreshold		0
+#define MaxLightThreshold		1023
 
-// Pin for communication with DHT sensor
-#define DHT_PIN 2
-
-// MAX7219
-#define PIN_DIN			14
-#define PIN_CLK			13
-#define PIN_LOAD		12
-#define MAX7219_DIGITS		8
-#define MAX7219_DIG_MASK	0xDB
-// ^^ reverse of -- 11011 011 -- без BCD декодирования 2, 5
+#define LedBrightMin				1
+#define LedBrightMiddl			3
+#define LedBrightMax				7
 
 #define CLOCK_CONFIG_FILE ".clock.conf" // leading point for security reasons :)
 
-struct ClockConfig
-{
-    ClockConfig ()
-    {
-        AddTZ = 2;
-        LightTrhLow = 341;
-        LightTrhHigh = 683;
-        BrightnessLow = 1;
-        BrightnessMiddle = 7;
-        BrightnessHigh = 15;
-    }
-
-    String NetworkSSID;
-    String NetworkPassword;
-
-    float AddTZ; // TimeZone - local time offset
-    uint16_t LightTrhLow; // Low Light level
-    uint16_t LightTrhHigh; // High Light level
-    int8_t BrightnessLow; // Low LED brightness level
-    int8_t BrightnessMiddle; // Middle LED brightness level
-    int8_t BrightnessHigh; // High LED brightness level
+struct ClockConfig {
+	ClockConfig()
+	{
+		AddTZ = 2;
+		LightTrhLow = 341;
+		LightTrhHigh = 683;
+		BrightnessLow = 1;
+		BrightnessMiddle = 7;
+		BrightnessHigh = 15;
+	}
+
+	String NetworkSSID;
+	String NetworkPassword;
+
+	float AddTZ; // TimeZone - local time offset
+	uint16_t LightTrhLow; // Low Light level
+	uint16_t LightTrhHigh; // High Light level
+	int8_t BrightnessLow; // Low LED brightness level
+	int8_t BrightnessMiddle; // Middle LED brightness level
+	int8_t BrightnessHigh; // High LED brightness level
 };
 
-ClockConfig
-loadConfig ();
-void
-saveConfig (ClockConfig& cfg);
+ClockConfig loadConfig();
+void saveConfig(ClockConfig& cfg);
 
 extern ClockConfig ActiveConfig;
 

+ 0 - 167
include/max7219.h

@@ -1,167 +0,0 @@
-/*
- * max7219.h
- *
- *  Created on: 29 січ. 2016
- *      Author: shilov
- */
-
-#ifndef INCLUDE_MAX7219_H_
-#define INCLUDE_MAX7219_H_
-
-// symbols
-// Для BCD
-#define MAX7219_CHAR_MINUS	    0x0A
-#define MAX7219_CHAR_E          0x0B
-#define MAX7219_CHAR_H          0x0C
-#define MAX7219_CHAR_L          0x0D
-#define MAX7219_CHAR_P          0x0E
-#define MAX7219_CHAR_BLANK      0x0F
-// без кодирования
-#define SYM_Gradus				0x63
-#define SYM_LGradus				0x1D
-#define SYM_Temp				0x0F
-#define SYM_Minus				0x01
-#define SYM_Minus2L				0x09
-#define SYM_Minus2H				0x41
-#define SYM_Minus3				0x49
-#define SYM_BLANK				0x00
-#define SYM_FULL				0xFF
-#define SYM_H					0x37
-#define SYM_H_SM				0x17
-#define SYM_C					0x4E
-#define SYM_C_sm				0x0D
-
-#define MAX7219_ON				0x01
-#define MAX7219_OFF				0x00
-#define MAX7219_BRIGHT			0x08
-
-// режимы работы
-#define MAX7219_MODE_DECODE		0x09
-#define MAX7219_MODE_INTENSITY	0x0A
-#define MAX7219_MODE_SCAN_LIMIT	0x0B
-#define MAX7219_MODE_POWER		0x0C
-#define MAX7219_MODE_TEST		0x0F
-#define MAX7219_MODE_NOOP		0x00
-
-// соответствие разрядов
-#define MAX7219_DIGIT0			0x01
-#define MAX7219_DIGIT1			0x02
-#define MAX7219_DIGIT2			0x03
-#define MAX7219_DIGIT3			0x04
-#define MAX7219_DIGIT4			0x05
-#define MAX7219_DIGIT5			0x06
-#define MAX7219_DIGIT6			0x07
-#define MAX7219_DIGIT7			0x08
-
-// соответсвие бит сегментам
-#define SEG_A					6
-#define SEG_B					5
-#define SEG_C					4
-#define SEG_D					3
-#define SEG_E					2
-#define SEG_F					1
-#define SEG_G					0
-#define SEG_DP					7
-
-/*
- * Цифры для секунд "Pseudo Gray Code"
- *   0   1     2      3    4      5     6     7     8      9
- * │    ┌──   ────   ───┐    │  │   │  │  │     │        │
- * │    │               │    │  │   │  └──┘  ───┘  ────  └───
- */
-// Коды GRAY для десятков секунд
-#define SYM_GRAY_0x			0x02
-#define SYM_GRAY_1x			0x42
-#define SYM_GRAY_2x			0x40
-#define SYM_GRAY_3x			0x60
-#define SYM_GRAY_4x			0x20
-#define SYM_GRAY_5x			0x22
-const uint8_t max7219_grayH[6] = {
-	SYM_GRAY_0x,
-	SYM_GRAY_1x,
-	SYM_GRAY_2x,
-	SYM_GRAY_3x,
-	SYM_GRAY_4x,
-	SYM_GRAY_5x
-};
-
-// Коды GRAY для единиц секунд
-#define SYM_GRAY_x0			0x04
-#define SYM_GRAY_x1			0x05
-#define SYM_GRAY_x2			0x01
-#define SYM_GRAY_x3			0x11
-#define SYM_GRAY_x4			0x10
-#define SYM_GRAY_x5			0x14
-#define SYM_GRAY_x6			0x1C
-#define SYM_GRAY_x7			0x18
-#define SYM_GRAY_x8			0x08
-#define SYM_GRAY_x9			0x0C
-const uint8_t max7219_grayL[10] = {
-	SYM_GRAY_x0,
-	SYM_GRAY_x1,
-	SYM_GRAY_x2,
-	SYM_GRAY_x3,
-	SYM_GRAY_x4,
-	SYM_GRAY_x5,
-	SYM_GRAY_x6,
-	SYM_GRAY_x7,
-	SYM_GRAY_x8,
-	SYM_GRAY_x9
-};
-// final second code
-#define SYM_GRAY_CODE(sec)	(max7219_grayH[sec/10] | max7219_grayL[sec%10])
-
-/*
- * Цифры для секунд "Pseudo Bin Code"
- *   0   1   2      3     4     5     6     7     8     9
- *     │    ────   ┌──      │  │  │  ───┐  ┌──┐        │
- *     │           │        │  │  │     │  │  │  ────  └───
- */
-// Коды BIN для десятков секунд
-#define SYM_BIN_0x			0x00
-#define SYM_BIN_1x			0x02
-#define SYM_BIN_2x			0x40
-#define SYM_BIN_3x			0x42
-#define SYM_BIN_4x			0x20
-#define SYM_BIN_5x			0x22
-const uint8_t max7219_binH[6] = {
-	SYM_BIN_0x,
-	SYM_BIN_1x,
-	SYM_BIN_2x,
-	SYM_BIN_3x,
-	SYM_BIN_4x,
-	SYM_BIN_5x
-};
-
-// Коды BIN для единиц секунд
-#define SYM_BIN_x0			0x00
-#define SYM_BIN_x1			0x04
-#define SYM_BIN_x2			0x01
-#define SYM_BIN_x3			0x05
-#define SYM_BIN_x4			0x10
-#define SYM_BIN_x5			0x14
-#define SYM_BIN_x6			0x11
-#define SYM_BIN_x7			0x15
-#define SYM_BIN_x8			0x08
-#define SYM_BIN_x9			0x0C
-const uint8_t max7219_BINL[10] = {
-	SYM_BIN_x0,
-	SYM_BIN_x1,
-	SYM_BIN_x2,
-	SYM_BIN_x3,
-	SYM_BIN_x4,
-	SYM_BIN_x5,
-	SYM_BIN_x6,
-	SYM_BIN_x7,
-	SYM_BIN_x8,
-	SYM_BIN_x9
-};
-// final second BIN code
-#define SYM_BIN_CODE(sec)	(max7219_binH[sec/10] | max7219_binL[sec%10])
-
-
-void MAX7219_writeData (uint8_t data_register, uint8_t data);
-void MAX7219_Init (void);
-void MAX7219_FillMinus(void);
-
-#endif /* INCLUDE_MAX7219_H_ */

+ 45 - 0
include/tm1650.h

@@ -0,0 +1,45 @@
+#ifndef INCLUDE_TM1650_H_
+#define INCLUDE_TM1650_H_
+
+#define LED_NUM   4
+
+typedef enum {
+  Sym_0 = 0x3f,
+  Sym_1 = 0x06,
+  Sym_2 = 0x5b,
+  Sym_3 = 0x4f,
+  Sym_4 = 0x66,
+  Sym_5 = 0x6d,
+  Sym_6 = 0x7d,
+  Sym_7 = 0x07,
+  Sym_8 = 0x7f,
+  Sym_9 = 0x6f,
+  Sym_A = 0x77,
+  Sym_B = 0x7c,
+  Sym_C = 0x39,
+  Sym_D = 0x5e,
+  Sym_E = 0x79,
+  Sym_F = 0x71,
+  Sym_Minus = 0x40,
+  Sym_Dot = 0x80
+} tm1650_sym_t;
+
+typedef enum {
+  Dig_1 = 0x0,
+  Dig_2 = 0x1,
+  Dig_3 = 0x2,
+  Dig_4 = 0x3,
+} tm1650_pos_t;
+
+/* Exported Functions */
+void TM1650_Init(void);
+void TM1650_Out(uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4);
+void TM1650_Out1(tm1650_sym_t value);
+void TM1650_Out2(tm1650_sym_t value);
+void TM1650_Out3(tm1650_sym_t value);
+void TM1650_Out4(tm1650_sym_t value);
+void TM1650_DotSet(tm1650_pos_t pos);
+void TM1650_DotRes(tm1650_pos_t pos);
+void TM1650_Bright(uint8_t bright);
+
+#endif /* INCLUDE_TM1650_H_ */

+ 0 - 46
include/user_config.h

@@ -1,46 +0,0 @@
-#ifndef __USER_CONFIG_H__
-#define __USER_CONFIG_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-// UART config
-#define SERIAL_BAUD_RATE 115200
-
-// ESP SDK config
-#define LWIP_OPEN_SRC
-#define USE_US_TIMER
-
-// Default types
-#define __CORRECT_ISO_CPP_STDLIB_H_PROTO
-#include <limits.h>
-#include <stdint.h>
-
-// Override c_types.h include and remove buggy espconn
-#define _C_TYPES_H_
-#define _NO_ESPCON_
-
-// Updated, compatible version of c_types.h
-// Just removed types declared in <stdint.h>
-#include <espinc/c_types_compatible.h>
-
-// System API declarations
-#include <esp_systemapi.h>
-
-// C++ Support
-#include <esp_cplusplus.h>
-// Extended string conversion for compatibility
-#include <stringconversion.h>
-// Network base API
-#include <espinc/lwip_includes.h>
-
-// Beta boards
-#define BOARD_ESP01
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 1 - 4
include/webserver.h

@@ -1,9 +1,6 @@
 #ifndef INCLUDE_WEBSERVER_H_
 #define INCLUDE_WEBSERVER_H_
 
-void
-startWebServer ();
-void
-downloadContentFiles ();
+void startWebServer();
 
 #endif /* INCLUDE_WEBSERVER_H_ */