DS18B20 devices detected/configured: %i",ds18_count);
+ return;
+ }
+
+ if (ds18_count > 0 ){
+ hprintf255(request, "DS18B20 devices| Name | "
+ " Address | Pin | CH | Temp | read | ",ds18_count);
+ for (int i=0; i < ds18_count; i++) {
+ const char * pinalias=NULL;
+ char gpioname[10];
+ char tmp[50];
+ pinalias = HAL_PIN_GetPinNameAlias(ds18b20devices.GPIO[i]);
+ if (! pinalias ) {
+ sprintf(gpioname,"GPIO %u",ds18b20devices.GPIO[i]);
+ pinalias = gpioname;
+ }
+ if (ds18b20devices.lasttemp[i] > -127){
+ sprintf(tmp,"%0.2f%i s ago",(ds18b20devices.lasttemp[i]),ds18b20devices.last_read[i]);
+ }
+ else {
+ sprintf(tmp, " -- | --");
+ }
+ int ch=ds18b20devices.channel[i];
+ char chan[5]=" - ";
+ if (ch >=0) sprintf(chan,"%i",(uint8_t)ch);
+ hprintf255(request, " | | %s | "
+ " %02X %02X %02X %02X %02X %02X %02X %02X | "
+ "%s | %s | %s |
",ds18b20devices.name[i],
+ DEV2STR(ds18b20devices.array[i]),
+ pinalias, chan, tmp);
+ }
+ hprintf255(request, "
");
+ }
+}
+
+#include "../httpserver/http_fns.h"
+
+int http_fn_cfg_ds18b20(http_request_t* request)
+{
+ char tmp[64], tmp2[64];
+
+ for (int i=0; i < ds18_count; i++) {
+ sprintf(tmp2,"ds1820name%i",i);
+ if (http_getArg(request->url, tmp2, tmp, sizeof(tmp))) {
+ DS18B20_set_devicename(ds18b20devices.array[i],tmp);
+ }
+ sprintf(tmp2,"ds1820chan%i",i);
+ if (http_getArg(request->url, tmp2, tmp, sizeof(tmp))) {
+ int c=atoi(tmp);
+ DS18B20_set_channel(ds18b20devices.array[i],c);
+ }
+
+ }
+
+ http_setup(request, httpMimeTypeHTML);
+ http_html_start(request, "DS18B20");
+
+
+// poststr_h2(request, "Here you can configure DS18B20 sensors detected or configured");
+ hprintf255(request, "Configure DS18B20 Sensors
");
+ poststr(request,"
Use multiline command
");
+ hprintf255(request, "");
+ poststr(request, htmlFooterReturnToCfgOrMainPage);
+ http_html_end(request);
+ poststr(request, NULL);
+ return 0;
+}
+
+void DS1820_full_OnEverySecond()
+{
+ // for now just find the pin used
+ Pin = PIN_FindPinIndexForRole(IOR_DS1820_IO, -1);
+
+ // only if (at least one) pin is set
+ if(Pin < 0) {
+ DS1820_LOG(INFO, "No Pin found\r\n");
+ return;
+ }
+ //Temperature measurement is done in two repeatable steps.
+ // Step 1 - dsread = 0. Sensor requested to do temperature conversion.
+ // That requires some time - 15-100-750ms, depending on sensor family/vendor.
+ // However, time between steps is always one second.
+ // Step 2 - dsread = 1. Sensor finished conversion, requesting conversion result.
+
+ // request temp if conversion was requested two seconds after request
+ // if (dsread == 1 && g_secondsElapsed % 5 == 2) {
+ // better if we don't use parasitic power, we can check if conversion is ready
+ DS1820_LOG(DEBUG, ".. Pin %i found! dsread=%i \r\n",Pin,dsread);
+ if(dsread == 1){
+#if WINDOWS
+ bk_printf("Reading temperature from fake DS18B20 sensor(s)\r\n");
+ for (int i=0; i < ds18_count; i++) {
+ ds18b20devices.last_read[i] += 1 ;
+ errcount = 0;
+ float t_float = 20.0 + i/10.0 + (float)(g_secondsElapsed%100)/100.0;
+ ds18b20devices.lasttemp[i] = t_float;
+ ds18b20devices.last_read[i] = 0;
+ if (ds18b20devices.channel[i]>=0) CHANNEL_Set(ds18b20devices.channel[i], (int)(t_float*100), CHANNEL_SET_FLAG_SILENT);
+ lastconv = g_secondsElapsed;
+ }
+#else // to #if WINDOWS
+ float t_float = -127;
+ const char * pinalias;
+ char gpioname[10];
+ DS1820_LOG(INFO, "Reading temperature from %i DS18B20 sensor(s)\r\n",ds18_count);
+ for (int i=0; i < ds18_count; i++) {
+ pinalias = HAL_PIN_GetPinNameAlias(ds18b20devices.GPIO[i]);
+ if (! pinalias ) {
+ sprintf(gpioname,"GPIO %u",ds18b20devices.GPIO[i]);
+ pinalias = gpioname;
+ }
+ ds18b20devices.last_read[i] += 1 ;
+ errcount = 0;
+ t_float = -127;
+ while ( t_float == -127 && errcount++ < 5){
+ t_float = ds18b20_getTempC((const uint8_t*)ds18b20devices.array[i]);
+ DS1820_LOG(DEBUG, "Device %i (" DEVSTR ") reported %0.2f\r\n",i,
+ DEV2STR(ds18b20devices.array[i]),t_float);
+ }
+ if (t_float != -127){
+ ds18b20devices.lasttemp[i] = t_float;
+ ds18b20devices.last_read[i] = 0;
+ if (ds18b20devices.channel[i]>=0) CHANNEL_Set(ds18b20devices.channel[i], (int)(t_float*100), CHANNEL_SET_FLAG_SILENT);
+ lastconv = g_secondsElapsed;
+ DS1820_LOG(INFO, "Sensor " DEVSTR " on %s reported %0.2f\r\n",DEV2STR(ds18b20devices.array[i]),pinalias,t_float);
+ } else{
+ if (ds18b20devices.last_read[i] > 60) {
+ DS1820_LOG(ERROR, "No temperature read for over 60 seconds for"
+ " device %i (" DEVSTR " on %s)! Setting to -127°C!\r\n",i,
+ DEV2STR(ds18b20devices.array[i]),pinalias);
+ ds18b20devices.lasttemp[i] = -127;
+ dsread=0;
+ }
+ }
+ }
+#endif // to #if WINDOWS
+ dsread=0;
+ }
+ else{
+// bk_printf("No tepms read! dsread=%i -- isConversionComplete()=%i\r\n",dsread,isConversionComplete());
+// DS1820_LOG(INFO, "No tepms read! dsread=%i -- isConversionComplete()=%i\r\n",dsread,isConversionComplete());
+ for (int i=0; i < ds18_count; i++) {
+ ds18b20devices.last_read[i] += 1 ;
+ }
+ if(dsread == 0 && (g_secondsElapsed % ds18_conversionPeriod == 0 || lastconv == 0))
+ {
+ DS1820_LOG(INFO, "Starting conversion");
+ for (int i=0; i
-#define noInterrupts() taskENTER_CRITICAL()
-#define interrupts() taskEXIT_CRITICAL()
-#endif
+#include "drv_ds1820_common.h"
static uint8_t dsread = 0;
static int Pin = -1;
-static int t = -127;
+static int t = -12700; //t is 100 * temperature (so we can represent 2 fractional digits)
static int errcount = 0;
static int lastconv; // secondsElapsed on last successfull reading
static uint8_t ds18_family = 0;
@@ -23,268 +15,10 @@ static int ds18_conversionPeriod = 0;
static int DS1820_DiscoverFamily();
+
#define DS1820_LOG(x, fmt, ...) addLogAdv(LOG_##x, LOG_FEATURE_SENSOR, "DS1820[%i] - " fmt, Pin, ##__VA_ARGS__)
-// usleep adopted from DHT driver
-static void usleepds(int r)
-{
- HAL_Delay_us(r);
-}
-// add some "special timing" for Beken - works w/o and with powerSave 1 for me
-static void usleepshort(int r) //delay function do 10*r nops, because rtos_delay_milliseconds is too much
-{
-#if PLATFORM_BEKEN
- int newr = r / (3 * g_powersave + 1); // devide by 4 if powerSave set to 1
- for(volatile int i = 0; i < newr; i++)
- {
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- //__asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- __asm__("nop\nnop\nnop\nnop");
- }
-
-#else
- usleepds(r);
-#endif
-}
-
-static void usleepmed(int r) //delay function do 10*r nops, because rtos_delay_milliseconds is too much
-{
-#if PLATFORM_BEKEN
- int newr = 10 * r / (10 + 5 * g_powersave); // devide by 1.5 powerSave set to 1
- for(volatile int i = 0; i < newr; i++)
- {
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); // 5
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- }
-
-#else
- usleepds(r);
-#endif
-}
-
-static void usleeplong(int r) //delay function do 10*r nops, because rtos_delay_milliseconds is too much
-{
-#if PLATFORM_BEKEN
- int newr = 10 * r / (10 + 5 * g_powersave); // devide by 1.5 powerSave set to 1
- for(volatile int i = 0; i < newr; i++)
- {
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- // __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); // 5
- __asm__("nop\nnop\nnop\nnop\nnop"); // 5
- }
-
-#else
- usleepds(r);
-#endif
-}
-
-/*
-
-timing numbers and general code idea from
-
-https://www.analog.com/en/resources/technical-articles/1wire-communication-through-software.html
-
-Parameter Speed Recommended (µs)
-A Standard 6
-B Standard 64
-C Standard 60
-D Standard 10
-E Standard 9
-F Standard 55
-G Standard 0
-H Standard 480
-I Standard 70
-J Standard 410
-
-*/
-
-#define OWtimeA 6
-#define OWtimeB 64
-#define OWtimeC 60
-#define OWtimeD 10
-#define OWtimeE 9
-#define OWtimeF 55
-#define OWtimeG 0
-#define OWtimeH 480
-#define OWtimeI 70
-#define OWtimeJ 410
-
-#define READ_ROM 0x33
-#define SKIP_ROM 0xCC
-#define CONVERT_T 0x44
-#define READ_SCRATCHPAD 0xBE
-#define WRITE_SCRATCHPAD 0x4E
-
-static int OWReset(int Pin)
-{
- int result;
-
- //usleep(OWtimeG);
- HAL_PIN_Setup_Output(Pin);
- HAL_PIN_SetOutputValue(Pin, 0); // Drives DQ low
- usleeplong(OWtimeH);
- HAL_PIN_SetOutputValue(Pin, 1); // Releases the bus
- usleepmed(OWtimeI);
- HAL_PIN_Setup_Input(Pin);
- result = HAL_PIN_ReadDigitalInput(Pin) ^ 0x01; // Sample for presence pulse from slave
- usleeplong(OWtimeJ); // Complete the reset sequence recovery
- return result; // Return sample presence pulse result
-}
-
-//-----------------------------------------------------------------------------
-// Send a 1-Wire write bit. Provide 10us recovery time.
-//-----------------------------------------------------------------------------
-static void OWWriteBit(int Pin, int bit)
-{
- if(bit)
- {
- // Write '1' bit
- HAL_PIN_Setup_Output(Pin);
- noInterrupts();
- HAL_PIN_SetOutputValue(Pin, 0); // Drives DQ low
- usleepshort(OWtimeA);
- HAL_PIN_SetOutputValue(Pin, 1); // Releases the bus
- interrupts(); // hope for the best for the following timer and keep CRITICAL as short as possible
- usleepmed(OWtimeB); // Complete the time slot and 10us recovery
- }
- else
- {
- // Write '0' bit
- HAL_PIN_Setup_Output(Pin);
- noInterrupts();
- HAL_PIN_SetOutputValue(Pin, 0); // Drives DQ low
- usleepmed(OWtimeC);
- HAL_PIN_SetOutputValue(Pin, 1); // Releases the bus
- interrupts(); // hope for the best for the following timer and keep CRITICAL as short as possible
- usleepshort(OWtimeD);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Read a bit from the 1-Wire bus and return it. Provide 10us recovery time.
-//-----------------------------------------------------------------------------
-static int OWReadBit(int Pin)
-{
- int result;
-
- noInterrupts();
- HAL_PIN_Setup_Output(Pin);
- HAL_PIN_SetOutputValue(Pin, 0); // Drives DQ low
- usleepshort(OWtimeA);
- HAL_PIN_SetOutputValue(Pin, 1); // Releases the bus
- usleepshort(OWtimeE);
- HAL_PIN_Setup_Input(Pin);
- result = HAL_PIN_ReadDigitalInput(Pin); // Sample for presence pulse from slave
- interrupts(); // hope for the best for the following timer and keep CRITICAL as short as possible
- usleepmed(OWtimeF); // Complete the time slot and 10us recovery
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// Poll if DS1820 temperature conversion is complete
-//-----------------------------------------------------------------------------
-static int DS1820TConversionDone(int Pin)
-{
- // Write '1' bit
- OWWriteBit(Pin, 1);
- // check for '1' - conversion complete (will be '0' else)
- return OWReadBit(Pin);
-}
-
-
-//-----------------------------------------------------------------------------
-// Write 1-Wire data byte
-//-----------------------------------------------------------------------------
-static void OWWriteByte(int Pin, int data)
-{
- int loop;
-
- // Loop to write each bit in the byte, LS-bit first
- for(loop = 0; loop < 8; loop++)
- {
- OWWriteBit(Pin, data & 0x01);
-
- // shift the data byte for the next bit
- data >>= 1;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Read 1-Wire data byte and return it
-//-----------------------------------------------------------------------------
-static int OWReadByte(int Pin)
-{
- int loop, result = 0;
-
- for(loop = 0; loop < 8; loop++)
- {
- // shift the result to get it ready for the next bit
- result >>= 1;
-
- // if result is one, then set MS bit
- if(OWReadBit(Pin))
- result |= 0x80;
- }
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// Write a 1-Wire data byte and return the sampled result.
-//-----------------------------------------------------------------------------
-static int OWTouchByte(int Pin, int data)
-{
- int loop, result = 0;
-
- for(loop = 0; loop < 8; loop++)
- {
- // shift the result to get it ready for the next bit
- result >>= 1;
-
- // If sending a '1' then read a bit else write a '0'
- if(data & 0x01)
- {
- if(OWReadBit(Pin))
- result |= 0x80;
- }
- else
- OWWriteBit(Pin, 0);
-
- // shift the data byte for the next bit
- data >>= 1;
- }
- return result;
-}
-
-// quicker CRC with lookup table
-// based on code found here: https://community.st.com/t5/stm32-mcus-security/use-stm32-crc-to-compare-ds18b20-crc/m-p/333749/highlight/true#M4690
-// Dallas 1-Wire CRC Test App -
-// x^8 + x^5 + x^4 + 1 0x8C (0x131)
-
-static uint8_t Crc8CQuick(uint8_t* Buffer, uint8_t Size)
-{
- // Nibble table for polynomial 0x8C
- static const uint8_t CrcTable[] =
- {
- 0x00,0x9D,0x23,0xBE,0x46,0xDB,0x65,0xF8,
- 0x8C,0x11,0xAF,0x32,0xCA,0x57,0xE9,0x74
- };
- uint8_t Crc = 0x00;
- while(Size--)
- {
- Crc ^= *Buffer++; // Apply Data
- Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; // Two rounds of 4-bits
- Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F];
- }
- return(Crc);
-}
int DS1820_getTemp()
{
@@ -304,12 +38,14 @@ static commandResult_t Cmd_SetResolution(const void* context, const char* cmd, c
DS1820_LOG(ERROR, "DS1820_SetResolution not supported by sensor");
return CMD_RES_UNKNOWN_COMMAND;
}
+ // arg can be 9 10 11 12
+ // the cfg for resolution shall be 9:0x1F 10:0x3F 11:0x5F 12:0x7F
+ // ignoring the "0x0F" an lookig just at the first digit,
+ // we can easily see this is 1+(arg-9)*2
+ // so this can be written as
+ uint8_t cfg = 0x1F | (arg-9)<<5 ;
- uint8_t cfg = arg;
- cfg = cfg - 9;
- cfg = cfg * 32;
- cfg |= 0x1F;
-
+ // use simple temperature setting, always write, ignoring actual scratchpad
if(OWReset(Pin) == 0)
{
DS1820_LOG(ERROR, "WriteScratchpad Reset failed");
@@ -341,15 +77,17 @@ void DS1820_driver_Init()
//cmddetail:"fn":"Cmd_SetResolution","file":"drv/drv_ds1820_simple.c","requires":"",
//cmddetail:"examples":""}
CMD_RegisterCommand("DS1820_SetResolution", Cmd_SetResolution, NULL);
-
//Find PIN and check device so DS1820_SetResolution could be used in autoexec.bat
Pin = PIN_FindPinIndexForRole(IOR_DS1820_IO, -1);
if (Pin >= 0)
DS1820_DiscoverFamily();
};
-void DS1820_AppendInformationToHTTPIndexPage(http_request_t* request)
+void DS1820_AppendInformationToHTTPIndexPage(http_request_t* request, int bPreState)
{
+ if (bPreState){
+ return;
+ }
hprintf255(request, "DS1820 Temperature: %.2f C (read %i secs ago)
", (float)t / 100, g_secondsElapsed - lastconv);
}
@@ -357,7 +95,7 @@ static int DS1820_DiscoverFamily()
{
if(!OWReset(Pin))
{
- DS1820_LOG(DEBUG, "Discover Reset failed");
+// DS1820_LOG(DEBUG, "Discover Reset failed");
return 0;
}
@@ -383,28 +121,32 @@ static int DS1820_DiscoverFamily()
if(family == 0x10 || family == 0x28)
{
ds18_family = family;
- DS1820_LOG(INFO, "Discover Family - discovered %x", family);
+ DS1820_LOG(INFO, "Discoverd Family: %x", family);
return 1;
}
else
{
- DS1820_LOG(DEBUG, "Discover Family %x not supported", family);
+ DS1820_LOG(DEBUG, "Discovered Family %x not supported", family);
return 0;
}
}
+
+
void DS1820_OnEverySecond()
{
uint8_t scratchpad[9], crc;
int16_t raw;
+
// for now just find the pin used
Pin = PIN_FindPinIndexForRole(IOR_DS1820_IO, -1);
// only if pin is set
- if(Pin < 0)
+ if(Pin < 0) {
+ DS1820_LOG(INFO, "No Pin found\r\n");
return;
-
+ }
//Temperature measurement is done in two repeatable steps.
// Step 1 - dsread = 0. Sensor requested to do temperature conversion.
// That requires some time - 15-100-750ms, depending on sensor family/vendor.
@@ -468,10 +210,12 @@ void DS1820_OnEverySecond()
}
// Raw is t * 128
+/*
t = (raw / 128) * 100; // Whole degrees
int frac = (raw % 128) * 100 / 128; // Fractional degrees
t += t > 0 ? frac : -frac;
-
+*/
+ t = (raw * 100) / 128; // no need to calc fractional, if we can simply get 100 * temp in one line
dsread = 0;
lastconv = g_secondsElapsed;
CHANNEL_Set(g_cfg.pins.channels[Pin], t, CHANNEL_SET_FLAG_SILENT);
@@ -492,7 +236,6 @@ void DS1820_OnEverySecond()
return;
}
}
-
if(OWReset(Pin) == 0)
{
lastconv = -1; // reset lastconv to avoid immediate retry
@@ -521,15 +264,16 @@ void DS1820_OnEverySecond()
// calc a new factor for usleepds
DS1820_LOG(ERROR, "usleepds duration divergates - proposed factor to adjust usleepds %f ", (float)100 / duration);
}
-#endif
+#endif // #if DS1820_DEBUG
return;
}
DS1820_LOG(INFO, "Starting conversion");
OWWriteByte(Pin, SKIP_ROM);
OWWriteByte(Pin, CONVERT_T);
-
errcount = 0;
dsread = 1;
}
}
+
+#endif // to #if (ENABLE_DRIVER_DS1820)
diff --git a/src/driver/drv_ds1820_simple.h b/src/driver/drv_ds1820_simple.h
index 21370652f..94d93a427 100644
--- a/src/driver/drv_ds1820_simple.h
+++ b/src/driver/drv_ds1820_simple.h
@@ -7,13 +7,11 @@
#include "../cmnds/cmd_public.h"
#include "../mqtt/new_mqtt.h"
#include "../logging/logging.h"
-#include "drv_local.h"
-#include "drv_uart.h"
#include "../httpserver/new_http.h"
-#include "../hal/hal_pins.h"
+
int DS1820_getTemp();
void DS1820_driver_Init();
void DS1820_OnEverySecond();
-void DS1820_AppendInformationToHTTPIndexPage(http_request_t *request);
+void DS1820_AppendInformationToHTTPIndexPage(http_request_t *request, int bPreState);
diff --git a/src/driver/drv_main.c b/src/driver/drv_main.c
index 2344f50d8..b580a82ad 100644
--- a/src/driver/drv_main.c
+++ b/src/driver/drv_main.c
@@ -13,6 +13,8 @@
#include "drv_tuyaMCU.h"
#include "drv_uart.h"
#include "drv_ds1820_simple.h"
+#include "drv_ds1820_full.h"
+#include "drv_ds1820_common.h"
typedef struct driver_s {
@@ -453,6 +455,13 @@ static driver_t g_drivers[] = {
//drvdetail:"requires":""}
{ "DS1820", DS1820_driver_Init, DS1820_OnEverySecond, DS1820_AppendInformationToHTTPIndexPage, NULL, NULL, NULL, false },
#endif
+#if ENABLE_DRIVER_DS1820_FULL
+ //drvdetail:{"name":"DS1820_FULL",
+ //drvdetail:"title":"TODO",
+ //drvdetail:"descr":"Driver for oneWire temperature sensor DS18(B)20.",
+ //drvdetail:"requires":""}
+ { "DS1820_FULL", DS1820_full_driver_Init, DS1820_full_OnEverySecond, DS1820_full_AppendInformationToHTTPIndexPage, NULL, NULL, NULL, false },
+#endif
#if ENABLE_DRIVER_HT16K33
//drvdetail:{"name":"HT16K33",
//drvdetail:"title":"TODO",
@@ -626,8 +635,24 @@ void DRV_StartDriver(const char* name) {
return;
}
bStarted = 0;
+#if (ENABLE_DRIVER_DS1820) && (ENABLE_DRIVER_DS1820_FULL)
+ bool twinrunning=false;
+#endif
for (i = 0; i < g_numDrivers; i++) {
if (!stricmp(g_drivers[i].name, name)) {
+#if (ENABLE_DRIVER_DS1820) && (ENABLE_DRIVER_DS1820_FULL)
+ twinrunning=false;
+ if (!stricmp("DS1820", name) && DRV_IsRunning("DS1820_FULL")){
+ addLogAdv(LOG_ERROR, LOG_FEATURE_MAIN, "Drv DS1820_FULL is already loaded - can't start DS1820, too.\n", name);
+ twinrunning=true;
+ break;
+ }
+ if (!stricmp("DS1820_FULL", name) && DRV_IsRunning("DS1820")){
+ addLogAdv(LOG_ERROR, LOG_FEATURE_MAIN, "Drv DS1820 is already loaded - can't start DS1820_FULL, too.\n", name);
+ twinrunning=true;
+ break;
+ }
+#endif
if (g_drivers[i].bLoaded) {
addLogAdv(LOG_INFO, LOG_FEATURE_MAIN, "Drv %s is already loaded.\n", name);
bStarted = 1;
@@ -645,7 +670,11 @@ void DRV_StartDriver(const char* name) {
}
}
}
+#if (ENABLE_DRIVER_DS1820) && (ENABLE_DRIVER_DS1820_FULL)
+ if (!bStarted && !twinrunning) {
+#else
if (!bStarted) {
+#endif
addLogAdv(LOG_INFO, LOG_FEATURE_MAIN, "Driver %s is not known in this build.\n", name);
addLogAdv(LOG_INFO, LOG_FEATURE_MAIN, "Available drivers: ");
for (i = 0; i < g_numDrivers; i++) {
diff --git a/src/driver/ds18b20.c b/src/driver/ds18b20.c
deleted file mode 100644
index 65bd8fb8e..000000000
--- a/src/driver/ds18b20.c
+++ /dev/null
@@ -1,475 +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 .
-*/
-#include "../new_common.h"
-#include "../new_pins.h"
-#include "../new_cfg.h"
-// Commands register, execution API and cmd tokenizer
-#include "../cmnds/cmd_public.h"
-#include "../mqtt/new_mqtt.h"
-#include "../logging/logging.h"
-#include "drv_local.h"
-#include "drv_uart.h"
-#include "../httpserver/new_http.h"
-#include "../hal/hal_pins.h"
-
-#include "ds18b20.h"
-
-// 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) {
- HAL_PIN_Setup_Output(DS_GPIO);
- noInterrupts();
- HAL_PIN_SetOutputValue(DS_GPIO, 0);
- usleep(6);
- HAL_PIN_Setup_Input(DS_GPIO); // release bus
- usleep(64);
- interrupts();
- }
- else {
- HAL_PIN_Setup_Output(DS_GPIO);
- noInterrupts();
- HAL_PIN_SetOutputValue(DS_GPIO, 0);
- usleep(60);
- HAL_PIN_Setup_Input(DS_GPIO); // release bus
- usleep(10);
- interrupts();
- }
-}
-
-// Reads one bit from bus
-unsigned char ds18b20_read(void) {
- unsigned char value = 0;
- HAL_PIN_Setup_Output(DS_GPIO);
- noInterrupts();
- HAL_PIN_SetOutputValue(DS_GPIO, 0);
- usleep(6);
- HAL_PIN_Setup_Input(DS_GPIO);
- usleep(9);
- value = HAL_PIN_ReadDigitalInput(DS_GPIO);
- usleep(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);
- }
- usleep(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;
- usleep(15);
- }
- return(data);
-}
-// Sends reset pulse
-unsigned char ds18b20_reset(void) {
- unsigned char presence;
- HAL_PIN_Setup_Output(DS_GPIO);
- noInterrupts();
- HAL_PIN_SetOutputValue(DS_GPIO, 0);
- usleep(480);
- HAL_PIN_SetOutputValue(DS_GPIO, 1);
- HAL_PIN_Setup_Input(DS_GPIO);
- usleep(70);
- presence = (HAL_PIN_ReadDigitalInput(DS_GPIO) == 0);
- usleep(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_getTempF(const DeviceAddress *deviceAddress) {
- ScratchPad scratchPad;
- if (ds18b20_isConnected(deviceAddress, scratchPad)) {
- int16_t rawTemp = calculateTemperature(deviceAddress, scratchPad);
- if (rawTemp <= DEVICE_DISCONNECTED_RAW)
- return DEVICE_DISCONNECTED_F;
- // C = RAW/128
- // F = (C*1.8)+32 = (RAW/128*1.8)+32 = (RAW*0.0140625)+32
- return ((float)rawTemp * 0.0140625f) + 32.0f;
- }
- return DEVICE_DISCONNECTED_F;
-}
-
-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_F;
- // 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_F;
-}
-
-// 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;
-}
\ No newline at end of file
diff --git a/src/driver/ds18b20.h b/src/driver/ds18b20.h
deleted file mode 100644
index 929005674..000000000
--- a/src/driver/ds18b20.h
+++ /dev/null
@@ -1,84 +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 .
-*/
-
-#ifndef DS18B20_H_
-#define DS18B20_H_
-
-#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
\ No newline at end of file
diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c
index fb02b0714..290550688 100644
--- a/src/httpserver/http_fns.c
+++ b/src/httpserver/http_fns.c
@@ -2615,6 +2615,9 @@ int http_fn_cfg(http_request_t* request) {
postFormAction(request, "cfg_wifi", "Configure WiFi & Web");
#if ENABLE_HTTP_IP
postFormAction(request, "cfg_ip", "Configure IP");
+#endif
+#if (ENABLE_DRIVER_DS1820_FULL)
+ postFormAction(request, "cfg_ds18b20", "Configure DS18B20 Sensors");
#endif
postFormAction(request, "cfg_mqtt", "Configure MQTT");
#if ENABLE_HTTP_NAMES
diff --git a/src/httpserver/new_http.c b/src/httpserver/new_http.c
index 066ca89c1..a34cff546 100644
--- a/src/httpserver/new_http.c
+++ b/src/httpserver/new_http.c
@@ -855,6 +855,12 @@ int HTTP_ProcessPacket(http_request_t* request) {
#if ENABLE_HTTP_IP
if (http_checkUrlBase(urlStr, "cfg_ip")) return http_fn_cfg_ip(request);
#endif
+#if (ENABLE_DRIVER_DS1820_FULL)
+ // including "../driver/drv_ds1820_simple.h" will complain about typedefs not used here
+ // so lets declare it "extern"
+ extern int http_fn_cfg_ds18b20(http_request_t* request);
+ if (http_checkUrlBase(urlStr, "cfg_ds18b20")) return http_fn_cfg_ds18b20(request);
+#endif
#if ENABLE_HTTP_WEBAPP
if (http_checkUrlBase(urlStr, "cfg_webapp")) return http_fn_cfg_webapp(request);
diff --git a/src/new_pins.c b/src/new_pins.c
index c18859d00..71c4c20eb 100644
--- a/src/new_pins.c
+++ b/src/new_pins.c
@@ -1735,6 +1735,10 @@ bool CHANNEL_IsInUse(int ch) {
}
}
}
+#if (ENABLE_DRIVER_DS1820_FULL)
+#include "driver/drv_ds1820_full.h"
+ return ds18b20_used_channel(ch);
+#endif
return false;
}
diff --git a/src/obk_config.h b/src/obk_config.h
index d42d16184..b3b4a1aab 100644
--- a/src/obk_config.h
+++ b/src/obk_config.h
@@ -174,6 +174,7 @@
#define ENABLE_DRIVER_SHIFTREGISTER 1
#define ENABLE_OBK_SCRIPTING 1
#define ENABLE_OBK_BERRY 1
+#define ENABLE_DRIVER_DS1820_FULL 1
#elif PLATFORM_BL602
@@ -319,7 +320,8 @@
#if (OBK_VARIANT == OBK_VARIANT_SENSORS)
#define ENABLE_DRIVER_BMP280 1
#define ENABLE_DRIVER_BMPI2C 1
-#define ENABLE_DRIVER_SHT3X 1
+#define ENABLE_DRIVER_SHT3X 1
+#define ENABLE_DRIVER_DS1820_FULL 1
#endif