DHT22 shown in Webpage (Arduino UNO)

Hello,

I've been strugling with a project for a while. I wanted to make a DHT22 web server and I managed it with a minor problem. I'm using the libraries;
#include <EtherCard.h>
#include <DHT.h>
#include <DHT_U.h>

and the sensors are;
DHT22 (for temperature and humidity)
ENC28J60 module (for LAN connection)

The problem is that a weird "Â" appers next to the printed value and the temperature is not printed, but humidity is printed fine and also the felt temperature is printed with this "Â" next to it.

Could someone help me to resolve this problem?

Besides, I would like an explanation about something in the code (becase this part, I took it almost copy-paste).
At line 96 after the CSS stylization there is this; $D$D:$D$D:$D$D:$D$D and at the lines 97, 98 and 99 there is $S.
What do they mean? It seems like at C, where if you want to print a float value you say %d.
How many of there arguments are valid in arduino?

To solve this problem I tried 2 different techniques;

  1. I printed the values as floats but in the webpage I could see only "Â" without values (the referrence in the HTML was $T in this case)
  2. I converted the floats to strings and I print them with the referrence of $S (like you will see in the code) and the problem is shown in the photo above.

I'm using Arduino UNO

My code is here;
https://www.mediafire.com/file/aq7nnmxn6r3di5s/sketch_jul03a.ino/file

#include <EtherCard.h>
#include <DHT.h>
#include <DHT_U.h>

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,1,8 };

byte Ethernet::buffer[500];
BufferFiller bfill;

#define DHTPIN 8
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

float temp;
float hum;
float felt_temp;
char t_str[6];
char h_str[6];
char ft_str[6];

void setup() {
  // put your setup code here, to run once:
  Serial.begin(57600);
  Serial.println("ENC28J60 Ethernet Server Test");
  Serial.println("DHT22 Temperature/Humidity Sensor");
  dht.begin();
  if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
  ether.staticSetup(myip);
  
  ether.printIp("Local IP: ", ether.myip);
  ether.printIp("Gateway: ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);
  
}



void loop() {
  // put your main code here, to run repeatedly:
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

  if (pos) {
    ether.httpServerReply(homePage());
    //return;
  }
  
  float temp = dht.readTemperature();
  float hum = dht.readHumidity();
  dtostrf(temp, 5, 3, t_str);
  dtostrf(hum, 5, 3, h_str);
    
  if (!isnan(temp) && !isnan(hum)) {
    float felt_temp = dht.computeHeatIndex(temp, hum, false);
    dtostrf(felt_temp, 5, 2, ft_str);
    Serial.println("Temperature :");
    Serial.println(hum);
    Serial.println("Humidity :");
    Serial.println(hum);
    Serial.println("Felt as: ");
    Serial.println(felt_temp);
    //return;
  }
  else {
    if (isnan(temp)) {
      Serial.println("Temperature fail");
      //return;
    }
    else {
      Serial.println("Humidity fail");
      //return;
    }
    //return;
  }
}




static word homePage() {
  long t = millis() / 1000;
  word h = t / 3600;
  byte m = (t / 60) % 60;
  byte s = t % 60;
  bfill = ether.tcpOffset();
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<meta http-equiv='refresh' content='1'/>"
    "<title>DHT22 server</title>"
    "<h1>DHT Temperature / Humidity Server<br></h1>"
    "<h1><font color=black>$D$D:$D$D:$D$D<br></h1>"
    "<h1><font color=red>Temperature: $S °C<br></h1>"
    "<h1><font color=green>Humidity: $S %<br></h1>"
    "<h1><font color=blue>Felt as: $S °C<br></h1>"),
      h/10, h%10, m/10, m%10, s/10, s%10, t_str, h_str, ft_str);
  return bfill.position();
}

If I forgot something, tell me to add it

Thanks in advance! :slightly_smiling_face:

You can't put unicode into your HTML directly. Try replacing your degree symbol with ° which is the HTML entity code for a degree symbol

    "<h1><font color=red>Temperature: $S &deg;C<br></h1>"
    "<h1><font color=green>Humidity: $S %<br></h1>"
    "<h1><font color=blue>Felt as: $S &deg;C<br></h1>"),

as for your other question about $D... it looks like the emit() function uses those to substitute in the values you pass. Commonly referred to as placeholders. $D probably refers to a 'decimal' value, $S = 'string', etc.

1 Like

@blh64
Hm, so the "Â" is a uninode character from degree symbol. And what about the red line (temperature)? It should have shown like the blue line (felt as), but it doesn't show any number.

Besides, is there any way to print the values as floats insted of converting them to strings?

I found this;
https://www.aelius.com/njh/ethercard/class_buffer_filler.html
but according to this table the $T should have worked, but as I mentioned, with $T it didn't show me any number. Maybe was the unicode character of degree symbol that was making the code crazy.

Thank you for you answer!! :smiley:

if you look at the docs in the link you provided, when you have a $D placeholder, you need to provide a uint16_t type variable. For your time, you are using minute and second (m,s) as byte which is 1 byte, but the code is expecting 2 (sizeof word == sizeof uint16_t == 2 on Uno). That is probably what is messing you up.

static word homePage() {
  unsigned long t = millis() / 1000;
  unint16_t h = t / 3600;
  unint16_t m = (t / 60) % 60;
  unint16_t s = t % 60;
  bfill = ether.tcpOffset();
  ...

Then, you can use your temp and humidity as double (float == double on Uno, not true for ESP32)

When you have functions like printf() or your emit() that take a variable number of arguments, the compiler does not know what size the arguments need to be so just puts all of them on the stack as-is. When the function is then parsing the input (first parameter) and doing the substitution, it expects a certain sized variable on the stack.

This is different from a function that takes a known parameter. In that case, if the function takes a long parameter and you pass it a byte parameter, the compiler adds code to promote that variable to the proper size....

With that fix, you may be able to go back to the degree sign embedded directly in your code.. I don't know for sure.