1 (edited by NeTgHoSt 2020-05-24 20:24:04)

Topic: Why does my level indicator go back to 0 bars?

I have a simple map function, using the values from a dht11 sensor,  (converted to farenheit as an integer type) that goes like this:

RemoteXY_Handler ();
  float TempF = dht.readTemperature(true);//Read Temp in F.  
  dtostrf (TempF, 11, 1, RemoteXY.text_1);
  RemoteXY.level_1 = map(TempF, 65, 75, 0, 100);
  RemoteXY.level_1 = constrain(RemoteXY.level_1, 0, 100);

It's supposed to apply the temperature values from 65-75F into a map from 0-100. It works fine until it goes over 75 degrees; the level indicator goes from full to empty, and remains empty above that temperature. Shouldn't it stay full over my desired max temp, especially since i included the map constraint? Am I doing something wrong?

Here is all the code:

#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 15
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// RemoteXY select connection mode and include library 
#define REMOTEXY_MODE__ESP32CORE_WIFI_CLOUD
#include <WiFi.h>
#include <RemoteXY.h>


// RemoteXY connection settings 
#define REMOTEXY_WIFI_SSID "router"
#define REMOTEXY_WIFI_PASSWORD "password"
#define REMOTEXY_CLOUD_SERVER "cloud.remotexy.com"
#define REMOTEXY_CLOUD_PORT 6376
#define REMOTEXY_CLOUD_TOKEN "138c72411d572af403ce616b********"

// RemoteXY configuration
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
   { 255,0,0,32,0,101,0,10,12,0,
  66,0,4,22,18,39,36,12,66,0,
  79,22,17,39,204,12,68,50,25,17,
  51,42,8,36,135,86,97,114,105,97,
  98,108,101,32,49,0,86,97,114,105,
  97,98,108,101,32,50,0,67,0,4,
  16,18,5,2,26,11,67,0,79,16,
  17,5,2,26,11,129,0,4,8,23,
  6,36,84,101,109,112,32,70,58,0,
  129,0,65,8,33,6,6,72,117,109,
  105,100,105,116,121,32,37,0 };
  
// this structure defines all the variables and events of your control interface 
struct {

    // output variables
  int8_t level_1; // =0..100 level position 
  int8_t level_2; // =0..100 level position 
  float TempHumidityHistory_var1;
  float TempHumidityHistory_var2;
  char text_1[11];  // string UTF8 end zero 
  char text_2[11];  // string UTF8 end zero 

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////



void setup() 
{
  RemoteXY_Init (); 
  Serial.begin(9600);
  dht.begin();
  
 
}

void loop() 
{ 
  RemoteXY_Handler ();
  float TempF = dht.readTemperature(true);//Read Temp in F.  
  dtostrf (TempF, 11, 1, RemoteXY.text_1);
  RemoteXY.level_1 = map(TempF, 65, 75, 0, 100);
  RemoteXY.level_1 = constrain(RemoteXY.level_1, 0, 100);
  RemoteXY.TempHumidityHistory_var1 = float (TempF);
  float Humid = dht.readHumidity();//Read Humidity in %RH.
  dtostrf (Humid, 11, 1, RemoteXY.text_2);
  RemoteXY.level_2 = map(TempF, 45, 55, 0, 100);
  RemoteXY.level_2 = constrain(RemoteXY.level_2, 0, 100);
  RemoteXY.TempHumidityHistory_var2 = float (Humid);
  
  // TODO you loop code
  // use the RemoteXY structure for data transfer
  // do not call delay() 


}

2

Re: Why does my level indicator go back to 0 bars?

Use integers not float, and constrain before map

For example:

const float minTemperature = 65.0f;
const float maxTemperature = 75.0f;

RemoteXY.level_1 = map(constrain((int)(TempF * 100.0f), (int)(minTemperature * 100.0f), (int)(maxTemperature * 100.0f)), (int)(minTemperature * 100.0f), (int)(maxTemperature * 100.0f), 0, 100);

3 (edited by NeTgHoSt 2020-05-25 20:50:52)

Re: Why does my level indicator go back to 0 bars?

Okay, I will try and make it work your way, although it looks very foreign to me.. where do I find documentation for the map function that uses syntax like that? It looks very confusing to me vs the normal way I'm used to.. not sure how that works exactly.. combining the constraint.. like what is the "*" for in "TempF * 100.0f" Thank you for helping, I will get to work on deciphering this.

EDIT: For example, is this correct for the Humidity level?

RemoteXY.level_2 = map(constrain((int)(Humid * 100.0%), (int)(minHumidity * 100.0%), (int)(maxHumidity * 100.0%)), (int)(minHumidity * 100.0%), (int)(maxHumidity * 100.0%), 0, 100);

EDIT2: Okay, so apparently the "f" in "100.0f" is called a "numeric operator" which I have not learned yet.. I replaced the "%" signs back to "f" and it compiled. Will try it now.

EDIT3: Now the Level Indicators are stuck at full smile I would upload an image, but I don't think that is possible on this forum?

4

Re: Why does my level indicator go back to 0 bars?

"100.0f" is the standard way to represent a floating point value (of value 100.0). You could also write "100" (not recommended), "100." or "100.f", but "100.0f" is the most common.

map and constrain are functions that needs integers, not float. So you first convert the temperature and humidity, which are floating point values, to integers, but as you don't want to lose precision, you multiply by 100, so for example temperature 70.75°F will become integer 7075. If you didn't multiply by 100 you would lose precision as the integer would be 70

The code will look like this:

RemoteXY.level_1 = map(constrain(7075, 6500, 7500), 6500, 7500, 0, 100);

Which can also be written like this:

int contrainedValue = constrain(7075, 6500, 7500);
RemoteXY.level_1 = map(contrainedValue, 6500, 7500, 0, 100);

5

Re: Why does my level indicator go back to 0 bars?

Ahh okay that makes more sense now! Thank you for taking the time to explain. I love when I learn new things. I have ADD (learning disability haha) so it takes me reading something at least 10X over before it soaks in.. so organization, and knowing exactly what code is doing, is paramount. I will get back to work now! Next issue is to figure out why my ESP32 wifi range sucks so bad! smile

6

Re: Why does my level indicator go back to 0 bars?

After failing to successfully apply the advice I've received here, I'm back to give it another go. I purchased another WiFi module; D1 MINI. This one has no connection issues, like the previous esp32 had that I was using. So, that's good. But I am still failing to get the level indicators to work properly. Here is my updated code, using Guillaume's suggestion for mapping and constraining my values for the indicators. I applied his code to the temperature section of my code, (commenting out my own map/constraints) and left the humidity one alone for now so you can see how I had it sort-of working before:

#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN D4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266WIFI_LIB_CLOUD
#include <ESP8266WiFi.h>

#include <RemoteXY.h>

// RemoteXY connection settings
#define REMOTEXY_WIFI_SSID "ASUS2.4Ghz"
#define REMOTEXY_WIFI_PASSWORD "5309651260"
#define REMOTEXY_CLOUD_SERVER "cloud.remotexy.com"
#define REMOTEXY_CLOUD_PORT 6376
#define REMOTEXY_CLOUD_TOKEN "34abbe937bbb551a58c011365ec0443b"


// RemoteXY configurate
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 255,0,0,32,0,230,0,10,24,2,
  66,163,2,18,44,14,1,34,28,27,
  25,36,130,0,48,10,4,23,0,21,
  63,3,25,66,163,54,18,44,14,34,
  34,28,27,25,190,67,1,1,1,22,
  8,0,5,19,7,36,26,11,67,1,
  53,1,23,8,34,5,18,7,205,26,
  11,68,50,1,33,98,29,0,67,63,
  33,8,36,191,84,101,109,112,101,114,
  97,116,117,114,101,0,72,117,109,105,
  100,105,116,121,0,129,0,1,12,13,
  5,1,29,9,4,164,54,53,42,70,
  0,129,0,37,12,10,5,21,29,9,
  4,38,55,53,42,70,0,129,0,53,
  12,13,5,33,29,14,4,94,52,53,
  37,82,72,0,129,0,82,12,17,5,
  48,29,14,4,192,53,53,37,82,72,
  0,130,0,48,0,4,8,30,3,3,
  18,25,130,0,0,8,100,3,30,24,
  3,43,25,129,0,24,2,18,6,6,
  13,18,6,36,68,101,103,46,32,70,
  0,129,0,76,2,18,6,41,13,14,
  6,205,37,82,72,0,130,0,0,-1,
  100,3,0,0,63,3,25 
};

// this structure defines all the variables and events of your control interface
struct {

  // output variables
  int8_t HumidLevel; // =-100..100 level position
  int8_t TempLevel; // =-100..100 level position
  char TempString[11];  // string UTF8 end zero
  char HumidString[11];  // string UTF8 end zero
  float TempHumidGraph_var1;
  float TempHumidGraph_var2;

  // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////



void setup()
{
  RemoteXY_Init ();
  Serial.begin(9600);
  dht.begin();

  // TODO you setup code

}

void loop()
{
  RemoteXY_Handler ();

  const float minTemp = 65.0f;
  const float maxTemp = 75.0f;

  float TempF = dht.readTemperature(true);//Read Temp in F. 
  dtostrf (TempF, 11, 2, RemoteXY.TempString);
  RemoteXY.TempLevel = map(constrain((int)(TempF*100.0f),(int)(minTemp*100.0f),(int)(maxTemp*100.0f)),(int)(minTemp*100.0f),(int)(maxTemp*100.0f),0,100);
  RemoteXY.TempHumidGraph_var1 = float (TempF);

/*
  float TempF = dht.readTemperature(true);//Read Temp in F.  
  dtostrf (TempF, 11, 2, RemoteXY.TempString);
  int intTempF = TempF;
  RemoteXY.TempLevel = map(intTempF, 65, 75, 0, 100);
  RemoteXY.TempLevel = constrain(RemoteXY.TempLevel, 0, 100);
  RemoteXY.TempHumidGraph_var1 = float (TempF);
*/
/*
  Serial.print("Temp Level: ");
  Serial.println(RemoteXY.TempLevel);
  Serial.print("TempF: ");
  Serial.println(TempF);
  Serial.print("intTempF: ");
  Serial.println(intTempF);
*/
  float Humid = dht.readHumidity();//Read Humidity in %RH.
  dtostrf (Humid, 11, 2, RemoteXY.HumidString);
  int intHumid = Humid;
  RemoteXY.HumidLevel = map(intHumid, 45, 55, 0, 100);
  RemoteXY.HumidLevel = constrain(RemoteXY.HumidLevel, 0, 100);
  RemoteXY.TempHumidGraph_var2 = float (Humid);
 
/* 
  Serial.print("Humidity Level: ");
  Serial.println(RemoteXY.HumidLevel);
  Serial.print("Humid: ");
  Serial.println(Humid);
  Serial.print("intHumid: ");
  Serial.println(intHumid);
  Serial.println();
*/

}

As it exists in this state, my temp level indicator is frozen in the middle, not responding as expected. The humidity level indicator is pegged to the right, now, at 39%RH. It should be pegged to the full left, seeing as my minimum and maximum humidity should range between 45% and 55% on the indicator, respectively. I haven't figured out how to get the serial monitor working with this different module, which is why I have those debug lines commented out currently. Output from that would probably help, if anyone knows what settings to use for the D1 MINI.

7

Re: Why does my level indicator go back to 0 bars?

Guillaume wrote:

.... map and constrain are functions that needs integers, not float.

According to the reference documentation....

"constrain" works with all data-types.

"map" uses integer math, so will truncate (not round) any float values you give it before mapping.

Everything works with smoke - if you let it out, things stop working....

8 (edited by NeTgHoSt 2020-08-04 13:19:21)

Re: Why does my level indicator go back to 0 bars?

Yes, I've used the map and constrain functions before, with predictable results. I cannot figure out yet why I am getting these unexpected results now, with this. I believe I had the baud rate wrong, making the serial monitor not work before. Going to fix that now and see if I can get any useful debug info.

EDIT: My debug info showed that TempF was reading a correct ~80*F, yet my TempLevel variable was coming back as 0! Shouldn't this code below return a value of 100 for TempLevel, if TempF is 80? As in this snippet of my code:

  RemoteXY.TempLevel = map(TempF, 65, 75, 0, 100);
  RemoteXY.TempLevel = constrain(RemoteXY.TempLevel, 0, 100);

So confused sad

Also.. have been trying to get an SSD1306 I2C display to work alongside the RemoteXY stuff, but can't get anything to display on the screen while also having the remotexy code in there.. an example for the SSD1306 library i'm using works fine with the same hardware config, so that shouldn't be this issue. Is it just not possible? Current code:

#include <DHT.h>
#include <DHT_U.h>
#include <Wire.h> 
#include "SSD1306Wire.h"
#define DHTPIN D5
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);
SSD1306Wire display(0x3c, SDA, SCL);

// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266WIFI_LIB_CLOUD
#include <ESP8266WiFi.h>
#include <RemoteXY.h>


// RemoteXY connection settings
#define REMOTEXY_WIFI_SSID "ASUS2.4Ghz"
#define REMOTEXY_WIFI_PASSWORD "5309651260"
#define REMOTEXY_CLOUD_SERVER "cloud.remotexy.com"
#define REMOTEXY_CLOUD_PORT 6376
#define REMOTEXY_CLOUD_TOKEN "34abbe937bbb551a58c011365ec0443b"


// RemoteXY configurate
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 255, 1, 0, 32, 0, 244, 0, 10, 24, 2,
  66, 163, 2, 18, 44, 14, 1, 34, 28, 27,
  25, 36, 130, 0, 48, 10, 4, 23, 0, 21,
  63, 3, 25, 66, 163, 54, 18, 44, 14, 34,
  34, 28, 27, 25, 190, 67, 1, 1, 1, 22,
  8, 0, 5, 19, 7, 36, 26, 11, 67, 1,
  53, 1, 23, 8, 34, 5, 18, 7, 205, 26,
  11, 68, 50, 1, 33, 98, 29, 0, 67, 63,
  33, 8, 36, 191, 84, 101, 109, 112, 101, 114,
  97, 116, 117, 114, 101, 0, 72, 117, 109, 105,
  100, 105, 116, 121, 0, 129, 0, 1, 12, 13,
  5, 1, 29, 9, 4, 164, 54, 53, 42, 70,
  0, 129, 0, 37, 12, 10, 5, 21, 29, 9,
  4, 38, 55, 53, 42, 70, 0, 129, 0, 53,
  12, 13, 5, 33, 29, 14, 4, 94, 52, 53,
  37, 82, 72, 0, 129, 0, 82, 12, 17, 5,
  48, 29, 14, 4, 192, 53, 53, 37, 82, 72,
  0, 130, 0, 48, 0, 4, 8, 30, 3, 3,
  18, 25, 130, 0, 0, 8, 100, 3, 30, 24,
  3, 43, 25, 129, 0, 24, 2, 18, 6, 6,
  13, 18, 6, 36, 68, 101, 103, 46, 32, 70,
  0, 129, 0, 76, 2, 18, 6, 41, 13, 14,
  6, 205, 37, 82, 72, 0, 130, 0, 0, -1,
  100, 3, 0, 0, 63, 3, 25, 1, 0, 44,
  0, 12, 12, 26, 16, 11, 11, 14, 165, 42,
  0
};

// this structure defines all the variables and events of your control interface
struct {

  // input variables
  uint8_t ledButton; // =1 if button pressed, else =0

  // output variables
  int8_t HumidLevel; // =-100..100 level position
  int8_t TempLevel; // =-100..100 level position
  char TempString[11];  // string UTF8 end zero
  char HumidString[11];  // string UTF8 end zero
  float TempHumidGraph_var1;
  float TempHumidGraph_var2;

  // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////
int LEDpin = D4;

void setup()
{
  Serial.begin(9600);
  display.init();
  display.flipScreenVertically();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_10);
  pinMode (LEDpin, OUTPUT);
  dht.begin();
  RemoteXY_Init ();
}

unsigned long previousMillis = 0;
unsigned int LEDBlinkInterval = 20;
boolean LEDBlinkState = true;

void loop()
{
  RemoteXY_Handler ();
  display.drawString(0, 0, "Hello world");
  unsigned long currentMillis = millis();
  if ((unsigned long)(currentMillis - previousMillis) >= LEDBlinkInterval) {
    previousMillis = currentMillis;
    if (LEDBlinkState == true) {
      digitalWrite(LEDpin, HIGH);
      LEDBlinkState = false;
    }
    else {
      digitalWrite(LEDpin, LOW);
      LEDBlinkState = true;
    }
  }
/*
  const float minTemp = 65.0f;
  const float maxTemp = 75.0f;
  
    float TempF = dht.readTemperature(true);//Read Temp in F.
    dtostrf (TempF, 11, 2, RemoteXY.TempString);
    RemoteXY.TempLevel = map(constrain((int)(TempF * 100.0f), (int)(minTemp * 100.0f), (int)(maxTemp * 100.0f)), (int)(minTemp * 100.0f), (int)(maxTemp * 100.0f), 0, 100);
    RemoteXY.TempHumidGraph_var1 = float (TempF);
*/

  float TempF = dht.readTemperature(true);//Read Temp in F.
  dtostrf (TempF, 11, 2, RemoteXY.TempString);
  RemoteXY.TempLevel = map(TempF, 65, 75, 0, 100);
  RemoteXY.TempLevel = constrain(RemoteXY.TempLevel, 0, 100);
  RemoteXY.TempHumidGraph_var1 = float (TempF);

    Serial.print("Temp Level: ");
    Serial.println(RemoteXY.TempLevel);
    Serial.print("TempF: ");
    Serial.println(TempF);
  
  float Humid = dht.readHumidity();//Read Humidity in %RH.
  dtostrf (Humid, 11, 2, RemoteXY.HumidString);
  RemoteXY.HumidLevel = map(Humid, 45, 55, 0, 100);
  RemoteXY.HumidLevel = constrain(RemoteXY.HumidLevel, 0, 100);
  RemoteXY.TempHumidGraph_var2 = float (Humid);

    Serial.print("Humidity Level: ");
    Serial.println(RemoteXY.HumidLevel);
    Serial.print("Humid: ");
    Serial.println(Humid);
  
}