瀏覽代碼

Merge branch 'test_esp32_owb' into VVBController

Thomas Chef 2 年之前
父節點
當前提交
1c1b2c728d
共有 15 個文件被更改,包括 187 次插入639 次删除
  1. 6 0
      .gitmodules
  2. 1 0
      components/esp32-ds18b20
  3. 1 0
      components/esp32-owb
  4. 3 9
      main/CMakeLists.txt
  5. 2 2
      main/config.h
  6. 0 464
      main/ds18b20.c
  7. 0 86
      main/ds18b20.h
  8. 14 1
      main/http_client.c
  9. 30 12
      main/kWhCounter.c
  10. 12 17
      main/main.c
  11. 21 2
      main/mqtt.c
  12. 88 37
      main/readTemps.c
  13. 2 1
      main/readTemps.h
  14. 1 1
      main/wifi.c
  15. 6 7
      sdkconfig.defaults

+ 6 - 0
.gitmodules

@@ -0,0 +1,6 @@
+[submodule "components/esp32-ds18b20"]
+	path = components/esp32-ds18b20
+	url = https://github.com/DavidAntliff/esp32-ds18b20.git
+[submodule "components/esp32-owb"]
+	path = components/esp32-owb
+	url = https://github.com/DavidAntliff/esp32-owb.git

+ 1 - 0
components/esp32-ds18b20

@@ -0,0 +1 @@
+Subproject commit d677f09a42898a7c3bd064cf8afd89f9d4d6ada9

+ 1 - 0
components/esp32-owb

@@ -0,0 +1 @@
+Subproject commit 60d977e7031f3fcb3900bce4f88befb159bfef4f

+ 3 - 9
main/CMakeLists.txt

@@ -1,11 +1,5 @@
-idf_component_register(SRCS
-"http_client.c" "mqtt.c" "wifi.c"
-"main.c"
-"wifi.c" "mqtt.c"
-"kWhCounter.c"
-"ds18b20.c"
-"readTemps.c"
 
+set(COMPONENT_SRCDIRS ".")
+set(COMPONENT_ADD_INCLUDEDIRS ".")
 
-
-                    INCLUDE_DIRS "")
+register_component()

+ 2 - 2
main/config.h

@@ -12,6 +12,8 @@
 #define ENABLE_KWH_COUNTER
 #define ENABLE_DS18B20
 
+//#define MQTT_DEBUG              // Add an extra debug string to the topic-string
+
 #define VVB_RELAY_OUTPUT_IO      GPIO_NUM_22   // Output GPIO of a relay control of VVB
 
 #define KWH_COUNTER_INPUT_IO      GPIO_NUM_16   // Input
@@ -19,6 +21,4 @@
 #define ONE_WIRE_BUS_IO           GPIO_NUM_26   // Temp sensors
 
 
-
-
 #endif

+ 0 - 464
main/ds18b20.c

@@ -1,464 +0,0 @@
-/*
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    You should have received a copy of the GNU General Public License
-     along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
-noInterrupts();
-             ^~~~                                                                                          
-warning: 'taskEXIT_CRITICAL(mux)' is deprecated in ESP-IDF, consider using 'portEXIT_CRITICAL(mux)'
-  interrupts();
-             ^~                                                                                          
-/Users/thomaschef/Documents/Develop/ESP32/HomeEnergyMeter/main/ds18b20.c: In function 'ds18b20_reset':
-/Users/thomaschef/Documents/Develop/ESP32/HomeEnergyMeter/main/ds18b20.c:123:13: warning: 'taskENTER_CRITICAL(mux)' is deprecated in ESP-IDF, consider using 'portENTER_CRITICAL(mux)'
-  noInterrupts();
-             ^~~~                                                                                          
-/Users/thomaschef/Documents/Develop/ESP32/HomeEnergyMeter/main/ds18b20.c:131:13: warning: 'taskEXIT_CRITICAL(mux)' is deprecated in ESP-IDF, consider using 'portEXIT_CR
-*/
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "driver/gpio.h"
-#include "esp32/rom/ets_sys.h"
-#include "ds18b20.h"
-#include "config.h"
-
-#ifdef ENABLE_DS18B20
-
-// OneWire commands
-#define GETTEMP			0x44  // Tells device to take a temperature reading and put it on the scratchpad
-#define SKIPROM			0xCC  // Command to address all devices on the bus
-#define SELECTDEVICE	0x55  // Command to address all devices on the bus
-#define COPYSCRATCH     0x48  // Copy scratchpad to EEPROM
-#define READSCRATCH     0xBE  // Read from scratchpad
-#define WRITESCRATCH    0x4E  // Write to scratchpad
-#define RECALLSCRATCH   0xB8  // Recall from EEPROM to scratchpad
-#define READPOWERSUPPLY 0xB4  // Determine if device needs parasite power
-#define ALARMSEARCH     0xEC  // Query bus for devices with an alarm condition
-// Scratchpad locations
-#define TEMP_LSB        0
-#define TEMP_MSB        1
-#define HIGH_ALARM_TEMP 2
-#define LOW_ALARM_TEMP  3
-#define CONFIGURATION   4
-#define INTERNAL_BYTE   5
-#define COUNT_REMAIN    6
-#define COUNT_PER_C     7
-#define SCRATCHPAD_CRC  8
-// DSROM FIELDS
-#define DSROM_FAMILY    0
-#define DSROM_CRC       7
-// Device resolution
-#define TEMP_9_BIT  0x1F //  9 bit
-#define TEMP_10_BIT 0x3F // 10 bit
-#define TEMP_11_BIT 0x5F // 11 bit
-#define TEMP_12_BIT 0x7F // 12 bit
-
-uint8_t DS_GPIO;
-uint8_t init=0;
-uint8_t bitResolution=12;
-uint8_t devices=0;
-
-DeviceAddress ROM_NO;
-uint8_t LastDiscrepancy;
-uint8_t LastFamilyDiscrepancy;
-bool LastDeviceFlag;
-
-/// Sends one bit to bus
-void ds18b20_write(char bit){
-	if (bit & 1) {
-		gpio_set_direction(DS_GPIO, GPIO_MODE_OUTPUT);
-		noInterrupts();
-		gpio_set_level(DS_GPIO,0);
-		ets_delay_us(6);
-		gpio_set_direction(DS_GPIO, GPIO_MODE_INPUT);	// release bus
-		ets_delay_us(64);
-		interrupts();
-	} else {
-		gpio_set_direction(DS_GPIO, GPIO_MODE_OUTPUT);
-		noInterrupts();
-		gpio_set_level(DS_GPIO,0);
-		ets_delay_us(60);
-		gpio_set_direction(DS_GPIO, GPIO_MODE_INPUT);	// release bus
-		ets_delay_us(10);
-		interrupts();
-	}
-}
-
-// Reads one bit from bus
-unsigned char ds18b20_read(void){
-	unsigned char value = 0;
-	gpio_set_direction(DS_GPIO, GPIO_MODE_OUTPUT);
-	noInterrupts();
-	gpio_set_level(DS_GPIO, 0);
-	ets_delay_us(6);
-	gpio_set_direction(DS_GPIO, GPIO_MODE_INPUT);
-	ets_delay_us(9);
-	value = gpio_get_level(DS_GPIO);
-	ets_delay_us(55);
-	interrupts();
-	return (value);
-}
-// Sends one byte to bus
-void ds18b20_write_byte(char data){
-  unsigned char i;
-  unsigned char x;
-  for(i=0;i<8;i++){
-    x = data>>i;
-    x &= 0x01;
-    ds18b20_write(x);
-  }
-  ets_delay_us(100);
-}
-// Reads one byte from bus
-unsigned char ds18b20_read_byte(void){
-  unsigned char i;
-  unsigned char data = 0;
-  for (i=0;i<8;i++)
-  {
-    if(ds18b20_read()) data|=0x01<<i;
-    ets_delay_us(15);
-  }
-  return(data);
-}
-// Sends reset pulse
-unsigned char ds18b20_reset(void){
-	unsigned char presence;
-	gpio_set_direction(DS_GPIO, GPIO_MODE_OUTPUT);
-	noInterrupts();
-	gpio_set_level(DS_GPIO, 0);
-	ets_delay_us(480);
-	gpio_set_level(DS_GPIO, 1);
-	gpio_set_direction(DS_GPIO, GPIO_MODE_INPUT);
-	ets_delay_us(70);
-	presence = (gpio_get_level(DS_GPIO) == 0);
-	ets_delay_us(410);
-	interrupts();
-	return presence;
-}
-
-bool ds18b20_setResolution(const DeviceAddress tempSensorAddresses[], int numAddresses, uint8_t newResolution) {
-	bool success = false;
-	// handle the sensors with configuration register
-	newResolution = constrain(newResolution, 9, 12);
-	uint8_t newValue = 0;
-	ScratchPad scratchPad;
-	// loop through each address
-	for (int i = 0; i < numAddresses; i++){
-		// we can only update the sensor if it is connected
-		if (ds18b20_isConnected((DeviceAddress*) tempSensorAddresses[i], scratchPad)) {
-			switch (newResolution) {
-			case 12:
-				newValue = TEMP_12_BIT;
-				break;
-			case 11:
-				newValue = TEMP_11_BIT;
-				break;
-			case 10:
-				newValue = TEMP_10_BIT;
-				break;
-			case 9:
-			default:
-				newValue = TEMP_9_BIT;
-				break;
-			}
-			// if it needs to be updated we write the new value
-			if (scratchPad[CONFIGURATION] != newValue) {
-				scratchPad[CONFIGURATION] = newValue;
-				ds18b20_writeScratchPad((DeviceAddress*) tempSensorAddresses[i], scratchPad);
-			}
-			// done
-			success = true;
-		}
-	}
-	return success;
-}
-
-void ds18b20_writeScratchPad(const DeviceAddress *deviceAddress, const uint8_t *scratchPad) {
-	ds18b20_reset();
-	ds18b20_select(deviceAddress);
-	ds18b20_write_byte(WRITESCRATCH);
-	ds18b20_write_byte(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp
-	ds18b20_write_byte(scratchPad[LOW_ALARM_TEMP]); // low alarm temp
-	ds18b20_write_byte(scratchPad[CONFIGURATION]);
-	ds18b20_reset();
-}
-
-bool ds18b20_readScratchPad(const DeviceAddress *deviceAddress, uint8_t* scratchPad) {
-	// send the reset command and fail fast
-	int b = ds18b20_reset();
-	if (b == 0) return false;
-	ds18b20_select(deviceAddress);
-	ds18b20_write_byte(READSCRATCH);
-	// Read all registers in a simple loop
-	// byte 0: temperature LSB
-	// byte 1: temperature MSB
-	// byte 2: high alarm temp
-	// byte 3: low alarm temp
-	// byte 4: DS18B20 & DS1822: configuration register
-	// byte 5: internal use & crc
-	// byte 6: DS18B20 & DS1822: store for crc
-	// byte 7: DS18B20 & DS1822: store for crc
-	// byte 8: SCRATCHPAD_CRC
-	for (uint8_t i = 0; i < 9; i++) {
-		scratchPad[i] = ds18b20_read_byte();
-	}
-	b = ds18b20_reset();
-	return (b == 1);
-}
-
-void ds18b20_select(const DeviceAddress *address){
-    uint8_t i;
-    ds18b20_write_byte(SELECTDEVICE);           // Choose ROM
-    for (i = 0; i < 8; i++) ds18b20_write_byte(((uint8_t *)address)[i]);
-}
-
-void ds18b20_requestTemperatures(){
-	ds18b20_reset();
-	ds18b20_write_byte(SKIPROM);
-	ds18b20_write_byte(GETTEMP);
-    unsigned long start = esp_timer_get_time() / 1000ULL;
-    while (!isConversionComplete() && ((esp_timer_get_time() / 1000ULL) - start < millisToWaitForConversion())) vPortYield();
-}
-
-bool isConversionComplete() {
-	uint8_t b = ds18b20_read();
-	return (b == 1);
-}
-
-uint16_t millisToWaitForConversion() {
-	switch (bitResolution) {
-	case 9:
-		return 94;
-	case 10:
-		return 188;
-	case 11:
-		return 375;
-	default:
-		return 750;
-	}
-}
-
-bool ds18b20_isConnected(const DeviceAddress *deviceAddress, uint8_t *scratchPad) {
-	bool b = ds18b20_readScratchPad(deviceAddress, scratchPad);
-	return b && !ds18b20_isAllZeros(scratchPad) && (ds18b20_crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]);
-}
-
-uint8_t ds18b20_crc8(const uint8_t *addr, uint8_t len){
-	uint8_t crc = 0;
-	while (len--) {
-		crc = *addr++ ^ crc;  // just re-using crc as intermediate
-		crc = pgm_read_byte(dscrc2x16_table + (crc & 0x0f)) ^
-		pgm_read_byte(dscrc2x16_table + 16 + ((crc >> 4) & 0x0f));
-	}
-	return crc;
-}
-
-bool ds18b20_isAllZeros(const uint8_t * const scratchPad) {
-	for (size_t i = 0; i < 9; i++) {
-		if (scratchPad[i] != 0) {
-			return false;
-		}
-	}
-	return true;
-}
-
-float ds18b20_getTempC(const DeviceAddress *deviceAddress) {
-	ScratchPad scratchPad;
-	if (ds18b20_isConnected(deviceAddress, scratchPad)){
-		int16_t rawTemp = calculateTemperature(deviceAddress, scratchPad);
-		if (rawTemp <= DEVICE_DISCONNECTED_RAW)
-			return DEVICE_DISCONNECTED_C;
-		// C = RAW/128
-		// F = (C*1.8)+32 = (RAW/128*1.8)+32 = (RAW*0.0140625)+32
-		return (float) rawTemp/128.0f;
-	}
-	return DEVICE_DISCONNECTED_C;
-}
-
-// reads scratchpad and returns fixed-point temperature, scaling factor 2^-7
-int16_t calculateTemperature(const DeviceAddress *deviceAddress, uint8_t* scratchPad) {
-	int16_t fpTemperature = (((int16_t) scratchPad[TEMP_MSB]) << 11) | (((int16_t) scratchPad[TEMP_LSB]) << 3);
-	return fpTemperature;
-}
-
-// Returns temperature from sensor
-float ds18b20_get_temp(void) {
-  if(init==1){
-    unsigned char check;
-    char temp1=0, temp2=0;
-      check=ds18b20_RST_PULSE();
-      if(check==1)
-      {
-        ds18b20_send_byte(0xCC);
-        ds18b20_send_byte(0x44);
-        vTaskDelay(750 / portTICK_RATE_MS);
-        check=ds18b20_RST_PULSE();
-        ds18b20_send_byte(0xCC);
-        ds18b20_send_byte(0xBE);
-        temp1=ds18b20_read_byte();
-        temp2=ds18b20_read_byte();
-        check=ds18b20_RST_PULSE();
-        float temp=0;
-        temp=(float)(temp1+(temp2*256))/16;
-        return temp;
-      }
-      else{return 0;}
-
-  }
-  else{return 0;}
-}
-
-void ds18b20_init(int GPIO) {
-	DS_GPIO = GPIO;
-	gpio_pad_select_gpio(DS_GPIO);
-	init = 1;
-}
-
-//
-// You need to use this function to start a search again from the beginning.
-// You do not need to do it for the first search, though you could.
-//
-void reset_search() {
-	devices=0;
-	// reset the search state
-	LastDiscrepancy = 0;
-	LastDeviceFlag = false;
-	LastFamilyDiscrepancy = 0;
-	for (int i = 7; i >= 0; i--) {
-		ROM_NO[i] = 0;
-	}
-}
-// --- Replaced by the one from the Dallas Semiconductor web site ---
-//--------------------------------------------------------------------------
-// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
-// search state.
-// Return TRUE  : device found, ROM number in ROM_NO buffer
-//        FALSE : device not found, end of search
-
-bool search(uint8_t *newAddr, bool search_mode) {
-	uint8_t id_bit_number;
-	uint8_t last_zero, rom_byte_number;
-	bool search_result;
-	uint8_t id_bit, cmp_id_bit;
-
-	unsigned char rom_byte_mask, search_direction;
-
-	// initialize for search
-	id_bit_number = 1;
-	last_zero = 0;
-	rom_byte_number = 0;
-	rom_byte_mask = 1;
-	search_result = false;
-
-	// if the last call was not the last one
-	if (!LastDeviceFlag) {
-		// 1-Wire reset
-		if (!ds18b20_reset()) {
-			// reset the search
-			LastDiscrepancy = 0;
-			LastDeviceFlag = false;
-			LastFamilyDiscrepancy = 0;
-			return false;
-		}
-
-		// issue the search command
-		if (search_mode == true) {
-			ds18b20_write_byte(0xF0);   // NORMAL SEARCH
-		} else {
-			ds18b20_write_byte(0xEC);   // CONDITIONAL SEARCH
-		}
-
-		// loop to do the search
-		do {
-			// read a bit and its complement
-			id_bit = ds18b20_read();
-			cmp_id_bit = ds18b20_read();
-
-			// check for no devices on 1-wire
-			if ((id_bit == 1) && (cmp_id_bit == 1)) {
-				break;
-			} else {
-				// all devices coupled have 0 or 1
-				if (id_bit != cmp_id_bit) {
-					search_direction = id_bit;  // bit write value for search
-				} else {
-					// if this discrepancy if before the Last Discrepancy
-					// on a previous next then pick the same as last time
-					if (id_bit_number < LastDiscrepancy) {
-						search_direction = ((ROM_NO[rom_byte_number]
-								& rom_byte_mask) > 0);
-					} else {
-						// if equal to last pick 1, if not then pick 0
-						search_direction = (id_bit_number == LastDiscrepancy);
-					}
-					// if 0 was picked then record its position in LastZero
-					if (search_direction == 0) {
-						last_zero = id_bit_number;
-
-						// check for Last discrepancy in family
-						if (last_zero < 9)
-							LastFamilyDiscrepancy = last_zero;
-					}
-				}
-
-				// set or clear the bit in the ROM byte rom_byte_number
-				// with mask rom_byte_mask
-				if (search_direction == 1)
-					ROM_NO[rom_byte_number] |= rom_byte_mask;
-				else
-					ROM_NO[rom_byte_number] &= ~rom_byte_mask;
-
-				// serial number search direction write bit
-				ds18b20_write(search_direction);
-
-				// increment the byte counter id_bit_number
-				// and shift the mask rom_byte_mask
-				id_bit_number++;
-				rom_byte_mask <<= 1;
-
-				// if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
-				if (rom_byte_mask == 0) {
-					rom_byte_number++;
-					rom_byte_mask = 1;
-				}
-			}
-		} while (rom_byte_number < 8);  // loop until through all ROM bytes 0-7
-
-		// if the search was successful then
-		if (!(id_bit_number < 65)) {
-			// search successful so set LastDiscrepancy,LastDeviceFlag,search_result
-			LastDiscrepancy = last_zero;
-
-			// check for last device
-			if (LastDiscrepancy == 0) {
-				LastDeviceFlag = true;
-			}
-			search_result = true;
-		}
-	}
-
-	// if no device found then reset counters so next 'search' will be like a first
-	if (!search_result || !ROM_NO[0]) {
-		devices=0;
-		LastDiscrepancy = 0;
-		LastDeviceFlag = false;
-		LastFamilyDiscrepancy = 0;
-		search_result = false;
-	} else {
-		for (int i = 0; i < 8; i++){
-			newAddr[i] = ROM_NO[i];
-		}
-		devices++;
-	}
-	return search_result;
-}
-
-#endif // ENABLE_DS18B20

+ 0 - 86
main/ds18b20.h

@@ -1,86 +0,0 @@
-/*
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#include <esp_system.h>
-
-#ifndef DS18B20_H_  
-#define DS18B20_H_
-
-// warning: 'taskENTER_CRITICAL(mux)' is deprecated in ESP-IDF, consider using 'portENTER_CRITICAL(mux)'
-//#define noInterrupts() portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;taskENTER_CRITICAL(&mux)
-//#define interrupts() taskEXIT_CRITICAL(&mux)
-#define noInterrupts() 
-#define interrupts() 
-
-#define DEVICE_DISCONNECTED_C -127
-#define DEVICE_DISCONNECTED_F -196.6
-#define DEVICE_DISCONNECTED_RAW -7040
-#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
-#define pgm_read_byte(addr)   (*(const unsigned char *)(addr))
-
-typedef uint8_t DeviceAddress[8];
-typedef uint8_t ScratchPad[9];
-
-// Dow-CRC using polynomial X^8 + X^5 + X^4 + X^0
-// Tiny 2x16 entry CRC table created by Arjen Lentz
-// See http://lentz.com.au/blog/calculating-crc-with-a-tiny-32-entry-lookup-table
-static const uint8_t dscrc2x16_table[] = {
-	0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83,
-	0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41,
-	0x00, 0x9D, 0x23, 0xBE, 0x46, 0xDB, 0x65, 0xF8,
-	0x8C, 0x11, 0xAF, 0x32, 0xCA, 0x57, 0xE9, 0x74
-};
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-    extern "C" {
-#endif
-/* *INDENT-ON* */
-
-void ds18b20_init(int GPIO);
-
-#define ds18b20_send ds18b20_write
-#define ds18b20_send_byte ds18b20_write_byte
-#define ds18b20_RST_PULSE ds18b20_reset
-
-void ds18b20_write(char bit);
-unsigned char ds18b20_read(void);
-void ds18b20_write_byte(char data);
-unsigned char ds18b20_read_byte(void);
-unsigned char ds18b20_reset(void);
-
-bool ds18b20_setResolution(const DeviceAddress tempSensorAddresses[], int numAddresses, uint8_t newResolution);
-bool ds18b20_isConnected(const DeviceAddress *deviceAddress, uint8_t *scratchPad);
-void ds18b20_writeScratchPad(const DeviceAddress *deviceAddress, const uint8_t *scratchPad);
-bool ds18b20_readScratchPad(const DeviceAddress *deviceAddress, uint8_t *scratchPad);
-void ds18b20_select(const DeviceAddress *address);
-uint8_t ds18b20_crc8(const uint8_t *addr, uint8_t len);
-bool ds18b20_isAllZeros(const uint8_t * const scratchPad);
-bool isConversionComplete();
-uint16_t millisToWaitForConversion();
-
-void ds18b20_requestTemperatures();
-float ds18b20_getTempF(const DeviceAddress *deviceAddress);
-float ds18b20_getTempC(const DeviceAddress *deviceAddress);
-int16_t calculateTemperature(const DeviceAddress *deviceAddress, uint8_t* scratchPad);
-float ds18b20_get_temp(void);
-
-void reset_search();
-bool search(uint8_t *newAddr, bool search_mode);
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-    }
-#endif
-/* *INDENT-ON* */
-
-#endif

+ 14 - 1
main/http_client.c

@@ -8,6 +8,9 @@
 
 #include "wifi.h"
 #include "config.h"
+#include "mqtt.h"
+
+static const char *TAG = "HTTP_CLIENT";
 
 #ifdef HTTP_ENABLED
 
@@ -17,7 +20,6 @@
 #include "esp_http_client.h"
 
 #define MAX_HTTP_RECV_BUFFER 512
-static const char *TAG = "HTTP_CLIENT";
 
 esp_err_t _http_event_handler(esp_http_client_event_t *evt)
 {
@@ -134,6 +136,17 @@ void http_rest_with_url()
 
     ESP_LOGI(TAG, "Set kontaktor state: %u",kontaktor);
     gpio_set_level(VVB_RELAY_OUTPUT_IO, kontaktor);
+
+    char txt[10];
+    sprintf(txt,"%u",kontaktor);
+    sendMQTTMessage("basement/boiler/contactor", txt);
+}
+
+#else
+
+void http_rest_with_url()
+{
+    ESP_LOGI(TAG, "Set kontaktor state (FAKE): 0");
 }
 
 

+ 30 - 12
main/kWhCounter.c

@@ -6,9 +6,11 @@
 #include "esp_attr.h"
 #include "esp_log.h"
 
+#include "mqtt.h"
+#include "readTemps.h"
 #include "kWhCounter.h"
 
-uint32_t kWh_cnt = 0;
+uint32_t kWh_cnt = 0;   // No of seconds of active VBB
 
 #ifdef ENABLE_KWH_COUNTER
 
@@ -16,12 +18,13 @@ void counterControlTask(void *pvParameters) {
 
     ESP_LOGI("kWhCounter", "counterControlTask starting. Core:%d",xPortGetCoreID());
 
-    uint32_t logCnt = 0;
-    
-    uint32_t state = 0;
+    char txt[50];
+
+    uint32_t secondCnt = 0;
+    uint32_t activeCnt = 0;
 
     TickType_t vLastWakeTime = xTaskGetTickCount();
-    const TickType_t xFreq = 100 / portTICK_PERIOD_MS;
+    const TickType_t xFreq = 100 / portTICK_PERIOD_MS;  // 100mS. 10 measurements / second
 
     while( 1 ) {
 
@@ -29,17 +32,32 @@ void counterControlTask(void *pvParameters) {
 
             vTaskDelayUntil( &vLastWakeTime, xFreq );
 
-            if( gpio_get_level(KWH_COUNTER_INPUT_IO) == 1 ) state++;
+            if( gpio_get_level(KWH_COUNTER_INPUT_IO) == 1 ) activeCnt++;
         }
 
-        if( state > 0 ) kWh_cnt++;
+        if( activeCnt > 0 ) kWh_cnt++;
+
+        if( ++secondCnt == 60 ) {
+            // Every 60 seconds
+            ESP_LOGI("kWhCounter", "60 sec. Measure. Pin: %u  Tot:%u", activeCnt, kWh_cnt);
+            
+            // Every 60 seconds we do a small 10 second pause to read out some temperature data
+            // The OWB is sensitive to interrupts, so thats why we pause everything a little while
+
+            sprintf(txt,"%u",kWh_cnt);
+            sendMQTTMessage("basement/boiler/onTime", txt);
+            vTaskDelayUntil( &vLastWakeTime, 5000 / portTICK_PERIOD_MS ); // Sleep 5s
+
+            // Start temp measuring task
+            xTaskCreatePinnedToCore(readAndSendTemps, "readAndSendTemps", 1024*10, NULL, 2, NULL,1);
+
+            vTaskDelayUntil( &vLastWakeTime, 5000 / portTICK_PERIOD_MS ); // Sleep 5s
 
-        if( ++logCnt == 10 ) {
-            ESP_LOGI("kWhCounter", "Measure. Pin: %u  Tot:%u", state, kWh_cnt);
-            logCnt = 0;
+            if( activeCnt > 0 ) kWh_cnt += 10;  // Add 10 seconds for the seconds that we where sleeping, if active
+            secondCnt = 10;
         }
 
-        state = 0;
+        activeCnt = 0;
     }
 
 }
@@ -53,7 +71,7 @@ void kWhCounter_init()
 
     gpio_set_direction(KWH_COUNTER_INPUT_IO, GPIO_MODE_INPUT);
 
-    xTaskCreate(counterControlTask, "counterControlTask", 1024*10, NULL, 2, NULL);
+    xTaskCreatePinnedToCore(counterControlTask, "counterControlTask", 1024*10, NULL, 2, NULL,1);
 }
 
 #endif

+ 12 - 17
main/main.c

@@ -16,13 +16,18 @@
 
 void app_main(void)
 {
-    char txt[50];
-
     ESP_LOGI("MAIN", "HomeEnergyMeter ESP32. Core:%d",xPortGetCoreID());
 
     gpio_reset_pin(VVB_RELAY_OUTPUT_IO);
     gpio_set_direction(VVB_RELAY_OUTPUT_IO, GPIO_MODE_OUTPUT);
 
+    // Wait for stable environment
+    vTaskDelay(2000.0 / portTICK_PERIOD_MS);
+
+#ifdef ENABLE_DS18B20
+    initTempReadings();
+#endif
+
 #ifdef ENABLE_KWH_COUNTER
     kWhCounter_init();
 #endif
@@ -35,27 +40,17 @@ void app_main(void)
     mqtt_init();
 #endif
 
-    const TickType_t xFreq = 30000 / portTICK_PERIOD_MS;
     TickType_t vLastWakeTime = xTaskGetTickCount();
 
+    // Do an initial delay to make the different tasks to work out of sync to each other (not send all data at same time)
+    vTaskDelayUntil( &vLastWakeTime, 30000 / portTICK_PERIOD_MS );
+
     // ---------------- MAIN WHILE -------------------
     while(1) {
 
-        vTaskDelayUntil( &vLastWakeTime, xFreq );
-#ifdef HTTP_ENABLED
-        http_rest_with_url();
-#endif
+        vTaskDelayUntil( &vLastWakeTime, 60000 / portTICK_PERIOD_MS );
 
-        vTaskDelayUntil( &vLastWakeTime, xFreq );
-        sprintf(txt,"%u",kWh_cnt);
-#ifdef MQTT_ENABLED
-        sendMQTTMessage("basement/boiler/onTime", txt);
-#endif
-
-
-#ifdef ENABLE_DS18B20
-        readTemps();
-#endif
+        http_rest_with_url();
     }
 
     vTaskDelete(NULL);

+ 21 - 2
main/mqtt.c

@@ -32,9 +32,11 @@
 
 #include "wifi.h"
 
+static const char *TAG = "MQTT";
+
 #ifdef MQTT_ENABLED
 
-static const char *TAG = "MQTT";
+
 static esp_mqtt_client_handle_t client;
 static bool connected = false;
 
@@ -103,14 +105,23 @@ void mqttTask(void *pvParameters) {
 
 void mqtt_init(void)
 {
-    xTaskCreate(mqttTask, "MQTT-Task", 1024*10, NULL, 2, NULL);
+    xTaskCreatePinnedToCore(mqttTask, "MQTT-Task", 1024*10, NULL, 2, NULL,0);
 
 }
 
 void sendMQTTMessage(const char * topic, const char * data) {
     if( connected ) {
+
         int msg_id;
+        
+#ifdef MQTT_DEBUG
+        char topic_debug_str[100];
+        sprintf(topic_debug_str,"debug_env/%s",topic);
+        msg_id = esp_mqtt_client_publish(client, topic_debug_str, data, 0, 1, 0);
+#else
         msg_id = esp_mqtt_client_publish(client, topic, data, 0, 1, 0);
+#endif
+
         ESP_LOGI(TAG, "sent publish successful, msg_id=%d   %s   %s", msg_id, topic, data);
     }
     else {
@@ -118,4 +129,12 @@ void sendMQTTMessage(const char * topic, const char * data) {
     }
 }
 
+#else
+
+void sendMQTTMessage(const char * topic, const char * data) {
+        ESP_LOGI(TAG, "sent publish FAKE, msg_id=-   %s   %s", topic, data);
+}
+
+
+
 #endif

+ 88 - 37
main/readTemps.c

@@ -3,66 +3,117 @@
 #include "driver/gpio.h"
 #include "esp32/rom/ets_sys.h"
 #include "esp_log.h"
-#include "ds18b20.h"
 #include "config.h"
 #include "readTemps.h"
 #include "mqtt.h"
 
+#include "owb.h"
+#include "owb_rmt.h"
+#include "ds18b20.h"
+
 #ifdef ENABLE_DS18B20
 
-/*
-#define MAX_NO_OF_SENSORS   1
+#define GPIO_DS18B20_0       (ONE_WIRE_BUS_IO)
+#define MAX_DEVICES          (8)
+#define DS18B20_RESOLUTION   (DS18B20_RESOLUTION_12_BIT)
+#define SAMPLE_PERIOD        (1000)   // milliseconds
+
+DS18B20_Info * devices[MAX_DEVICES] = {0};
+int num_devices = 0;
+
+OneWireBus * owb;
+owb_rmt_driver_info rmt_driver_info;
+
+void initTempReadings() {
 
-// This section is for finding out which address that the sensors on the bus has.
-DeviceAddress tempSensors[MAX_NO_OF_SENSORS];
+    ESP_LOGI("TEMPS", "Init temp readings.");
 
-int getTempAddresses(DeviceAddress *tsa) {
-	
-    unsigned int i = 0;
-	reset_search();
+    
+    owb = owb_rmt_initialize(&rmt_driver_info, GPIO_DS18B20_0, RMT_CHANNEL_1, RMT_CHANNEL_0);
+    owb_use_crc(owb, true);  // enable CRC check for ROM code
 
-	while (search(tsa[i],true)) {
+    // Find all connected devices
+    ESP_LOGI("TEMPS", "Find devices:");
+    OneWireBus_ROMCode device_rom_codes[MAX_DEVICES] = {0};
+    OneWireBus_SearchState search_state = {0};
+    bool found = false;
+    owb_search_first(owb, &search_state, &found);
 
-        ESP_LOGI("READ_TEMP", "Found a temp sensor. Address:");
-        ESP_LOG_BUFFER_HEX_LEVEL("READ_TEMP", &tsa[i][0], 8, ESP_LOG_INFO);
-        i++;
-	}
-    return i;
-}*/
+    while (found)
+    {
+        char rom_code_s[17];
+        owb_string_from_rom_code(search_state.rom_code, rom_code_s, sizeof(rom_code_s));
+        ESP_LOGI("TEMPS", "  %d : %s", num_devices, rom_code_s);
+        device_rom_codes[num_devices] = search_state.rom_code;
+        ++num_devices;
+        owb_search_next(owb, &search_state, &found);
+    }
+    ESP_LOGI("TEMPS", "Found %d device%s", num_devices, num_devices == 1 ? "" : "s");
 
-void readTemps() {
+    // Create DS18B20 devices on the 1-Wire bus
+    for (int i = 0; i < num_devices; ++i)
+    {
+        DS18B20_Info * ds18b20_info = ds18b20_malloc();  // heap allocation
+        devices[i] = ds18b20_info;
 
-    char txt[10];
-    static bool initDone = false;
+        ds18b20_init(ds18b20_info, owb, device_rom_codes[i]); // associate with bus and device
+        ds18b20_use_crc(ds18b20_info, true);           // enable CRC check on all reads
+        ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION);
+    }
+}
 
-    const uint8_t intTempAddressBytes[8]={0x28,0x41,0x2e,0x7b,0x0d,0x00,0x00,0x2a}; // Address of the internal 
-    DeviceAddress *intTempSensorAdr = (DeviceAddress *) intTempAddressBytes;
+void readAndSendTemps(void *pvParameters) {
 
-    if( initDone == false ) {
-        ESP_LOGI("READ_TEMP", "Init of readTemps");
+    ESP_LOGI("TEMPS", "Read temperature task. Core:%d",xPortGetCoreID());
 
-        ds18b20_init(ONE_WIRE_BUS_IO);
-        //ESP_LOGI("READ_TEMP", "getTempAddresses()");
-        //const int noOfSensors = getTempAddresses(tempSensors);
-        //ds18b20_setResolution(tempSensors,noOfSensors,10);
+    // Read temperatures more efficiently by starting conversions on all devices at the same time
+    int errors_count[MAX_DEVICES] = {0};
+    if (num_devices > 0)
+    {
+        ds18b20_convert_all(owb);
 
-        ds18b20_setResolution(intTempSensorAdr,1,10);
+        // In this application all devices use the same resolution,
+        // so use the first device to determine the delay
+        const float sampleTime = ds18b20_wait_for_conversion(devices[0]);
 
-        initDone = true;
-    }
+        // Read the results immediately after conversion otherwise it may fail
+        // (using printf before reading may take too long)
+        float readings[MAX_DEVICES] = { 0 };
+        DS18B20_ERROR errors[MAX_DEVICES] = { 0 };
 
-    ds18b20_requestTemperatures();
-    float int_temp = ds18b20_getTempC(intTempSensorAdr);
-    ESP_LOGI("READ_TEMPS","Internal temp: %.1f",int_temp);
+        for (int i = 0; i < num_devices; ++i)
+        {
+            errors[i] = ds18b20_read_temp(devices[i], &readings[i]);
+        }
 
-#ifdef MQTT_ENABLED
-    sprintf(txt,"%.1f",int_temp);
-    sendMQTTMessage("basement/boiler/controllerTemp", txt);
-#endif
+        ESP_LOGI("TEMPS","Sample time:%.0fms",sampleTime);
 
+        // Print results in a separate loop, after all have been read
+        for (int i = 0; i < num_devices; ++i)
+        {
+            if (errors[i] != DS18B20_OK)
+            {
+                ++errors_count[i];
+            }
+            
+            char rom_code_s[25];
+            char mqtt_s[50];
+            char value_s[10];
+            owb_string_from_rom_code(devices[i]->rom_code, rom_code_s, sizeof(rom_code_s));
 
+            sprintf(mqtt_s,"basement/boiler/temps/%s", rom_code_s);
+            sprintf(value_s,"%.1f",readings[i]);
+            ESP_LOGI("TEMPS","%s %s", mqtt_s, value_s);
 
+            sendMQTTMessage(mqtt_s, value_s);
+        }
 
+    }
+    else
+    {
+        ESP_LOGE("TEMPS", "No DS18B20 devices detected!");
+    }
+    vTaskDelete(NULL);
 }
 
 

+ 2 - 1
main/readTemps.h

@@ -2,7 +2,8 @@
 #define READ_TEMPS_H
 
 
-void readTemps();
+void initTempReadings();
+void readAndSendTemps(void *pvParameters);
 
 
 #endif

+ 1 - 1
main/wifi.c

@@ -177,7 +177,7 @@ void wifiTask(void *pvParameters)
 
 void initWifi(void)
 {
-    xTaskCreate(wifiTask, "WiFi-Task", 1024*10, NULL, 2, NULL);
+    xTaskCreatePinnedToCore(wifiTask, "WiFi-Task", 1024*10, NULL, 2, NULL,0);
 }
 
 #endif

+ 6 - 7
sdkconfig.defaults

@@ -1,10 +1,9 @@
-CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y
+#CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y
+CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y
 
-CONFIG_FREERTOS_USE_TRACE_FACILITY=y
-CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
-CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
+CONFIG_FREERTOS_USE_TRACE_FACILITY=n
+CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=n
+CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=n
 
-CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
+CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=n
 
-# CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER=y
-CONFIG_FREERTOS_RUN_TIME_STATS_USING_CPU_CLK=y