Pages: [1]   Go Down
Author Topic: creating multiple text boxes on a arduino web page  (Read 1504 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My first (I'm new to arduino and to C/C++ and while I'm at it HTML) big project is an arduino thermostat with a simple web page hosted by the arduino. I started with a basic web page that displayed the current temperature, target temperature, temperature at which the heat turns on and off and if the arduino was controlling the temperature or not. Just simple no frills text. Through an example that was posted on this forum I was able to figure out how to set the target temperature through the web page using a text input box. Now I would like to add a second (and maybe even more) text input box to the web page. Problem is I just don't understand how the code works for the one box I have now which is makes it difficult to add another one. If someone can explain how the code works and maybe how to add another box it would be appriciated. I'm not looking for someone to do the code for me, or else how would I learn, but if someone does, please explain to me what you did.

Here is my entire code.
Code:
#include <SPI.h>
#include <Ethernet.h>
#define maxLength 25

byte mac[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
byte ip[] = { 192, 168, 1, 102 };

EthernetServer server(80);

char TargetTemp[4];
int val;
String inString = String(maxLength);

// Define I/O pins
const int TempSensor = A4;        // pin that the temp sensor is attached to
const int HeatONMain = 8;         // pin that activates heat on relay
const int HeatONFailSafe = 9;     // pin that activates heat on relay 2

// Other constant stuff
const int RelayON = LOW;
const int RelayOFF = HIGH;

char* HeatStatusStg[]={"OFF", "ON"};
char* CntrlStatusStg[]={"NO", "YES"};

// Define the number of readings to take.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// us use this value to determine the size of the readings array.
const int numReadings = 15;

int TempReadings[numReadings];      // the readings from the analog input
int TempIndex = 0;                  // the index of the current reading
int TempTotal = 0;                  // the running total

int RoomTemperature = 0;          // result after converting analog value to degf
int AvgTemperature = 0;           // averaged current room temperature
int TempSetpoint = 70;           // room temperature setpoint as set from the web page
int RoomTemperatureSPmin = 69;   // room temperature minimum setpoint (SP - temperature deadband)
int RoomTemperatureSPmax = 71;   // room temperature maximum setpoint (SP + temperature deadband)
int TemperatureDB = 1;   // deadband

int HeatStatus = 0;
int CntrlStatus = 0;

long HeatCntrlDelayTime = 120000;  // wait for 2 minutes after bootup before trying to control temp

//==================================================================================================================
void setup()
//==================================================================================================================
{
  // Initialize pins so relays are inactive at startup/reset
  digitalWrite(HeatONMain, RelayOFF);
  digitalWrite(HeatONFailSafe, RelayOFF);
  // Set pins that are wired to relay board as outputs
  pinMode(HeatONMain, OUTPUT);
  pinMode(HeatONFailSafe, OUTPUT);
  delay (2000);
  // start the serial connection
  Serial.begin(9600);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
}
//==================================================================================================================
void loop()
//==================================================================================================================
{
  // Convert analog reading from temperature sensor to degrees fahrenheit:
  RoomTemperature = ((5.0 * analogRead(TempSensor) * 100.0)/1024.0);      //convert the analog data to temperature
  // subtract the last reading:
  TempTotal= TempTotal - A0Readings[TempIndex];         
  // read from the sensor: 
  TempReadings[TempIndex] = RoomTemperature;
  // add the reading to the total:
  TempTotal= TempTotal + TempReadings[TempIndex];       
  // advance to the next position in the array: 
  TempIndex = TempIndex + 1;                   

  // if we're at the end of the array...
  if (TempIndex >= numReadings) {             
    // ...wrap around to the beginning:
    TempIndex = 0; 
    }                         

  // calculate the average:
  AvgTemperature = TempTotal / numReadings;   

  // set the min and temperature setpoint relative to the temperature entered in through the web page
  RoomTemperatureSPmin = (TempSetpoint - TemperatureDB);
  RoomTemperatureSPmax = (TempSetpoint + TemperatureDB);

  if (millis() < HeatCntrlDelayTime) {
    CntrlStatus = 0;
    digitalWrite(HeatONMain, LOW);
    digitalWrite(HeatONFailSafe, LOW);
    HeatStatus = 0;
  }

  if (millis() > HeatCntrlDelayTime) {
    CntrlStatus = 1;
    // monitor Room Temperature and turn on heat when temperature drops below setpoint
    if ((AvgTemperature) < (RoomTemperatureSPmin)) {
      digitalWrite(HeatONMain, HIGH);
      digitalWrite(HeatONFailSafe, HIGH);
      HeatStatus = 1;}
    if ((AvgTemperature) > (RoomTemperatureSPmax)) {
      digitalWrite(HeatONMain, LOW);
      digitalWrite(HeatONFailSafe, LOW);
      HeatStatus = 0;}
  }

  int bufLength;
  EthernetClient client = server.available();
  if (client) {
    boolean current_line_is_blank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (inString.length() < maxLength) {
          inString += c;
        }       
        if (c == '\n' && current_line_is_blank) {
          if (inString.indexOf("?") > -1) {
            int Pos_L = inString.indexOf("L");
            int End = inString.indexOf("H", Pos_L);
            if(End < 0){
              End =  inString.length() + 1;
            }
            bufLength = ((Pos_L) - (Pos_L+2));
            if(bufLength > 4){  //dont overflow the buffer
              bufLength = 4;
            }   
            inString.substring((Pos_L+2), (End-1)).toCharArray(TargetTemp, bufLength);  //transfer substring to buffer
            val = atoi(TargetTemp);
            Serial.print("TargetTemp = ");
            Serial.println( val );
            TempSetpoint = val;
          }
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<html><head></head><body>");
          client.println("<h1>WEB ENABLED ARDUINO THERMOSTAT</h1>");
          client.println("<br />");
  client.println("<hr />");
          // add a meta refresh tag, so the browser pulls again every 20 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"20\">");
          client.print("Room Temperature:");
          client.print(" ");
          client.print(AvgTemperature);
          client.print(" ");
          client.print("DEGF");
          client.println();  // send a cr/lf
          client.println("<br />");   
          client.print("Heat turns on below:");
          client.print(" ");
          client.print(RoomTemperatureSPmin);
          client.print(" ");
          client.print("DEGF");
          client.println();  // send a cr/lf
          client.println("<br />");       
          client.print("Heat turns off above:");
          client.print(" ");
          client.print(RoomTemperatureSPmax);
          client.print(" ");
          client.print("DEGF");
          client.println();  // send a cr/lf
          client.println("<br />");       
          client.print("Temperature is being controlled?");
          client.print(" ");
          client.print(CntrlStatusStg[CntrlStatus]);
          client.println();  // send a cr/lf
          client.println("<br />");       
          client.print("Heat is:");
          client.print(" ");
          client.print(HeatStatusStg[HeatStatus]);
          client.println();  // send a cr/lf
          client.println("<Hr />");
          client.print("<form method=get>CHANGE TEMPERATURE SETPOINT:<input type=text size=3 name=L value=");
          client.print(val);
          client.print(">&nbsp;<input name=H type=submit value=submit></form>");
          client.println("<Hr />");
          client.println("</body></html>");
          break;
        }
        if (c == '\n') {
          current_line_is_blank = true;
        }
        else if (c != '\r') {
          current_line_is_blank = false;
        }
      }
    }
    delay(1);
    inString = "";
    client.stop();
  }
}



Moderator edit: [code] [/code] tags added.
« Last Edit: November 07, 2012, 08:33:26 pm by Coding Badly » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Forgot to list hardware

- Uno
- Wiznet 5100 ethernet shield
Logged

0
Offline Offline
Edison Member
*
Karma: 7
Posts: 1235
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

wrapping your code in CODE tags will help you get better responses.. smiley
Logged


UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12579
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There are three parts to the problem.

Firstly, your sketch supplies an HTML page which includes a form. Look at the page source in your web browser to understand what is in this page. Currently it has one input field named "L". You will want to extend this form so that it has an extra field with some other name.

Secondly, when your browser submits the form it sends an HTTP request to the Arduino which includes the values that were in the form. Your sketch has some logic to extract these values from the HTTP request:
Code:
if (inString.indexOf("?") > -1) {
            int Pos_L = inString.indexOf("L");
            int End = inString.indexOf("H", Pos_L);
            if(End < 0){
              End =  inString.length() + 1;
            }
            bufLength = ((Pos_L) - (Pos_L+2));
            if(bufLength > 4){  //dont overflow the buffer
              bufLength = 4;
            }   
            inString.substring((Pos_L+2), (End-1)).toCharArray(TargetTemp, bufLength);  //transfer substring to buffer
            val = atoi(TargetTemp);
            Serial.print("TargetTemp = ");
            Serial.println( val );
            TempSetpoint = val;
          }

Some of that looks a bit dodgy (I'm not sure what "((Pos_L) - (Pos_L+2))" is supposed to give you) but you will need to modify this code to parse two field values from the incoming request instead of just one. I suggest that the easiest way to understand what this is doing is to print out the whole input line when you reach this bit of code. You will see that the code looks for the position in the string where it expects to find the field value, extracts that value from the string and parses it to get a number. You would need to add similar code for the second field.

Once you've got the values from the form you need to save/apply them somehow within your sketch.

The third part is that you might want to have the current values displayed in the form rather than leave those fields blank. In that case you would need to change the code that prints out the HTML source for the form to include the value within the HTML.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Tasmania - Australia
Offline Offline
Sr. Member
****
Karma: 14
Posts: 307
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
If you think your project may grow in terms of wanting to capture real world sensor data, doing statistical munching and then producing nice web pages, can I suggest you take a look at this thread here http://arduino.cc/forum/index.php/topic,129122.0.html.

It demonstrates what I think is a better way of doing this task.

Firstly, your web page is more coded up to relieve the Arduino from having to continuously send complete web pages when you only want to have updated data values.
This is done by useing a RESTful web service, where your web page request small packets of data from the Arduino, typically 'jason' formatted.

You can elect to serve up a web page from either a dedicated web server or from your Arduino.
To get a little more fancy, you'll be wanting to serve up some styled HTML, so there will be CCS files, maybe some js (javascript) files, such as libraries or specific to your project.

Also, think about modularising your code.
For example having all your real world sensing in a routine of its own, the web stuff also in a routine of its own.
Then use the main loop to go through the routines you need at specific timings.

Also, look into smoothing your analogues with something like a moving average filter.
I use an array that gets a new value every 100mSec and the oldest in the array kicked out and then re-average the array.
It makes a difference, firstly for accuracy with presenting present values data or stats. Also especially if you are wanting to do things like produce alarm trip point settings.

You'll be amazed what you can do using this concept I am mentioning, I am playing around with nice analogue meters on my web page and also historical trends displays from the SD card.
The bonus is, you'll learn a lot more about all these programing models and be able to create a truly effective, efficient and eye catching application.

Paul
Logged


0
Offline Offline
Tesla Member
***
Karma: 141
Posts: 9470
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A google search like below should provide info and examples of html forms.

https://www.google.com/search?hl=en&as_q=form+html+tutorial&as_epq=&as_oq=&as_eq=&as_nlo=&as_nhi=&lr=&cr=&as_qdr=all&as_sitesearch=&as_occt=any&safe=images&tbs=&as_filetype=&as_rights=
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the replies and suggestions!

I renamed some variables and tried adding the second text box (nightenter, nightsubmit). Now when I enter in a value for either text box and hit enter the website times out.

Code was too long so I had to attach it.

* Arduino_web_thermostat_night_heat.ino (11.61 KB - downloaded 29 times.)
Logged

Pages: [1]   Go Up
Jump to: