3.9.14 20170211
* Add False and True as alternatives for 0/Off and 1/On (#49)
* Fix Status10 JSON format (#52)
* Fix DS18x20 using OneWire library (#53)
This commit is contained in:
arendst 2017-02-11 15:06:23 +01:00
parent 3a07c9bf6a
commit bb5251c2c8
8 changed files with 129 additions and 97 deletions

View File

@ -1,7 +1,7 @@
## Sonoff-Tasmota
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.
Current version is **3.9.13** - See ```sonoff/_releasenotes.ino``` for change information.
Current version is **3.9.14** - See ```sonoff/_releasenotes.ino``` for change information.
- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic.
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.

Binary file not shown.

View File

@ -1,4 +1,9 @@
/* 3.9.13 20170210
/* 3.9.14 20170211
* Add False and True as alternatives for 0/Off and 1/On (#49)
* Fix Status10 JSON format (#52)
* Fix DS18x20 using OneWire library (#53)
*
* 3.9.13 20170210
* Add FlashChipSize to Status 4
* Removed redundant DHT2 option and code
* Add Sonoff SV GPIO pin 05 configuration (#40)

View File

@ -10,7 +10,7 @@
* ====================================================
*/
#define VERSION 0x03090D00 // 3.9.13
#define VERSION 0x03090E00 // 3.9.14
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
enum week_t {Last, First, Second, Third, Fourth};
@ -46,10 +46,6 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#define MQTT_FINGERPRINT "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07"
#endif
#ifndef USE_DHT2
#define USE_DHT // Default DHT11 sensor needs no external library
#endif
#ifndef USE_DS18x20
#define USE_DS18B20 // Default DS18B20 sensor needs no external library
#endif
@ -59,6 +55,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#endif
#define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address>
#define USE_DHT // Default DHT11 sensor needs no external library
#define CONFIG_FILE_SIGN 0xA5 // Configuration file signature
#define CONFIG_FILE_XOR 0x5A // Configuration file xor (0 = No Xor)
@ -1147,8 +1144,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
if (!strcmp(dataBufUc,"?")) data_len = 0;
int16_t payload = atoi(dataBuf); // -32766 - 32767
uint16_t payload16 = atoi(dataBuf); // 0 - 65535
if (!strcmp(dataBufUc,"OFF") || !strcmp(dataBufUc,"STOP")) payload = 0;
if (!strcmp(dataBufUc,"ON") || !strcmp(dataBufUc,"START") || !strcmp(dataBufUc,"USER")) payload = 1;
if (!strcmp(dataBufUc,"OFF") || !strcmp(dataBufUc,"FALSE") || !strcmp(dataBufUc,"STOP")) payload = 0;
if (!strcmp(dataBufUc,"ON") || !strcmp(dataBufUc,"TRUE") || !strcmp(dataBufUc,"START") || !strcmp(dataBufUc,"USER")) payload = 1;
if (!strcmp(dataBufUc,"TOGGLE") || !strcmp(dataBufUc,"ADMIN")) payload = 2;
if (!strcmp(dataBufUc,"BLINK")) payload = 3;
if (!strcmp(dataBufUc,"BLINKOFF")) payload = 4;
@ -1272,7 +1269,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
else if (!strcmp(type,"GPIO") && (index < MAX_GPIO_PIN)) {
mytmplt cmodule;
memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
if ((data_len > 0) && (cmodule.gp.io[index] == GPIO_USER) && (payload >= GPIO_SENSOR_START) && (payload < GPIO_SENSOR_END)) {
if ((data_len > 0) && (cmodule.gp.io[index] == GPIO_USER) && (payload >= 0) && (payload < GPIO_SENSOR_END)) {
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if ((cmodule.gp.io[i] == GPIO_USER) && (sysCfg.my_module.gp.io[i] == payload)) sysCfg.my_module.gp.io[i] = 0;
}
@ -1928,7 +1925,7 @@ void publish_status(uint8_t payload)
uint8_t djson = 0;
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusSNS\":"));
sensors_mqttPresent(svalue, sizeof(svalue), &djson);
if (!djson) snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
mqtt_publish_topic_P(option, PSTR("STATUS10"), svalue);
}
}
@ -1948,9 +1945,9 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
ds18x20_mqttPresent(svalue, ssvalue, djson);
#endif // USE_DS18x20
}
#if defined(USE_DHT) || defined(USE_DHT2)
#ifdef USE_DHT
if (dht_type) dht_mqttPresent(svalue, ssvalue, djson);
#endif // USE_DHT/2
#endif // USE_DHT
#ifdef USE_I2C
if (i2c_flg) {
#ifdef USE_HTU
@ -2019,7 +2016,7 @@ void every_second()
if (sysCfg.tele_period) {
tele_period++;
if (tele_period == sysCfg.tele_period -1) {
if (pin[GPIO_DSB]) {
if (pin[GPIO_DSB] < 99) {
#ifdef USE_DS18B20
dsb_readTempPrep();
#endif // USE_DS18B20
@ -2388,6 +2385,7 @@ void GPIO_init()
if (sysCfg.my_module.gp.io[i] > GPIO_NONE) my_module.gp.io[i] = sysCfg.my_module.gp.io[i];
if ((def_module.gp.io[i] > GPIO_NONE) && (def_module.gp.io[i] < GPIO_USER)) my_module.gp.io[i] = def_module.gp.io[i];
}
for (byte i = 0; i < GPIO_MAX; i++) pin[i] = 99;
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
mpin = my_module.gp.io[i];
@ -2404,13 +2402,13 @@ void GPIO_init()
led_inverted[mpin - GPIO_LED1_INV] = 1;
mpin -= 4;
}
else if (mpin == GPIO_DHT11) dht_type = DHT11;
else if (mpin == GPIO_DHT11) dht_type = mpin;
else if (mpin == GPIO_DHT21) {
dht_type = DHT21;
dht_type = mpin;
mpin--;
}
else if (mpin == GPIO_DHT22) {
dht_type = DHT22;
dht_type = mpin;
mpin -= 2;
}
pin[mpin] = i;
@ -2460,9 +2458,13 @@ void GPIO_init()
hlw_flg = ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99));
if (hlw_flg) hlw_init();
#if defined(USE_DHT) || defined(USE_DHT2)
#ifdef USE_DHT
if (dht_type) dht_init();
#endif // USE_DHT/2
#endif // USE_DHT
#ifdef USE_DS18x20
if (pin[GPIO_DSB] < 99) ds18x20_init();
#endif // USE_DS18x20
#ifdef USE_I2C
i2c_flg = ((pin[GPIO_I2C_SCL] < 99) && (pin[GPIO_I2C_SDA] < 99));

View File

@ -2,73 +2,95 @@
* Template parameters
\*********************************************************************************************/
#define GPIO_SENSOR_START 0
#define GPIO_NONE 0 // Not used
#define GPIO_DHT11 1 // DHT11
#define GPIO_DHT21 2 // DHT21
#define GPIO_AM2301 2 // AM2301
#define GPIO_DHT22 3 // DHT22
#define GPIO_AM2302 3 // AM2302
#define GPIO_AM2321 3 // AM2321
#define GPIO_DSB 4 // Single wire DS18B20 or DS18S20
#define GPIO_I2C_SCL 5 // I2C SCL
#define GPIO_I2C_SDA 6 // I2C SDA
#define GPIO_WS2812 7 // WS2812 Led string
#define GPIO_SWT1 8 // User connected external switches
#define GPIO_SENSOR_END 9
// User selectable GPIO functionality
enum upins_t {
GPIO_NONE, // Not used
GPIO_DHT11, // DHT11
GPIO_DHT21, // DHT21, AM2301
GPIO_DHT22, // DHT22, AM2302, AM2321
GPIO_DSB, // Single wire DS18B20 or DS18S20
GPIO_I2C_SCL, // I2C SCL
GPIO_I2C_SDA, // I2C SDA
GPIO_WS2812, // WS2812 Led string
GPIO_SWT1, // User connected external switches
GPIO_SENSOR_END };
#define GPIO_SWT2 9
#define GPIO_SWT3 10
#define GPIO_SWT4 11
#define GPIO_KEY1 12 // Button usually connected to GPIO0
#define GPIO_KEY2 13
#define GPIO_KEY3 14
#define GPIO_KEY4 15
#define GPIO_REL1 16 // Relays
#define GPIO_REL2 17
#define GPIO_REL3 18
#define GPIO_REL4 19
#define GPIO_REL1_INV 20
#define GPIO_REL2_INV 21
#define GPIO_REL3_INV 22
#define GPIO_REL4_INV 23
#define GPIO_LED1 24 // Leds
#define GPIO_LED2 25
#define GPIO_LED3 26
#define GPIO_LED4 27
#define GPIO_LED1_INV 28
#define GPIO_LED2_INV 29
#define GPIO_LED3_INV 30
#define GPIO_LED4_INV 31
#define GPIO_PWM0 32 // Cold
#define GPIO_PWM1 33 // Warm
#define GPIO_PWM2 34 // Red (swapped with Blue from original)
#define GPIO_PWM3 35 // Green
#define GPIO_PWM4 36 // Blue (swapped with Red from original)
#define GPIO_RXD 37 // Serial interface
#define GPIO_TXD 38 // Serial interface
#define GPIO_HLW_SEL 39 // HLW8012 Sel output (Sonoff Pow)
#define GPIO_HLW_CF1 40 // HLW8012 CF1 voltage / current (Sonoff Pow)
#define GPIO_HLW_CF 41 // HLW8012 CF power (Sonoff Pow)
#define GPIO_USER 42 // User configurable
#define GPIO_MAX 43
// Text in webpage Module Parameters and commands GPIOS and GPIO
const char sensors[GPIO_SENSOR_END][8] PROGMEM = {
"None",
"DHT11",
"AM2301",
"DHT22",
"DS18x20",
"I2C SCL",
"I2C SDA",
"WS2812",
"Switch" };
// Programmer selectable GPIO functionality offset by user selectable GPIOs
enum fpins_t {
GPIO_SWT2 = GPIO_SENSOR_END,
GPIO_SWT3,
GPIO_SWT4,
GPIO_KEY1, // Button usually connected to GPIO0
GPIO_KEY2,
GPIO_KEY3,
GPIO_KEY4,
GPIO_REL1, // Relays
GPIO_REL2,
GPIO_REL3,
GPIO_REL4,
GPIO_REL1_INV,
GPIO_REL2_INV,
GPIO_REL3_INV,
GPIO_REL4_INV,
GPIO_LED1, // Leds
GPIO_LED2,
GPIO_LED3,
GPIO_LED4,
GPIO_LED1_INV,
GPIO_LED2_INV,
GPIO_LED3_INV,
GPIO_LED4_INV,
GPIO_PWM0, // Cold
GPIO_PWM1, // Warm
GPIO_PWM2, // Red (swapped with Blue from original)
GPIO_PWM3, // Green
GPIO_PWM4, // Blue (swapped with Red from original)
GPIO_RXD, // Serial interface
GPIO_TXD, // Serial interface
GPIO_HLW_SEL, // HLW8012 Sel output (Sonoff Pow)
GPIO_HLW_CF1, // HLW8012 CF1 voltage / current (Sonoff Pow)
GPIO_HLW_CF, // HLW8012 CF power (Sonoff Pow)
GPIO_USER, // User configurable
GPIO_MAX };
/********************************************************************************************/
enum module_t {SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, S20, SLAMPHER, SONOFF_TOUCH, SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, USER_TEST, MAXMODULE};
// Supported hardware modules
enum module_t {
SONOFF_BASIC,
SONOFF_RF,
SONOFF_SV,
SONOFF_TH,
SONOFF_DUAL,
SONOFF_POW,
SONOFF_4CH,
S20,
SLAMPHER,
SONOFF_TOUCH,
SONOFF_LED,
CH1,
CH4,
MOTOR,
ELECTRODRAGON,
USER_TEST,
MAXMODULE };
/********************************************************************************************/
#define MAX_GPIO_PIN 17 // Number of supported GPIO
#define DHT11 11
#define DHT21 21
#define AM2301 21
#define DHT22 22
#define AM2302 22
#define AM2321 22
typedef struct MYIO {
uint8_t io[MAX_GPIO_PIN];
} myio;
@ -78,9 +100,7 @@ typedef struct MYTMPLT {
myio gp;
} mytmplt;
const char sensors[GPIO_SENSOR_END][8] PROGMEM =
{ "None", "DHT11", "AM2301", "DHT22", "DS18x20", "I2C SCL", "I2C SDA", "WS2812", "Switch" };
// Default module settings
const mytmplt modules[MAXMODULE] PROGMEM = {
{ "Sonoff Basic", // Sonoff Basic
GPIO_KEY1, // GPIO00 Button

View File

@ -491,11 +491,11 @@ void handleRoot()
if (pin[GPIO_DSB] < 99) tpage += dsb_webPresent();
#endif // USE_DS18B20
#ifdef USE_DS18x20
if (pin[GPIO_DSB] < 99) page += ds18x20_webPresent();
if (pin[GPIO_DSB] < 99) tpage += ds18x20_webPresent();
#endif // USE_DS18x20
#if defined(USE_DHT) || defined(USE_DHT2)
#ifdef USE_DHT
if (dht_type) tpage += dht_webPresent();
#endif // USE_DHT/2
#endif // USE_DHT
#ifdef USE_I2C
if (i2c_flg) {
tpage += htu_webPresent();
@ -570,7 +570,7 @@ void handleModule()
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if (cmodule.gp.io[i] == GPIO_USER) {
page += F("<br/><b>GPIO"); page += String(i); page += F("</b> <select id='g"); page += String(i); page += F("' name='g"); page += String(i); page += F("'>");
for (byte j = GPIO_SENSOR_START; j < GPIO_SENSOR_END; j++) {
for (byte j = 0; j < GPIO_SENSOR_END; j++) {
page += F("<option ");
if (j == my_module.gp.io[i]) page += F("selected ");
page += F("value='"); page += String(j); page += F("'>");

View File

@ -137,13 +137,13 @@ boolean dht_readTempHum(bool S, float &t, float &h)
if (dht_read()) {
switch (dht_type) {
case DHT11:
case GPIO_DHT11:
h = data[0];
t = data[2];
if(S) t = dht_convertCtoF(t);
break;
case DHT22:
case DHT21:
case GPIO_DHT22:
case GPIO_DHT21:
h = data[0];
h *= 256;
h += data[1];

View File

@ -36,23 +36,28 @@ POSSIBILITY OF SUCH DAMAGE.
#include <OneWire.h>
OneWire ds(pin[GPIO_DSB]);
OneWire *ds = NULL;
uint8_t ds18x20_addr[DS18X20_MAX_SENSORS][8];
uint8_t ds18x20_idx[DS18X20_MAX_SENSORS];
uint8_t ds18x20_snsrs = 0;
void ds18x20_init()
{
ds = new OneWire(pin[GPIO_DSB]);
}
void ds18x20_search()
{
uint8_t num_sensors=0;
uint8_t sensor = 0;
uint8_t i;
ds.reset_search();
ds->reset_search();
for (num_sensors = 0; num_sensors < DS18X20_MAX_SENSORS; num_sensors)
{
if (!ds.search(ds18x20_addr[num_sensors])) {
ds.reset_search();
if (!ds->search(ds18x20_addr[num_sensors])) {
ds->reset_search();
break;
}
// If CRC Ok and Type DS18S20 or DS18B20
@ -104,9 +109,9 @@ String ds18x20_type(uint8_t sensor)
void ds18x20_convert()
{
ds.reset();
ds.write(W1_SKIP_ROM); // Address all Sensors on Bus
ds.write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
ds->reset();
ds->write(W1_SKIP_ROM); // Address all Sensors on Bus
ds->write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
// delay(750); // 750ms should be enough for 12bit conv
}
@ -125,11 +130,11 @@ boolean ds18x20_read(uint8_t sensor, bool S, float &t)
t = NAN;
ds.reset();
ds.select(ds18x20_addr[ds18x20_idx[sensor]]);
ds.write(W1_READ_SCRATCHPAD); // Read Scratchpad
ds->reset();
ds->select(ds18x20_addr[ds18x20_idx[sensor]]);
ds->write(W1_READ_SCRATCHPAD); // Read Scratchpad
for (i = 0; i < 9; i++) data[i] = ds.read();
for (i = 0; i < 9; i++) data[i] = ds->read();
if (OneWire::crc8(data, 8) == data[8]) {
switch(ds18x20_addr[ds18x20_idx[sensor]][0]) {
case 0x10: // DS18S20