Skip to content

Commit 88648a8

Browse files
committed
v5.1.1
5.1.1 20170517 * Allow command FullTopic in group mode * Prepare for more use of RTC memory * Add independant WS2812 led string power control (#386, #390) * Add command Counter<x> to control up to four GPIO falling edge interrupt counters or timers (#459) * Add command CounterType<x> to select between pulse counting or pulse timing * Add command CounterDebounce to select global counter debounce time in mSec
1 parent afc7b96 commit 88648a8

13 files changed

+201
-27
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## Sonoff-Tasmota
22
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
33

4-
Current version is **5.1.0** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
4+
Current version is **5.1.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
55

66
### **** ATTENTION Version 5.x.x specific information ****
77

@@ -44,5 +44,9 @@ The following devices are supported:
4444
- [iTead Motor Clockwise/Anticlockwise](https://www.itead.cc/smart-home/motor-reversing-wifi-wireless-switch.html)
4545
- [Electrodragon IoT Relay Board](http://www.electrodragon.com/product/wifi-iot-relay-board-based-esp8266/)
4646

47+
Future support
48+
- [iTead Sonoff 4CH Pro](https://www.itead.cc/sonoff-4ch-pro.html)
49+
50+
4751
<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonofftoucheu.jpg" height="280" align="left" />
4852
<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoff4ch.jpg" height="250" align="right" />

api/arduino/sonoff.ino.bin

1.41 KB
Binary file not shown.

sonoff/_releasenotes.ino

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
/* 5.1.0 20170513
1+
/* 5.1.1 20170517
2+
* Allow command FullTopic in group mode
3+
* Prepare for more use of RTC memory
4+
* Add independant WS2812 led string power control (#386, #390)
5+
* Add command Counter<x> to control up to four GPIO falling edge interrupt counters or timers (#459)
6+
* Add command CounterType<x> to select between pulse counting or pulse timing
7+
* Add command CounterDebounce to select global counter debounce time in mSec
8+
*
9+
* 5.1.0 20170513
210
* Fix Offline/Removal of retained topic when FullTopic is changed
311
* Add FullTopic to MQTT Configuration and Information web pages
412
* Add license model GPLv3 (#188)

sonoff/settings.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,20 @@ struct SYSCFG {
196196
// 5.0.4a
197197
char mqtt_fulltopic[101];
198198

199+
// 5.1.1
200+
unsigned long pCounter[4];
201+
uint16_t pCounterType;
202+
uint16_t pCounterDebounce;
203+
199204
} sysCfg;
200205

201206
struct RTCMEM {
202207
uint16_t valid;
203208
byte osw_flag;
204-
byte nu1;
209+
uint8_t power;
205210
unsigned long hlw_kWhtoday;
206211
unsigned long hlw_kWhtotal;
212+
unsigned long pCounter[4];
207213
} rtcMem;
208214

209215
// See issue https://github.com/esp8266/Arduino/issues/2913

sonoff/settings.ino

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ void RTC_Load()
5959
if (rtcMem.valid != RTC_MEM_VALID) {
6060
memset(&rtcMem, 0x00, sizeof(RTCMEM));
6161
rtcMem.valid = RTC_MEM_VALID;
62+
rtcMem.power = sysCfg.power;
63+
rtcMem.hlw_kWhtoday = sysCfg.hlw_kWhtoday;
64+
rtcMem.hlw_kWhtotal = sysCfg.hlw_kWhtotal;
65+
for (byte i = 0; i < 4; i++) {
66+
rtcMem.pCounter[i] = sysCfg.pCounter[i];
67+
}
6268
RTC_Save();
6369
}
6470
_rtcHash = getRtcHash();
@@ -633,6 +639,14 @@ void CFG_Delta()
633639
if (sysCfg.version < 0x05000600) {
634640
sysCfg.mqtt_retry = MQTT_RETRY_SECS;
635641
}
642+
if (sysCfg.version < 0x05010100) {
643+
sysCfg.pCounterType = 0;
644+
sysCfg.pCounterDebounce = 0;
645+
for (byte i = 0; i < 4; i++) {
646+
sysCfg.pCounter[i] = 0;
647+
rtcMem.pCounter[i] = 0;
648+
}
649+
}
636650
sysCfg.version = VERSION;
637651
}
638652
}

sonoff/sonoff.ino

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,15 @@
1616
You should have received a copy of the GNU General Public License
1717
along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
*/
19-
20-
/*
21-
====================================================
19+
/*====================================================
2220
Prerequisites:
2321
- Change libraries/PubSubClient/src/PubSubClient.h
2422
#define MQTT_MAX_PACKET_SIZE 512
2523
2624
- Select IDE Tools - Flash size: "1M (no SPIFFS)"
27-
====================================================
28-
*/
25+
====================================================*/
2926

30-
#define VERSION 0x05010000 // 5.1.0
27+
#define VERSION 0x05010100 // 5.1.1
3128

3229
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
3330
enum week_t {Last, First, Second, Third, Fourth};
@@ -254,6 +251,7 @@ uint8_t blink_powersave; // Blink start power save state
254251
uint16_t mqtt_cmnd_publish = 0; // ignore flag for publish command
255252
uint8_t latching_power = 0; // Power state at latching start
256253
uint8_t latching_relay_pulse = 0; // Latching relay pulse timer
254+
unsigned long pTimeLast[4]; // Last counter time in milli seconds
257255

258256
#ifdef USE_MQTT_TLS
259257
WiFiClientSecure espClient; // Wifi Secure Client
@@ -706,7 +704,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
706704
}
707705
snprintf_P(svalue, ssvalue, PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
708706
}
709-
else if (!grpflg && !strcmp_P(type,PSTR("FULLTOPIC"))) {
707+
else if (!strcmp_P(type,PSTR("FULLTOPIC"))) {
710708
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_fulltopic))) {
711709
for (i = 0; i <= data_len; i++) {
712710
if ((dataBuf[i] == '+') || (dataBuf[i] == '#') || (dataBuf[i] == ' ')) {
@@ -1213,6 +1211,27 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
12131211
}
12141212
snprintf_P(svalue, sizeof(svalue), PSTR("%s}}"),svalue);
12151213
}
1214+
else if (!strcmp_P(type,PSTR("COUNTER")) && (index > 0) && (index <= 4)) {
1215+
if ((data_len > 0) && (pin[GPIO_CNTR1 + index -1] < 99)) {
1216+
rtcMem.pCounter[index -1] = payload16;
1217+
sysCfg.pCounter[index -1] = payload16;
1218+
}
1219+
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Counter%d\":%d}"), index, rtcMem.pCounter[index -1]);
1220+
}
1221+
else if (!strcmp_P(type,PSTR("COUNTERTYPE")) && (index > 0) && (index <= 4)) {
1222+
if ((data_len > 0) && (payload >= 0) && (payload <= 1) && (pin[GPIO_CNTR1 + index -1] < 99)) {
1223+
bitWrite(sysCfg.pCounterType, index -1, payload &1);
1224+
rtcMem.pCounter[index -1] = 0;
1225+
sysCfg.pCounter[index -1] = 0;
1226+
}
1227+
snprintf_P(svalue, sizeof(svalue), PSTR("{\"CounterType%d\":%d}"), index, bitRead(sysCfg.pCounterType, index -1));
1228+
}
1229+
else if (!strcmp_P(type,PSTR("COUNTERDEBOUNCE"))) {
1230+
if ((data_len > 0) && (payload16 < 32001) && (pin[GPIO_CNTR1 + index -1] < 99)) {
1231+
sysCfg.pCounterDebounce = payload16;
1232+
}
1233+
snprintf_P(svalue, sizeof(svalue), PSTR("{\"CounterDebounce\":%d}"), sysCfg.pCounterDebounce);
1234+
}
12161235
else if (!strcmp_P(type,PSTR("SLEEP"))) {
12171236
if ((data_len > 0) && (payload >= 0) && (payload < 251)) {
12181237
if ((!sysCfg.sleep && payload) || (sysCfg.sleep && !payload)) {
@@ -1527,7 +1546,9 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
15271546
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Command\":\"Unknown\"}"));
15281547
type = (char*)topicBuf;
15291548
}
1530-
mqtt_publish_topic_P(5, type, svalue);
1549+
if (svalue[0] != '\0') {
1550+
mqtt_publish_topic_P(5, type, svalue);
1551+
}
15311552
}
15321553

15331554
/********************************************************************************************/
@@ -1786,6 +1807,12 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
17861807
*djson = 1;
17871808
}
17881809
}
1810+
for (byte i = 0; i < 4; i++) {
1811+
if (pin[GPIO_CNTR1 +i] < 99) {
1812+
snprintf_P(svalue, ssvalue, PSTR("%s, {\"Counter%d\":%d}"), svalue, i +1, rtcMem.pCounter[i]);
1813+
*djson = 1;
1814+
}
1815+
}
17891816
#ifndef USE_ADC_VCC
17901817
if (pin[GPIO_ADC0] < 99) {
17911818
snprintf_P(svalue, ssvalue, PSTR("%s, \"AnalogInput0\":%d"), svalue, analogRead(A0));
@@ -2187,6 +2214,9 @@ void stateloop()
21872214
}
21882215
break;
21892216
case (STATES/10)*4:
2217+
if (rtc_midnight_now()) {
2218+
counter_savestate();
2219+
}
21902220
if (savedatacounter) {
21912221
savedatacounter--;
21922222
if (savedatacounter <= 0) {
@@ -2221,6 +2251,7 @@ void stateloop()
22212251
if (hlw_flg) {
22222252
hlw_savestate();
22232253
}
2254+
counter_savestate();
22242255
CFG_Save();
22252256
restartflag--;
22262257
if (restartflag <= 0) {
@@ -2436,7 +2467,8 @@ void GPIO_init()
24362467
analogWrite(pin[GPIO_PWM1 +i], sysCfg.pwmvalue[i]);
24372468
}
24382469
}
2439-
2470+
counter_init();
2471+
24402472
if (EXS_RELAY == sysCfg.module) {
24412473
setLatchingRelay(0,2);
24422474
setLatchingRelay(1,2);
@@ -2469,7 +2501,8 @@ void GPIO_init()
24692501

24702502
#ifdef USE_WS2812
24712503
if (pin[GPIO_WS2812] < 99) {
2472-
ws2812_init();
2504+
Maxdevice++;
2505+
ws2812_init(Maxdevice);
24732506
}
24742507
#endif // USE_WS2812
24752508

sonoff/sonoff_template.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ enum upins_t {
5757
GPIO_PWM3, // Red (swapped with Blue from original)
5858
GPIO_PWM4, // Green
5959
GPIO_PWM5, // Blue (swapped with Red from original)
60+
GPIO_CNTR1,
61+
GPIO_CNTR2,
62+
GPIO_CNTR3,
63+
GPIO_CNTR4,
6064
GPIO_SENSOR_END };
6165

6266
// Text in webpage Module Parameters and commands GPIOS and GPIO
@@ -98,7 +102,11 @@ const char sensors[GPIO_SENSOR_END][9] PROGMEM = {
98102
"PWM2",
99103
"PWM3",
100104
"PWM4",
101-
"PWM5"
105+
"PWM5",
106+
"Counter1",
107+
"Counter2",
108+
"Counter3",
109+
"Counter4"
102110
};
103111

104112
// Programmer selectable GPIO functionality offset by user selectable GPIOs

sonoff/support.ino

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ uint32_t dsttime = 0;
682682
uint32_t stdtime = 0;
683683
uint32_t ntptime = 0;
684684
uint32_t midnight = 1451602800;
685+
uint8_t midnightnow = 0;
685686

686687
String getBuildDateTime()
687688
{
@@ -867,6 +868,15 @@ uint32_t rtc_midnight()
867868
return midnight;
868869
}
869870

871+
boolean rtc_midnight_now()
872+
{
873+
boolean mnflg = midnightnow;
874+
if (mnflg) {
875+
midnightnow = 0;
876+
}
877+
return mnflg;
878+
}
879+
870880
void rtc_second()
871881
{
872882
char log[LOGSZ];
@@ -919,6 +929,7 @@ void rtc_second()
919929
breakTime(loctime, rtcTime);
920930
if (!rtcTime.Hour && !rtcTime.Minute && !rtcTime.Second && rtcTime.Valid) {
921931
midnight = loctime;
932+
midnightnow = 1;
922933
}
923934
rtcTime.Year += 1970;
924935
}
@@ -936,6 +947,70 @@ void rtc_init()
936947
tickerRTC.attach(1, rtc_second);
937948
}
938949

950+
/*********************************************************************************************\
951+
* Counter sensors (water meters, electricity meters etc.)
952+
\*********************************************************************************************/
953+
954+
void counter_update(byte index)
955+
{
956+
// char log[LOGSZ];
957+
958+
unsigned long pTime = millis() - pTimeLast[index -1];
959+
if (pTime > sysCfg.pCounterDebounce) {
960+
pTimeLast[index -1] = millis();
961+
if (bitRead(sysCfg.pCounterType, index -1)) {
962+
rtcMem.pCounter[index -1] = pTime;
963+
} else {
964+
rtcMem.pCounter[index -1]++;
965+
}
966+
967+
// snprintf_P(log, sizeof(log), PSTR("CNTR: Interrupt %d"), index);
968+
// addLog(LOG_LEVEL_DEBUG, log);
969+
}
970+
}
971+
972+
void counter_update1()
973+
{
974+
counter_update(1);
975+
}
976+
977+
void counter_update2()
978+
{
979+
counter_update(2);
980+
}
981+
982+
void counter_update3()
983+
{
984+
counter_update(3);
985+
}
986+
987+
void counter_update4()
988+
{
989+
counter_update(4);
990+
}
991+
992+
void counter_savestate()
993+
{
994+
for (byte i = 0; i < 4; i++) {
995+
if (pin[GPIO_CNTR1 +i] < 99) {
996+
sysCfg.pCounter[i] = rtcMem.pCounter[i];
997+
}
998+
}
999+
}
1000+
1001+
void counter_init()
1002+
{
1003+
typedef void (*function) () ;
1004+
function counter_callbacks[] = { counter_update1, counter_update2, counter_update3, counter_update4 };
1005+
1006+
for (byte i = 0; i < 4; i++) {
1007+
if (pin[GPIO_CNTR1 +i] < 99) {
1008+
pinMode(pin[GPIO_CNTR1 +i], INPUT_PULLUP);
1009+
attachInterrupt(pin[GPIO_CNTR1 +i], counter_callbacks[i], FALLING);
1010+
}
1011+
}
1012+
}
1013+
9391014
/*********************************************************************************************\
9401015
* Miscellaneous
9411016
\*********************************************************************************************/

sonoff/user_config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@
165165

166166
#define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+8k code, +1k mem) - Disable by //
167167
#define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB)
168-
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial TXD) (+1k mem)
168+
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem)
169169
// When USE_WS2812_DMA is enabled expect Exceptions on Pow
170170

171171
/*********************************************************************************************\

sonoff/webserver.ino

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ const char HTTP_TABLE100[] PROGMEM =
250250
"<table style='width:100%'>";
251251
const char HTTP_COUNTER[] PROGMEM =
252252
"<br/><div id='t' name='t' style='text-align:center;'></div>";
253+
const char HTTP_SNS_COUNTER[] PROGMEM =
254+
"<tr><th>Counter%d</th><td>%d</td></tr>";
253255
const char HTTP_SNS_TEMP[] PROGMEM =
254256
"<tr><th>%s Temperature</th><td>%s&deg;%c</td></tr>";
255257
const char HTTP_SNS_HUM[] PROGMEM =
@@ -447,7 +449,7 @@ void handleRoot()
447449

448450
void handleAjax2()
449451
{
450-
char svalue[16];
452+
char svalue[80];
451453

452454
if (strlen(webServer->arg("o").c_str())) {
453455
do_cmnd_power(atoi(webServer->arg("o").c_str()), 2);
@@ -458,6 +460,12 @@ void handleAjax2()
458460
}
459461

460462
String tpage = "";
463+
for (byte i = 0; i < 4; i++) {
464+
if (pin[GPIO_CNTR1 +i] < 99) {
465+
snprintf_P(svalue, sizeof(svalue), HTTP_SNS_COUNTER, i+1, rtcMem.pCounter[i]);
466+
tpage += svalue;
467+
}
468+
}
461469
if (hlw_flg) {
462470
tpage += hlw_webPresent();
463471
}

0 commit comments

Comments
 (0)