Passing variable to bfill.emit_p function from loop

I am hosting a web server from my Arduino uno and have a sensor also connected. I have both of these working independently, so I know it is not a hardware issue, and am trying to display the sensor information on the webserver. The variable I created for the sensor information is not being displayed on the web server. The variable CM reads a number in the serial monitor but reads 0 on my webpage. The t variable being used in the same function to display the webpage works correctly, so I am wondering if I am doing something wrong with the CM variable.

Here is the code:

// Arduino Webserver with Ethernet shield ENC28J60. Static IP or DHCP.
// Webpage shows temperature from sensor DS18B20 and time since reset.
// Library https://github.com/jcw/ethercard ethercard-master rename to ethercardmaster 
// 2010-05-28 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php
// Library https://github.com/milesburton/Arduino-Temperature-Control-Library rename to DallasTemperature
// Dallas library is buggy. Examples compiled often show -127. 
// Code adopted by Janis Alnis 2016.11.30. Compiled with Arduino IDE version 1.0.0. 

// ENC SCK -> Arduino pin 13 
// ENC SO  -> Arduino pin 12
// ENC SI  -> Arduino pin 11
// ENC CS  -> Arduino pin 10  (some other online examples use pin 8)
// ENC VCC ->  3V3 from USB serial adapter CP2102 or PL2303 but not enough from CH340
// ENC GND -> GND
#include <SPI.h>

#include <EEPROM.h>
#include "RTClib.h"
#include <EtherCard.h>
int trigger = 7;
int echoPin = 8;
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x49,0x2D,0x30,0x33 };
#define STATIC 1  //  DHCP=0 ,  static=1
#if STATIC  
static byte myip[] = { 192,168,0,76 }; // static ip address
#endif
byte Ethernet::buffer[500]; BufferFiller bfill;




float t1;
float CM; 
int button=3; long state=0; long clicks=0; // for the digital input button
long AIN;
long duration, cm, mm, MM;

void setup(){ Serial.begin(9600);
 pinMode(7, OUTPUT);
  pinMode(8, INPUT);

   #ifndef ESP8266
  //while(!Serial);
     //wait for serial port to connect
  #endif

  rtc.begin();

  /* If the RTC is uninitialized, set the time to the compile time.
   *  Set a bit in EEPROM so that we don't set the RTC on reset or reprogram.
   *  To set the time, clear the bit using eeprom_clear.ino.
   */
  if (!rtc.isrunning() || !EEPROM.read(0)) {
    Serial.println("Setting RTC");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    EEPROM.write(0, 1);
  }

  Serial.println("\nArduino Webserver with ENC28J60 Ethernet");
  Serial.println ("Temperature sensor DS18B20 on D8");
  pinMode(button, INPUT); digitalWrite(button, HIGH); // button
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");
#if STATIC 
   ether.staticSetup(myip);
#else
  if (!ether.dhcpSetup()) 
     Serial.println("DHCP failed");
#endif
  ether.printIp("IP:  ", ether.myip);
}


 static word homePage() {

  long T1=int(t1); long T1A=t1*10-10*T1; // fractional part
  long t = millis() / 1000;

bfill = ether.tcpOffset();
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n<meta http-equiv='refresh' content='1'/>"
    "<body><html><u>Arduino Ethernet ENC28J60 webserver #3</u><BR><B>Uptime $L (Seconds)<BR><B>Uptime $L (Seconds)"),
      t,CM);
  return bfill.position();
}



void loop () {
 
  if (millis()%100>70){if (digitalRead(button)==LOW) {if (state==0) {clicks=clicks+1; state=1;}} 
    delay(50); if (digitalRead(button)==HIGH){if (state==1) {state=0;}}}

  
//    Serial.print ("t1= ");  Serial.println (t1);}    // t2 = sensors.getTempCByIndex(1); 

AIN=analogRead(A0); AIN=AIN*100/1023;   analogWrite(9, AIN);           

  word len = ether.packetReceive();  word pos = ether.packetLoop(len);
    if (pos) ether.httpServerReply(homePage()); // if valid tcp data received send web page


long duration, cm, CM, mm, MM;
DateTime now = rtc.now();
digitalWrite(7, LOW);
delayMicroseconds(2);
digitalWrite(7,HIGH);
delayMicroseconds(10);
digitalWrite(7,LOW);

duration=pulseIn(8, HIGH);
 // convert the time into a distance
cm = (duration / 2.0) / 27.9;
mm = (duration / 2.0) / 2.79;

CM = (64.3 - cm); // Substract the total distance in cm by the distance the sensor is measuring
MM = (643 - mm);
delay(10);
{
  /* This poortion of code writes the distance measured by the sensor on one line
   *  followed by the distance after substraction of total distance
   *  followed by the date and time the data was calculated
   */
    Serial.print(CM);
      Serial.print(",cm,");
      Serial.print(MM);
      Serial.print(",mm,");
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
 
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
  
    Serial.println();
    delay(100);

}
}

You have CM declared twice... so my guess is you are picking up the wrong variable when calling the routine.

I fixed this issue by removing CM from the long; part now the webserver is returning very large numbers ( example of one:181141545) while the serial monitor is displaying 41.

Sounds like it is overflowing.

Is the variable supposed to be a long? ... and you now have declared as float?

I am not sure. I have tried float, long, int and still get this behavior on the webpage but not the serial monitor.

These variable are also declared twice.

long duration, cm, mm, MM;
long duration, cm, CM, mm, MM;

Can you add a print to just before you call PSTR()

  Serial.print("CM = ");  
  Serial.println(CM);

  bfill.emit_p(PSTR(
                 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n<meta http-equiv='refresh' content='1'/>"
                 "<body><html><u>Arduino Ethernet ENC28J60 webserver #3</u><BR><B>Uptime $L (Seconds)<BR><B>Uptime $L (Seconds)"),
               t, CM);

Post your complete current code.

I did this, and the serial monitor shows the correct value for CM, but the web server still shows a really long number.

// Arduino Webserver with Ethernet shield ENC28J60. Static IP or DHCP.
// Webpage shows temperature from sensor DS18B20 and time since reset.
// Library https://github.com/jcw/ethercard ethercard-master rename to ethercardmaster 
// 2010-05-28 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php
// Library https://github.com/milesburton/Arduino-Temperature-Control-Library rename to DallasTemperature
// Dallas library is buggy. Examples compiled often show -127. 
// Code adopted by Janis Alnis 2016.11.30. Compiled with Arduino IDE version 1.0.0. 

// ENC SCK -> Arduino pin 13 
// ENC SO  -> Arduino pin 12
// ENC SI  -> Arduino pin 11
// ENC CS  -> Arduino pin 10  (some other online examples use pin 8)
// ENC VCC ->  3V3 from USB serial adapter CP2102 or PL2303 but not enough from CH340
// ENC GND -> GND
#include <SPI.h>

#include <EEPROM.h>
#include "RTClib.h"
#include <EtherCard.h>
int trigger = 7;
int echoPin = 8;
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x49,0x2D,0x30,0x33 };
#define STATIC 1  //  DHCP=0 ,  static=1
#if STATIC  
static byte myip[] = { 192,168,0,76 }; // static ip address
#endif
byte Ethernet::buffer[500]; BufferFiller bfill;




long t1;
float CM; // depth
int button=3; long state=0; long clicks=0; // for the digital input button
long AIN;
long duration, cm, mm, MM;

void setup(){ Serial.begin(9600);
 pinMode(7, OUTPUT);
  pinMode(8, INPUT);

   #ifndef ESP8266
  //while(!Serial);
     //wait for serial port to connect
  #endif

  rtc.begin();

  /* If the RTC is uninitialized, set the time to the compile time.
   *  Set a bit in EEPROM so that we don't set the RTC on reset or reprogram.
   *  To set the time, clear the bit using eeprom_clear.ino.
   */
  if (!rtc.isrunning() || !EEPROM.read(0)) {
    Serial.println("Setting RTC");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    EEPROM.write(0, 1);
  }

  Serial.println("\nArduino Webserver with ENC28J60 Ethernet");
  Serial.println ("Temperature sensor DS18B20 on D8");
  pinMode(button, INPUT); digitalWrite(button, HIGH); // button
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");
#if STATIC 
   ether.staticSetup(myip);
#else
  if (!ether.dhcpSetup()) 
     Serial.println("DHCP failed");
#endif
  ether.printIp("IP:  ", ether.myip);
}


 static word homePage() {

  long T1=int(t1); long T1A=t1*10-10*T1; // fractional part
  long t = millis() / 1000;

bfill = ether.tcpOffset();
    Serial.print("CM = ");  
  Serial.println(CM);
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n<meta http-equiv='refresh' content='1'/>"
    "<body><html><u>Arduino Ethernet ENC28J60 webserver #3</u><BR><B>Uptime $L (Seconds)<BR><B>Sensor Data $L (cm)"),
      t,CM);
  return bfill.position();
}



void loop () {
 
  if (millis()%100>70){if (digitalRead(button)==LOW) {if (state==0) {clicks=clicks+1; state=1;}} 
    delay(50); if (digitalRead(button)==HIGH){if (state==1) {state=0;}}}

  
//    Serial.print ("t1= ");  Serial.println (t1);}    // t2 = sensors.getTempCByIndex(1); 

AIN=analogRead(A0); AIN=AIN*100/1023;   analogWrite(9, AIN);           

  word len = ether.packetReceive();  word pos = ether.packetLoop(len);
    if (pos) ether.httpServerReply(homePage()); // if valid tcp data received send web page



DateTime now = rtc.now();
digitalWrite(7, LOW);
delayMicroseconds(2);
digitalWrite(7,HIGH);
delayMicroseconds(10);
digitalWrite(7,LOW);

duration=pulseIn(8, HIGH);
 // convert the time into a distance
cm = (duration / 2.0) / 27.9;
mm = (duration / 2.0) / 2.79;

CM = (64.3 - cm); // Substract the total distance in cm by the distance the sensor is measuring
MM = (643 - mm);
delay(10);
{
  /* This poortion of code writes the distance measured by the sensor on one line
   *  followed by the distance after substraction of total distance
   *  followed by the date and time the data was calculated
   */
    Serial.print(CM);
      Serial.print(",cm,");
      Serial.print(MM);
      Serial.print(",mm,");
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
 
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
  
    Serial.println();
    delay(100);

}
}

What if you change $L to $F ?

changing #L to $F caused the reading to be random characters on the webserver such as : "¡±ÒÏ’’¶’"

OK.. maybe it doesn't support floats.

Try to convert to a string and pass that (as $S).

char text[10];
dtostrf(CM, 6, 2, text);
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n<meta http-equiv='refresh' content='1'/>"
    "<body><html><u>Arduino Ethernet ENC28J60 webserver #3</u><BR><B>Uptime $L (Seconds)<BR><B>Sensor Data $S (cm)"),
      t,text);

That did it. Thank you for your help

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.